mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
improved mysql/oracle sql parser.
This commit is contained in:
@@ -243,7 +243,7 @@ public class Lexer {
|
||||
}
|
||||
|
||||
public String info() {
|
||||
return this.token + " " + this.stringVal();
|
||||
return "pos " + this.pos + ", " + this.token + " " + this.stringVal();
|
||||
}
|
||||
|
||||
public final void nextTokenComma() {
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.alibaba.druid.sql.ast.statement.SQLConstraint;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLTableElement;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
|
||||
public class SQLCreateTableParser extends SQLDDLParser {
|
||||
|
||||
@@ -82,19 +83,25 @@ public class SQLCreateTableParser extends SQLDDLParser {
|
||||
lexer.nextToken();
|
||||
|
||||
for (;;) {
|
||||
if (lexer.token() == Token.IDENTIFIER //
|
||||
|| lexer.token() == Token.LITERAL_ALIAS) {
|
||||
Token token = lexer.token();
|
||||
if (token == Token.IDENTIFIER
|
||||
&& lexer.stringVal().equalsIgnoreCase("SUPPLEMENTAL")
|
||||
&& JdbcConstants.ORACLE.equals(dbType)) {
|
||||
this.parseCreateTableSupplementalLogingProps(createTable);
|
||||
} else if (token == Token.IDENTIFIER //
|
||||
|| token == Token.LITERAL_ALIAS) {
|
||||
SQLColumnDefinition column = this.exprParser.parseColumn();
|
||||
createTable.getTableElementList().add(column);
|
||||
} else if (lexer.token == Token.PRIMARY //
|
||||
|| lexer.token == Token.UNIQUE //
|
||||
|| lexer.token == Token.CHECK //
|
||||
|| lexer.token == Token.CONSTRAINT) {
|
||||
} else if (token == Token.PRIMARY //
|
||||
|| token == Token.UNIQUE //
|
||||
|| token == Token.CHECK //
|
||||
|| token == Token.CONSTRAINT
|
||||
|| token == Token.FOREIGN) {
|
||||
SQLConstraint constraint = this.exprParser.parseConstaint();
|
||||
constraint.setParent(createTable);
|
||||
createTable.getTableElementList().add((SQLTableElement) constraint);
|
||||
} else if (lexer.token() == Token.TABLESPACE) {
|
||||
throw new ParserException("TODO " + lexer.token());
|
||||
} else if (token == Token.TABLESPACE) {
|
||||
throw new ParserException("TODO " + token);
|
||||
} else {
|
||||
SQLColumnDefinition column = this.exprParser.parseColumn();
|
||||
createTable.getTableElementList().add(column);
|
||||
@@ -135,6 +142,10 @@ public class SQLCreateTableParser extends SQLDDLParser {
|
||||
return createTable;
|
||||
}
|
||||
|
||||
protected void parseCreateTableSupplementalLogingProps(SQLCreateTableStatement stmt) {
|
||||
throw new ParserException("TODO " + lexer.info());
|
||||
}
|
||||
|
||||
protected SQLCreateTableStatement newCreateStatement() {
|
||||
return new SQLCreateTableStatement(getDbType());
|
||||
}
|
||||
|
||||
@@ -264,9 +264,17 @@ public class SQLExprParser extends SQLParser {
|
||||
sqlExpr = new SQLNCharExpr(lexer.stringVal());
|
||||
lexer.nextToken();
|
||||
break;
|
||||
case VARIANT:
|
||||
SQLVariantRefExpr varRefExpr = new SQLVariantRefExpr(lexer.stringVal());
|
||||
case VARIANT: {
|
||||
String varName = lexer.stringVal();
|
||||
lexer.nextToken();
|
||||
|
||||
if (varName.equals(":") && lexer.token() == Token.IDENTIFIER && JdbcConstants.ORACLE.equals(dbType)) {
|
||||
String part2 = lexer.stringVal();
|
||||
lexer.nextToken();
|
||||
varName += part2;
|
||||
}
|
||||
|
||||
SQLVariantRefExpr varRefExpr = new SQLVariantRefExpr(varName);
|
||||
if (varRefExpr.getName().equals("@") && lexer.token() == Token.LITERAL_CHARS) {
|
||||
varRefExpr.setName("@'" + lexer.stringVal() + "'");
|
||||
lexer.nextToken();
|
||||
@@ -275,6 +283,7 @@ public class SQLExprParser extends SQLParser {
|
||||
lexer.nextToken();
|
||||
}
|
||||
sqlExpr = varRefExpr;
|
||||
}
|
||||
break;
|
||||
case DEFAULT:
|
||||
sqlExpr = new SQLDefaultExpr();
|
||||
@@ -1018,6 +1027,7 @@ public class SQLExprParser extends SQLParser {
|
||||
case BINARY:
|
||||
case OVER:
|
||||
case ORDER:
|
||||
case DO:
|
||||
identName = lexer.stringVal();
|
||||
lexer.nextToken();
|
||||
break;
|
||||
@@ -2023,6 +2033,18 @@ public class SQLExprParser extends SQLParser {
|
||||
} else if (lexer.token() == Token.ENABLE) {
|
||||
lexer.nextToken();
|
||||
check.setEnable(true);
|
||||
} else if (identifierEquals("VALIDATE")) {
|
||||
lexer.nextToken();
|
||||
check.setValidate(Boolean.TRUE);
|
||||
} else if (identifierEquals("NOVALIDATE")) {
|
||||
lexer.nextToken();
|
||||
check.setValidate(Boolean.FALSE);
|
||||
} else if (identifierEquals("RELY")) {
|
||||
lexer.nextToken();
|
||||
check.setRely(Boolean.TRUE);
|
||||
} else if (identifierEquals("NORELY")) {
|
||||
lexer.nextToken();
|
||||
check.setRely(Boolean.FALSE);
|
||||
}
|
||||
return check;
|
||||
}
|
||||
@@ -2152,7 +2174,7 @@ public class SQLExprParser extends SQLParser {
|
||||
accept(Token.FOREIGN);
|
||||
accept(Token.KEY);
|
||||
|
||||
SQLForeignKeyConstraint fk = createForeignKey();
|
||||
SQLForeignKeyImpl fk = createForeignKey();
|
||||
|
||||
accept(Token.LPAREN);
|
||||
this.names(fk.getReferencingColumns());
|
||||
@@ -2168,10 +2190,23 @@ public class SQLExprParser extends SQLParser {
|
||||
accept(Token.RPAREN);
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.ON) {
|
||||
lexer.nextToken();
|
||||
accept(Token.DELETE);
|
||||
if (identifierEquals("CASCADE")) {
|
||||
lexer.nextToken();
|
||||
fk.setOnDeleteCascade(true);
|
||||
} else {
|
||||
accept(Token.SET);
|
||||
accept(Token.NULL);
|
||||
fk.setOnDeleteSetNull(true);
|
||||
}
|
||||
}
|
||||
|
||||
return fk;
|
||||
}
|
||||
|
||||
protected SQLForeignKeyConstraint createForeignKey() {
|
||||
protected SQLForeignKeyImpl createForeignKey() {
|
||||
return new SQLForeignKeyImpl();
|
||||
}
|
||||
|
||||
@@ -2205,6 +2240,8 @@ public class SQLExprParser extends SQLParser {
|
||||
expr = this.primaryRest(expr);
|
||||
expr = this.exprRest(expr);
|
||||
}
|
||||
} else if (lexer.token() == Token.DO) {
|
||||
expr = this.name();
|
||||
} else {
|
||||
expr = expr();
|
||||
}
|
||||
|
||||
@@ -444,6 +444,10 @@ public class SQLSelectParser extends SQLParser {
|
||||
tableReference.setExpr(expr());
|
||||
}
|
||||
|
||||
protected SQLTableSource primaryTableSourceRest(SQLTableSource tableSource) {
|
||||
return tableSource;
|
||||
}
|
||||
|
||||
protected SQLTableSource parseTableSourceRest(SQLTableSource tableSource) {
|
||||
if ((tableSource.getAlias() == null) || (tableSource.getAlias().length() == 0)) {
|
||||
if (lexer.token() != Token.LEFT && lexer.token() != Token.RIGHT && lexer.token() != Token.FULL
|
||||
@@ -520,7 +524,37 @@ public class SQLSelectParser extends SQLParser {
|
||||
SQLJoinTableSource join = new SQLJoinTableSource();
|
||||
join.setLeft(tableSource);
|
||||
join.setJoinType(joinType);
|
||||
join.setRight(parseTableSource());
|
||||
|
||||
|
||||
SQLTableSource rightTableSource;
|
||||
if (lexer.token() == Token.LPAREN) {
|
||||
lexer.nextToken();
|
||||
SQLSelect select = this.select();
|
||||
rightTableSource = new SQLSubqueryTableSource(select);
|
||||
accept(Token.RPAREN);
|
||||
} else {
|
||||
SQLExpr expr = this.expr();
|
||||
rightTableSource = new SQLExprTableSource(expr);
|
||||
}
|
||||
|
||||
if (identifierEquals("USING")) {
|
||||
lexer.nextToken();
|
||||
if (lexer.token() == Token.LPAREN) {
|
||||
lexer.nextToken();
|
||||
this.exprParser.exprList(join.getUsing(), join);
|
||||
accept(Token.RPAREN);
|
||||
} else {
|
||||
join.getUsing().add(this.expr());
|
||||
}
|
||||
|
||||
join.setAlias(this.tableAlias());
|
||||
} else {
|
||||
rightTableSource.setAlias(this.tableAlias());
|
||||
|
||||
primaryTableSourceRest(rightTableSource);
|
||||
}
|
||||
|
||||
join.setRight(rightTableSource);
|
||||
|
||||
if (!natural) {
|
||||
if (JdbcConstants.MYSQL.equals(dbType) && "NATURAL".equalsIgnoreCase(tableSource.getAlias())) {
|
||||
|
||||
@@ -1682,6 +1682,10 @@ public class SQLStatementParser extends SQLParser {
|
||||
} else if (token == Token.OR) {
|
||||
lexer.nextToken();
|
||||
accept(Token.REPLACE);
|
||||
|
||||
if (identifierEquals("FORCE")) {
|
||||
lexer.nextToken();
|
||||
}
|
||||
if (lexer.token() == Token.PROCEDURE) {
|
||||
lexer.reset(markBp, markChar, Token.CREATE);
|
||||
return parseCreateProcedure();
|
||||
@@ -1980,6 +1984,11 @@ public class SQLStatementParser extends SQLParser {
|
||||
lexer.nextToken();
|
||||
}
|
||||
|
||||
if (identifierEquals("FORCE")) {
|
||||
lexer.nextToken();
|
||||
createView.setForce(true);
|
||||
}
|
||||
|
||||
this.accept(Token.VIEW);
|
||||
|
||||
if (lexer.token() == Token.IF || identifierEquals("IF")) {
|
||||
@@ -2025,7 +2034,8 @@ public class SQLStatementParser extends SQLParser {
|
||||
|
||||
this.accept(Token.AS);
|
||||
|
||||
createView.setSubQuery(new SQLSelectParser(this.exprParser).select());
|
||||
SQLSelectParser selectParser = this.createSQLSelectParser();
|
||||
createView.setSubQuery(selectParser.select());
|
||||
return createView;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user