mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
refactor sql parser.
This commit is contained in:
@@ -906,7 +906,7 @@ public class SQLExprParser extends SQLParser {
|
||||
if (expr instanceof SQLIdentifierExpr) {
|
||||
SQLIdentifierExpr identifierExpr = (SQLIdentifierExpr) expr;
|
||||
methodName = identifierExpr.getName();
|
||||
hash_lower = identifierExpr.hash_lower();
|
||||
hash_lower = identifierExpr.name_hash_lower();
|
||||
|
||||
if (hash_lower == FNVUtils.TRIM) {
|
||||
if (lexer.identifierEquals(FNVUtils.LEADING)) {
|
||||
@@ -1005,9 +1005,14 @@ public class SQLExprParser extends SQLParser {
|
||||
expr = new SQLPropertyExpr(expr, "*");
|
||||
} else {
|
||||
String name;
|
||||
long hash_lower = 0L;
|
||||
|
||||
if (lexer.token == Token.IDENTIFIER || lexer.token == Token.LITERAL_CHARS
|
||||
|| lexer.token == Token.LITERAL_ALIAS) {
|
||||
if (lexer.token == Token.IDENTIFIER) {
|
||||
name = lexer.stringVal();
|
||||
hash_lower = lexer.hash_lower;
|
||||
lexer.nextToken();
|
||||
} else if (lexer.token == Token.LITERAL_CHARS
|
||||
|| lexer.token == Token.LITERAL_ALIAS) {
|
||||
name = lexer.stringVal();
|
||||
lexer.nextToken();
|
||||
} else if (lexer.getKeywods().containsValue(lexer.token)) {
|
||||
@@ -1055,7 +1060,7 @@ public class SQLExprParser extends SQLParser {
|
||||
expr = methodInvokeExpr;
|
||||
}
|
||||
} else {
|
||||
expr = new SQLPropertyExpr(expr, name);
|
||||
expr = new SQLPropertyExpr(expr, name, hash_lower);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1642,7 +1647,7 @@ public class SQLExprParser extends SQLParser {
|
||||
if (lexer.token == Token.AND
|
||||
&& lexer.isEnabled(SQLParserFeature.EnableSQLBinaryOpExprGroup)) {
|
||||
|
||||
SQLBinaryOpExprGroup group = new SQLBinaryOpExprGroup(SQLBinaryOperator.BooleanAnd);
|
||||
SQLBinaryOpExprGroup group = new SQLBinaryOpExprGroup(SQLBinaryOperator.BooleanAnd, dbType);
|
||||
group.add(expr);
|
||||
group.add(rightExp);
|
||||
|
||||
@@ -1697,25 +1702,31 @@ public class SQLExprParser extends SQLParser {
|
||||
}
|
||||
|
||||
public SQLExpr orRest(SQLExpr expr) {
|
||||
// SQLBinaryOpExprGroup group = new SQLBinaryOpExprGroup(SQLBinaryOperator.BooleanAnd);
|
||||
for (;;) {
|
||||
if (lexer.token == Token.OR) {
|
||||
lexer.nextToken();
|
||||
SQLExpr rightExp = and();
|
||||
|
||||
// expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BooleanOr, rightExp, dbType);
|
||||
if (lexer.token == Token.OR
|
||||
&& lexer.isEnabled(SQLParserFeature.EnableSQLBinaryOpExprGroup)) {
|
||||
|
||||
SQLBinaryOpExprGroup group = new SQLBinaryOpExprGroup(SQLBinaryOperator.BooleanOr);
|
||||
SQLBinaryOpExprGroup group = new SQLBinaryOpExprGroup(SQLBinaryOperator.BooleanOr, dbType);
|
||||
group.add(expr);
|
||||
group.add(rightExp);
|
||||
|
||||
if (lexer.isKeepComments() && lexer.hasComment()) {
|
||||
rightExp.addAfterComment(lexer.readAndResetComments());
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
lexer.nextToken();
|
||||
SQLExpr more = relational();
|
||||
group.add(more);
|
||||
if (lexer.token == Token.OR) {
|
||||
if (lexer.isKeepComments() && lexer.hasComment()) {
|
||||
more.addAfterComment(lexer.readAndResetComments());
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -43,7 +43,10 @@ public class SQLSelectParser extends SQLParser {
|
||||
public SQLSelect select() {
|
||||
SQLSelect select = new SQLSelect();
|
||||
|
||||
withSubquery(select);
|
||||
if (lexer.token() == Token.WITH) {
|
||||
SQLWithSubqueryClause with = this.parseWith();
|
||||
select.setWithSubQuery(with);
|
||||
}
|
||||
|
||||
select.setQuery(query());
|
||||
select.setOrderBy(parseOrderBy());
|
||||
@@ -211,7 +214,10 @@ public class SQLSelectParser extends SQLParser {
|
||||
for (;;) {
|
||||
SQLWithSubqueryClause.Entry entry = new SQLWithSubqueryClause.Entry();
|
||||
entry.setParent(withQueryClause);
|
||||
entry.setName((SQLIdentifierExpr) this.exprParser.name());
|
||||
|
||||
String alias = this.lexer.stringVal();
|
||||
lexer.nextToken();
|
||||
entry.setAlias(alias);
|
||||
|
||||
if (lexer.token == Token.LPAREN) {
|
||||
lexer.nextToken();
|
||||
@@ -238,6 +244,56 @@ public class SQLSelectParser extends SQLParser {
|
||||
}
|
||||
}
|
||||
|
||||
public SQLWithSubqueryClause parseWith() {
|
||||
accept(Token.WITH);
|
||||
|
||||
SQLWithSubqueryClause withQueryClause = new SQLWithSubqueryClause();
|
||||
|
||||
if (lexer.token == Token.RECURSIVE || lexer.identifierEquals("RECURSIVE")) {
|
||||
lexer.nextToken();
|
||||
withQueryClause.setRecursive(true);
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
SQLWithSubqueryClause.Entry entry = new SQLWithSubqueryClause.Entry();
|
||||
entry.setParent(withQueryClause);
|
||||
|
||||
String alias = this.lexer.stringVal();
|
||||
lexer.nextToken();
|
||||
entry.setAlias(alias);
|
||||
|
||||
if (lexer.token == Token.LPAREN) {
|
||||
lexer.nextToken();
|
||||
exprParser.names(entry.getColumns());
|
||||
accept(Token.RPAREN);
|
||||
}
|
||||
|
||||
accept(Token.AS);
|
||||
accept(Token.LPAREN);
|
||||
|
||||
switch (lexer.token) {
|
||||
case SELECT:
|
||||
entry.setSubQuery(select());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
accept(Token.RPAREN);
|
||||
|
||||
withQueryClause.addEntry(entry);
|
||||
|
||||
if (lexer.token == Token.COMMA) {
|
||||
lexer.nextToken();
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return withQueryClause;
|
||||
}
|
||||
|
||||
protected void parseWhere(SQLSelectQueryBlock queryBlock) {
|
||||
if (lexer.token == Token.WHERE) {
|
||||
lexer.nextToken();
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.alibaba.druid.sql.ast.statement.SQLCreateTriggerStatement.TriggerEven
|
||||
import com.alibaba.druid.sql.ast.statement.SQLCreateTriggerStatement.TriggerType;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlRepeatStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.parser.OracleExprParser;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.*;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
import com.alibaba.druid.util.JdbcUtils;
|
||||
|
||||
@@ -127,14 +128,12 @@ public class SQLStatementParser extends SQLParser {
|
||||
|
||||
continue;
|
||||
}
|
||||
case WITH:
|
||||
if (!JdbcConstants.POSTGRESQL.equals(dbType)){
|
||||
SQLStatement stmt = parseSelect();
|
||||
case WITH: {
|
||||
SQLStatement stmt = parseWith();
|
||||
stmt.setParent(parent);
|
||||
statementList.add(stmt);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case SELECT: {
|
||||
SQLStatement stmt = parseSelect();
|
||||
stmt.setParent(parent);
|
||||
@@ -2778,4 +2777,85 @@ public class SQLStatementParser extends SQLParser {
|
||||
}
|
||||
return stmt;
|
||||
}
|
||||
|
||||
public SQLWithSubqueryClause parseWithQuery() {
|
||||
accept(Token.WITH);
|
||||
|
||||
SQLWithSubqueryClause withQueryClause = new SQLWithSubqueryClause();
|
||||
|
||||
if (lexer.token == Token.RECURSIVE || lexer.identifierEquals("RECURSIVE")) {
|
||||
lexer.nextToken();
|
||||
withQueryClause.setRecursive(true);
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
SQLWithSubqueryClause.Entry entry = new SQLWithSubqueryClause.Entry();
|
||||
entry.setParent(withQueryClause);
|
||||
|
||||
String alias = this.lexer.stringVal();
|
||||
lexer.nextToken();
|
||||
entry.setAlias(alias);
|
||||
|
||||
if (lexer.token == Token.LPAREN) {
|
||||
lexer.nextToken();
|
||||
exprParser.names(entry.getColumns());
|
||||
accept(Token.RPAREN);
|
||||
}
|
||||
|
||||
accept(Token.AS);
|
||||
accept(Token.LPAREN);
|
||||
|
||||
switch (lexer.token) {
|
||||
case VALUES:
|
||||
case SELECT:
|
||||
entry.setSubQuery(
|
||||
this.createSQLSelectParser()
|
||||
.select());
|
||||
break;
|
||||
case INSERT:
|
||||
entry.setReturningStatement(
|
||||
this.parseInsert()
|
||||
);
|
||||
break;
|
||||
case UPDATE:
|
||||
entry.setReturningStatement(
|
||||
this.parseUpdateStatement()
|
||||
);
|
||||
break;
|
||||
case DELETE:
|
||||
entry.setReturningStatement(
|
||||
this.parseDeleteStatement()
|
||||
);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
accept(Token.RPAREN);
|
||||
|
||||
withQueryClause.addEntry(entry);
|
||||
|
||||
if (lexer.token == Token.COMMA) {
|
||||
lexer.nextToken();
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return withQueryClause;
|
||||
}
|
||||
|
||||
public SQLStatement parseWith() {
|
||||
SQLWithSubqueryClause with = this.parseWithQuery();
|
||||
|
||||
if (lexer.token() == Token.SELECT) {
|
||||
SQLSelectParser selectParser = createSQLSelectParser();
|
||||
SQLSelect select = selectParser.select();
|
||||
select.setWithSubQuery(with);
|
||||
return new SQLSelectStatement(select, dbType);
|
||||
}
|
||||
|
||||
throw new ParserException("TODO. " + lexer.info());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user