improved sql parser.

This commit is contained in:
wenshao
2017-06-04 21:30:23 +08:00
parent de4bfb0ae3
commit 21ae9b5722
63 changed files with 1049 additions and 350 deletions
@@ -479,21 +479,7 @@ public class SQLUtils {
}
public static List<SQLExpr> split(SQLBinaryOpExpr x) {
List<SQLExpr> groupList = new ArrayList<SQLExpr>();
groupList.add(x.getRight());
SQLExpr left = x.getLeft();
for (;;) {
if (left instanceof SQLBinaryOpExpr && ((SQLBinaryOpExpr) left).getOperator() == x.getOperator()) {
SQLBinaryOpExpr binaryLeft = (SQLBinaryOpExpr) left;
groupList.add(binaryLeft.getRight());
left = binaryLeft.getLeft();
} else {
groupList.add(left);
break;
}
}
return groupList;
return SQLBinaryOpExpr.split(x);
}
public static String translateOracleToMySql(String sql) {
@@ -789,5 +775,40 @@ public class SQLUtils {
return new SQLUnaryExpr(SQLUnaryOperator.Not, expr);
}
public static String normalize(String name) {
if (name.length() > 2) {
char c0 = name.charAt(0);
char x0 = name.charAt(name.length() - 1);
if ((c0 == '"' && x0 == '"') || (c0 == '`' && x0 == '`')) {
name = name.substring(1, name.length() - 1);
}
}
return name;
}
public static boolean isValue(SQLExpr expr) {
if (expr instanceof SQLLiteralExpr) {
return true;
}
if (expr instanceof SQLVariantRefExpr) {
return true;
}
if (expr instanceof SQLBinaryOpExpr) {
SQLBinaryOpExpr binaryOpExpr = (SQLBinaryOpExpr) expr;
SQLBinaryOperator op = binaryOpExpr.getOperator();
if (op == SQLBinaryOperator.Add
|| op == SQLBinaryOperator.Subtract
|| op == SQLBinaryOperator.Multiply) {
return isValue(binaryOpExpr.getLeft())
&& isValue(binaryOpExpr.getRight());
}
}
return false;
}
}
@@ -26,6 +26,6 @@ public abstract class SQLExprImpl extends SQLObjectImpl implements SQLExpr {
public abstract int hashCode();
public SQLExpr clone() {
throw new UnsupportedOperationException();
throw new UnsupportedOperationException(this.getClass().getName());
}
}
@@ -71,7 +71,17 @@ public class SQLLimit extends SQLObjectImpl {
}
public SQLLimit clone() {
throw new UnsupportedOperationException();
SQLLimit x = new SQLLimit();
if (offset != null) {
x.setOffset(offset.clone());
}
if (rowCount != null) {
x.setRowCount(rowCount.clone());
}
return x;
}
}
@@ -209,6 +209,6 @@ public abstract class SQLObjectImpl implements SQLObject {
}
public SQLObject clone() {
throw new UnsupportedOperationException();
throw new UnsupportedOperationException(this.getClass().getName());
}
}
@@ -98,6 +98,16 @@ public class SQLOrderBy extends SQLObjectImpl {
}
public SQLOrderBy clone() {
throw new UnsupportedOperationException();
SQLOrderBy x = new SQLOrderBy();
for (SQLSelectOrderByItem item : items) {
SQLSelectOrderByItem item1 = item.clone();
item1.setParent(x);
x.items.add(item1);
}
x.sibings = sibings;
return x;
}
}
@@ -40,4 +40,8 @@ public class SQLAllColumnExpr extends SQLExprImpl {
public boolean equals(Object o) {
return o instanceof SQLAllColumnExpr;
}
public SQLAllColumnExpr clone() {
return new SQLAllColumnExpr();
}
}
@@ -16,6 +16,8 @@
package com.alibaba.druid.sql.ast.expr;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLExpr;
@@ -152,4 +154,139 @@ public class SQLBinaryOpExpr extends SQLExprImpl implements Serializable {
public String toString() {
return SQLUtils.toSQLString(this, getDbType());
}
public static SQLExpr combine(List<SQLExpr> items, SQLBinaryOperator op) {
if (items == null || op == null) {
return null;
}
int size = items.size();
if (size == 0) {
return null;
}
if (size == 1) {
return items.get(0);
}
SQLBinaryOpExpr expr = new SQLBinaryOpExpr(items.get(0), op, items.get(1));
for (int i = 2; i < size; ++i) {
SQLExpr item = items.get(i);
expr = new SQLBinaryOpExpr(expr, op, item);
}
return expr;
}
public static List<SQLExpr> split(SQLBinaryOpExpr x) {
return split(x, x.getOperator());
}
public static List<SQLExpr> split(SQLBinaryOpExpr x, SQLBinaryOperator op) {
if (x.getOperator() != op) {
List<SQLExpr> groupList = new ArrayList<SQLExpr>(1);
groupList.add(x);
return groupList;
}
List<SQLExpr> groupList = new ArrayList<SQLExpr>();
split(groupList, x, op);
return groupList;
}
public static void split(List<SQLExpr> outList, SQLExpr expr, SQLBinaryOperator op) {
if (expr == null) {
return;
}
if (!(expr instanceof SQLBinaryOpExpr)) {
outList.add(expr);
return;
}
SQLBinaryOpExpr binaryExpr = (SQLBinaryOpExpr) expr;
if (binaryExpr.getOperator() != op) {
outList.add(binaryExpr);
return;
}
List<SQLExpr> rightList = new ArrayList<SQLExpr>();
rightList.add(binaryExpr.getRight());
for (SQLExpr left = binaryExpr.getLeft();;) {
if (left instanceof SQLBinaryOpExpr) {
SQLBinaryOpExpr leftBinary = (SQLBinaryOpExpr) left;
if (leftBinary.operator == op) {
left = ((SQLBinaryOpExpr) leftBinary).getLeft();
rightList.add(leftBinary.getRight());
} else {
outList.add(leftBinary);
break;
}
} else {
outList.add(left);
break;
}
}
for (int i = rightList.size() - 1; i >= 0; --i) {
SQLExpr right = rightList.get(i);
if (right instanceof SQLBinaryOpExpr) {
SQLBinaryOpExpr binaryRight = (SQLBinaryOpExpr) right;
if (binaryRight.operator == op) {
{
SQLExpr rightLeft = binaryRight.getLeft();
if (rightLeft instanceof SQLBinaryOpExpr) {
SQLBinaryOpExpr rightLeftBinary = (SQLBinaryOpExpr) rightLeft;
if (rightLeftBinary.operator == op) {
split(outList, rightLeftBinary, op);
} else {
outList.add(rightLeftBinary);
}
} else {
outList.add(rightLeft);
}
}
{
SQLExpr rightRight = binaryRight.getRight();
if (rightRight instanceof SQLBinaryOpExpr) {
SQLBinaryOpExpr rightRightBinary = (SQLBinaryOpExpr) rightRight;
if (rightRightBinary.operator == op) {
split(outList, rightRightBinary, op);
} else {
outList.add(rightRightBinary);
}
} else {
outList.add(rightRight);
}
}
} else {
outList.add(binaryRight);
}
} else {
outList.add(right);
}
}
}
public static SQLExpr and(SQLExpr a, SQLExpr b) {
if (a == null) {
return b;
}
if (b == null) {
return a;
}
if (b instanceof SQLBinaryOpExpr) {
SQLBinaryOpExpr bb = (SQLBinaryOpExpr) b;
if (bb.operator == SQLBinaryOperator.BooleanAnd) {
return and(and(a, bb.left), bb.right);
}
}
return new SQLBinaryOpExpr(a, SQLBinaryOperator.BooleanAnd, b);
}
}
@@ -147,6 +147,17 @@ public class SQLCaseExpr extends SQLExprImpl implements Serializable {
return true;
}
public Item clone() {
Item x = new Item();
if (conditionExpr != null) {
x.setConditionExpr(conditionExpr.clone());
}
if (valueExpr != null) {
x.setValueExpr(valueExpr.clone());
}
return x;
}
}
@Override
@@ -195,4 +206,22 @@ public class SQLCaseExpr extends SQLExprImpl implements Serializable {
return true;
}
public SQLCaseExpr clone() {
SQLCaseExpr x = new SQLCaseExpr();
for (Item item : items) {
x.addItem(item.clone());
}
if (valueExpr != null) {
x.setValueExpr(valueExpr.clone());
}
if (elseExpr != null) {
x.setElseExpr(elseExpr.clone());
}
return x;
}
}
@@ -42,4 +42,8 @@ public class SQLNCharExpr extends SQLTextLiteralExpr {
visitor.visit(this);
visitor.endVisit(this);
}
public SQLNCharExpr clone() {
return new SQLNCharExpr(text);
}
}
@@ -86,4 +86,12 @@ public class SQLNotExpr extends SQLExprImpl implements Serializable {
}
return true;
}
public SQLNotExpr clone() {
SQLNotExpr x = new SQLNotExpr();
if (expr != null) {
x.setExpr(expr.clone());
}
return x;
}
}
@@ -48,4 +48,8 @@ public class SQLNullExpr extends SQLExprImpl implements SQLLiteralExpr, SQLValua
public Object getValue() {
return EVAL_VALUE_NULL;
}
public SQLNullExpr clone() {
return new SQLNullExpr();
}
}
@@ -76,4 +76,8 @@ public class SQLNumberExpr extends SQLNumericLiteralExpr {
}
return true;
}
public SQLNumberExpr clone() {
return new SQLNumberExpr(number);
}
}
@@ -47,6 +47,14 @@ public class SQLPropertyExpr extends SQLExprImpl implements SQLName {
return this.owner;
}
public String getOwnernName() {
if (owner instanceof SQLIdentifierExpr) {
return ((SQLIdentifierExpr) owner).getName();
}
return null;
}
public void setOwner(SQLExpr owner) {
if (owner != null) {
owner.setParent(this);
@@ -123,4 +131,11 @@ public class SQLPropertyExpr extends SQLExprImpl implements SQLName {
return propertyExpr;
}
public boolean matchOwner(String alias) {
if (owner instanceof SQLIdentifierExpr) {
return ((SQLIdentifierExpr) owner).getName().equalsIgnoreCase(alias);
}
return false;
}
}
@@ -18,6 +18,7 @@ package com.alibaba.druid.sql.ast.statement;
import java.util.ArrayList;
import java.util.List;
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.SQLName;
@@ -271,14 +272,6 @@ public class SQLColumnDefinition extends SQLObjectImpl implements SQLTableElemen
alias = ((SQLPropertyExpr) name).getName();
}
if (alias.length() > 2) {
char c0 = alias.charAt(0);
char x0 = alias.charAt(alias.length() - 1);
if ((c0 == '"' && x0 == '"') || (c0 == '`' && x0 == '`')) {
alias = alias.substring(1, alias.length() - 1);
}
}
return alias;
return SQLUtils.normalize(alias);
}
}
@@ -19,9 +19,14 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLStatementImpl;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlTableIndex;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
import com.alibaba.druid.stat.TableStat;
public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLStatement {
@@ -152,5 +157,60 @@ public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLS
return !comments.isEmpty();
}
public String computeName() {
if (tableSource == null) {
return null;
}
SQLExpr expr = tableSource.getExpr();
if (expr instanceof SQLName) {
String name = ((SQLName) expr).getSimpleName();
return SQLUtils.normalize(name);
}
return null;
}
public SQLColumnDefinition findColumn(String columName) {
for (SQLTableElement element : tableElementList) {
if (element instanceof SQLColumnDefinition) {
SQLColumnDefinition column = (SQLColumnDefinition) element;
String name = column.computeAlias();
if (columName.equalsIgnoreCase(name)) {
return column;
}
}
}
return null;
}
public SQLTableElement findKey(String columnName) {
for (SQLTableElement element : tableElementList) {
List<SQLExpr> keyColumns = null;
if (element instanceof SQLUniqueConstraint) {
SQLUniqueConstraint unique = (SQLUniqueConstraint) element;
keyColumns = unique.getColumns();
} else if (element instanceof MySqlTableIndex) {
keyColumns = ((MySqlTableIndex) element).getColumns();
}
if (keyColumns == null) {
continue;
}
for (SQLExpr columnExpr : keyColumns) {
if (columnExpr instanceof SQLIdentifierExpr) {
String keyColumName = ((SQLIdentifierExpr) columnExpr).getName();
keyColumName = SQLUtils.normalize(keyColumName);
if (keyColumName.equalsIgnoreCase(columnName)) {
return element;
}
}
}
}
return null;
}
}
@@ -18,6 +18,7 @@ package com.alibaba.druid.sql.ast.statement;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
@@ -117,15 +118,7 @@ public class SQLExprTableSource extends SQLTableSourceImpl {
}
}
if (alias.length() > 2) {
char c0 = alias.charAt(0);
char x0 = alias.charAt(alias.length() - 1);
if ((c0 == '"' && x0 == '"') || (c0 == '`' && x0 == '`')) {
alias = alias.substring(1, alias.length() - 1);
}
}
return alias;
return SQLUtils.normalize(alias);
}
public SQLExprTableSource clone() {
@@ -135,6 +128,8 @@ public class SQLExprTableSource extends SQLTableSourceImpl {
}
public void cloneTo(SQLExprTableSource x) {
x.alias = alias;
if (expr != null) {
x.expr = expr.clone();
}
@@ -165,4 +165,33 @@ public class SQLJoinTableSource extends SQLTableSourceImpl {
return joinType.name;
}
}
public void cloneTo(SQLJoinTableSource x) {
x.alias = alias;
if (left != null) {
x.setLeft(left.clone());
}
x.joinType = joinType;
if (right != null) {
x.setRight(right.clone());
}
for (SQLExpr item : using) {
SQLExpr item2 = item.clone();
item2.setParent(x);
x.using.add(item2);
}
x.natural = natural;
}
public SQLJoinTableSource clone() {
SQLJoinTableSource x = new SQLJoinTableSource();
cloneTo(x);
return x;
}
}
@@ -33,7 +33,7 @@ public class SQLSelect extends SQLObjectImpl {
protected SQLObject restriction;
protected boolean forBrowse;
protected List<String> forXmlOptions = new ArrayList<String>(4);
protected List<String> forXmlOptions = null;
protected SQLExpr xmlPath;
protected SQLExpr rowCount;
@@ -148,7 +148,7 @@ public class SQLSelect extends SQLObjectImpl {
x.withSubQuery = this.withSubQuery;
x.query = this.query;
if (orderBy != null) {
x.setOrderBy(this.orderBy);
x.setOrderBy(this.orderBy.clone());
}
if (restriction != null) {
x.setRestriction(restriction.clone());
@@ -160,9 +160,39 @@ public class SQLSelect extends SQLObjectImpl {
}
}
x.forBrowse = forBrowse;
if (forXmlOptions != null) {
x.forXmlOptions = new ArrayList<String>(forXmlOptions);
}
if (xmlPath != null) {
x.setXmlPath(xmlPath.clone());
}
if (rowCount != null) {
x.setRowCount(rowCount.clone());
}
if (offset != null) {
x.setOffset(offset.clone());
}
return x;
}
public boolean isSimple() {
return withSubQuery == null
&& orderBy == null
&& (hints == null || hints.size() == 0)
&& restriction == null
&& (!forBrowse)
&& (forXmlOptions == null || forXmlOptions.size() == 0)
&& xmlPath == null
&& rowCount == null
&& offset == null;
}
public SQLObject getRestriction() {
return this.restriction;
}
@@ -183,11 +213,18 @@ public class SQLSelect extends SQLObjectImpl {
}
public List<String> getForXmlOptions() {
if (forXmlOptions == null) {
forXmlOptions = new ArrayList<String>(4);
}
return forXmlOptions;
}
public void setForXmlOptions(List<String> forXmlOptions) {
this.forXmlOptions = forXmlOptions;
public int getForXmlOptionsSize() {
if (forXmlOptions == null) {
return 0;
}
return forXmlOptions.size();
}
public SQLExpr getRowCount() {
@@ -15,6 +15,7 @@
*/
package com.alibaba.druid.sql.ast.statement;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLObjectImpl;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
@@ -75,15 +76,7 @@ public class SQLSelectItem extends SQLObjectImpl {
}
}
if (alias.length() > 2) {
char c0 = alias.charAt(0);
char x0 = alias.charAt(alias.length() - 1);
if ((c0 == '"' && x0 == '"') || (c0 == '`' && x0 == '`')) {
alias = alias.substring(1, alias.length() - 1);
}
}
return alias;
return SQLUtils.normalize(alias);
}
public String getAlias() {
@@ -119,4 +119,15 @@ public class SQLSelectOrderByItem extends SQLObjectImpl {
throw new IllegalArgumentException();
}
}
public SQLSelectOrderByItem clone() {
SQLSelectOrderByItem x = new SQLSelectOrderByItem();
if (expr != null) {
x.setExpr(expr.clone());
}
x.collate = collate;
x.type = type;
x.nullsOrderType = nullsOrderType;
return x;
}
}
@@ -318,11 +318,11 @@ public class SQLSelectQueryBlock extends SQLObjectImpl implements SQLSelectQuery
public SQLSelectQueryBlock clone() {
SQLSelectQueryBlock x = new SQLSelectQueryBlock();
clone(x);
cloneTo(x);
return x;
}
public void clone(SQLSelectQueryBlock x) {
public void cloneTo(SQLSelectQueryBlock x) {
x.distionOption = distionOption;
@@ -69,6 +69,9 @@ public class SQLSubqueryTableSource extends SQLTableSourceImpl {
public SQLSubqueryTableSource clone() {
SQLSubqueryTableSource x = new SQLSubqueryTableSource();
x.alias = alias;
if (select != null) {
x.select = select.clone();
}
@@ -29,4 +29,6 @@ public interface SQLTableSource extends SQLObject {
List<SQLHint> getHints();
SQLTableSource clone();
String computeAlias();
}
@@ -64,7 +64,11 @@ public abstract class SQLTableSourceImpl extends SQLObjectImpl implements SQLTab
}
public SQLTableSource clone() {
throw new UnsupportedOperationException();
throw new UnsupportedOperationException(this.getClass().getName());
}
public String computeAlias() {
return alias;
}
}
@@ -113,4 +113,19 @@ public class OracleSelectJoin extends SQLJoinTableSource implements OracleSelect
public String toString () {
return SQLUtils.toOracleString(this);
}
public SQLJoinTableSource clone() {
OracleSelectJoin x = new OracleSelectJoin();
cloneTo(x);
if (pivot != null) {
x.setPivot(pivot.clone());
}
if (flashback != null) {
x.setFlashback(flashback.clone());
}
return x;
}
}
@@ -28,32 +28,36 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class OracleSelectQueryBlock extends SQLSelectQueryBlock {
private final List<SQLCommentHint> hints = new ArrayList<SQLCommentHint>(1);
private List<SQLCommentHint> hints;
private ModelClause modelClause;
private final List<SQLExpr> forUpdateOf = new ArrayList<SQLExpr>(1);
private List<SQLExpr> forUpdateOf;
private boolean skipLocked = false;
public OracleSelectQueryBlock clone() {
OracleSelectQueryBlock x = new OracleSelectQueryBlock();
super.clone(x);
super.cloneTo(x);
for (SQLCommentHint hint : hints) {
SQLCommentHint hint1 = hint.clone();
hint1.setParent(x);
x.getHints().add(hint1);
if (hints != null) {
for (SQLCommentHint hint : hints) {
SQLCommentHint hint1 = hint.clone();
hint1.setParent(x);
x.getHints().add(hint1);
}
}
if (modelClause != null) {
x.setModelClause(modelClause.clone());
}
for (SQLExpr item : forUpdateOf) {
SQLExpr item1 = item.clone();
item1.setParent(x);
forUpdateOf.add(item1);
if (forUpdateOf != null) {
for (SQLExpr item : forUpdateOf) {
SQLExpr item1 = item.clone();
item1.setParent(x);
forUpdateOf.add(item1);
}
}
x.skipLocked = skipLocked;
@@ -74,13 +78,35 @@ public class OracleSelectQueryBlock extends SQLSelectQueryBlock {
}
public List<SQLCommentHint> getHints() {
if (hints == null) {
hints = new ArrayList<SQLCommentHint>(1);
}
return this.hints;
}
public int getHintsSize() {
if (hints == null) {
return 0;
}
return hints.size();
}
public List<SQLExpr> getForUpdateOf() {
if (forUpdateOf == null) {
forUpdateOf = new ArrayList<SQLExpr>(1);
}
return forUpdateOf;
}
public int getForUpdateOfSize() {
if (forUpdateOf == null) {
return 0;
}
return forUpdateOf.size();
}
public boolean isSkipLocked() {
return skipLocked;
}
@@ -34,31 +34,6 @@ public class OracleSelectTableReference extends SQLExprTableSource implements Or
protected FlashbackQueryClause flashback;
public OracleSelectTableReference clone() {
OracleSelectTableReference x = new OracleSelectTableReference();
cloneTo(x);
x.only = only;
if (pivot != null) {
x.setPivot(pivot.clone());
}
if (partition != null) {
x.setPartition(partition.clone());
}
if (sampleClause != null) {
x.setSampleClause(sampleClause.clone());
}
if (flashback != null) {
setFlashback(flashback.clone());
}
return x;
}
public OracleSelectTableReference(){
}
@@ -167,4 +142,29 @@ public class OracleSelectTableReference extends SQLExprTableSource implements Or
return SQLUtils.toOracleString(this);
}
public OracleSelectTableReference clone() {
OracleSelectTableReference x = new OracleSelectTableReference();
cloneTo(x);
x.only = only;
if (pivot != null) {
x.setPivot(pivot.clone());
}
if (partition != null) {
x.setPartition(partition.clone());
}
if (sampleClause != null) {
x.setSampleClause(sampleClause.clone());
}
if (flashback != null) {
setFlashback(flashback.clone());
}
return x;
}
}
@@ -807,7 +807,7 @@ public class OracleStatementParser extends SQLStatementParser {
return stmt;
}
SQLBlockStatement block = this.parseBlock();
SQLStatement block = this.parseBlock();
stmt.setBlock(block);
@@ -1460,7 +1460,7 @@ public class OracleStatementParser extends SQLStatementParser {
return stmt;
}
public SQLBlockStatement parseBlock() {
public SQLStatement parseBlock() {
SQLBlockStatement block = new SQLBlockStatement();
block.setDbType(JdbcConstants.ORACLE);
@@ -1475,6 +1475,15 @@ public class OracleStatementParser extends SQLStatementParser {
}
}
if (lexer.token() == Token.PROCEDURE) {
SQLCreateProcedureStatement stmt = this.parseCreateProcedure();
for (SQLParameter param : block.getParameters()) {
param.setParent(stmt);
stmt.getParameters().add(param);
}
return stmt;
}
accept(Token.BEGIN);
parseStatementList(block.getStatementList(), -1, block);
@@ -2113,7 +2122,7 @@ public class OracleStatementParser extends SQLStatementParser {
return stmt;
}
SQLBlockStatement block = this.parseBlock();
SQLStatement block = this.parseBlock();
stmt.setBlock(block);
@@ -383,7 +383,7 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
public boolean visit(OracleSelectQueryBlock x) {
print0(ucase ? "SELECT " : "select ");
if (x.getHints().size() > 0) {
if (x.getHintsSize() > 0) {
printAndAccept(x.getHints(), ", ");
print(' ');
}
@@ -437,7 +437,7 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
if (x.isForUpdate()) {
println();
print0(ucase ? "FOR UPDATE" : "for update");
if (x.getForUpdateOf().size() > 0) {
if (x.getForUpdateOfSize() > 0) {
print('(');
printAndAccept(x.getForUpdateOf(), ", ");
print(')');
@@ -423,7 +423,7 @@ public class SQLServerOutputVisitor extends SQLASTOutputVisitor implements SQLSe
print0(ucase ? "FOR BROWSE" : "for browse");
}
if (x.getForXmlOptions().size() > 0) {
if (x.getForXmlOptionsSize() > 0) {
println();
print0(ucase ? "FOR XML " : "for xml ");
for (int i = 0; i < x.getForXmlOptions().size(); ++i) {
@@ -20,6 +20,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.*;
import com.alibaba.druid.sql.ast.expr.*;
import com.alibaba.druid.sql.ast.statement.SQLNotNullConstraint;
@@ -822,8 +823,10 @@ public class SQLExprParser extends SQLParser {
methodInvokeExpr = new SQLMethodInvokeExpr(methodName);
}
if (isAggreateFunction(methodName)) {
SQLAggregateExpr aggregateExpr = parseAggregateExpr(methodName);
String aggMethodName = SQLUtils.normalize(methodName);
if (isAggreateFunction(aggMethodName)) {
SQLAggregateExpr aggregateExpr = parseAggregateExpr(aggMethodName);
if (distinct) {
aggregateExpr.setOption(SQLAggregateOption.DISTINCT);
}
@@ -18,15 +18,8 @@ package com.alibaba.druid.sql.visitor;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.ast.SQLDataType;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLObject;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator;
import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr;
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
import com.alibaba.druid.sql.ast.*;
import com.alibaba.druid.sql.ast.expr.*;
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
import com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem;
import com.alibaba.druid.sql.dialect.db2.visitor.DB2OutputVisitor;
@@ -38,6 +31,7 @@ import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerTop;
import com.alibaba.druid.sql.dialect.sqlserver.visitor.SQLServerOutputVisitor;
import com.alibaba.druid.sql.parser.SQLParserUtils;
import com.alibaba.druid.sql.parser.SQLStatementParser;
import com.alibaba.druid.util.JdbcConstants;
import com.alibaba.druid.util.JdbcUtils;
public class ParameterizedOutputVisitorUtils {
@@ -21,4 +21,6 @@ public interface ParameterizedVisitor extends PrintableVisitor {
void incrementReplaceCunt();
String getDbType();
}
@@ -251,16 +251,25 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
protected void printSelectList(List<SQLSelectItem> selectList) {
incrementIndent();
for (int i = 0, size = selectList.size(); i < size; ++i) {
for (int i = 0, lineItemCount = 0, size = selectList.size()
; i < size; ++i, ++lineItemCount) {
SQLSelectItem selectItem = selectList.get(i);
SQLExpr selectItemExpr = selectItem.getExpr();
if (i != 0) {
if (i % selectListNumberOfLine == 0) {
if (lineItemCount == selectListNumberOfLine
|| selectItemExpr instanceof SQLQueryExpr) {
lineItemCount = 0;
println();
}
print0(", ");
}
selectList.get(i).accept(this);
if (selectItem.getClass() == SQLSelectItem.class) {
this.visit(selectItem);
} else {
selectItem.accept(this);
}
}
decrementIndent();
}
@@ -623,8 +632,8 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
incrementIndent();
println();
x.getSubQuery().accept(this);
println();
decrementIndent();
println();
print(')');
return false;
}
@@ -816,6 +825,23 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
}
public boolean visit(SQLIntegerExpr x) {
int val = x.getNumber().intValue();
if (val == 1
&& JdbcConstants.ORACLE.equals(dbType)) {
SQLObject parent = x.getParent();
if (parent instanceof SQLBinaryOpExpr) {
SQLBinaryOpExpr binaryOpExpr = (SQLBinaryOpExpr) parent;
SQLExpr left = binaryOpExpr.getLeft();
if (left instanceof SQLIdentifierExpr
&& binaryOpExpr.getOperator() == SQLBinaryOperator.Equality) {
String name = ((SQLIdentifierExpr) left).getName();
if ("rownum".equals(name)) {
print(1);
return false;
}
}
}
}
if (this.parameterized
&& ParameterizedOutputVisitorUtils.checkParameterize(x)) {
if (!ParameterizedOutputVisitorUtils.checkParameterize(x)) {
@@ -1074,8 +1100,8 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
incrementIndent();
println();
x.getSubQuery().accept(this);
println();
decrementIndent();
println();
print(')');
}
return false;
@@ -1984,22 +2010,28 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
print(' ');
SQLTableSource right = x.getRight();
boolean isSubquery = false;
if(right instanceof SQLSubqueryTableSource) {
isSubquery = true;
}
right.accept(this);
if (x.getCondition() != null) {
if (isSubquery) {
SQLExpr condition = x.getCondition();
if (condition != null) {
boolean newLine = false;
if(right instanceof SQLSubqueryTableSource) {
newLine = true;
} else if (condition instanceof SQLBinaryOpExpr) {
SQLBinaryOperator op = ((SQLBinaryOpExpr) condition).getOperator();
if (op == SQLBinaryOperator.BooleanAnd || op == SQLBinaryOperator.BooleanOr) {
newLine = true;
}
}
if (newLine) {
println();
} else {
print(' ');
}
incrementIndent();
print0(ucase ? "ON " : "on ");
x.getCondition().accept(this);
condition.accept(this);
decrementIndent();
}
@@ -2090,8 +2122,10 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
}
incrementIndent();
println();
x.getSubQuery().accept(this);
decrementIndent();
println();
print(')');
return false;
@@ -15,8 +15,10 @@
*/
package com.alibaba.druid.util;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.support.logging.Log;
import com.alibaba.druid.support.logging.LogFactory;
import com.fasterxml.jackson.databind.ObjectMapper;
import javax.sql.DataSource;
import java.io.Closeable;
@@ -740,4 +742,31 @@ public final class JdbcUtils implements JdbcConstants {
return sql.toString();
}
public static <T> void executeQuery(DataSource dataSource
, ResultSetConsumer<T> consumer
, String sql
, Object... parameters) throws SQLException {
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
conn = dataSource.getConnection();
stmt = conn.prepareStatement(sql);
for (int i = 0; i < parameters.length; ++i) {
stmt.setObject(i + 1, parameters[i]);
}
rs = stmt.executeQuery();
while (rs.next()) {
if (consumer != null) {
T object = consumer.apply(rs);
consumer.accept(object);
}
}
} finally {
close(rs);
close(stmt);
close(conn);
}
}
}
@@ -0,0 +1,27 @@
/*
* 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.util;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* Created by wenshao on 03/06/2017.
*/
public interface ResultSetConsumer<T> {
T apply(ResultSet rs) throws SQLException;
void accept(T object);
}
@@ -120,7 +120,7 @@ public class WallVisitorUtils {
public static boolean check(WallVisitor visitor, SQLBinaryOpExpr x) {
if (x.getOperator() == SQLBinaryOperator.BooleanOr || x.getOperator() == SQLBinaryOperator.BooleanAnd) {
List<SQLExpr> groupList = SQLUtils.split(x);
List<SQLExpr> groupList = SQLBinaryOpExpr.split(x);
for (SQLExpr item : groupList) {
item.accept(visitor);
}
@@ -128,7 +128,7 @@ public class WallVisitorUtils {
}
if (x.getOperator() == SQLBinaryOperator.Add || x.getOperator() == SQLBinaryOperator.Concat) {
List<SQLExpr> groupList = SQLUtils.split(x);
List<SQLExpr> groupList = SQLBinaryOpExpr.split(x);
if (groupList.size() >= 4) {
int chrCount = 0;
for (int i = 0; i < groupList.size(); ++i) {
@@ -922,7 +922,7 @@ public class WallVisitorUtils {
public static Object getValue(WallVisitor visitor, SQLBinaryOpExpr x) {
if (x.getOperator() == SQLBinaryOperator.BooleanOr) {
List<SQLExpr> groupList = SQLUtils.split(x);
List<SQLExpr> groupList = SQLBinaryOpExpr.split(x);
boolean allFalse = true;
for (int i = groupList.size() - 1; i >= 0; --i) {
@@ -951,7 +951,7 @@ public class WallVisitorUtils {
if (x.getOperator() == SQLBinaryOperator.BooleanAnd) {
List<SQLExpr> groupList = SQLUtils.split(x);
List<SQLExpr> groupList = SQLBinaryOpExpr.split(x);
int dalConst = 0;
Boolean allTrue = Boolean.TRUE;