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:
@@ -214,9 +214,8 @@ public class Lexer {
|
||||
this.skipComment = skipComment;
|
||||
|
||||
this.text = input;
|
||||
this.pos = -1;
|
||||
|
||||
scanChar();
|
||||
this.pos = 0;
|
||||
ch = charAt(pos);
|
||||
}
|
||||
|
||||
public Lexer(char[] input, int inputLength, boolean skipComment){
|
||||
@@ -419,6 +418,12 @@ public class Lexer {
|
||||
}
|
||||
}
|
||||
|
||||
if (ch == ')') {
|
||||
scanChar();
|
||||
token = Token.RPAREN;
|
||||
return;
|
||||
}
|
||||
|
||||
if (isFirstIdentifierChar(ch)) {
|
||||
scanIdentifier();
|
||||
return;
|
||||
@@ -487,6 +492,25 @@ public class Lexer {
|
||||
nextToken();
|
||||
}
|
||||
|
||||
public final void nextTokenIdent() {
|
||||
while (ch == ' ') {
|
||||
scanChar();
|
||||
}
|
||||
|
||||
if (isFirstIdentifierChar(ch)) {
|
||||
scanIdentifier();
|
||||
return;
|
||||
}
|
||||
|
||||
if (ch == ')') {
|
||||
scanChar();
|
||||
token = RPAREN;
|
||||
return;
|
||||
}
|
||||
|
||||
nextToken();
|
||||
}
|
||||
|
||||
public final void nextToken() {
|
||||
startPos = pos;
|
||||
bufPos = 0;
|
||||
|
||||
@@ -362,6 +362,9 @@ public class SQLExprParser extends SQLParser {
|
||||
}
|
||||
|
||||
SQLVariantRefExpr varRefExpr = new SQLVariantRefExpr(varName);
|
||||
if (varName.startsWith(":")) {
|
||||
varRefExpr.setIndex(lexer.nextVarIndex());
|
||||
}
|
||||
if (varRefExpr.getName().equals("@") && lexer.token == Token.LITERAL_CHARS) {
|
||||
varRefExpr.setName("@'" + lexer.stringVal() + "'");
|
||||
lexer.nextToken();
|
||||
@@ -1575,11 +1578,12 @@ public class SQLExprParser extends SQLParser {
|
||||
|
||||
public final SQLExpr inRest(SQLExpr expr) {
|
||||
if (lexer.token == Token.IN) {
|
||||
lexer.nextToken();
|
||||
lexer.nextTokenLParen();
|
||||
|
||||
SQLInListExpr inListExpr = new SQLInListExpr(expr);
|
||||
List<SQLExpr> targetList = inListExpr.getTargetList();
|
||||
if (lexer.token == Token.LPAREN) {
|
||||
lexer.nextToken();
|
||||
lexer.nextTokenValue();
|
||||
|
||||
if (lexer.token == Token.WITH) {
|
||||
SQLSelect select = this.createSelectParser().select();
|
||||
@@ -1589,7 +1593,6 @@ public class SQLExprParser extends SQLParser {
|
||||
return queryExpr;
|
||||
}
|
||||
|
||||
List<SQLExpr> targetList = inListExpr.getTargetList();
|
||||
for (;;) {
|
||||
SQLExpr item = this.expr();
|
||||
item.setParent(inListExpr);
|
||||
@@ -1605,13 +1608,13 @@ public class SQLExprParser extends SQLParser {
|
||||
} else {
|
||||
SQLExpr itemExpr = primary();
|
||||
itemExpr.setParent(inListExpr);
|
||||
inListExpr.getTargetList().add(itemExpr);
|
||||
targetList.add(itemExpr);
|
||||
}
|
||||
|
||||
expr = inListExpr;
|
||||
|
||||
if (inListExpr.getTargetList().size() == 1) {
|
||||
SQLExpr targetExpr = inListExpr.getTargetList().get(0);
|
||||
if (targetList.size() == 1) {
|
||||
SQLExpr targetExpr = targetList.get(0);
|
||||
if (targetExpr instanceof SQLQueryExpr) {
|
||||
SQLInSubQueryExpr inSubQueryExpr = new SQLInSubQueryExpr();
|
||||
inSubQueryExpr.setExpr(inListExpr.getExpr());
|
||||
@@ -2629,7 +2632,7 @@ public class SQLExprParser extends SQLParser {
|
||||
token = lexer.token;
|
||||
|
||||
if (token == Token.DOT) {
|
||||
lexer.nextToken();
|
||||
lexer.nextTokenIdent();
|
||||
String name;
|
||||
long name_hash_lower;
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.alibaba.druid.sql.dialect.db2.parser.DB2ExprParser;
|
||||
import com.alibaba.druid.sql.dialect.db2.parser.DB2Lexer;
|
||||
import com.alibaba.druid.sql.dialect.db2.parser.DB2StatementParser;
|
||||
import com.alibaba.druid.sql.dialect.h2.parser.H2StatementParser;
|
||||
import com.alibaba.druid.sql.dialect.hive.parser.HiveStatementParser;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock;
|
||||
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlExprParser;
|
||||
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlLexer;
|
||||
@@ -105,6 +106,14 @@ public class SQLParserUtils {
|
||||
return new PhoenixStatementParser(sql);
|
||||
}
|
||||
|
||||
if (JdbcUtils.HIVE.equals(dbType)) {
|
||||
return new HiveStatementParser(sql);
|
||||
}
|
||||
|
||||
if (JdbcUtils.ELASTIC_SEARCH.equals(dbType)) {
|
||||
return new MySqlStatementParser(sql);
|
||||
}
|
||||
|
||||
return new SQLStatementParser(sql, dbType);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,8 +18,7 @@ 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.expr.*;
|
||||
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;
|
||||
@@ -318,13 +317,47 @@ public class SQLSelectParser extends SQLParser {
|
||||
|
||||
public void parseWhere(SQLSelectQueryBlock queryBlock) {
|
||||
if (lexer.token == Token.WHERE) {
|
||||
lexer.nextToken();
|
||||
lexer.nextTokenIdent();
|
||||
|
||||
List<String> beforeComments = null;
|
||||
if (lexer.hasComment() && lexer.isKeepComments()) {
|
||||
beforeComments = lexer.readAndResetComments();
|
||||
}
|
||||
SQLExpr where = expr();
|
||||
|
||||
SQLExpr where;
|
||||
|
||||
if (lexer.token == Token.IDENTIFIER) {
|
||||
String ident = lexer.stringVal();
|
||||
long hash_lower = lexer.hash_lower();
|
||||
lexer.nextTokenEq();
|
||||
|
||||
SQLExpr identExpr = new SQLIdentifierExpr(ident, hash_lower);
|
||||
|
||||
if (lexer.token == Token.DOT) {
|
||||
identExpr = this.exprParser.primaryRest(identExpr);
|
||||
}
|
||||
|
||||
if (lexer.token == Token.EQ) {
|
||||
SQLExpr rightExp;
|
||||
|
||||
lexer.nextToken();
|
||||
try {
|
||||
rightExp = this.exprParser.bitOr();
|
||||
} catch (EOFParserException e) {
|
||||
throw new ParserException("EOF, " + ident + "=", e);
|
||||
}
|
||||
|
||||
where = new SQLBinaryOpExpr(identExpr, SQLBinaryOperator.Equality, rightExp, dbType);
|
||||
where = this.exprParser.andRest(where);
|
||||
where = this.exprParser.orRest(where);
|
||||
} else {
|
||||
identExpr = this.exprParser.primaryRest(identExpr);
|
||||
where = this.exprParser.exprRest(identExpr);
|
||||
}
|
||||
} else {
|
||||
where = this.exprParser.expr();
|
||||
}
|
||||
// where = this.exprParser.expr();
|
||||
|
||||
if (beforeComments != null) {
|
||||
where.addBeforeComment(beforeComments);
|
||||
|
||||
@@ -2433,7 +2433,26 @@ public class SQLStatementParser extends SQLParser {
|
||||
}
|
||||
|
||||
public SQLStatement parseStatement() {
|
||||
return parseStatement(false);
|
||||
if (lexer.token == Token.SELECT) {
|
||||
return this.parseSelect();
|
||||
}
|
||||
|
||||
if (lexer.token == Token.INSERT) {
|
||||
return this.parseInsert();
|
||||
}
|
||||
|
||||
|
||||
if (lexer.token == Token.UPDATE) {
|
||||
return this.parseUpdateStatement();
|
||||
}
|
||||
|
||||
if (lexer.token == Token.DELETE) {
|
||||
return this.parseDeleteStatement();
|
||||
}
|
||||
|
||||
List<SQLStatement> list = new ArrayList<SQLStatement>(1);
|
||||
this.parseStatementList(list, 1, null);
|
||||
return list.get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user