mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
improved sql parser.
This commit is contained in:
@@ -284,7 +284,12 @@ public class SQLUtils {
|
||||
visitor.setTableMapping(tableMapping);
|
||||
}
|
||||
|
||||
boolean printStmtSeperator = !JdbcConstants.ORACLE.equals(dbType);
|
||||
boolean printStmtSeperator;
|
||||
if (JdbcConstants.SQL_SERVER.equals(dbType)) {
|
||||
printStmtSeperator = false;
|
||||
} else {
|
||||
printStmtSeperator = !JdbcConstants.ORACLE.equals(dbType);
|
||||
}
|
||||
|
||||
for (int i = 0, size = statementList.size(); i < size; i++) {
|
||||
SQLStatement stmt = statementList.get(i);
|
||||
|
||||
@@ -168,6 +168,10 @@ public abstract class SQLObjectImpl implements SQLObject {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void addAfterComment(List<String> comments) {
|
||||
if (comments == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (attributes == null) {
|
||||
attributes = new HashMap<String, Object>(1);
|
||||
}
|
||||
|
||||
+6
-4
@@ -13,17 +13,19 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.oracle.ast.stmt;
|
||||
package com.alibaba.druid.sql.ast.statement;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLStatementImpl;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class OraclePLSQLCommitStatement extends OracleStatementImpl {
|
||||
public class SQLScriptCommitStatement extends SQLStatementImpl {
|
||||
|
||||
public OraclePLSQLCommitStatement(){
|
||||
public SQLScriptCommitStatement(){
|
||||
|
||||
}
|
||||
|
||||
public void accept0(OracleASTVisitor visitor) {
|
||||
public void accept0(SQLASTVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
@@ -144,18 +144,13 @@ public class MySqlLexer extends Lexer {
|
||||
}
|
||||
|
||||
public void scanVariable() {
|
||||
if (ch != '@' && ch != ':' && ch != '#' && ch != '$') {
|
||||
if (ch != ':' && ch != '#' && ch != '$') {
|
||||
throw new ParserException("illegal variable. " + info());
|
||||
}
|
||||
|
||||
mark = pos;
|
||||
bufPos = 1;
|
||||
|
||||
if (charAt(pos + 1) == '@') {
|
||||
ch = charAt(++pos);
|
||||
bufPos++;
|
||||
}
|
||||
|
||||
if (charAt(pos + 1) == '`') {
|
||||
++pos;
|
||||
++bufPos;
|
||||
@@ -221,6 +216,61 @@ public class MySqlLexer extends Lexer {
|
||||
token = Token.VARIANT;
|
||||
}
|
||||
|
||||
protected void scanVariable_at() {
|
||||
if (ch != '@') {
|
||||
throw new ParserException("illegal variable. " + info());
|
||||
}
|
||||
|
||||
mark = pos;
|
||||
bufPos = 1;
|
||||
|
||||
if (charAt(pos + 1) == '@') {
|
||||
ch = charAt(++pos);
|
||||
bufPos++;
|
||||
}
|
||||
|
||||
if (charAt(pos + 1) == '`') {
|
||||
++pos;
|
||||
++bufPos;
|
||||
char ch;
|
||||
for (;;) {
|
||||
ch = charAt(++pos);
|
||||
|
||||
if (ch == '`') {
|
||||
bufPos++;
|
||||
++pos;
|
||||
break;
|
||||
} else if (ch == EOI) {
|
||||
throw new ParserException("illegal identifier. " + info());
|
||||
}
|
||||
|
||||
bufPos++;
|
||||
continue;
|
||||
}
|
||||
|
||||
this.ch = charAt(pos);
|
||||
|
||||
stringVal = subString(mark, bufPos);
|
||||
token = Token.VARIANT;
|
||||
} else {
|
||||
for (; ; ) {
|
||||
ch = charAt(++pos);
|
||||
|
||||
if (!isIdentifierChar(ch)) {
|
||||
break;
|
||||
}
|
||||
|
||||
bufPos++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
this.ch = charAt(pos);
|
||||
|
||||
stringVal = subString(mark, bufPos);
|
||||
token = Token.VARIANT;
|
||||
}
|
||||
|
||||
public void scanIdentifier() {
|
||||
hash_lower = 0;
|
||||
hash = 0;
|
||||
@@ -342,6 +392,8 @@ public class MySqlLexer extends Lexer {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected final void scanString() {
|
||||
scanString2();
|
||||
}
|
||||
|
||||
+91
-56
@@ -17,15 +17,7 @@ package com.alibaba.druid.sql.dialect.mysql.parser;
|
||||
|
||||
import com.alibaba.druid.sql.ast.*;
|
||||
import com.alibaba.druid.sql.ast.SQLParameter.ParameterType;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLNCharExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLQueryExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.*;
|
||||
import com.alibaba.druid.sql.ast.statement.*;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement.ValuesClause;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.MysqlForeignKey;
|
||||
@@ -65,7 +57,6 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
private static final String GLOBAL = "GLOBAL";
|
||||
private static final String VARIABLES = "VARIABLES";
|
||||
private static final String STATUS = "STATUS";
|
||||
private static final String IGNORE = "IGNORE";
|
||||
private static final String RESET = "RESET";
|
||||
private static final String DESCRIBE = "DESCRIBE";
|
||||
private static final String WRITE = "WRITE";
|
||||
@@ -75,7 +66,6 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
private static final String TEMPORARY = "TEMPORARY";
|
||||
private static final String SPATIAL = "SPATIAL";
|
||||
private static final String FULLTEXT = "FULLTEXT";
|
||||
private static final String DELAYED = "DELAYED";
|
||||
private static final String LOW_PRIORITY = "LOW_PRIORITY";
|
||||
private static final String CONNECTION = "CONNECTION";
|
||||
private static final String EXTENDED = "EXTENDED";
|
||||
@@ -151,7 +141,7 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
this.getExprParser().parseHints(deleteStatement.getHints());
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals(LOW_PRIORITY)) {
|
||||
if (lexer.identifierEquals(FnvHash.Constants.LOW_PRIORITY)) {
|
||||
deleteStatement.setLowPriority(true);
|
||||
lexer.nextToken();
|
||||
}
|
||||
@@ -161,7 +151,7 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
lexer.nextToken();
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals(IGNORE)) {
|
||||
if (lexer.identifierEquals(FnvHash.Constants.IGNORE)) {
|
||||
deleteStatement.setIgnore(true);
|
||||
lexer.nextToken();
|
||||
}
|
||||
@@ -607,7 +597,7 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
}
|
||||
} else if (lexer.identifierEquals(WRITE)) {
|
||||
stmt.setLockType(LockType.WRITE);
|
||||
} else if (lexer.identifierEquals(LOW_PRIORITY)) {
|
||||
} else if (lexer.identifierEquals(FnvHash.Constants.LOW_PRIORITY)) {
|
||||
lexer.nextToken();
|
||||
acceptIdentifier(WRITE);
|
||||
stmt.setLockType(LockType.LOW_PRIORITY_WRITE);
|
||||
@@ -1792,12 +1782,12 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
lexer.nextToken();
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals(LOW_PRIORITY)) {
|
||||
if (lexer.identifierEquals(FnvHash.Constants.LOW_PRIORITY)) {
|
||||
stmt.setLowPriority(true);
|
||||
lexer.nextToken();
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals(DELAYED)) {
|
||||
if (lexer.identifierEquals(FnvHash.Constants.DELAYED)) {
|
||||
stmt.setDelayed(true);
|
||||
lexer.nextToken();
|
||||
}
|
||||
@@ -1879,7 +1869,7 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
|
||||
MySqlLoadXmlStatement stmt = new MySqlLoadXmlStatement();
|
||||
|
||||
if (lexer.identifierEquals(LOW_PRIORITY)) {
|
||||
if (lexer.identifierEquals(FnvHash.Constants.LOW_PRIORITY)) {
|
||||
stmt.setLowPriority(true);
|
||||
lexer.nextToken();
|
||||
}
|
||||
@@ -1904,7 +1894,7 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
lexer.nextToken();
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals(IGNORE)) {
|
||||
if (lexer.identifierEquals(FnvHash.Constants.IGNORE)) {
|
||||
stmt.setIgnore(true);
|
||||
lexer.nextToken();
|
||||
}
|
||||
@@ -1936,7 +1926,7 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
stmt.setRowsIdentifiedBy(rowsIdentifiedBy);
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals(IGNORE)) {
|
||||
if (lexer.identifierEquals(FnvHash.Constants.IGNORE)) {
|
||||
throw new ParserException("TODO. " + lexer.info());
|
||||
}
|
||||
|
||||
@@ -1953,7 +1943,7 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
|
||||
MySqlLoadDataInFileStatement stmt = new MySqlLoadDataInFileStatement();
|
||||
|
||||
if (lexer.identifierEquals(LOW_PRIORITY)) {
|
||||
if (lexer.identifierEquals(FnvHash.Constants.LOW_PRIORITY)) {
|
||||
stmt.setLowPriority(true);
|
||||
lexer.nextToken();
|
||||
}
|
||||
@@ -1978,7 +1968,7 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
lexer.nextToken();
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals(IGNORE)) {
|
||||
if (lexer.identifierEquals(FnvHash.Constants.IGNORE)) {
|
||||
stmt.setIgnore(true);
|
||||
lexer.nextToken();
|
||||
}
|
||||
@@ -2048,7 +2038,7 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
}
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals(IGNORE)) {
|
||||
if (lexer.identifierEquals(FnvHash.Constants.IGNORE)) {
|
||||
lexer.nextToken();
|
||||
stmt.setIgnoreLinesNumber(this.exprParser.expr());
|
||||
acceptIdentifier("LINES");
|
||||
@@ -2115,35 +2105,40 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
lexer.nextToken();
|
||||
|
||||
for (; ; ) {
|
||||
if (lexer.identifierEquals(LOW_PRIORITY)) {
|
||||
insertStatement.setLowPriority(true);
|
||||
lexer.nextToken();
|
||||
continue;
|
||||
if (lexer.token() == Token.IDENTIFIER) {
|
||||
long hash = lexer.hash_lower();
|
||||
|
||||
if (hash == FnvHash.Constants.LOW_PRIORITY) {
|
||||
insertStatement.setLowPriority(true);
|
||||
lexer.nextToken();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (hash == FnvHash.Constants.DELAYED) {
|
||||
insertStatement.setDelayed(true);
|
||||
lexer.nextToken();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (hash == FnvHash.Constants.HIGH_PRIORITY) {
|
||||
insertStatement.setHighPriority(true);
|
||||
lexer.nextToken();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (hash == FnvHash.Constants.IGNORE) {
|
||||
insertStatement.setIgnore(true);
|
||||
lexer.nextToken();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (hash == FnvHash.Constants.ROLLBACK_ON_FAIL) {
|
||||
insertStatement.setRollbackOnFail(true);
|
||||
lexer.nextToken();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals(DELAYED)) {
|
||||
insertStatement.setDelayed(true);
|
||||
lexer.nextToken();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals("HIGH_PRIORITY")) {
|
||||
insertStatement.setHighPriority(true);
|
||||
lexer.nextToken();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals(IGNORE)) {
|
||||
insertStatement.setIgnore(true);
|
||||
lexer.nextToken();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals("ROLLBACK_ON_FAIL")) {
|
||||
insertStatement.setRollbackOnFail(true);
|
||||
lexer.nextToken();
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -2155,7 +2150,8 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
SQLName tableName = this.exprParser.name();
|
||||
insertStatement.setTableName(tableName);
|
||||
|
||||
if (lexer.token() == Token.IDENTIFIER && !lexer.identifierEquals("VALUE")) {
|
||||
if (lexer.token() == Token.IDENTIFIER
|
||||
&& !lexer.identifierEquals(FnvHash.Constants.VALUE)) {
|
||||
insertStatement.setAlias(lexer.stringVal());
|
||||
lexer.nextToken();
|
||||
}
|
||||
@@ -2163,20 +2159,59 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
}
|
||||
|
||||
int columnSize = 0;
|
||||
if (lexer.token() == (Token.LPAREN)) {
|
||||
if (lexer.token() == Token.LPAREN) {
|
||||
lexer.nextToken();
|
||||
if (lexer.token() == (Token.SELECT)) {
|
||||
if (lexer.token() == Token.SELECT) {
|
||||
SQLSelect select = this.exprParser.createSelectParser().select();
|
||||
select.setParent(insertStatement);
|
||||
insertStatement.setQuery(select);
|
||||
} else {
|
||||
this.exprParser.exprList(insertStatement.getColumns(), insertStatement);
|
||||
columnSize = insertStatement.getColumns().size();
|
||||
List<SQLExpr> columns = insertStatement.getColumns();
|
||||
//this.exprParser.exprList(insertStatement.getColumns(), insertStatement);
|
||||
|
||||
if (lexer.token() != Token.RPAREN) {
|
||||
for (; ; ) {
|
||||
String identName;
|
||||
long hash;
|
||||
|
||||
Token token = lexer.token();
|
||||
if (token == Token.IDENTIFIER) {
|
||||
identName = lexer.stringVal();
|
||||
hash = lexer.hash_lower();
|
||||
} else if (token == Token.LITERAL_CHARS) {
|
||||
identName = '\'' + lexer.stringVal() + '\'';
|
||||
hash = 0;
|
||||
} else {
|
||||
identName = lexer.stringVal();
|
||||
hash = 0;
|
||||
}
|
||||
lexer.nextTokenComma();
|
||||
SQLExpr expr = new SQLIdentifierExpr(identName, hash);
|
||||
while (lexer.token() == Token.DOT) {
|
||||
lexer.nextToken();
|
||||
String propertyName = lexer.stringVal();
|
||||
lexer.nextToken();
|
||||
expr = new SQLPropertyExpr(expr, propertyName);
|
||||
}
|
||||
|
||||
expr.setParent(insertStatement);
|
||||
columns.add(expr);
|
||||
columnSize++;
|
||||
|
||||
if (lexer.token() == Token.COMMA) {
|
||||
lexer.nextToken();
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
columnSize = insertStatement.getColumns().size();
|
||||
}
|
||||
}
|
||||
accept(Token.RPAREN);
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.VALUES || lexer.identifierEquals("VALUE")) {
|
||||
if (lexer.token() == Token.VALUES || lexer.identifierEquals(FnvHash.Constants.VALUE)) {
|
||||
lexer.nextTokenLParen();
|
||||
parseValueClause(insertStatement.getValuesList(), columnSize, insertStatement);
|
||||
} else if (lexer.token() == Token.SET) {
|
||||
@@ -2472,7 +2507,7 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
|
||||
boolean ignore = false;
|
||||
|
||||
if (lexer.identifierEquals(IGNORE)) {
|
||||
if (lexer.identifierEquals(FnvHash.Constants.IGNORE)) {
|
||||
ignore = true;
|
||||
lexer.nextToken();
|
||||
}
|
||||
|
||||
@@ -1072,7 +1072,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
|
||||
print0(ucase ? "INTO " : "into ");
|
||||
|
||||
printExpr(x.getTableName());
|
||||
printTableSourceExpr(x.getTableName());
|
||||
|
||||
List<SQLExpr> columns = x.getColumns();
|
||||
if (columns.size() > 0) {
|
||||
|
||||
+1
-9
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.mysql.visitor;
|
||||
|
||||
import com.alibaba.druid.sql.ast.statement.SQLScriptCommitStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalDay;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalYear;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.*;
|
||||
@@ -34,10 +35,6 @@ public class OracleToMySqlOutputVisitor extends MySqlOutputVisitor implements Or
|
||||
super(appender, parameterized);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OraclePLSQLCommitStatement astNode) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OracleAnalytic x) {
|
||||
@@ -109,11 +106,6 @@ public class OracleToMySqlOutputVisitor extends MySqlOutputVisitor implements Or
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OraclePLSQLCommitStatement astNode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleAnalytic x) {
|
||||
return false;
|
||||
|
||||
@@ -153,24 +153,6 @@ public class OdpsExprParser extends SQLExprParser {
|
||||
return super.primaryRest(expr);
|
||||
}
|
||||
|
||||
public SQLExpr equalityRest(SQLExpr expr) {
|
||||
if (lexer.token() == Token.EQEQ) {
|
||||
SQLExpr rightExp;
|
||||
lexer.nextToken();
|
||||
try {
|
||||
rightExp = bitOr();
|
||||
} catch (EOFParserException e) {
|
||||
throw new ParserException("EOF, " + expr + "=", e);
|
||||
}
|
||||
rightExp = equalityRest(rightExp);
|
||||
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Equality, rightExp, getDbType());
|
||||
|
||||
return expr;
|
||||
}
|
||||
|
||||
return super.equalityRest(expr);
|
||||
}
|
||||
|
||||
public SQLExpr relationalRest(SQLExpr expr) {
|
||||
if (lexer.identifierEquals("REGEXP")) {
|
||||
|
||||
@@ -362,6 +362,10 @@ public class OdpsLexer extends Lexer {
|
||||
super.scanVariable();
|
||||
}
|
||||
|
||||
protected void scanVariable_at() {
|
||||
scanVariable();
|
||||
}
|
||||
|
||||
protected final void scanString() {
|
||||
scanString2();
|
||||
}
|
||||
|
||||
@@ -998,43 +998,6 @@ public class OracleExprParser extends SQLExprParser {
|
||||
return name;
|
||||
}
|
||||
|
||||
public SQLExpr equalityRest(SQLExpr expr) {
|
||||
SQLExpr rightExp;
|
||||
if (lexer.token() == Token.EQ) {
|
||||
lexer.nextToken();
|
||||
|
||||
if (lexer.token() == Token.GT) {
|
||||
lexer.nextToken();
|
||||
rightExp = expr();
|
||||
String argumentName = ((SQLIdentifierExpr) expr).getName();
|
||||
return new OracleArgumentExpr(argumentName, rightExp);
|
||||
}
|
||||
|
||||
rightExp = shift();
|
||||
|
||||
rightExp = equalityRest(rightExp);
|
||||
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Equality, rightExp, getDbType());
|
||||
} else if (lexer.token() == Token.BANGEQ || lexer.token() == Token.CARETEQ) {
|
||||
lexer.nextToken();
|
||||
rightExp = shift();
|
||||
|
||||
rightExp = equalityRest(rightExp);
|
||||
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotEqual, rightExp, getDbType());
|
||||
} else if (lexer.token() == Token.BANG) {
|
||||
lexer.nextToken();
|
||||
accept(Token.EQ);
|
||||
rightExp = shift();
|
||||
|
||||
rightExp = equalityRest(rightExp);
|
||||
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotEqual, rightExp, getDbType());
|
||||
}
|
||||
|
||||
return expr;
|
||||
}
|
||||
|
||||
public OraclePrimaryKey parsePrimaryKey() {
|
||||
lexer.nextToken();
|
||||
accept(Token.KEY);
|
||||
@@ -1043,7 +1006,6 @@ public class OracleExprParser extends SQLExprParser {
|
||||
accept(Token.LPAREN);
|
||||
orderBy(primaryKey.getColumns(), primaryKey);
|
||||
accept(Token.RPAREN);
|
||||
|
||||
|
||||
if (lexer.token() == Token.USING) {
|
||||
OracleUsingIndexClause using = parseUsingIndex();
|
||||
|
||||
@@ -144,12 +144,6 @@ public class OracleLexer extends Lexer {
|
||||
}
|
||||
|
||||
public void scanVariable() {
|
||||
if (ch == '@') {
|
||||
scanChar();
|
||||
token = Token.MONKEYS_AT;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ch != ':' && ch != '#' && ch != '$') {
|
||||
throw new ParserException("illegal variable. " + info());
|
||||
}
|
||||
@@ -206,6 +200,12 @@ public class OracleLexer extends Lexer {
|
||||
}
|
||||
}
|
||||
|
||||
protected void scanVariable_at() {
|
||||
scanChar();
|
||||
token = Token.MONKEYS_AT;
|
||||
return;
|
||||
}
|
||||
|
||||
public void scanComment() {
|
||||
if (ch != '/' && ch != '-') {
|
||||
throw new IllegalStateException();
|
||||
|
||||
+1
-1
@@ -129,7 +129,7 @@ public class OracleStatementParser extends SQLStatementParser {
|
||||
if (lexer.token() == (Token.SLASH)) {
|
||||
lexer.nextToken();
|
||||
|
||||
SQLStatement stmt = new OraclePLSQLCommitStatement();
|
||||
SQLStatement stmt = new SQLScriptCommitStatement();
|
||||
stmt.setParent(parent);
|
||||
statementList.add(stmt);
|
||||
continue;
|
||||
|
||||
@@ -36,7 +36,7 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public interface OracleASTVisitor extends SQLASTVisitor {
|
||||
|
||||
void endVisit(OraclePLSQLCommitStatement astNode);
|
||||
|
||||
|
||||
void endVisit(OracleAnalytic x);
|
||||
|
||||
@@ -68,8 +68,6 @@ public interface OracleASTVisitor extends SQLASTVisitor {
|
||||
|
||||
void endVisit(OracleUpdateStatement x);
|
||||
|
||||
boolean visit(OraclePLSQLCommitStatement astNode);
|
||||
|
||||
boolean visit(OracleAnalytic x);
|
||||
|
||||
boolean visit(OracleAnalyticWindowing x);
|
||||
|
||||
+3
-2
@@ -17,6 +17,7 @@ package com.alibaba.druid.sql.dialect.oracle.visitor;
|
||||
|
||||
import com.alibaba.druid.sql.ast.statement.SQLMergeStatement.MergeInsertClause;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLMergeStatement.MergeUpdateClause;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLScriptCommitStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalDay;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalYear;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.CycleClause;
|
||||
@@ -49,7 +50,7 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitorAdapter;
|
||||
public class OracleASTVisitorAdapter extends SQLASTVisitorAdapter implements OracleASTVisitor {
|
||||
|
||||
@Override
|
||||
public void endVisit(OraclePLSQLCommitStatement astNode) {
|
||||
public void endVisit(SQLScriptCommitStatement astNode) {
|
||||
|
||||
}
|
||||
|
||||
@@ -124,7 +125,7 @@ public class OracleASTVisitorAdapter extends SQLASTVisitorAdapter implements Ora
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OraclePLSQLCommitStatement astNode) {
|
||||
public boolean visit(SQLScriptCommitStatement astNode) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -212,7 +212,7 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(OraclePLSQLCommitStatement astNode) {
|
||||
public boolean visit(SQLScriptCommitStatement astNode) {
|
||||
print('/');
|
||||
println();
|
||||
return false;
|
||||
@@ -624,11 +624,6 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OraclePLSQLCommitStatement astNode) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OracleAnalytic x) {
|
||||
|
||||
|
||||
+1
-7
@@ -17,7 +17,6 @@ package com.alibaba.druid.sql.dialect.oracle.visitor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
@@ -222,11 +221,6 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
|
||||
return super.visit(x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OraclePLSQLCommitStatement astNode) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OracleAnalytic x) {
|
||||
|
||||
@@ -288,7 +282,7 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OraclePLSQLCommitStatement astNode) {
|
||||
public boolean visit(SQLScriptCommitStatement astNode) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -15,15 +15,13 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.postgresql.parser;
|
||||
|
||||
import static com.alibaba.druid.sql.parser.CharTypes.isIdentifierChar;
|
||||
import static com.alibaba.druid.sql.parser.Token.LITERAL_CHARS;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.druid.sql.parser.Keywords;
|
||||
import com.alibaba.druid.sql.parser.Lexer;
|
||||
import com.alibaba.druid.sql.parser.SQLParserFeature;
|
||||
import com.alibaba.druid.sql.parser.Token;
|
||||
import com.alibaba.druid.sql.parser.*;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
|
||||
public class PGLexer extends Lexer {
|
||||
@@ -187,4 +185,43 @@ public class PGLexer extends Lexer {
|
||||
token = Token.POUND;
|
||||
}
|
||||
}
|
||||
|
||||
protected void scanVariable_at() {
|
||||
if (ch != '@') {
|
||||
throw new ParserException("illegal variable. " + info());
|
||||
}
|
||||
|
||||
mark = pos;
|
||||
bufPos = 1;
|
||||
char ch;
|
||||
|
||||
final char c1 = charAt(pos + 1);
|
||||
if (c1 == '@') {
|
||||
pos += 2;
|
||||
token = Token.MONKEYS_AT_AT;
|
||||
this.ch = charAt(++pos);
|
||||
return;
|
||||
} else if (c1 == '>') {
|
||||
pos += 2;
|
||||
token = Token.MONKEYS_AT_GT;
|
||||
this.ch = charAt(++pos);
|
||||
return;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
ch = charAt(++pos);
|
||||
|
||||
if (!isIdentifierChar(ch)) {
|
||||
break;
|
||||
}
|
||||
|
||||
bufPos++;
|
||||
continue;
|
||||
}
|
||||
|
||||
this.ch = charAt(pos);
|
||||
|
||||
stringVal = addSymbol();
|
||||
token = Token.VARIANT;
|
||||
}
|
||||
}
|
||||
|
||||
+13
-4
@@ -38,6 +38,7 @@ import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerSetTransactionI
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerUpdateStatement;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerWaitForStatement;
|
||||
import com.alibaba.druid.sql.parser.*;
|
||||
import com.alibaba.druid.util.FnvHash;
|
||||
|
||||
public class SQLServerStatementParser extends SQLStatementParser {
|
||||
|
||||
@@ -64,7 +65,7 @@ public class SQLServerStatementParser extends SQLStatementParser {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals("EXEC") || lexer.identifierEquals("EXECUTE")) {
|
||||
if (lexer.identifierEquals(FnvHash.Constants.EXEC) || lexer.identifierEquals(FnvHash.Constants.EXECUTE)) {
|
||||
lexer.nextToken();
|
||||
|
||||
SQLServerExecStatement execStmt = new SQLServerExecStatement();
|
||||
@@ -109,10 +110,18 @@ public class SQLServerStatementParser extends SQLStatementParser {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals("WAITFOR")) {
|
||||
if (lexer.identifierEquals(FnvHash.Constants.WAITFOR)) {
|
||||
statementList.add(this.parseWaitFor());
|
||||
return true;
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals(FnvHash.Constants.GO)) {
|
||||
lexer.nextToken();
|
||||
|
||||
SQLStatement stmt = new SQLScriptCommitStatement();
|
||||
statementList.add(stmt);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -442,7 +451,7 @@ public class SQLServerStatementParser extends SQLStatementParser {
|
||||
|
||||
stmt.setCondition(this.exprParser.expr());
|
||||
|
||||
this.parseStatementList(stmt.getStatements(), 1);
|
||||
this.parseStatementList(stmt.getStatements(), 1, stmt);
|
||||
|
||||
if(lexer.token() == Token.SEMI) {
|
||||
lexer.nextToken();
|
||||
@@ -452,7 +461,7 @@ public class SQLServerStatementParser extends SQLStatementParser {
|
||||
lexer.nextToken();
|
||||
|
||||
SQLIfStatement.Else elseItem = new SQLIfStatement.Else();
|
||||
this.parseStatementList(elseItem.getStatements(), 1);
|
||||
this.parseStatementList(elseItem.getStatements(), 1, elseItem);
|
||||
stmt.setElseItem(elseItem);
|
||||
}
|
||||
|
||||
|
||||
+6
@@ -573,4 +573,10 @@ public class SQLServerOutputVisitor extends SQLASTOutputVisitor implements SQLSe
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLScriptCommitStatement x) {
|
||||
print0(ucase ? "GO" : "go");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -325,6 +325,40 @@ public class Lexer {
|
||||
nextToken();
|
||||
}
|
||||
|
||||
public final void nextTokenEq() {
|
||||
if (ch == ' ') {
|
||||
scanChar();
|
||||
}
|
||||
|
||||
if (ch == '=') {
|
||||
scanChar();
|
||||
token = EQ;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ch == '.') {
|
||||
scanChar();
|
||||
token = DOT;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ch == 'a' || ch == 'A') {
|
||||
char ch_next = charAt(pos + 1);
|
||||
if (ch_next == 's' || ch_next == 'S') {
|
||||
char ch_next_2 = charAt(pos + 2);
|
||||
if (ch_next_2 == ' ') {
|
||||
pos += 2;
|
||||
ch = ' ';
|
||||
token = Token.AS;
|
||||
stringVal = "AS";
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nextToken();
|
||||
}
|
||||
|
||||
public final void nextTokenLParen() {
|
||||
if (ch == ' ') {
|
||||
scanChar();
|
||||
@@ -362,7 +396,30 @@ public class Lexer {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isFirstIdentifierChar(ch) && ch != 'N') {
|
||||
if (ch == 'n' || ch == 'N') {
|
||||
char c1 = 0, c2, c3, c4;
|
||||
if (pos + 4 < text.length()
|
||||
&& ((c1 = text.charAt(pos + 1)) == 'u' || c1 == 'U')
|
||||
&& ((c2 = text.charAt(pos + 2)) == 'l' || c2 == 'L')
|
||||
&& ((c3 = text.charAt(pos + 3)) == 'l' || c3 == 'L')
|
||||
&& (isWhitespace(c4 = text.charAt(pos + 4)) || c4 == ',' || c4 == ')')) {
|
||||
pos += 4;
|
||||
ch = c4;
|
||||
token = Token.NULL;
|
||||
stringVal = "NULL";
|
||||
return;
|
||||
}
|
||||
|
||||
if (c1 == '\'') {
|
||||
++pos;
|
||||
ch = '\'';
|
||||
scanString();
|
||||
token = Token.LITERAL_NCHARS;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (isFirstIdentifierChar(ch)) {
|
||||
scanIdentifier();
|
||||
return;
|
||||
}
|
||||
@@ -608,7 +665,7 @@ public class Lexer {
|
||||
case '`':
|
||||
throw new ParserException("TODO. " + info()); // TODO
|
||||
case '@':
|
||||
scanVariable();
|
||||
scanVariable_at();
|
||||
return;
|
||||
case '-':
|
||||
if (charAt(pos +1) == '-') {
|
||||
@@ -736,6 +793,9 @@ public class Lexer {
|
||||
if (ch == '=') {
|
||||
scanChar();
|
||||
token = Token.EQEQ;
|
||||
} else if (ch == '>') {
|
||||
scanChar();
|
||||
token = Token.EQGT;
|
||||
} else {
|
||||
token = Token.EQ;
|
||||
}
|
||||
@@ -781,6 +841,9 @@ public class Lexer {
|
||||
break;
|
||||
case '!':
|
||||
scanChar();
|
||||
while (isWhitespace(ch)) {
|
||||
scanChar();
|
||||
}
|
||||
if (ch == '=') {
|
||||
scanChar();
|
||||
token = Token.BANGEQ;
|
||||
@@ -1145,7 +1208,7 @@ public class Lexer {
|
||||
}
|
||||
|
||||
public void scanVariable() {
|
||||
if (ch != '@' && ch != ':' && ch != '#' && ch != '$') {
|
||||
if (ch != ':' && ch != '#' && ch != '$') {
|
||||
throw new ParserException("illegal variable. " + info());
|
||||
}
|
||||
|
||||
@@ -1154,17 +1217,7 @@ public class Lexer {
|
||||
char ch;
|
||||
|
||||
final char c1 = charAt(pos + 1);
|
||||
if (c1 == '@') {
|
||||
if (JdbcConstants.POSTGRESQL.equalsIgnoreCase(dbType)) {
|
||||
pos += 2;
|
||||
token = Token.MONKEYS_AT_AT;
|
||||
this.ch = charAt(++pos);
|
||||
return;
|
||||
}
|
||||
ch = charAt(++pos);
|
||||
|
||||
bufPos++;
|
||||
} else if (c1 == '>' && JdbcConstants.POSTGRESQL.equalsIgnoreCase(dbType)) {
|
||||
if (c1 == '>' && JdbcConstants.POSTGRESQL.equalsIgnoreCase(dbType)) {
|
||||
pos += 2;
|
||||
token = Token.MONKEYS_AT_GT;
|
||||
this.ch = charAt(++pos);
|
||||
@@ -1214,6 +1267,38 @@ public class Lexer {
|
||||
token = Token.VARIANT;
|
||||
}
|
||||
|
||||
protected void scanVariable_at() {
|
||||
if (ch != '@') {
|
||||
throw new ParserException("illegal variable. " + info());
|
||||
}
|
||||
|
||||
mark = pos;
|
||||
bufPos = 1;
|
||||
char ch;
|
||||
|
||||
final char c1 = charAt(pos + 1);
|
||||
if (c1 == '@') {
|
||||
++pos;
|
||||
bufPos++;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
ch = charAt(++pos);
|
||||
|
||||
if (!isIdentifierChar(ch)) {
|
||||
break;
|
||||
}
|
||||
|
||||
bufPos++;
|
||||
continue;
|
||||
}
|
||||
|
||||
this.ch = charAt(pos);
|
||||
|
||||
stringVal = addSymbol();
|
||||
token = Token.VARIANT;
|
||||
}
|
||||
|
||||
public void scanComment() {
|
||||
if (!allowComment) {
|
||||
throw new NotAllowCommentException();
|
||||
@@ -1641,12 +1726,12 @@ public class Lexer {
|
||||
}
|
||||
multmin = negative ? MULTMIN_RADIX_TEN : N_MULTMAX_RADIX_TEN;
|
||||
if (i < max) {
|
||||
digit = digits[charAt(i++)];
|
||||
digit = charAt(i++) - '0';
|
||||
result = -digit;
|
||||
}
|
||||
while (i < max) {
|
||||
// Accumulating negatively avoids surprises near MAX_VALUE
|
||||
digit = digits[charAt(i++)];
|
||||
digit = charAt(i++) - '0';
|
||||
if (result < multmin) {
|
||||
return new BigInteger(numberString());
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectItem;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUnique;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleArgumentExpr;
|
||||
import com.alibaba.druid.util.FnvHash;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
|
||||
@@ -1462,12 +1463,38 @@ public class SQLExprParser extends SQLParser {
|
||||
accept(Token.RPAREN);
|
||||
item.setColumn(list);
|
||||
} else {
|
||||
item.setColumn(this.primary());
|
||||
String identName;
|
||||
long hash;
|
||||
|
||||
Token token = lexer.token();
|
||||
if (token == Token.IDENTIFIER) {
|
||||
identName = lexer.stringVal();
|
||||
hash = lexer.hash_lower();
|
||||
} else if (token == Token.LITERAL_CHARS) {
|
||||
identName = '\'' + lexer.stringVal() + '\'';
|
||||
hash = 0;
|
||||
} else {
|
||||
identName = lexer.stringVal();
|
||||
hash = 0;
|
||||
}
|
||||
lexer.nextTokenEq();
|
||||
SQLExpr expr = new SQLIdentifierExpr(identName, hash);
|
||||
while (lexer.token() == Token.DOT) {
|
||||
lexer.nextToken();
|
||||
String propertyName = lexer.stringVal();
|
||||
lexer.nextTokenEq();
|
||||
expr = new SQLPropertyExpr(expr, propertyName);
|
||||
}
|
||||
|
||||
item.setColumn(expr);
|
||||
}
|
||||
if (lexer.token == Token.COLONEQ) {
|
||||
lexer.nextToken();
|
||||
lexer.nextTokenValue();
|
||||
} else if (lexer.token == Token.EQ) {
|
||||
lexer.nextTokenValue();
|
||||
} else {
|
||||
accept(Token.EQ);
|
||||
throw new ParserException("syntax error, expect EQ, actual " + lexer.token + " "
|
||||
+ lexer.info());
|
||||
}
|
||||
|
||||
item.setValue(this.expr());
|
||||
@@ -1519,28 +1546,28 @@ public class SQLExprParser extends SQLParser {
|
||||
} catch (EOFParserException e) {
|
||||
throw new ParserException("EOF, " + expr + "=", e);
|
||||
}
|
||||
rightExp = equalityRest(rightExp);
|
||||
|
||||
if (lexer.token == Token.COLONEQ) {
|
||||
lexer.nextToken();
|
||||
SQLExpr colonExpr = expr();
|
||||
rightExp = new SQLBinaryOpExpr(rightExp, SQLBinaryOperator.Assignment, colonExpr, dbType);
|
||||
}
|
||||
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Equality, rightExp, dbType);
|
||||
} else if (token == Token.BANGEQ) {
|
||||
} else if (lexer.token() == Token.EQGT) {
|
||||
lexer.nextToken();
|
||||
rightExp = expr();
|
||||
String argumentName = ((SQLIdentifierExpr) expr).getName();
|
||||
return new OracleArgumentExpr(argumentName, rightExp);
|
||||
} else if (token == Token.BANGEQ || token == Token.CARETEQ) {
|
||||
lexer.nextToken();
|
||||
rightExp = bitOr();
|
||||
|
||||
rightExp = equalityRest(rightExp);
|
||||
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotEqual, rightExp, getDbType());
|
||||
} else if (token == Token.BANG) {
|
||||
lexer.nextToken();
|
||||
accept(Token.EQ);
|
||||
rightExp = bitOr();
|
||||
|
||||
rightExp = equalityRest(rightExp);
|
||||
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotEqual, rightExp, getDbType());
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotEqual, rightExp, dbType);
|
||||
} else if (token == Token.COLONEQ) {
|
||||
lexer.nextToken();
|
||||
rightExp = expr();
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Assignment, rightExp, getDbType());
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Assignment, rightExp, dbType);
|
||||
}
|
||||
|
||||
return expr;
|
||||
@@ -1562,9 +1589,19 @@ public class SQLExprParser extends SQLParser {
|
||||
return queryExpr;
|
||||
}
|
||||
|
||||
exprList(inListExpr.getTargetList(), inListExpr);
|
||||
List<SQLExpr> targetList = inListExpr.getTargetList();
|
||||
for (;;) {
|
||||
SQLExpr item = this.expr();
|
||||
item.setParent(inListExpr);
|
||||
targetList.add(item);
|
||||
if (lexer.token == Token.COMMA) {
|
||||
lexer.nextTokenValue();
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
accept(Token.RPAREN);
|
||||
expr = inListExpr;
|
||||
} else {
|
||||
SQLExpr itemExpr = primary();
|
||||
itemExpr.setParent(inListExpr);
|
||||
@@ -2632,6 +2669,13 @@ public class SQLExprParser extends SQLParser {
|
||||
String as = lexer.stringVal();
|
||||
|
||||
lexer.nextTokenComma();
|
||||
|
||||
if (lexer.token == Token.DOT) {
|
||||
lexer.nextToken();
|
||||
as += '.' + lexer.stringVal();
|
||||
lexer.nextToken();
|
||||
}
|
||||
|
||||
return new SQLSelectItem(expr, as, connectByRoot);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,8 +18,11 @@ package com.alibaba.druid.sql.parser;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.druid.sql.ast.*;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.*;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOrderingExpr;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock;
|
||||
import com.alibaba.druid.util.FnvHash;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
|
||||
@@ -317,7 +320,7 @@ public class SQLSelectParser extends SQLParser {
|
||||
}
|
||||
SQLExpr where = expr();
|
||||
|
||||
if (where != null && beforeComments != null) {
|
||||
if (beforeComments != null) {
|
||||
where.addBeforeComment(beforeComments);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,12 +19,10 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.druid.sql.ast.*;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLQueryExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.*;
|
||||
import com.alibaba.druid.sql.ast.statement.*;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLCreateTriggerStatement.TriggerType;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock;
|
||||
import com.alibaba.druid.sql.dialect.oracle.parser.OracleExprParser;
|
||||
import com.alibaba.druid.util.FnvHash;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
@@ -77,7 +75,7 @@ public class SQLStatementParser extends SQLParser {
|
||||
}
|
||||
|
||||
public void parseStatementList(List<SQLStatement> statementList) {
|
||||
parseStatementList(statementList, -1);
|
||||
parseStatementList(statementList, -1, null);
|
||||
}
|
||||
|
||||
public void parseStatementList(List<SQLStatement> statementList, int max) {
|
||||
@@ -2430,7 +2428,7 @@ public class SQLStatementParser extends SQLParser {
|
||||
*/
|
||||
public SQLStatement parseStatement( final boolean tryBest) {
|
||||
List<SQLStatement> list = new ArrayList<SQLStatement>();
|
||||
this.parseStatementList(list, 1);
|
||||
this.parseStatementList(list, 1, null);
|
||||
if (tryBest) {
|
||||
if (lexer.token != Token.EOF) {
|
||||
throw new ParserException("sql syntax error, no terminated. " + lexer.token);
|
||||
|
||||
@@ -317,7 +317,8 @@ public enum Token {
|
||||
COLON(":"),
|
||||
COLONCOLON("::"),
|
||||
COLONEQ(":="),
|
||||
EQEQ("=="),
|
||||
EQEQ("=="),
|
||||
EQGT("=>"),
|
||||
LTEQ("<="),
|
||||
LTEQGT("<=>"),
|
||||
LTGT("<>"),
|
||||
|
||||
@@ -1041,13 +1041,8 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
}
|
||||
|
||||
public boolean visit(SQLIdentifierExpr x) {
|
||||
final String name = x.getName();
|
||||
if (!this.parameterized) {
|
||||
print0(x.getName());
|
||||
return false;
|
||||
}
|
||||
|
||||
return printName(x, name);
|
||||
print0(x.getName());
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean printName(SQLName x, String name) {
|
||||
@@ -1535,7 +1530,12 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
if (mapTableName != null) {
|
||||
print0(mapTableName);
|
||||
} else {
|
||||
printExpr(owner);
|
||||
if (owner instanceof SQLIdentifierExpr) {
|
||||
SQLIdentifierExpr ownerIdent = (SQLIdentifierExpr) owner;
|
||||
printName(ownerIdent, ownerIdent.getName());
|
||||
} else {
|
||||
printExpr(owner);
|
||||
}
|
||||
}
|
||||
print('.');
|
||||
|
||||
@@ -1961,9 +1961,54 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
}
|
||||
|
||||
if (expr instanceof SQLIdentifierExpr) {
|
||||
visit((SQLIdentifierExpr) expr);
|
||||
SQLIdentifierExpr identifierExpr = (SQLIdentifierExpr) expr;
|
||||
final String name = identifierExpr.getName();
|
||||
if (!this.parameterized) {
|
||||
print0(name);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean shardingSupport = this.shardingSupport
|
||||
&& this.parameterized;
|
||||
|
||||
if (shardingSupport) {
|
||||
String nameUnwrappe = unwrapShardingTable(name);
|
||||
|
||||
if (!name.equals(nameUnwrappe)) {
|
||||
incrementReplaceCunt();
|
||||
}
|
||||
|
||||
print0(nameUnwrappe);
|
||||
} else {
|
||||
print0(name);
|
||||
}
|
||||
} else if (expr instanceof SQLPropertyExpr) {
|
||||
visit((SQLPropertyExpr) expr);
|
||||
SQLPropertyExpr propertyExpr = (SQLPropertyExpr) expr;
|
||||
SQLExpr owner = propertyExpr.getOwner();
|
||||
|
||||
printTableSourceExpr(owner);
|
||||
print('.');
|
||||
|
||||
final String name = propertyExpr.getName();
|
||||
if (!this.parameterized) {
|
||||
print0(propertyExpr.getName());
|
||||
return;
|
||||
}
|
||||
|
||||
boolean shardingSupport = this.shardingSupport
|
||||
&& this.parameterized;
|
||||
|
||||
if (shardingSupport) {
|
||||
String nameUnwrappe = unwrapShardingTable(name);
|
||||
|
||||
if (!name.equals(nameUnwrappe)) {
|
||||
incrementReplaceCunt();
|
||||
}
|
||||
|
||||
print0(nameUnwrappe);
|
||||
} else {
|
||||
print0(name);
|
||||
}
|
||||
} else {
|
||||
expr.accept(this);
|
||||
}
|
||||
|
||||
@@ -738,5 +738,8 @@ public interface SQLASTVisitor {
|
||||
boolean visit(SQLBinaryOpExprGroup x);
|
||||
|
||||
void endVisit(SQLBinaryOpExprGroup x);
|
||||
//
|
||||
|
||||
boolean visit(SQLScriptCommitStatement astNode);
|
||||
|
||||
void endVisit(SQLScriptCommitStatement astNode);
|
||||
}
|
||||
|
||||
@@ -1689,6 +1689,16 @@ public class SQLASTVisitorAdapter implements SQLASTVisitor {
|
||||
features = VisitorFeature.config(features, feature, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLScriptCommitStatement x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(SQLScriptCommitStatement astNode) {
|
||||
|
||||
}
|
||||
|
||||
public final boolean isEnabled(VisitorFeature feature) {
|
||||
return VisitorFeature.isEnabled(this.features, feature);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user