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:
@@ -605,7 +605,7 @@ public class SQLTransformUtils {
|
||||
|| nameHash == FnvHash.Constants.NCLOB
|
||||
|| nameHash == FnvHash.Constants.LONG) {
|
||||
argumentns.clear();
|
||||
dataType = new SQLCharacterDataType("TEXT");
|
||||
dataType = new SQLCharacterDataType("text");
|
||||
|
||||
} else if (nameHash == FnvHash.Constants.XMLTYPE) {
|
||||
dataType = new SQLDataTypeImpl("xml");
|
||||
|
||||
@@ -25,6 +25,8 @@ import com.alibaba.druid.sql.dialect.db2.visitor.DB2OutputVisitor;
|
||||
import com.alibaba.druid.sql.dialect.db2.visitor.DB2SchemaStatVisitor;
|
||||
import com.alibaba.druid.sql.dialect.h2.visitor.H2OutputVisitor;
|
||||
import com.alibaba.druid.sql.dialect.h2.visitor.H2SchemaStatVisitor;
|
||||
import com.alibaba.druid.sql.dialect.hive.visitor.HiveOutputVisitor;
|
||||
import com.alibaba.druid.sql.dialect.hive.visitor.HiveSchemaStatVisitor;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlOutputVisitor;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor;
|
||||
import com.alibaba.druid.sql.dialect.odps.visitor.OdpsOutputVisitor;
|
||||
@@ -130,10 +132,18 @@ public class SQLUtils {
|
||||
return format(sql, JdbcConstants.ODPS);
|
||||
}
|
||||
|
||||
public static String formatHive(String sql) {
|
||||
return format(sql, JdbcConstants.HIVE);
|
||||
}
|
||||
|
||||
public static String formatOdps(String sql, FormatOption option) {
|
||||
return format(sql, JdbcConstants.ODPS, option);
|
||||
}
|
||||
|
||||
public static String formatHive(String sql, FormatOption option) {
|
||||
return format(sql, JdbcConstants.HIVE, option);
|
||||
}
|
||||
|
||||
public static String formatSQLServer(String sql) {
|
||||
return format(sql, JdbcConstants.SQL_SERVER);
|
||||
}
|
||||
@@ -389,6 +399,14 @@ public class SQLUtils {
|
||||
return new H2OutputVisitor(out);
|
||||
}
|
||||
|
||||
if (JdbcConstants.HIVE.equals(dbType)) {
|
||||
return new HiveOutputVisitor(out);
|
||||
}
|
||||
|
||||
if (JdbcConstants.ELASTIC_SEARCH.equals(dbType)) {
|
||||
return new MySqlOutputVisitor(out);
|
||||
}
|
||||
|
||||
return new SQLASTOutputVisitor(out, dbType);
|
||||
}
|
||||
|
||||
@@ -427,6 +445,14 @@ public class SQLUtils {
|
||||
return new H2SchemaStatVisitor();
|
||||
}
|
||||
|
||||
if (JdbcConstants.HIVE.equals(dbType)) {
|
||||
return new HiveSchemaStatVisitor();
|
||||
}
|
||||
|
||||
if (JdbcConstants.ELASTIC_SEARCH.equals(dbType)) {
|
||||
return new MySqlSchemaStatVisitor();
|
||||
}
|
||||
|
||||
return new SchemaStatVisitor();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 1999-2017 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.hive.parser;
|
||||
|
||||
import com.alibaba.druid.sql.parser.Lexer;
|
||||
import com.alibaba.druid.sql.parser.SQLExprParser;
|
||||
import com.alibaba.druid.sql.parser.SQLParserFeature;
|
||||
import com.alibaba.druid.util.FnvHash;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class HiveExprParser extends SQLExprParser {
|
||||
private final static String[] AGGREGATE_FUNCTIONS;
|
||||
private final static long[] AGGREGATE_FUNCTIONS_CODES;
|
||||
|
||||
static {
|
||||
String[] strings = { "AVG", "COUNT", "MAX", "MIN", "STDDEV", "SUM", "ROW_NUMBER",
|
||||
"ROWNUMBER" };
|
||||
|
||||
AGGREGATE_FUNCTIONS_CODES = FnvHash.fnv1a_64_lower(strings, true);
|
||||
AGGREGATE_FUNCTIONS = new String[AGGREGATE_FUNCTIONS_CODES.length];
|
||||
for (String str : strings) {
|
||||
long hash = FnvHash.fnv1a_64_lower(str);
|
||||
int index = Arrays.binarySearch(AGGREGATE_FUNCTIONS_CODES, hash);
|
||||
AGGREGATE_FUNCTIONS[index] = str;
|
||||
}
|
||||
}
|
||||
|
||||
public HiveExprParser(String sql){
|
||||
this(new HiveLexer(sql));
|
||||
this.lexer.nextToken();
|
||||
}
|
||||
|
||||
public HiveExprParser(String sql, SQLParserFeature... features){
|
||||
this(new HiveLexer(sql, features));
|
||||
this.lexer.nextToken();
|
||||
}
|
||||
|
||||
public HiveExprParser(Lexer lexer){
|
||||
super(lexer);
|
||||
this.aggregateFunctions = AGGREGATE_FUNCTIONS;
|
||||
this.aggregateFunctionHashCodes = AGGREGATE_FUNCTIONS_CODES;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 1999-2017 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.hive.parser;
|
||||
|
||||
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 java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class HiveLexer extends Lexer {
|
||||
public final static Keywords DEFAULT_HIVE_KEYWORDS;
|
||||
|
||||
static {
|
||||
Map<String, Token> map = new HashMap<String, Token>();
|
||||
|
||||
map.putAll(Keywords.DEFAULT_KEYWORDS.getKeywords());
|
||||
|
||||
map.put("OF", Token.OF);
|
||||
map.put("CONCAT", Token.CONCAT);
|
||||
map.put("CONTINUE", Token.CONTINUE);
|
||||
map.put("MERGE", Token.MERGE);
|
||||
map.put("USING", Token.USING);
|
||||
|
||||
map.put("ROW", Token.ROW);
|
||||
map.put("LIMIT", Token.LIMIT);
|
||||
|
||||
DEFAULT_HIVE_KEYWORDS = new Keywords(map);
|
||||
}
|
||||
|
||||
public HiveLexer(String input){
|
||||
super(input);
|
||||
super.keywods = DEFAULT_HIVE_KEYWORDS;
|
||||
}
|
||||
|
||||
public HiveLexer(String input, SQLParserFeature... features){
|
||||
super(input);
|
||||
super.keywods = DEFAULT_HIVE_KEYWORDS;
|
||||
for (SQLParserFeature feature : features) {
|
||||
config(feature, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 1999-2017 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.hive.parser;
|
||||
|
||||
import com.alibaba.druid.sql.parser.SQLExprParser;
|
||||
import com.alibaba.druid.sql.parser.SQLSelectListCache;
|
||||
import com.alibaba.druid.sql.parser.SQLSelectParser;
|
||||
|
||||
public class HiveSelectParser extends SQLSelectParser {
|
||||
|
||||
public HiveSelectParser(SQLExprParser exprParser){
|
||||
super(exprParser);
|
||||
}
|
||||
|
||||
public HiveSelectParser(SQLExprParser exprParser, SQLSelectListCache selectListCache){
|
||||
super(exprParser, selectListCache);
|
||||
}
|
||||
|
||||
public HiveSelectParser(String sql){
|
||||
this(new HiveExprParser(sql));
|
||||
}
|
||||
|
||||
protected SQLExprParser createExprParser() {
|
||||
return new HiveExprParser(lexer);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright 1999-2017 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.hive.parser;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLQueryExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLReplaceStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelect;
|
||||
import com.alibaba.druid.sql.parser.Lexer;
|
||||
import com.alibaba.druid.sql.parser.SQLParserFeature;
|
||||
import com.alibaba.druid.sql.parser.SQLStatementParser;
|
||||
import com.alibaba.druid.sql.parser.Token;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
|
||||
public class HiveStatementParser extends SQLStatementParser {
|
||||
public HiveStatementParser(String sql) {
|
||||
super (new HiveExprParser(sql));
|
||||
}
|
||||
|
||||
public HiveStatementParser(String sql, SQLParserFeature... features) {
|
||||
super (new HiveExprParser(sql, features));
|
||||
}
|
||||
|
||||
public HiveStatementParser(Lexer lexer){
|
||||
super(new HiveExprParser(lexer));
|
||||
}
|
||||
|
||||
public HiveSelectParser createSQLSelectParser() {
|
||||
return new HiveSelectParser(this.exprParser, selectListCache);
|
||||
}
|
||||
|
||||
public SQLStatement parseMerge() {
|
||||
accept(Token.MERGE);
|
||||
accept(Token.INTO);
|
||||
|
||||
SQLReplaceStatement stmt = new SQLReplaceStatement();
|
||||
stmt.setDbType(JdbcConstants.HIVE);
|
||||
|
||||
SQLName tableName = exprParser.name();
|
||||
stmt.setTableName(tableName);
|
||||
|
||||
if (lexer.token() == Token.KEY) {
|
||||
lexer.nextToken();
|
||||
accept(Token.LPAREN);
|
||||
this.exprParser.exprList(stmt.getColumns(), stmt);
|
||||
accept(Token.RPAREN);
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.VALUES || lexer.identifierEquals("VALUE")) {
|
||||
lexer.nextToken();
|
||||
|
||||
parseValueClause(stmt.getValuesList(), 0, stmt);
|
||||
} else if (lexer.token() == Token.SELECT) {
|
||||
SQLQueryExpr queryExpr = (SQLQueryExpr) this.exprParser.expr();
|
||||
stmt.setQuery(queryExpr);
|
||||
} else if (lexer.token() == Token.LPAREN) {
|
||||
SQLSelect select = this.createSQLSelectParser().select();
|
||||
SQLQueryExpr queryExpr = new SQLQueryExpr(select);
|
||||
stmt.setQuery(queryExpr);
|
||||
}
|
||||
|
||||
return stmt;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 1999-2017 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.hive.visitor;
|
||||
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public interface HiveASTVisitor extends SQLASTVisitor {
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 1999-2017 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.hive.visitor;
|
||||
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitorAdapter;
|
||||
|
||||
public class HiveASTVisitorAdapter extends SQLASTVisitorAdapter implements HiveASTVisitor {
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 1999-2017 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.hive.visitor;
|
||||
|
||||
import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class HiveOutputVisitor extends SQLASTOutputVisitor implements HiveASTVisitor {
|
||||
public HiveOutputVisitor(Appendable appender) {
|
||||
super(appender);
|
||||
}
|
||||
|
||||
public HiveOutputVisitor(Appendable appender, String dbType) {
|
||||
super(appender, dbType);
|
||||
}
|
||||
|
||||
public HiveOutputVisitor(Appendable appender, boolean parameterized) {
|
||||
super(appender, parameterized);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 1999-2017 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.hive.visitor;
|
||||
|
||||
import com.alibaba.druid.sql.visitor.SchemaStatVisitor;
|
||||
|
||||
public class HiveSchemaStatVisitor extends SchemaStatVisitor {
|
||||
}
|
||||
@@ -83,8 +83,50 @@ public class MySqlExprParser extends SQLExprParser {
|
||||
}
|
||||
|
||||
public MySqlExprParser(String sql, SQLParserFeature... features){
|
||||
this(new MySqlLexer(sql, features));
|
||||
super(new MySqlLexer(sql, features), JdbcConstants.MYSQL);
|
||||
this.aggregateFunctions = AGGREGATE_FUNCTIONS;
|
||||
this.aggregateFunctionHashCodes = AGGREGATE_FUNCTIONS_CODES;
|
||||
if (sql.length() > 6) {
|
||||
char c0 = sql.charAt(0);
|
||||
char c1 = sql.charAt(1);
|
||||
char c2 = sql.charAt(2);
|
||||
char c3 = sql.charAt(3);
|
||||
char c4 = sql.charAt(4);
|
||||
char c5 = sql.charAt(5);
|
||||
char c6 = sql.charAt(6);
|
||||
|
||||
if (c0 == 'S' && c1 == 'E' && c2 == 'L' && c3 == 'E' && c4 == 'C' && c5 == 'T' && c6 == ' ') {
|
||||
lexer.reset(6, ' ', Token.SELECT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (c0 == 's' && c1 == 'e' && c2 == 'l' && c3 == 'e' && c4 == 'c' && c5 == 't' && c6 == ' ') {
|
||||
lexer.reset(6, ' ', Token.SELECT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (c0 == 'I' && c1 == 'N' && c2 == 'S' && c3 == 'E' && c4 == 'R' && c5 == 'T' && c6 == ' ') {
|
||||
lexer.reset(6, ' ', Token.INSERT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (c0 == 'i' && c1 == 'n' && c2 == 's' && c3 == 'e' && c4 == 'r' && c5 == 't' && c6 == ' ') {
|
||||
lexer.reset(6, ' ', Token.INSERT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (c0 == 'U' && c1 == 'P' && c2 == 'D' && c3 == 'A' && c4 == 'T' && c5 == 'E' && c6 == ' ') {
|
||||
lexer.reset(6, ' ', Token.UPDATE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (c0 == 'u' && c1 == 'p' && c2 == 'd' && c3 == 'a' && c4 == 't' && c5 == 'e' && c6 == ' ') {
|
||||
lexer.reset(6, ' ', Token.UPDATE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.lexer.nextToken();
|
||||
|
||||
}
|
||||
|
||||
public MySqlExprParser(String sql, boolean keepComments){
|
||||
|
||||
@@ -74,7 +74,10 @@ public class MySqlLexer extends Lexer {
|
||||
}
|
||||
|
||||
public MySqlLexer(String input, SQLParserFeature... features){
|
||||
this(input, true, true);
|
||||
super(input, true);
|
||||
this.keepComments = true;
|
||||
super.keywods = DEFAULT_MYSQL_KEYWORDS;
|
||||
|
||||
for (SQLParserFeature feature : features) {
|
||||
config(feature, true);
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ public class MySqlSelectParser extends SQLSelectParser {
|
||||
return;
|
||||
}
|
||||
|
||||
lexer.nextToken();
|
||||
lexer.nextTokenIdent();
|
||||
|
||||
if (lexer.token() == Token.UPDATE) { // taobao returning to urgly syntax
|
||||
updateStmt = this.parseUpdateStatment();
|
||||
|
||||
@@ -2199,7 +2199,7 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
columnSize++;
|
||||
|
||||
if (lexer.token() == Token.COMMA) {
|
||||
lexer.nextToken();
|
||||
lexer.nextTokenIdent();
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -2256,7 +2256,27 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
accept(Token.KEY);
|
||||
accept(Token.UPDATE);
|
||||
|
||||
exprParser.exprList(insertStatement.getDuplicateKeyUpdate(), insertStatement);
|
||||
List<SQLExpr> duplicateKeyUpdate = insertStatement.getDuplicateKeyUpdate();
|
||||
for (;;) {
|
||||
SQLName name = this.exprParser.name();
|
||||
accept(Token.EQ);
|
||||
SQLExpr value;
|
||||
try {
|
||||
value = this.exprParser.expr();
|
||||
} catch (EOFParserException e) {
|
||||
throw new ParserException("EOF, " + name + "=", e);
|
||||
}
|
||||
|
||||
SQLBinaryOpExpr assignment = new SQLBinaryOpExpr(name, SQLBinaryOperator.Equality, value);
|
||||
assignment.setParent(insertStatement);
|
||||
duplicateKeyUpdate.add(assignment);
|
||||
|
||||
if (lexer.token() == Token.COMMA) {
|
||||
lexer.nextTokenIdent();
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return insertStatement;
|
||||
|
||||
@@ -942,10 +942,10 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
|
||||
protected void printValuesList(List<SQLInsertStatement.ValuesClause> valuesList) {
|
||||
|
||||
if (this.parameterized) {
|
||||
if (this.parameterized && valuesList.size() > 0) {
|
||||
print0(ucase ? "VALUES " : "values ");
|
||||
this.indentCount++;
|
||||
valuesList.get(0).accept(this);
|
||||
visit(valuesList.get(0));
|
||||
this.indentCount--;
|
||||
if (valuesList.size() > 1) {
|
||||
this.incrementReplaceCunt();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -119,6 +119,10 @@ public class ParameterizedOutputVisitorUtils {
|
||||
return new PhoenixOutputVisitor(out, true);
|
||||
}
|
||||
|
||||
if (JdbcUtils.ELASTIC_SEARCH.equals(dbType)) {
|
||||
return new MySqlOutputVisitor(out, true);
|
||||
}
|
||||
|
||||
return new SQLASTOutputVisitor(out, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1897,9 +1897,6 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
|
||||
protected void printTableSourceExpr(SQLExpr expr) {
|
||||
if (exportTables) {
|
||||
if (expr instanceof SQLIdentifierExpr) {
|
||||
|
||||
}
|
||||
addTable(expr.toString());
|
||||
}
|
||||
|
||||
|
||||
@@ -105,4 +105,7 @@ public interface JdbcConstants {
|
||||
public static final String ALIYUN_DRDS = "aliyun_drds";
|
||||
|
||||
public static final String PRESTO = "presto";
|
||||
|
||||
public static final String ELASTIC_SEARCH = "elastic_search";
|
||||
String ELASTIC_SEARCH_DRIVER = "com.alibaba.xdriver.elastic.jdbc.ElasticDriver";
|
||||
}
|
||||
|
||||
@@ -462,6 +462,8 @@ public final class JdbcUtils implements JdbcConstants {
|
||||
return JdbcConstants.PHOENIX_DRIVER;
|
||||
} else if (rawUrl.startsWith("jdbc:kylin:")) {
|
||||
return JdbcConstants.KYLIN_DRIVER;
|
||||
} else if (rawUrl.startsWith("jdbc:elastic:")) {
|
||||
return JdbcConstants.ELASTIC_SEARCH_DRIVER;
|
||||
} else {
|
||||
throw new SQLException("unkow jdbc driver : " + rawUrl);
|
||||
}
|
||||
@@ -547,6 +549,8 @@ public final class JdbcUtils implements JdbcConstants {
|
||||
return HIVE;
|
||||
} else if (rawUrl.startsWith("jdbc:phoenix:")) {
|
||||
return PHOENIX;
|
||||
} else if (rawUrl.startsWith("jdbc:elastic:")) {
|
||||
return ELASTIC_SEARCH;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -864,6 +864,18 @@ public class WallConfig implements WallConfigMBean {
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
Boolean propertyValue = getBoolean(properties, "druid.wall.updateWhereNoneCheck");
|
||||
if (propertyValue != null) {
|
||||
this.setUpdateWhereNoneCheck(propertyValue);
|
||||
}
|
||||
}
|
||||
{
|
||||
Boolean propertyValue = getBoolean(properties, "druid.wall.deleteWhereNoneCheck");
|
||||
if (propertyValue != null) {
|
||||
this.setDeleteWhereNoneCheck(propertyValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addUpdateCheckCoumns(String columnInfo) {
|
||||
|
||||
Reference in New Issue
Block a user