From 54b83c55e99aab240181634a7cbd359aa4664099 Mon Sep 17 00:00:00 2001 From: wenshao Date: Tue, 13 Nov 2012 14:43:09 +0800 Subject: [PATCH] improve SQL Visitor --- .../druid/pool/DruidAbstractDataSource.java | 30 +- .../sql/dialect/mysql/parser/MySqlLexer.java | 61 ++-- .../mysql/visitor/MySqlOutputVisitor.java | 10 +- .../oracle/parser/OracleSelectParser.java | 12 + .../dialect/postgresql/parser/PGLexer.java | 5 +- .../com/alibaba/druid/sql/parser/Lexer.java | 17 +- .../druid/sql/parser/SQLSelectParser.java | 4 + .../sql/visitor/SQLASTOutputVisitor.java | 18 +- .../sql/visitor/SQLEvalVisitorUtils.java | 335 +++++++++++++++++- .../com/alibaba/druid/util/JdbcConstants.java | 15 + 10 files changed, 455 insertions(+), 52 deletions(-) diff --git a/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java index d1523683f8..83fa7cfbfc 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java @@ -228,6 +228,8 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements protected AtomicLong createCount = new AtomicLong(); protected AtomicLong destroyCount = new AtomicLong(); + private Boolean useUnfairLock = null; + public DruidAbstractDataSource(boolean lockFair){ lock = new ReentrantLock(lockFair); @@ -246,6 +248,32 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements this.isOracle = isOracle; } + public boolean isUseUnfairLock() { + return lock.isFair(); + } + + public void setUseUnfairLock(boolean useUnfairLock) { + if (lock.isFair() == !useUnfairLock) { + return; + } + + if (!this.inited) { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + if (!this.inited) { + this.lock = new ReentrantLock(!useUnfairLock); + this.notEmpty = this.lock.newCondition(); + this.empty = this.lock.newCondition(); + + this.useUnfairLock = useUnfairLock; + } + } finally { + lock.unlock(); + } + } + } + public boolean isUseOracleImplicitCache() { return useOracleImplicitCache; } @@ -794,7 +822,7 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements return; } - if (maxWaitMillis > 0 && !this.inited) { + if (maxWaitMillis > 0 && useUnfairLock == null && !this.inited) { final ReentrantLock lock = this.lock; lock.lock(); try { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java index a2dbf44073..0938a7d2eb 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlLexer.java @@ -20,6 +20,7 @@ import static com.alibaba.druid.sql.parser.CharTypes.isIdentifierChar; import static com.alibaba.druid.sql.parser.LayoutCharacters.EOI; import static com.alibaba.druid.sql.parser.Token.LITERAL_CHARS; +import java.util.Arrays; import java.util.HashMap; import java.util.Map; @@ -35,9 +36,9 @@ public class MySqlLexer extends Lexer { static { Map map = new HashMap(); - + map.putAll(Keywords.DEFAULT_KEYWORDS.getKeywords()); - + map.put("DUAL", Token.DUAL); map.put("FALSE", Token.FALSE); map.put("IDENTIFIED", Token.IDENTIFIED); @@ -46,7 +47,7 @@ public class MySqlLexer extends Lexer { map.put("LIMIT", Token.LIMIT); map.put("TRUE", Token.TRUE); - + DEFAULT_MYSQL_KEYWORDS = new Keywords(map); } @@ -97,28 +98,28 @@ public class MySqlLexer extends Lexer { stringVal = subString(mark, bufPos); token = Token.VARIANT; } else if (charAt(pos + 1) == '{') { - ++pos; - ++bufPos; - char ch; - for (;;) { - ch = charAt(++pos); - - if (ch == '}') { - bufPos++; - ch = charAt(++pos); - break; - } else if (ch == EOI) { - throw new SQLParseException("illegal identifier"); - } - + ++pos; + ++bufPos; + char ch; + for (;;) { + ch = charAt(++pos); + + if (ch == '}') { bufPos++; - continue; + ch = charAt(++pos); + break; + } else if (ch == EOI) { + throw new SQLParseException("illegal identifier"); } - - this.ch = charAt(pos); - - stringVal = subString(mark, bufPos); - token = Token.VARIANT; + + bufPos++; + continue; + } + + this.ch = charAt(pos); + + stringVal = subString(mark, bufPos); + token = Token.VARIANT; } else { for (;;) { ch = charAt(++pos); @@ -222,9 +223,7 @@ public class MySqlLexer extends Lexer { if (ch == '\\') { scanChar(); if (!hasSpecial) { - if (buf == null) { - buf = new char[32]; - } + initBuff(bufPos); arraycopy(mark + 1, buf, 0, bufPos); hasSpecial = true; } @@ -270,9 +269,7 @@ public class MySqlLexer extends Lexer { token = LITERAL_CHARS; break; } else { - if (buf == null) { - buf = new char[32]; - } + initBuff(bufPos); arraycopy(mark + 1, buf, 0, bufPos); hasSpecial = true; putChar('\''); @@ -298,7 +295,7 @@ public class MySqlLexer extends Lexer { stringVal = new String(buf, 0, bufPos); } } - + public void scanComment() { if (ch != '/' && ch != '-') { throw new IllegalStateException(); @@ -345,14 +342,14 @@ public class MySqlLexer extends Lexer { stringVal = subString(mark, bufPos); token = Token.MULTI_LINE_COMMENT; } - + if (token != Token.HINT && !isAllowComment()) { throw new NotAllowCommentException(); } return; } - + if (!isAllowComment()) { throw new NotAllowCommentException(); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java index 955bdb1ac6..20821add4f 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java @@ -488,7 +488,15 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV } public boolean visit(SQLCharExpr x) { - print(x.toString()); + print('\''); + + String text = x.getText(); + text = text.replaceAll("'", "''"); + text = text.replaceAll("\\\\", "\\\\"); + + print(text); + + print('\''); return false; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java index c75a4eabcc..b02fba05bd 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java @@ -643,6 +643,12 @@ public class OracleSelectParser extends SQLSelectParser { if (identifierEquals("NOCYCLE")) { hierachical.setNoCycle(true); + lexer.nextToken(); + + if (lexer.token() == Token.PRIOR) { + lexer.nextToken(); + hierachical.setPrior(true); + } } hierachical.setConnectBy(this.exprParser.expr()); } @@ -672,6 +678,12 @@ public class OracleSelectParser extends SQLSelectParser { if (identifierEquals("NOCYCLE")) { hierachical.setNoCycle(true); + lexer.nextToken(); + + if (lexer.token() == Token.PRIOR) { + lexer.nextToken(); + hierachical.setPrior(true); + } } hierachical.setConnectBy(this.exprParser.expr()); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGLexer.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGLexer.java index a1d8818b60..590caa6016 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGLexer.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/parser/PGLexer.java @@ -84,9 +84,7 @@ public class PGLexer extends Lexer { if (ch == '\\') { scanChar(); if (!hasSpecial) { - if (buf == null) { - buf = new char[32]; - } + initBuff(bufPos); arraycopy(mark + 1, buf, 0, bufPos); hasSpecial = true; } @@ -132,6 +130,7 @@ public class PGLexer extends Lexer { token = LITERAL_CHARS; break; } else { + initBuff(bufPos); arraycopy(mark + 1, buf, 0, bufPos); hasSpecial = true; putChar('\''); diff --git a/src/main/java/com/alibaba/druid/sql/parser/Lexer.java b/src/main/java/com/alibaba/druid/sql/parser/Lexer.java index 11ccfc2ce0..965aeb2c72 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Lexer.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Lexer.java @@ -34,6 +34,7 @@ import static com.alibaba.druid.sql.parser.Token.RPAREN; import java.math.BigDecimal; import java.math.BigInteger; +import java.util.Arrays; /** * @author wenshao @@ -85,6 +86,18 @@ public class Lexer { public final String subString(int offset, int count) { return text.substring(offset, offset + count); } + + protected void initBuff(int size) { + if (buf == null) { + if (size < 32) { + buf = new char[32]; + } else { + buf = new char[size + 32]; + } + } else if(buf.length < size) { + buf = Arrays.copyOf(buf, size); + } + } public void arraycopy(int srcPos, char[] dest, int destPos, int length) { text.getChars(srcPos, srcPos + length, dest, destPos); @@ -494,9 +507,7 @@ public class Lexer { break; } else { if (!hasSpecial) { - if (buf == null) { - buf = new char[32]; - } + initBuff(bufPos); arraycopy(mark + 1, buf, 0, bufPos); hasSpecial = true; } diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java index f758edd7c2..9bb086c199 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java @@ -306,6 +306,10 @@ public class SQLSelectParser extends SQLParser { } else if (identifierEquals("STRAIGHT_JOIN")) { lexer.nextToken(); joinType = SQLJoinTableSource.JoinType.STRAIGHT_JOIN; + } else if (identifierEquals("CROSS")) { + lexer.nextToken(); + accept(Token.JOIN); + joinType = SQLJoinTableSource.JoinType.CROSS_JOIN; } if (joinType != null) { diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java index 658f336a38..38ce1f2b70 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -97,8 +97,9 @@ import com.alibaba.druid.sql.ast.statement.SQLUseStatement; public class SQLASTOutputVisitor extends SQLASTVisitorAdapter { protected final Appendable appender; - private String indent = "\t"; - private int indentCount = 0; + private String indent = "\t"; + private int indentCount = 0; + private boolean prettyFormat = true; public SQLASTOutputVisitor(Appendable appender){ this.appender = appender; @@ -112,6 +113,14 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter { return appender; } + public boolean isPrettyFormat() { + return prettyFormat; + } + + public void setPrettyFormat(boolean prettyFormat) { + this.prettyFormat = prettyFormat; + } + public void decrementIndent() { this.indentCount -= 1; } @@ -193,6 +202,11 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter { } public void println() { + if (!isPrettyFormat()) { + print(' '); + return; + } + print("\n"); printIndent(); } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitorUtils.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitorUtils.java index 5ce07dfc33..4b08cbf15a 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitorUtils.java @@ -309,6 +309,316 @@ public class SQLEvalVisitorUtils { String result = strValue.toLowerCase(); x.putAttribute(EVAL_VALUE, result); + + } else if ("mod".equalsIgnoreCase(x.getMethodName())) { + if (x.getParameters().size() != 2) { + return false; + } + + SQLExpr param0 = x.getParameters().get(0); + SQLExpr param1 = x.getParameters().get(1); + param0.accept(visitor); + param1.accept(visitor); + + Object param0Value = param0.getAttributes().get(EVAL_VALUE); + Object param1Value = param1.getAttributes().get(EVAL_VALUE); + if (param0Value == null || param1Value == null) { + return false; + } + + int intValue0 = _int(param0Value); + int intValue1 = _int(param1Value); + + int result = intValue0 % intValue1; + + x.putAttribute(EVAL_VALUE, result); + } else if ("abs".equalsIgnoreCase(x.getMethodName())) { + if (x.getParameters().size() != 1) { + return false; + } + + SQLExpr param0 = x.getParameters().get(0); + param0.accept(visitor); + + Object paramValue = param0.getAttributes().get(EVAL_VALUE); + if (paramValue == null) { + return false; + } + + Object result; + if (paramValue instanceof Integer) { + result = Math.abs(((Integer) paramValue).intValue()); + } else if (paramValue instanceof Long) { + result = Math.abs(((Long) paramValue).longValue()); + } else { + result = _decimal(paramValue).abs(); + } + + x.putAttribute(EVAL_VALUE, result); + } else if ("acos".equalsIgnoreCase(x.getMethodName())) { + if (x.getParameters().size() != 1) { + return false; + } + + SQLExpr param0 = x.getParameters().get(0); + param0.accept(visitor); + + Object paramValue = param0.getAttributes().get(EVAL_VALUE); + if (paramValue == null) { + return false; + } + + double doubleValue = _double(paramValue); + double result = Math.acos(doubleValue); + + if (Double.isNaN(result)) { + x.putAttribute(EVAL_VALUE, null); + } else { + x.putAttribute(EVAL_VALUE, result); + } + } else if ("asin".equalsIgnoreCase(x.getMethodName())) { + if (x.getParameters().size() != 1) { + return false; + } + + SQLExpr param0 = x.getParameters().get(0); + param0.accept(visitor); + + Object paramValue = param0.getAttributes().get(EVAL_VALUE); + if (paramValue == null) { + return false; + } + + double doubleValue = _double(paramValue); + double result = Math.asin(doubleValue); + + if (Double.isNaN(result)) { + x.putAttribute(EVAL_VALUE, null); + } else { + x.putAttribute(EVAL_VALUE, result); + } + } else if ("atan".equalsIgnoreCase(x.getMethodName())) { + if (x.getParameters().size() != 1) { + return false; + } + + SQLExpr param0 = x.getParameters().get(0); + param0.accept(visitor); + + Object paramValue = param0.getAttributes().get(EVAL_VALUE); + if (paramValue == null) { + return false; + } + + double doubleValue = _double(paramValue); + double result = Math.atan(doubleValue); + + if (Double.isNaN(result)) { + x.putAttribute(EVAL_VALUE, null); + } else { + x.putAttribute(EVAL_VALUE, result); + } + } else if ("atan2".equalsIgnoreCase(x.getMethodName())) { + if (x.getParameters().size() != 2) { + return false; + } + + SQLExpr param0 = x.getParameters().get(0); + SQLExpr param1 = x.getParameters().get(1); + param0.accept(visitor); + param1.accept(visitor); + + Object param0Value = param0.getAttributes().get(EVAL_VALUE); + Object param1Value = param1.getAttributes().get(EVAL_VALUE); + if (param0Value == null || param1Value == null) { + return false; + } + + double doubleValue0 = _double(param0Value); + double doubleValue1 = _double(param1Value); + double result = Math.atan2(doubleValue0, doubleValue1); + + if (Double.isNaN(result)) { + x.putAttribute(EVAL_VALUE, null); + } else { + x.putAttribute(EVAL_VALUE, result); + } + } else if ("ceil".equalsIgnoreCase(x.getMethodName()) || "ceiling".equalsIgnoreCase(x.getMethodName())) { + if (x.getParameters().size() != 1) { + return false; + } + + SQLExpr param0 = x.getParameters().get(0); + param0.accept(visitor); + + Object paramValue = param0.getAttributes().get(EVAL_VALUE); + if (paramValue == null) { + return false; + } + + double doubleValue = _double(paramValue); + int result = (int) Math.ceil(doubleValue); + + if (Double.isNaN(result)) { + x.putAttribute(EVAL_VALUE, null); + } else { + x.putAttribute(EVAL_VALUE, result); + } + } else if ("cos".equalsIgnoreCase(x.getMethodName())) { + if (x.getParameters().size() != 1) { + return false; + } + + SQLExpr param0 = x.getParameters().get(0); + param0.accept(visitor); + + Object paramValue = param0.getAttributes().get(EVAL_VALUE); + if (paramValue == null) { + return false; + } + + double doubleValue = _double(paramValue); + int result = (int) Math.cos(doubleValue); + + if (Double.isNaN(result)) { + x.putAttribute(EVAL_VALUE, null); + } else { + x.putAttribute(EVAL_VALUE, result); + } + } else if ("sin".equalsIgnoreCase(x.getMethodName())) { + if (x.getParameters().size() != 1) { + return false; + } + + SQLExpr param0 = x.getParameters().get(0); + param0.accept(visitor); + + Object paramValue = param0.getAttributes().get(EVAL_VALUE); + if (paramValue == null) { + return false; + } + + double doubleValue = _double(paramValue); + int result = (int) Math.sin(doubleValue); + + if (Double.isNaN(result)) { + x.putAttribute(EVAL_VALUE, null); + } else { + x.putAttribute(EVAL_VALUE, result); + } + } else if ("log".equalsIgnoreCase(x.getMethodName())) { + if (x.getParameters().size() != 1) { + return false; + } + + SQLExpr param0 = x.getParameters().get(0); + param0.accept(visitor); + + Object paramValue = param0.getAttributes().get(EVAL_VALUE); + if (paramValue == null) { + return false; + } + + double doubleValue = _double(paramValue); + int result = (int) Math.log(doubleValue); + + if (Double.isNaN(result)) { + x.putAttribute(EVAL_VALUE, null); + } else { + x.putAttribute(EVAL_VALUE, result); + } + } else if ("log10".equalsIgnoreCase(x.getMethodName())) { + if (x.getParameters().size() != 1) { + return false; + } + + SQLExpr param0 = x.getParameters().get(0); + param0.accept(visitor); + + Object paramValue = param0.getAttributes().get(EVAL_VALUE); + if (paramValue == null) { + return false; + } + + double doubleValue = _double(paramValue); + int result = (int) Math.log10(doubleValue); + + if (Double.isNaN(result)) { + x.putAttribute(EVAL_VALUE, null); + } else { + x.putAttribute(EVAL_VALUE, result); + } + } else if ("tan".equalsIgnoreCase(x.getMethodName())) { + if (x.getParameters().size() != 1) { + return false; + } + + SQLExpr param0 = x.getParameters().get(0); + param0.accept(visitor); + + Object paramValue = param0.getAttributes().get(EVAL_VALUE); + if (paramValue == null) { + return false; + } + + double doubleValue = _double(paramValue); + int result = (int) Math.tan(doubleValue); + + if (Double.isNaN(result)) { + x.putAttribute(EVAL_VALUE, null); + } else { + x.putAttribute(EVAL_VALUE, result); + } + } else if ("sqrt".equalsIgnoreCase(x.getMethodName())) { + if (x.getParameters().size() != 1) { + return false; + } + + SQLExpr param0 = x.getParameters().get(0); + param0.accept(visitor); + + Object paramValue = param0.getAttributes().get(EVAL_VALUE); + if (paramValue == null) { + return false; + } + + double doubleValue = _double(paramValue); + int result = (int) Math.sqrt(doubleValue); + + if (Double.isNaN(result)) { + x.putAttribute(EVAL_VALUE, null); + } else { + x.putAttribute(EVAL_VALUE, result); + } + } else if ("power".equalsIgnoreCase(x.getMethodName())) { + if (x.getParameters().size() != 2) { + return false; + } + + SQLExpr param0 = x.getParameters().get(0); + SQLExpr param1 = x.getParameters().get(1); + param0.accept(visitor); + param1.accept(visitor); + + Object param0Value = param0.getAttributes().get(EVAL_VALUE); + Object param1Value = param1.getAttributes().get(EVAL_VALUE); + if (param0Value == null || param1Value == null) { + return false; + } + + double doubleValue0 = _double(param0Value); + double doubleValue1 = _double(param1Value); + double result = Math.pow(doubleValue0, doubleValue1); + + if (Double.isNaN(result)) { + x.putAttribute(EVAL_VALUE, null); + } else { + x.putAttribute(EVAL_VALUE, result); + } + } else if ("pi".equalsIgnoreCase(x.getMethodName())) { + x.putAttribute(EVAL_VALUE, Math.PI); + } else if ("rand".equalsIgnoreCase(x.getMethodName())) { + x.putAttribute(EVAL_VALUE, Math.random()); } return false; } @@ -361,14 +671,19 @@ public class SQLEvalVisitorUtils { } public static boolean visit(SQLEvalVisitor visitor, SQLCaseExpr x) { - x.getValueExpr().accept(visitor); + Object value; + if (x.getValueExpr() != null) { + x.getValueExpr().accept(visitor); - if (!x.getValueExpr().getAttributes().containsKey(EVAL_VALUE)) { - return false; + if (!x.getValueExpr().getAttributes().containsKey(EVAL_VALUE)) { + return false; + } + + value = x.getValueExpr().getAttribute(EVAL_VALUE); + } else { + value = null; } - Object value = x.getValueExpr().getAttribute(EVAL_VALUE); - for (SQLCaseExpr.Item item : x.getItems()) { item.getConditionExpr().accept(visitor); @@ -427,7 +742,7 @@ public class SQLEvalVisitorUtils { public static boolean visit(SQLEvalVisitor visitor, SQLQueryExpr x) { if (x.getSubQuery().getQuery() instanceof SQLSelectQueryBlock) { SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) x.getSubQuery().getQuery(); - + boolean nullFrom = false; if (queryBlock.getFrom() == null) { nullFrom = true; @@ -439,7 +754,7 @@ public class SQLEvalVisitorUtils { } } } - + if (nullFrom) { List row = new ArrayList(queryBlock.getSelectList().size()); for (int i = 0; i < queryBlock.getSelectList().size(); ++i) { @@ -450,16 +765,16 @@ public class SQLEvalVisitorUtils { } List> rows = new ArrayList>(1); rows.add(row); - + Object result = rows; queryBlock.putAttribute(EVAL_VALUE, result); x.getSubQuery().putAttribute(EVAL_VALUE, result); x.putAttribute(EVAL_VALUE, result); - + return false; } } - + return false; } diff --git a/src/main/java/com/alibaba/druid/util/JdbcConstants.java b/src/main/java/com/alibaba/druid/util/JdbcConstants.java index d7b2a59cbd..20f0c4c066 100644 --- a/src/main/java/com/alibaba/druid/util/JdbcConstants.java +++ b/src/main/java/com/alibaba/druid/util/JdbcConstants.java @@ -1,3 +1,18 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.alibaba.druid.util; public interface JdbcConstants {