improved mysql/oracle sql parser.

This commit is contained in:
wenshao
2017-05-20 22:03:21 +08:00
parent ae0ae2e9e0
commit ac4b6059f0
53 changed files with 1449 additions and 296 deletions
@@ -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;
}