improved sql parser.

This commit is contained in:
wenshao
2017-08-24 10:40:09 +08:00
parent 0c46c2a165
commit 026295ddbd
41 changed files with 565 additions and 186 deletions
@@ -143,7 +143,7 @@ public class MySqlMockExecuteHandlerImpl implements MockExecuteHandler {
row[i] = ((SQLNCharExpr) expr).getText();
column.setColumnType(Types.NVARCHAR);
} else if (expr instanceof SQLBooleanExpr) {
row[i] = ((SQLBooleanExpr) expr).getValue();
row[i] = ((SQLBooleanExpr) expr).getBooleanValue();
column.setColumnType(Types.NVARCHAR);
} else if (expr instanceof SQLNullExpr) {
row[i] = null;
@@ -0,0 +1,91 @@
/*
* 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;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.expr.*;
import java.util.List;
public class SQLTransformUtils {
public static SQLExpr transformDecode(SQLMethodInvokeExpr x) {
if (x == null) {
return null;
}
if (!"decode".equalsIgnoreCase(x.getMethodName())) {
throw new IllegalArgumentException(x.getMethodName());
}
List<SQLExpr> parameters = x.getParameters();
SQLCaseExpr caseExpr = new SQLCaseExpr();
caseExpr.setParent(x.getParent());
caseExpr.setValueExpr(parameters.get(0));
if (parameters.size() == 4) {
SQLExpr param1 = parameters.get(1);
x.setMethodName("if");
SQLBinaryOpExpr condition;
if (param1 instanceof SQLNullExpr) {
condition = new SQLBinaryOpExpr(parameters.get(0), SQLBinaryOperator.Is, param1);
} else {
condition = new SQLBinaryOpExpr(parameters.get(0), SQLBinaryOperator.Equality, param1);
}
condition.setParent(x);
parameters.set(0, condition);
parameters.set(1, parameters.get(2));
parameters.set(2, parameters.get(3));
parameters.remove(3);
return x;
}
for (int i = 1; i + 1 < parameters.size(); i += 2) {
SQLCaseExpr.Item item = new SQLCaseExpr.Item();
SQLExpr conditionExpr = parameters.get(i);
item.setConditionExpr(conditionExpr);
SQLExpr valueExpr = parameters.get(i + 1);
if (valueExpr instanceof SQLMethodInvokeExpr) {
SQLMethodInvokeExpr methodInvokeExpr = (SQLMethodInvokeExpr) valueExpr;
if ("decode".equalsIgnoreCase(methodInvokeExpr.getMethodName())) {
valueExpr = transformDecode(methodInvokeExpr);
}
}
item.setValueExpr(valueExpr);
caseExpr.addItem(item);
}
if (parameters.size() % 2 == 0) {
SQLExpr defaultExpr = parameters.get(parameters.size() - 1);
if (defaultExpr instanceof SQLMethodInvokeExpr) {
SQLMethodInvokeExpr methodInvokeExpr = (SQLMethodInvokeExpr) defaultExpr;
if ("decode".equalsIgnoreCase(methodInvokeExpr.getMethodName())) {
defaultExpr = transformDecode(methodInvokeExpr);
}
}
caseExpr.setElseExpr(defaultExpr);
}
return caseExpr;
}
}
@@ -863,53 +863,8 @@ public class SQLUtils {
return false;
}
public static SQLCaseExpr decodeToCase(SQLMethodInvokeExpr x) {
if (x == null) {
return null;
}
if (!"decode".equalsIgnoreCase(x.getMethodName())) {
throw new IllegalArgumentException(x.getMethodName());
}
List<SQLExpr> parameters = x.getParameters();
SQLCaseExpr caseExpr = new SQLCaseExpr();
caseExpr.setParent(x.getParent());
caseExpr.setValueExpr(parameters.get(0));
for (int i = 1; i + 1 < parameters.size(); i += 2) {
SQLCaseExpr.Item item = new SQLCaseExpr.Item();
SQLExpr conditionExpr = parameters.get(i);
item.setConditionExpr(conditionExpr);
SQLExpr valueExpr = parameters.get(i + 1);
if (valueExpr instanceof SQLMethodInvokeExpr) {
SQLMethodInvokeExpr methodInvokeExpr = (SQLMethodInvokeExpr) valueExpr;
if ("decode".equalsIgnoreCase(methodInvokeExpr.getMethodName())) {
valueExpr = decodeToCase(methodInvokeExpr);
}
}
item.setValueExpr(valueExpr);
caseExpr.addItem(item);
}
if (parameters.size() % 2 == 0) {
SQLExpr defaultExpr = parameters.get(parameters.size() - 1);
if (defaultExpr instanceof SQLMethodInvokeExpr) {
SQLMethodInvokeExpr methodInvokeExpr = (SQLMethodInvokeExpr) defaultExpr;
if ("decode".equalsIgnoreCase(methodInvokeExpr.getMethodName())) {
defaultExpr = decodeToCase(methodInvokeExpr);
}
}
caseExpr.setElseExpr(defaultExpr);
}
return caseExpr;
public static SQLExpr decodeToCase(SQLMethodInvokeExpr x) {
return SQLTransformUtils.transformDecode(x);
}
public static boolean replaceInParent(SQLExpr expr, SQLExpr target) {
@@ -23,7 +23,7 @@ import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.*;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class SQLAggregateExpr extends SQLExprImpl implements Serializable {
public class SQLAggregateExpr extends SQLExprImpl implements Serializable, SQLReplaceable {
private static final long serialVersionUID = 1L;
protected String methodName;
@@ -223,4 +223,18 @@ public class SQLAggregateExpr extends SQLExprImpl implements Serializable {
return null;
}
public boolean replace(SQLExpr expr, SQLExpr target) {
if (target == null) {
return false;
}
for (int i = 0; i < arguments.size(); ++i) {
if (arguments.get(i) == expr) {
arguments.set(i, target);
target.setParent(this);
return true;
}
}
return false;
}
}
@@ -16,9 +16,11 @@
package com.alibaba.druid.sql.ast.expr;
import com.alibaba.druid.sql.ast.SQLExprImpl;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class SQLAllColumnExpr extends SQLExprImpl {
private transient SQLTableSource resolvedTableSource;
public SQLAllColumnExpr(){
@@ -42,6 +44,17 @@ public class SQLAllColumnExpr extends SQLExprImpl {
}
public SQLAllColumnExpr clone() {
return new SQLAllColumnExpr();
SQLAllColumnExpr x = new SQLAllColumnExpr();
x.resolvedTableSource = resolvedTableSource;
return x;
}
public SQLTableSource getResolvedTableSource() {
return resolvedTableSource;
}
public void setResolvedTableSource(SQLTableSource resolvedTableSource) {
this.resolvedTableSource = resolvedTableSource;
}
}
@@ -18,7 +18,7 @@ package com.alibaba.druid.sql.ast.expr;
import com.alibaba.druid.sql.ast.SQLExprImpl;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class SQLBinaryExpr extends SQLExprImpl implements SQLLiteralExpr {
public class SQLBinaryExpr extends SQLExprImpl implements SQLLiteralExpr, SQLValuableExpr {
private String value;
@@ -21,7 +21,7 @@ import com.alibaba.druid.sql.ast.SQLExprImpl;
import com.alibaba.druid.sql.ast.statement.SQLCharacterDataType;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class SQLBooleanExpr extends SQLExprImpl implements SQLExpr, SQLLiteralExpr {
public class SQLBooleanExpr extends SQLExprImpl implements SQLExpr, SQLLiteralExpr, SQLValuableExpr {
public static final SQLDataType DEFAULT_DATA_TYPE = new SQLCharacterDataType("boolean");
private boolean value;
@@ -34,7 +34,11 @@ public class SQLBooleanExpr extends SQLExprImpl implements SQLExpr, SQLLiteralEx
this.value = value;
}
public boolean getValue() {
public boolean getBooleanValue() {
return value;
}
public Boolean getValue() {
return value;
}
@@ -19,6 +19,7 @@ import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.*;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
@@ -270,4 +271,8 @@ public class SQLCaseExpr extends SQLExprImpl implements SQLReplaceable, Serializ
return null;
}
public String toString() {
return SQLUtils.toSQLString(this, null);
}
}
@@ -22,7 +22,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleExpr;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class SQLDateExpr extends SQLExprImpl implements SQLLiteralExpr {
public class SQLDateExpr extends SQLExprImpl implements SQLLiteralExpr, SQLValuableExpr {
public static final SQLDataType DEFAULT_DATA_TYPE = new SQLCharacterDataType("date");
private String literal;
@@ -43,6 +43,10 @@ public class SQLDateExpr extends SQLExprImpl implements SQLLiteralExpr {
this.literal = literal;
}
public String getValue() {
return literal;
}
@Override
protected void accept0(SQLASTVisitor visitor) {
visitor.visit(this);
@@ -19,7 +19,7 @@ import com.alibaba.druid.sql.ast.SQLExprImpl;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
import com.alibaba.druid.util.HexBin;
public class SQLHexExpr extends SQLExprImpl implements SQLLiteralExpr {
public class SQLHexExpr extends SQLExprImpl implements SQLLiteralExpr, SQLValuableExpr {
private final String hex;
@@ -84,4 +84,8 @@ public class SQLHexExpr extends SQLExprImpl implements SQLLiteralExpr {
public SQLHexExpr clone () {
return new SQLHexExpr(hex);
}
public byte[] getValue() {
return toBytes();
}
}
@@ -135,7 +135,10 @@ public class SQLIdentifierExpr extends SQLExprImpl implements SQLName {
}
public SQLIdentifierExpr clone() {
return new SQLIdentifierExpr(this.name);
SQLIdentifierExpr x = new SQLIdentifierExpr(this.name);
x.resolvedColumn = resolvedColumn;
x.resolvedTableSource = resolvedTableSource;
return x;
}
public String normalizedName() {
@@ -35,6 +35,7 @@ public class SQLMethodInvokeExpr extends SQLExprImpl implements SQLReplaceable,
private final List<SQLExpr> parameters = new ArrayList<SQLExpr>();
private SQLExpr from;
private SQLExpr using;
public SQLMethodInvokeExpr(){
@@ -173,6 +174,10 @@ public class SQLMethodInvokeExpr extends SQLExprImpl implements SQLReplaceable,
x.setFrom(from.clone());
}
if (using != null) {
x.setUsing(using.clone());
}
return x;
}
@@ -216,6 +221,11 @@ public class SQLMethodInvokeExpr extends SQLExprImpl implements SQLReplaceable,
}
public SQLDataType computeDataType() {
if (SQLUtils.nameEquals("to_date", methodName)
|| SQLUtils.nameEquals("add_months", methodName)) {
return SQLDateExpr.DEFAULT_DATA_TYPE;
}
if (parameters.size() == 1) {
if (SQLUtils.nameEquals("trunc", methodName)) {
return parameters.get(0).computeDataType();
@@ -234,4 +244,15 @@ public class SQLMethodInvokeExpr extends SQLExprImpl implements SQLReplaceable,
}
return null;
}
public SQLExpr getUsing() {
return using;
}
public void setUsing(SQLExpr using) {
if (using != null) {
using.setParent(this);
}
this.using = using;
}
}
@@ -22,7 +22,7 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitor;
import java.io.IOException;
import java.math.BigDecimal;
public class SQLNumberExpr extends SQLNumericLiteralExpr {
public class SQLNumberExpr extends SQLNumericLiteralExpr implements SQLValuableExpr {
private static SQLDataType defaultDataType = new SQLDataTypeImpl("number");
private Number number;
@@ -48,6 +48,10 @@ public class SQLNumberExpr extends SQLNumericLiteralExpr {
return this.number;
}
public Number getValue() {
return getNumber();
}
public void setNumber(Number number) {
this.number = number;
this.chars = null;
@@ -133,12 +133,16 @@ public class SQLPropertyExpr extends SQLExprImpl implements SQLName {
}
public SQLPropertyExpr clone() {
SQLPropertyExpr propertyExpr = new SQLPropertyExpr();
propertyExpr.name = this.name;
SQLPropertyExpr x = new SQLPropertyExpr();
x.name = this.name;
if (owner != null) {
propertyExpr.setOwner(owner.clone());
x.setOwner(owner.clone());
}
return propertyExpr;
x.resolvedColumn = resolvedColumn;
x.resolvedTableSource = resolvedTableSource;
return x;
}
public boolean matchOwner(String alias) {
@@ -21,7 +21,7 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitor;
* See the License for the specific language governing permissions and
* limitations under the License.
*/
public class SQLTimestampExpr extends SQLExprImpl {
public class SQLTimestampExpr extends SQLExprImpl implements SQLValuableExpr {
public static final SQLDataType DEFAULT_DATA_TYPE = new SQLCharacterDataType("datetime");
protected String literal;
@@ -40,6 +40,10 @@ public class SQLTimestampExpr extends SQLExprImpl {
return x;
}
public String getValue() {
return literal;
}
public String getLiteral() {
return literal;
}
@@ -16,10 +16,7 @@
package com.alibaba.druid.sql.ast.statement;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLDataType;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLObjectImpl;
import com.alibaba.druid.sql.ast.SQLReplaceable;
import com.alibaba.druid.sql.ast.*;
import com.alibaba.druid.sql.ast.expr.SQLAllColumnExpr;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
@@ -180,7 +177,12 @@ public class SQLSelectItem extends SQLObjectImpl implements SQLReplaceable {
}
if (expr instanceof SQLAllColumnExpr) {
return true;
SQLTableSource resolvedTableSource = ((SQLAllColumnExpr) expr).getResolvedTableSource();
if (resolvedTableSource != null
&& resolvedTableSource.findColumn(alias) != null) {
return true;
}
return false;
}
if (expr instanceof SQLIdentifierExpr) {
@@ -191,7 +193,12 @@ public class SQLSelectItem extends SQLObjectImpl implements SQLReplaceable {
if (expr instanceof SQLPropertyExpr) {
String ident = ((SQLPropertyExpr) expr).getName();
if ("*".equals(ident)) {
return true;
SQLTableSource resolvedTableSource = ((SQLPropertyExpr) expr).getResolvedTableSource();
if (resolvedTableSource != null
&& resolvedTableSource.findColumn(alias) != null) {
return true;
}
return false;
}
return alias_normalized.equalsIgnoreCase(SQLUtils.normalize(ident));
@@ -177,8 +177,9 @@ public class MySqlExprParser extends SQLExprParser {
}
case CACHE:
case GROUP:
String strVal = lexer.stringVal();
lexer.nextToken();
return primaryRest(new SQLIdentifierExpr(lexer.stringVal()));
return primaryRest(new SQLIdentifierExpr(strVal));
default:
return super.primary();
}
@@ -269,52 +269,47 @@ public class MySqlLexer extends Lexer {
token = Token.IDENTIFIER;
}
} else {
final boolean firstFlag = isFirstIdentifierChar(first);
if (!firstFlag) {
throw new ParserException("illegal identifier. " + info());
}
long hashCode = 0xcbf29ce484222325L;
hashCode ^= ((ch >= 'A' && ch <= 'Z') ? (ch + 32) : ch);
hashCode *= 0x100000001b3L;
mark = pos;
bufPos = 1;
char ch = '\0', last_ch;
char ch = '\0';
for (;;) {
last_ch = ch;
ch = charAt(++pos);
if (!isIdentifierChar(ch)) {
// if (ch == '-' && pos < text.length() - 1) {
// if (mark > 0 && text.charAt(mark - 1) == '.') {
// break;
// }
//
// char next_char = text.charAt(pos + 1);
// if (isIdentifierChar(next_char)) {
// bufPos++;
// continue;
// }
// }
// if (last_ch == '-' && charAt(pos-2) != '-') {
// ch = last_ch;
// bufPos--;
// pos--;
// }
break;
}
bufPos++;
hashCode ^= ((ch >= 'A' && ch <= 'Z') ? (ch + 32) : ch);
hashCode *= 0x100000001b3L;
continue;
}
this.ch = charAt(pos);
stringVal = addSymbol();
Token tok = keywods.getKeyword(stringVal);
Token tok = keywods.getKeyword(hashCode);
if (tok != null) {
token = tok;
} else {
token = Token.IDENTIFIER;
}
if (token == Token.IDENTIFIER) {
stringVal = addSymbol();
} else {
stringVal = null;
}
}
}
@@ -99,10 +99,6 @@ public class MySqlSelectParser extends SQLSelectParser {
this.exprParser.parseHints(queryBlock.getHints());
}
if (lexer.token() == Token.COMMENT) {
lexer.nextToken();
}
if (lexer.token() == (Token.DISTINCT)) {
queryBlock.setDistionOption(SQLSetQuantifier.DISTINCT);
lexer.nextToken();
@@ -165,7 +165,7 @@ public class MySqlEvalVisitorImpl extends MySqlASTVisitorAdapter implements SQLE
@Override
public boolean visit(SQLBooleanExpr x) {
x.getAttributes().put(EVAL_VALUE, x.getValue());
x.getAttributes().put(EVAL_VALUE, x.getBooleanValue());
return false;
}
}
@@ -889,7 +889,6 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
println();
incrementIndent();
print0(ucase ? "WHERE " : "where ");
x.getWhere().setParent(x);
x.getWhere().accept(this);
decrementIndent();
}
@@ -1252,7 +1251,6 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
if (x.getWhere() != null) {
print0(ucase ? " WHERE " : " where ");
x.getWhere().setParent(x);
x.getWhere().accept(this);
}
@@ -1279,7 +1277,6 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
if (x.getWhere() != null) {
print0(ucase ? " WHERE " : " where ");
x.getWhere().setParent(x);
x.getWhere().accept(this);
}
@@ -1302,7 +1299,6 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
if (x.getWhere() != null) {
print0(ucase ? " WHERE " : " where ");
x.getWhere().setParent(x);
x.getWhere().accept(this);
}
@@ -1355,7 +1351,6 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
if (x.getWhere() != null) {
print0(ucase ? " WHERE " : " where ");
x.getWhere().setParent(x);
x.getWhere().accept(this);
}
@@ -1688,7 +1683,6 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
println();
incrementIndent();
print0(ucase ? "WHERE " : "where ");
x.getWhere().setParent(x);
x.getWhere().accept(this);
decrementIndent();
}
@@ -2377,7 +2371,6 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
if (x.getWhere() != null) {
print0(ucase ? " WHERE " : " where ");
x.getWhere().setParent(x);
x.getWhere().accept(this);
}
@@ -2410,7 +2403,6 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
if (x.getWhere() != null) {
print0(ucase ? " WHERE " : " where ");
x.getWhere().setParent(x);
x.getWhere().accept(this);
}
@@ -3124,7 +3116,6 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
println();
for (int i = 0, size = x.getStatements().size(); i < size; ++i) {
SQLStatement item = x.getStatements().get(i);
item.setParent(x);
item.accept(this);
if (i != size - 1) {
println();
@@ -3151,7 +3142,6 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
println();
for (int i = 0, size = x.getStatements().size(); i < size; ++i) {
SQLStatement item = x.getStatements().get(i);
item.setParent(x);
item.accept(this);
if (i != size - 1) {
println();
@@ -3169,7 +3159,6 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
println();
for (int i = 0, size = x.getStatements().size(); i < size; ++i) {
SQLStatement item = x.getStatements().get(i);
item.setParent(x);
item.accept(this);
if (i != size - 1) {
println();
@@ -3259,7 +3248,6 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
println();
for (int i = 0, size = x.getStatements().size(); i < size; ++i) {
SQLStatement item = x.getStatements().get(i);
item.setParent(x);
item.accept(this);
if (i != size - 1) {
println();
@@ -3583,7 +3571,6 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
}
println();
x.getBlock().setParent(x);
x.getBlock().accept(this);
return false;
}
@@ -1179,8 +1179,6 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS
@Override
public boolean visit(MySqlDeclareStatement x) {
for (SQLDeclareItem item : x.getVarList()) {
item.setParent(x);
SQLName var = (SQLName) item.getName();
this.variants.put(var.toString(), var);
}
@@ -30,7 +30,8 @@ public class NameResolveVisitor extends OracleASTVisitorAdapter {
public boolean visit(SQLIdentifierExpr x) {
SQLObject parent = x.getParent();
if (parent instanceof SQLBinaryOpExpr) {
if (parent instanceof SQLBinaryOpExpr
&& x.getResolvedColumn() == null) {
SQLBinaryOpExpr binaryOpExpr = (SQLBinaryOpExpr) parent;
boolean isJoinCondition = binaryOpExpr.getLeft() instanceof SQLName
&& binaryOpExpr.getRight() instanceof SQLName;
@@ -163,7 +163,6 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
println();
incrementIndent();
print0(ucase ? "WHERE " : "where ");
x.getWhere().setParent(x);
x.getWhere().accept(this);
decrementIndent();
}
@@ -401,14 +400,12 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
if (x.getFrom() == null) {
print0(ucase ? "DUAL" : "dual");
} else {
x.getFrom().setParent(x);
x.getFrom().accept(this);
}
if (x.getWhere() != null) {
println();
print0(ucase ? "WHERE " : "where ");
x.getWhere().setParent(x);
x.getWhere().accept(this);
}
@@ -611,7 +608,6 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
println();
print0(ucase ? "WHERE " : "where ");
incrementIndent();
x.getWhere().setParent(x);
x.getWhere().accept(this);
decrementIndent();
}
@@ -1155,7 +1151,6 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
} else {
if (x.getQuery() != null) {
println();
x.getQuery().setParent(x);
x.getQuery().accept(this);
}
}
@@ -1208,7 +1203,6 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
} else {
if (x.getQuery() != null) {
println();
x.getQuery().setParent(x);
x.getQuery().accept(this);
}
}
@@ -1943,7 +1937,6 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
println();
}
SQLStatement item = x.getStatements().get(i);
item.setParent(x);
item.accept(this);
}
@@ -3214,7 +3207,6 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
for (int i = 0, size = x.getStatements().size(); i < size; ++i) {
println();
SQLStatement item = x.getStatements().get(i);
item.setParent(x);
item.accept(this);
}
@@ -213,10 +213,6 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
}
public boolean visit(OracleSelectQueryBlock x) {
if (x.getWhere() != null) {
x.getWhere().setParent(x);
}
if (x.getInto() instanceof SQLName) {
String tableName = x.getInto().toString();
TableStat stat = getTableStat(tableName);
@@ -742,11 +738,6 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
setAliasMap();
accept(x.getSubQuery());
for (OracleMultiInsertStatement.Entry entry : x.getEntries()) {
entry.setParent(x);
}
accept(x.getEntries());
return false;
@@ -759,12 +750,6 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
@Override
public boolean visit(ConditionalInsertClause x) {
for (ConditionalInsertClauseItem item : x.getItems()) {
item.setParent(x);
}
if (x.getElseItem() != null) {
x.getElseItem().setParent(x);
}
return true;
}
@@ -1031,8 +1016,6 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
@Override
public boolean visit(OracleForStatement x) {
x.getRange().setParent(x);
SQLName index = x.getIndex();
this.getVariants().put(index.toString(), x);
@@ -208,7 +208,6 @@ public class PGOutputVisitor extends SQLASTOutputVisitor implements PGASTVisitor
if (x.getWhere() != null) {
println();
print0(ucase ? "WHERE " : "where ");
x.getWhere().setParent(x);
x.getWhere().accept(this);
}
@@ -307,7 +306,6 @@ public class PGOutputVisitor extends SQLASTOutputVisitor implements PGASTVisitor
println();
print0(ucase ? "WHERE " : "where ");
incrementIndent();
x.getWhere().setParent(x);
x.getWhere().accept(this);
decrementIndent();
}
@@ -412,7 +410,6 @@ public class PGOutputVisitor extends SQLASTOutputVisitor implements PGASTVisitor
println();
print0(ucase ? "WHERE " : "where ");
incrementIndent();
x.getWhere().setParent(x);
x.getWhere().accept(this);
decrementIndent();
}
@@ -15,6 +15,11 @@
*/
package com.alibaba.druid.sql.parser;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.util.JdbcUtils;
import com.alibaba.druid.util.Utils;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@@ -25,6 +30,9 @@ public class Keywords {
private final Map<String, Token> keywords;
private long[] hashArray;
private Token[] tokens;
public final static Keywords DEFAULT_KEYWORDS;
public final static Keywords SQLITE_KEYWORDS;
@@ -169,11 +177,38 @@ public class Keywords {
public Keywords(Map<String, Token> keywords){
this.keywords = keywords;
this.hashArray = new long[keywords.size()];
this.tokens = new Token[keywords.size()];
int index = 0;
for (String k : keywords.keySet()) {
hashArray[index++] = Utils.fnv_64_lower(k);
}
Arrays.sort(hashArray);
for (Map.Entry<String, Token> entry : keywords.entrySet()) {
long k = Utils.fnv_64_lower(entry.getKey());
index = Arrays.binarySearch(hashArray, k);
tokens[index] = entry.getValue();
}
}
public Token getKeyword(long hash) {
int index = Arrays.binarySearch(hashArray, hash);
if (index < 0) {
return null;
}
return tokens[index];
}
public Token getKeyword(String key) {
key = key.toUpperCase();
return keywords.get(key);
long k = Utils.fnv_64_lower(key);
int index = Arrays.binarySearch(hashArray, k);
if (index < 0) {
return null;
}
return tokens[index];
// return keywords.get(key);
}
public Map<String, Token> getKeywords() {
@@ -1417,6 +1417,9 @@ public class Lexer {
* The value of a literal token, recorded as a string. For integers, leading 0x and 'l' suffixes are suppressed.
*/
public final String stringVal() {
if (stringVal == null) {
stringVal = subString(mark, bufPos);
}
return stringVal;
}
@@ -659,7 +659,7 @@ public class SQLExprParser extends SQLParser {
break;
}
default:
throw new ParserException("ERROR" + lexer.info());
throw new ParserException("ERROR. " + lexer.info());
}
SQLExpr expr = primaryRest(sqlExpr);
@@ -882,6 +882,12 @@ public class SQLExprParser extends SQLParser {
methodInvokeExpr.setFrom(from);
}
if (lexer.token == Token.USING) {
lexer.nextToken();
SQLExpr using = this.primary();
methodInvokeExpr.setUsing(using);
}
accept(Token.RPAREN);
if (lexer.token() == Token.OVER) {
@@ -422,6 +422,11 @@ public class SchemaRepository {
return true;
}
public boolean visit(SQLAllColumnExpr x) {
resolve(this, x);
return false;
}
@Override
public boolean isEnabled(Option option) {
return (options & option.mask) != 0;
@@ -464,12 +469,41 @@ public class SchemaRepository {
return true;
}
public boolean visit(SQLAllColumnExpr x) {
resolve(this, x);
return false;
}
@Override
public boolean isEnabled(Option option) {
return (options & option.mask) != 0;
}
}
private void resolve(SchemaResolveVisitor visitor, SQLAllColumnExpr x) {
SQLSelectQueryBlock queryBlock = null;
for (SQLObject parent = x.getParent(); parent != null; parent = parent.getParent()) {
if (parent instanceof SQLTableSource) {
return;
}
if (parent instanceof SQLSelectQueryBlock) {
queryBlock = (SQLSelectQueryBlock) parent;
break;
}
}
if (queryBlock == null) {
return;
}
SQLTableSource from = queryBlock.getFrom();
if (from == null || from instanceof SQLJoinTableSource) {
return;
}
x.setResolvedTableSource(from);
}
private void resolve(SchemaResolveVisitor visitor, SQLPropertyExpr x) {
String owner = x.getOwnernName();
if (owner == null) {
@@ -91,7 +91,7 @@ public final class ExportParameterVisitorUtils {
}
if (param instanceof SQLBooleanExpr) {
value = ((SQLBooleanExpr) param).getValue();
value = ((SQLBooleanExpr) param).getBooleanValue();
replace = true;
}
@@ -39,7 +39,6 @@ import com.alibaba.druid.sql.dialect.oracle.ast.OracleSegmentAttributes;
import com.alibaba.druid.sql.ast.statement.SQLDeclareStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreatePackageStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleForStatement;
import com.alibaba.druid.sql.visitor.functions.Ucase;
import com.alibaba.druid.util.JdbcConstants;
import com.alibaba.druid.util.JdbcUtils;
@@ -605,8 +604,10 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
public boolean visit(SQLCaseExpr x) {
incrementIndent();
print0(ucase ? "CASE " : "case ");
if (x.getValueExpr() != null) {
x.getValueExpr().accept(this);
SQLExpr valueExpr = x.getValueExpr();
if (valueExpr != null) {
valueExpr.accept(this);
}
for (int i = 0, size = x.getItems().size(); i < size; ++i) {
@@ -1073,6 +1074,12 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
from.accept(this);
}
SQLExpr using = x.getUsing();
if (using != null) {
print0(ucase ? " USING " : " using ");
using.accept(this);
}
print(')');
return false;
}
@@ -1367,8 +1374,6 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
}
public boolean visit(SQLSelect x) {
x.getQuery().setParent(x);
if (x.getWithSubQuery() != null) {
x.getWithSubQuery().accept(this);
println();
@@ -1425,7 +1430,6 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
if (where != null) {
println();
print0(ucase ? "WHERE " : "where ");
where.setParent(x);
where.accept(this);
}
@@ -1938,7 +1942,6 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
println();
print0(ucase ? "WHERE " : "where ");
incrementIndent();
x.getWhere().setParent(x);
x.getWhere().accept(this);
decrementIndent();
}
@@ -1970,7 +1973,6 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
} else {
if (x.getQuery() != null) {
println();
x.getQuery().setParent(x);
x.getQuery().accept(this);
}
}
@@ -2037,7 +2039,6 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
println();
incrementIndent();
print0(ucase ? "WHERE " : "where ");
x.getWhere().setParent(x);
x.getWhere().accept(this);
decrementIndent();
}
@@ -2282,7 +2283,17 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
@Override
public boolean visit(SQLJoinTableSource x) {
x.getLeft().accept(this);
SQLTableSource left = x.getLeft();
if (left instanceof SQLJoinTableSource
&& ((SQLJoinTableSource) left).getJoinType() == JoinType.COMMA
&& x.getJoinType() != JoinType.COMMA) {
print('(');
left.accept(this);
print(')');
} else {
left.accept(this);
}
incrementIndent();
if (x.getJoinType() == JoinType.COMMA) {
@@ -3436,7 +3447,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
}
public boolean visit(SQLBooleanExpr x) {
print0(x.getValue() ? "true" : "false");
print0(x.getBooleanValue() ? "true" : "false");
return false;
}
@@ -3727,7 +3738,6 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
println();
for (int i = 0, size = x.getStatements().size(); i < size; ++i) {
SQLStatement item = x.getStatements().get(i);
item.setParent(x);
item.accept(this);
if (i != size - 1) {
println();
@@ -3758,7 +3768,6 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
println();
}
SQLStatement item = x.getStatements().get(i);
item.setParent(x);
item.accept(this);
}
@@ -3779,7 +3788,6 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
println();
}
SQLStatement item = x.getStatements().get(i);
item.setParent(x);
item.accept(this);
}
@@ -3796,7 +3804,6 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
for (int i = 0, size = x.getStatements().size(); i < size; ++i) {
SQLStatement item = x.getStatements().get(i);
item.setParent(x);
item.accept(this);
if (i != size - 1) {
@@ -4403,7 +4410,6 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
incrementIndent();
println();
print0(ucase ? "WHERE " : "where ");
x.getWhere().setParent(x);
x.getWhere().accept(this);
decrementIndent();
}
@@ -4412,7 +4418,6 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
incrementIndent();
println();
print0(ucase ? "DELETE WHERE " : "delete where ");
x.getDeleteWhere().setParent(x);
x.getDeleteWhere().accept(this);
decrementIndent();
}
@@ -4434,7 +4439,6 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
incrementIndent();
println();
print0(ucase ? "WHERE " : "where ");
x.getWhere().setParent(x);
x.getWhere().accept(this);
decrementIndent();
}
@@ -4665,7 +4669,6 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
println();
for (int i = 0, size = x.getStatements().size(); i < size; ++i) {
SQLStatement item = x.getStatements().get(i);
item.setParent(x);
item.accept(this);
if (i != size - 1) {
println();
@@ -148,7 +148,7 @@ public class SQLEvalVisitorImpl extends SQLASTVisitorAdapter implements SQLEvalV
@Override
public boolean visit(SQLBooleanExpr x) {
x.getAttributes().put(EVAL_VALUE, x.getValue());
x.getAttributes().put(EVAL_VALUE, x.getBooleanValue());
return false;
}
@@ -427,9 +427,6 @@ public class Utils {
long hashCode = 0xcbf29ce484222325L;
for (int i = 0; i < key.length(); ++i) {
char ch = key.charAt(i);
if (ch == '_' || ch == '-') {
continue;
}
if (ch >= 'A' && ch <= 'Z') {
ch = (char) (ch + 32);
@@ -15,7 +15,6 @@
*/
package com.alibaba.druid.wall.spi;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLCommentHint;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLLimit;
@@ -63,7 +62,6 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowGrantsStatemen
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement;
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleAlterIndexStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleExecuteImmediateStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGShowStatement;
@@ -232,11 +230,6 @@ public class WallVisitorUtils {
}
public static void checkSelelct(WallVisitor visitor, SQLSelectQueryBlock x) {
for (SQLSelectItem item : x.getSelectList()) {
item.setParent(x);
}
if (x.getInto() != null) {
checkReadOnly(visitor, x.getInto());
}
@@ -246,13 +239,8 @@ public class WallVisitorUtils {
return;
}
if (x.getFrom() != null) {
x.getFrom().setParent(x);
}
SQLExpr where = x.getWhere();
if (where != null) {
where.setParent(x);
checkCondition(visitor, x.getWhere());
Object whereValue = getConditionValue(visitor, where, visitor.getConfig().isSelectWhereAlwayTrueCheck());
@@ -334,7 +322,7 @@ public class WallVisitorUtils {
Object evalValue = part.getAttribute(EVAL_VALUE);
if (evalValue == null) {
if (part instanceof SQLBooleanExpr) {
evalValue = ((SQLBooleanExpr) part).getValue();
evalValue = ((SQLBooleanExpr) part).getBooleanValue();
} else if (part instanceof SQLNumericLiteralExpr) {
evalValue = ((SQLNumericLiteralExpr) part).getNumber();
} else if (part instanceof SQLCharExpr) {
@@ -1475,7 +1463,7 @@ public class WallVisitorUtils {
}
if (x instanceof SQLBooleanExpr) {
return ((SQLBooleanExpr) x).getValue();
return ((SQLBooleanExpr) x).getBooleanValue();
}
if (x instanceof SQLNumericLiteralExpr) {