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:
@@ -185,6 +185,12 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
}
|
||||
|
||||
public void configFromPropety(Properties properties) {
|
||||
{
|
||||
String property = properties.getProperty("druid.name");
|
||||
if (property != null) {
|
||||
this.setName(property);
|
||||
}
|
||||
}
|
||||
{
|
||||
String property = properties.getProperty("druid.url");
|
||||
if (property != null) {
|
||||
|
||||
@@ -96,7 +96,7 @@ public class MySqlExceptionSorter implements ExceptionSorter {
|
||||
|
||||
Throwable cause = e.getCause();
|
||||
for (int i = 0; i < 5 && cause != null; ++i) {
|
||||
if (cause instanceof SocketTimeoutException || cause instanceof IOException) {
|
||||
if (cause instanceof SocketTimeoutException) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -443,7 +443,7 @@ public class PagerUtils {
|
||||
countSelectQuery.setFrom(fromSubquery);
|
||||
|
||||
SQLSelect countSelect = new SQLSelect(countSelectQuery);
|
||||
SQLSelectStatement countStmt = new SQLSelectStatement(countSelect);
|
||||
SQLSelectStatement countStmt = new SQLSelectStatement(countSelect, dbType);
|
||||
|
||||
return SQLUtils.toSQLString(countStmt, dbType);
|
||||
}
|
||||
|
||||
@@ -301,7 +301,7 @@ public class SQLUtils {
|
||||
if (j != 0) {
|
||||
visitor.println();
|
||||
}
|
||||
visitor.print(comment);
|
||||
visitor.printComment(comment);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -317,7 +317,8 @@ public class SQLUtils {
|
||||
List<String> comments = stmt.getBeforeCommentsDirect();
|
||||
if (comments != null){
|
||||
for(String comment : comments) {
|
||||
visitor.println(comment);
|
||||
visitor.printComment(comment);
|
||||
visitor.println();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -331,7 +332,7 @@ public class SQLUtils {
|
||||
if (j != 0) {
|
||||
visitor.println();
|
||||
}
|
||||
visitor.print(comment);
|
||||
visitor.printComment(comment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.ast;
|
||||
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
@@ -50,10 +52,18 @@ public class SQLLimit extends SQLObjectImpl {
|
||||
this.rowCount = rowCount;
|
||||
}
|
||||
|
||||
public void setRowCount(int rowCount) {
|
||||
this.setRowCount(new SQLIntegerExpr(rowCount));
|
||||
}
|
||||
|
||||
public SQLExpr getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
public void setOffset(int offset) {
|
||||
this.setOffset(new SQLIntegerExpr(offset));
|
||||
}
|
||||
|
||||
public void setOffset(SQLExpr offset) {
|
||||
if (offset != null) {
|
||||
offset.setParent(this);
|
||||
|
||||
@@ -53,6 +53,19 @@ public class SQLBinaryOpExpr extends SQLExprImpl implements SQLReplaceable, Seri
|
||||
setLeft(left);
|
||||
setRight(right);
|
||||
this.operator = operator;
|
||||
|
||||
if (dbType == null) {
|
||||
if (left instanceof SQLBinaryOpExpr) {
|
||||
dbType = ((SQLBinaryOpExpr) left).dbType;
|
||||
}
|
||||
}
|
||||
|
||||
if (dbType == null) {
|
||||
if (right instanceof SQLBinaryOpExpr) {
|
||||
dbType = ((SQLBinaryOpExpr) right).dbType;
|
||||
}
|
||||
}
|
||||
|
||||
this.dbType = dbType;
|
||||
}
|
||||
|
||||
@@ -392,4 +405,16 @@ public class SQLBinaryOpExpr extends SQLExprImpl implements SQLReplaceable, Seri
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public SQLExpr other(SQLExpr x) {
|
||||
if (x == left) {
|
||||
return right;
|
||||
}
|
||||
|
||||
if (x == right) {
|
||||
return left;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLExprImpl;
|
||||
import com.alibaba.druid.sql.ast.SQLReplaceable;
|
||||
@@ -185,4 +186,28 @@ public class SQLMethodInvokeExpr extends SQLExprImpl implements SQLReplaceable,
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean match(String owner, String function) {
|
||||
if (function == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!SQLUtils.nameEquals(function, methodName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (owner == null && this.owner == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (owner == null || this.owner == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.owner instanceof SQLIdentifierExpr) {
|
||||
return SQLUtils.nameEquals(((SQLIdentifierExpr) this.owner).name, owner);
|
||||
}
|
||||
|
||||
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.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.SQLObjectImpl;
|
||||
@@ -58,6 +59,20 @@ public class SQLCreateViewStatement extends SQLStatementImpl implements SQLDDLSt
|
||||
super(dbType);
|
||||
}
|
||||
|
||||
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 boolean isOrReplace() {
|
||||
return orReplace;
|
||||
}
|
||||
|
||||
@@ -79,22 +79,22 @@ public class SQLJoinTableSource extends SQLTableSourceImpl implements SQLReplace
|
||||
this.left = left;
|
||||
}
|
||||
|
||||
public void setLeft(String tableName) {
|
||||
public void setLeft(String tableName, String alias) {
|
||||
SQLExprTableSource tableSource;
|
||||
if (tableName == null || tableName.length() == 0) {
|
||||
tableSource = null;
|
||||
} else {
|
||||
tableSource = new SQLExprTableSource(new SQLIdentifierExpr(tableName));
|
||||
tableSource = new SQLExprTableSource(new SQLIdentifierExpr(tableName), alias);
|
||||
}
|
||||
this.setLeft(tableSource);
|
||||
}
|
||||
|
||||
public void setRight(String tableName) {
|
||||
public void setRight(String tableName, String alias) {
|
||||
SQLExprTableSource tableSource;
|
||||
if (tableName == null || tableName.length() == 0) {
|
||||
tableSource = null;
|
||||
} else {
|
||||
tableSource = new SQLExprTableSource(new SQLIdentifierExpr(tableName));
|
||||
tableSource = new SQLExprTableSource(new SQLIdentifierExpr(tableName), alias);
|
||||
}
|
||||
this.setRight(tableSource);
|
||||
}
|
||||
@@ -228,4 +228,41 @@ public class SQLJoinTableSource extends SQLTableSourceImpl implements SQLReplace
|
||||
cloneTo(x);
|
||||
return x;
|
||||
}
|
||||
|
||||
public void reverse() {
|
||||
SQLTableSource temp = left;
|
||||
left = right;
|
||||
right = temp;
|
||||
|
||||
if (left instanceof SQLJoinTableSource) {
|
||||
((SQLJoinTableSource) left).reverse();
|
||||
}
|
||||
|
||||
if (right instanceof SQLJoinTableSource) {
|
||||
((SQLJoinTableSource) right).reverse();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* a inner_join (b inner_join c) -> a inner_join b innre_join c
|
||||
*/
|
||||
public void rearrangement() {
|
||||
if (right instanceof SQLJoinTableSource) {
|
||||
SQLJoinTableSource rightJoin = (SQLJoinTableSource) right;
|
||||
|
||||
SQLTableSource a = left;
|
||||
SQLTableSource b = rightJoin.getLeft();
|
||||
SQLTableSource c = rightJoin.getRight();
|
||||
SQLExpr on_ab = condition;
|
||||
SQLExpr on_bc = rightJoin.condition;
|
||||
|
||||
setLeft(rightJoin);
|
||||
rightJoin.setLeft(a);
|
||||
rightJoin.setRight(b);
|
||||
rightJoin.setCondition(on_ab);
|
||||
|
||||
setRight(c);
|
||||
setCondition(on_bc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,12 +162,12 @@ public class SQLSelectQueryBlock extends SQLObjectImpl implements SQLSelectQuery
|
||||
this.from = from;
|
||||
}
|
||||
|
||||
public void setFrom(String tableName) {
|
||||
public void setFrom(String tableName, String alias) {
|
||||
SQLExprTableSource from;
|
||||
if (tableName == null || tableName.length() == 0) {
|
||||
from = null;
|
||||
} else {
|
||||
from = new SQLExprTableSource(new SQLIdentifierExpr(tableName));
|
||||
from = new SQLExprTableSource(new SQLIdentifierExpr(tableName), alias);
|
||||
}
|
||||
this.setFrom(from);
|
||||
}
|
||||
|
||||
@@ -250,45 +250,51 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
|
||||
printSelectList(x.getSelectList());
|
||||
|
||||
if (x.getInto() != null) {
|
||||
SQLExprTableSource into = x.getInto();
|
||||
if (into != null) {
|
||||
println();
|
||||
print0(ucase ? "INTO " : "into ");
|
||||
x.getInto().accept(this);
|
||||
into.accept(this);
|
||||
}
|
||||
|
||||
if (x.getFrom() != null) {
|
||||
SQLTableSource form = x.getFrom();
|
||||
if (form != null) {
|
||||
println();
|
||||
print0(ucase ? "FROM " : "from ");
|
||||
x.getFrom().accept(this);
|
||||
form.accept(this);
|
||||
}
|
||||
|
||||
if (x.getWhere() != null) {
|
||||
SQLExpr where = x.getWhere();
|
||||
if (where != null) {
|
||||
println();
|
||||
print0(ucase ? "WHERE " : "where ");
|
||||
x.getWhere().setParent(x);
|
||||
x.getWhere().accept(this);
|
||||
where.accept(this);
|
||||
}
|
||||
|
||||
printHierarchical(x);
|
||||
|
||||
if (x.getGroupBy() != null) {
|
||||
SQLSelectGroupByClause groupBy = x.getGroupBy();
|
||||
if (groupBy != null) {
|
||||
println();
|
||||
x.getGroupBy().accept(this);
|
||||
groupBy.accept(this);
|
||||
}
|
||||
|
||||
if (x.getOrderBy() != null) {
|
||||
SQLOrderBy orderBy = x.getOrderBy();
|
||||
if (orderBy != null) {
|
||||
println();
|
||||
x.getOrderBy().accept(this);
|
||||
orderBy.accept(this);
|
||||
}
|
||||
|
||||
if (x.getLimit() != null) {
|
||||
SQLLimit limit = x.getLimit();
|
||||
if (limit != null) {
|
||||
println();
|
||||
x.getLimit().accept(this);
|
||||
limit.accept(this);
|
||||
}
|
||||
|
||||
if (x.getProcedureName() != null) {
|
||||
SQLName procedureName = x.getProcedureName();
|
||||
if (procedureName != null) {
|
||||
print0(ucase ? " PROCEDURE " : " procedure ");
|
||||
x.getProcedureName().accept(this);
|
||||
procedureName.accept(this);
|
||||
if (!x.getProcedureArgumentList().isEmpty()) {
|
||||
print('(');
|
||||
printAndAccept(x.getProcedureArgumentList(), ", ");
|
||||
|
||||
+49
-5
@@ -16,17 +16,21 @@
|
||||
package com.alibaba.druid.sql.dialect.mysql.visitor.transform;
|
||||
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
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.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.*;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectJoin;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectSubqueryTableSource;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectTableReference;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitorAdapter;
|
||||
import oracle.sql.SQLName;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author wenshao[szujobs@hotmail.com]
|
||||
@@ -34,6 +38,9 @@ import java.util.List;
|
||||
public class FromSubqueryResolver extends OracleASTVisitorAdapter {
|
||||
private final List<SQLStatement> targetList;
|
||||
private final String viewName;
|
||||
private final Map<String, String> mappings = new LinkedHashMap<String, String>();
|
||||
|
||||
private int viewNameSeed = 1;
|
||||
|
||||
public FromSubqueryResolver(List<SQLStatement> targetList, String viewName) {
|
||||
this.targetList = targetList;
|
||||
@@ -50,13 +57,13 @@ public class FromSubqueryResolver extends OracleASTVisitorAdapter {
|
||||
SQLObject parent = x.getParent();
|
||||
if(parent instanceof SQLSelectQueryBlock) {
|
||||
SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) parent;
|
||||
queryBlock.setFrom(subViewName);
|
||||
queryBlock.setFrom(subViewName, x.getAlias());
|
||||
} else if(parent instanceof SQLJoinTableSource) {
|
||||
SQLJoinTableSource join = (SQLJoinTableSource) parent;
|
||||
if (join.getLeft() == x) {
|
||||
join.setLeft(subViewName);
|
||||
join.setLeft(subViewName, x.getAlias());
|
||||
} else if (join.getRight() == x) {
|
||||
join.setRight(subViewName);
|
||||
join.setRight(subViewName, x.getAlias());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +71,6 @@ public class FromSubqueryResolver extends OracleASTVisitorAdapter {
|
||||
|
||||
stmt.setName(generateSubViewName());
|
||||
|
||||
|
||||
SQLSelect select = x.getSelect();
|
||||
stmt.setSubQuery(select);
|
||||
|
||||
@@ -75,6 +81,23 @@ public class FromSubqueryResolver extends OracleASTVisitorAdapter {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLExprTableSource x) {
|
||||
SQLExpr expr = x.getExpr();
|
||||
if (expr instanceof SQLIdentifierExpr) {
|
||||
SQLIdentifierExpr identifierExpr = (SQLIdentifierExpr) expr;
|
||||
String ident = identifierExpr.getName();
|
||||
String mappingIdent = mappings.get(ident);
|
||||
if (mappingIdent != null) {
|
||||
identifierExpr.setName(mappingIdent);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(OracleSelectTableReference x) {
|
||||
return visit((SQLExprTableSource) x);
|
||||
}
|
||||
|
||||
private String generateSubViewName() {
|
||||
return this.viewName + "_" + targetList.size();
|
||||
}
|
||||
@@ -86,6 +109,28 @@ public class FromSubqueryResolver extends OracleASTVisitorAdapter {
|
||||
String viewName = SQLUtils.normalize(stmt.getName().getSimpleName());
|
||||
|
||||
FromSubqueryResolver visitor = new FromSubqueryResolver(targetList, viewName);
|
||||
|
||||
SQLWithSubqueryClause withSubqueryClause = stmt.getSubQuery().getWithSubQuery();
|
||||
if (withSubqueryClause != null) {
|
||||
stmt.getSubQuery().setWithSubQuery(null);
|
||||
|
||||
for (SQLWithSubqueryClause.Entry entry : withSubqueryClause.getEntries()) {
|
||||
String entryName = entry.getName().getName();
|
||||
|
||||
SQLCreateViewStatement entryStmt = new SQLCreateViewStatement();
|
||||
entryStmt.setDbType(stmt.getDbType());
|
||||
|
||||
String entryViewName = visitor.generateSubViewName();
|
||||
entryStmt.setName(entryViewName);
|
||||
entryStmt.setSubQuery(entry.getSubQuery());
|
||||
|
||||
visitor.targetList.add(0, entryStmt);
|
||||
visitor.mappings.put(entryName, entryViewName);
|
||||
|
||||
entryStmt.accept(visitor);
|
||||
}
|
||||
}
|
||||
|
||||
stmt.accept(visitor);
|
||||
|
||||
String dbType = stmt.getDbType();
|
||||
@@ -95,7 +140,6 @@ public class FromSubqueryResolver extends OracleASTVisitorAdapter {
|
||||
targetStmt.setAfterSemi(true);
|
||||
}
|
||||
|
||||
|
||||
return targetList;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -456,22 +456,23 @@ public class OdpsOutputVisitor extends SQLASTOutputVisitor implements OdpsASTVis
|
||||
|
||||
printSelectList(x.getSelectList());
|
||||
|
||||
if (x.getFrom() != null) {
|
||||
SQLTableSource from = x.getFrom();
|
||||
if (from != null) {
|
||||
println();
|
||||
print0(ucase ? "FROM " : "from ");
|
||||
x.getFrom().accept(this);
|
||||
from.accept(this);
|
||||
}
|
||||
|
||||
if (x.getWhere() != null) {
|
||||
SQLExpr where = x.getWhere();
|
||||
if (where != null) {
|
||||
println();
|
||||
print0(ucase ? "WHERE " : "where ");
|
||||
if (x.getWhere().hasBeforeComment() && isPrettyFormat()) {
|
||||
if (where.hasBeforeComment() && isPrettyFormat()) {
|
||||
printlnComments(x.getWhere().getBeforeCommentsDirect());
|
||||
}
|
||||
|
||||
x.getWhere().setParent(x);
|
||||
x.getWhere().accept(this);
|
||||
if (x.getWhere().hasAfterComment() && isPrettyFormat()) {
|
||||
where.accept(this);
|
||||
if (where.hasAfterComment() && isPrettyFormat()) {
|
||||
print(' ');
|
||||
printlnComment(x.getWhere().getAfterCommentsDirect());
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
@@ -35,6 +36,9 @@ public class OracleSelectJoin extends SQLJoinTableSource implements OracleSelect
|
||||
|
||||
}
|
||||
|
||||
public OracleSelectJoin(SQLTableSource left, JoinType joinType, SQLTableSource right, SQLExpr condition){
|
||||
super (left, joinType, right, condition);
|
||||
}
|
||||
|
||||
public OracleSelectPivotBase getPivot() {
|
||||
return pivot;
|
||||
|
||||
@@ -241,6 +241,8 @@ public class OracleExprParser extends SQLExprParser {
|
||||
}
|
||||
|
||||
accept(Token.RPAREN);
|
||||
// } else if (lexer.token() == Token.RPAREN) {
|
||||
// return charType;
|
||||
} else if (restrict) {
|
||||
accept(Token.LPAREN);
|
||||
}
|
||||
@@ -1218,6 +1220,12 @@ public class OracleExprParser extends SQLExprParser {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.CACHE) {
|
||||
lexer.nextToken();
|
||||
clause.setCache(true);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.KEEP_DUPLICATES) {
|
||||
lexer.nextToken();
|
||||
clause.setKeepDuplicate(true);
|
||||
|
||||
+1
-1
@@ -142,7 +142,7 @@ public class OracleStatementParser extends SQLStatementParser {
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.WITH) {
|
||||
SQLSelectStatement stmt = new SQLSelectStatement(this.createSQLSelectParser().select());
|
||||
SQLSelectStatement stmt = new SQLSelectStatement(this.createSQLSelectParser().select(), dbType);
|
||||
stmt.setParent(parent);
|
||||
statementList.add(stmt);
|
||||
continue;
|
||||
|
||||
@@ -118,42 +118,42 @@ public class SQLExprParser extends SQLParser {
|
||||
if (token == Token.CARET) {
|
||||
lexer.nextToken();
|
||||
SQLExpr rightExp = primary();
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BitwiseXor, rightExp, getDbType());
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BitwiseXor, rightExp, dbType);
|
||||
expr = bitXorRest(expr);
|
||||
} else if (token == Token.SUBGT) {
|
||||
lexer.nextToken();
|
||||
SQLExpr rightExp = primary();
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.SubGt, rightExp, getDbType());
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.SubGt, rightExp, dbType);
|
||||
expr = bitXorRest(expr);
|
||||
} else if (token == Token.SUBGTGT) {
|
||||
lexer.nextToken();
|
||||
SQLExpr rightExp = primary();
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.SubGtGt, rightExp, getDbType());
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.SubGtGt, rightExp, dbType);
|
||||
expr = bitXorRest(expr);
|
||||
} else if (token == Token.POUNDGT) {
|
||||
lexer.nextToken();
|
||||
SQLExpr rightExp = primary();
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.PoundGt, rightExp, getDbType());
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.PoundGt, rightExp, dbType);
|
||||
expr = bitXorRest(expr);
|
||||
} else if (token == Token.POUNDGTGT) {
|
||||
lexer.nextToken();
|
||||
SQLExpr rightExp = primary();
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.PoundGtGt, rightExp, getDbType());
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.PoundGtGt, rightExp, dbType);
|
||||
expr = bitXorRest(expr);
|
||||
} else if (token == Token.QUESQUES) {
|
||||
lexer.nextToken();
|
||||
SQLExpr rightExp = primary();
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.QuesQues, rightExp, getDbType());
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.QuesQues, rightExp, dbType);
|
||||
expr = bitXorRest(expr);
|
||||
} else if (token == Token.QUESBAR) {
|
||||
lexer.nextToken();
|
||||
SQLExpr rightExp = primary();
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.QuesBar, rightExp, getDbType());
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.QuesBar, rightExp, dbType);
|
||||
expr = bitXorRest(expr);
|
||||
} else if (token == Token.QUESAMP) {
|
||||
lexer.nextToken();
|
||||
SQLExpr rightExp = primary();
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.QuesAmp, rightExp, getDbType());
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.QuesAmp, rightExp, dbType);
|
||||
expr = bitXorRest(expr);
|
||||
}
|
||||
|
||||
@@ -462,7 +462,7 @@ public class SQLExprParser extends SQLParser {
|
||||
SQLCastExpr cast = new SQLCastExpr();
|
||||
cast.setExpr(expr());
|
||||
accept(Token.AS);
|
||||
cast.setDataType(parseDataType());
|
||||
cast.setDataType(parseDataType(false));
|
||||
accept(Token.RPAREN);
|
||||
|
||||
sqlExpr = cast;
|
||||
@@ -1798,8 +1798,8 @@ public class SQLExprParser extends SQLParser {
|
||||
}
|
||||
|
||||
public SQLDataType parseDataType(boolean restrict) {
|
||||
|
||||
if (lexer.token() == Token.DEFAULT || lexer.token() == Token.NOT || lexer.token() == Token.NULL) {
|
||||
Token token = lexer.token();
|
||||
if (token == Token.DEFAULT || token == Token.NOT || token == Token.NULL) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,372 @@
|
||||
/*
|
||||
* 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.repository;
|
||||
|
||||
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.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLAggregateExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLAllColumnExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.*;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateTableStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitorAdapter;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentSkipListMap;
|
||||
|
||||
/**
|
||||
* Created by wenshao on 21/07/2017.
|
||||
*/
|
||||
public class Schema {
|
||||
private String name;
|
||||
|
||||
protected final Map<String, SchemaObject> objects = new ConcurrentSkipListMap<String, SchemaObject>();
|
||||
|
||||
private final Map<String, SchemaObject> functions = new ConcurrentSkipListMap<String, SchemaObject>();
|
||||
|
||||
private final Schema.SchemaVisitor visitor = new Schema.SchemaVisitor();
|
||||
|
||||
private SchemaRepository repository;
|
||||
|
||||
public Schema(SchemaRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public SchemaObject findTable(String tableName) {
|
||||
String lowerName = tableName.toLowerCase();
|
||||
SchemaObject object = objects.get(lowerName);
|
||||
|
||||
if (object != null && object.getType() == SchemaObjectType.Table) {
|
||||
return object;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public SchemaObject findTableOrView(String tableName) {
|
||||
String lowerName = tableName.toLowerCase();
|
||||
SchemaObject object = objects.get(lowerName);
|
||||
|
||||
if (object == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
SchemaObjectType type = object.getType();
|
||||
if (type == SchemaObjectType.Table || type == SchemaObjectType.View) {
|
||||
return object;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public SchemaObject findFunction(String functionName) {
|
||||
String lowerName = functionName.toLowerCase();
|
||||
return functions.get(lowerName);
|
||||
}
|
||||
|
||||
public void acceptDDL(String ddl, String dbType) {
|
||||
List<SQLStatement> stmtList = SQLUtils.parseStatements(ddl, dbType);
|
||||
for (SQLStatement stmt : stmtList) {
|
||||
accept(stmt);
|
||||
}
|
||||
}
|
||||
|
||||
public void accept(SQLStatement stmt) {
|
||||
stmt.accept(visitor);
|
||||
}
|
||||
|
||||
public boolean isSequence(String name) {
|
||||
SchemaObject object = objects.get(name);
|
||||
return object != null
|
||||
&& object.getType() == SchemaObjectType.Sequence;
|
||||
}
|
||||
|
||||
public class SchemaVisitor extends OracleASTVisitorAdapter {
|
||||
|
||||
public boolean visit(SQLDropSequenceStatement x) {
|
||||
String name = x.getName().getSimpleName();
|
||||
objects.remove(name);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateSequenceStatement x) {
|
||||
String name = x.getName().getSimpleName();
|
||||
SchemaObject object = new SchemaObjectImpl(name, SchemaObjectType.Sequence);
|
||||
|
||||
objects.put(name.toLowerCase(), object);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(OracleCreateTableStatement x) {
|
||||
visit((SQLCreateTableStatement) x);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateTableStatement x) {
|
||||
String name = x.computeName();
|
||||
SchemaObject object = new SchemaObjectImpl(name, SchemaObjectType.Table, x);
|
||||
|
||||
String name_lower = name.toLowerCase();
|
||||
if (objects.containsKey(name_lower)) {
|
||||
return false;
|
||||
}
|
||||
objects.put(name_lower, object);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateViewStatement x) {
|
||||
String name = x.computeName();
|
||||
SchemaObject object = new SchemaObjectImpl(name, SchemaObjectType.View, x);
|
||||
|
||||
String name_lower = name.toLowerCase();
|
||||
if (objects.containsKey(name_lower)) {
|
||||
return false;
|
||||
}
|
||||
objects.put(name_lower, object);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateIndexStatement x) {
|
||||
String name = x.getName().getSimpleName();
|
||||
SchemaObject object = new SchemaObjectImpl(name, SchemaObjectType.Index);
|
||||
|
||||
objects.put(name.toLowerCase(), object);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateFunctionStatement x) {
|
||||
String name = x.getName().getSimpleName();
|
||||
SchemaObject object = new SchemaObjectImpl(name, SchemaObjectType.Function, x);
|
||||
|
||||
functions.put(name.toLowerCase(), object);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public SchemaObject findTable(SQLTableSource tableSource, String alias) {
|
||||
if (tableSource instanceof SQLExprTableSource) {
|
||||
if (alias.equalsIgnoreCase(tableSource.computeAlias())) {
|
||||
SQLExprTableSource exprTableSource = (SQLExprTableSource) tableSource;
|
||||
|
||||
SchemaObject tableObject = exprTableSource.getSchemaObject();
|
||||
if (tableObject != null) {
|
||||
return tableObject;
|
||||
}
|
||||
|
||||
SQLExpr expr = exprTableSource.getExpr();
|
||||
if (expr instanceof SQLIdentifierExpr) {
|
||||
String tableName = ((SQLIdentifierExpr) expr).getName();
|
||||
|
||||
tableObject = findTable(tableName);
|
||||
if (tableObject != null) {
|
||||
exprTableSource.setSchemaObject(tableObject);
|
||||
}
|
||||
return tableObject;
|
||||
}
|
||||
|
||||
if (expr instanceof SQLPropertyExpr) {
|
||||
String tableName = ((SQLPropertyExpr) expr).getName();
|
||||
|
||||
tableObject = findTable(tableName);
|
||||
if (tableObject != null) {
|
||||
exprTableSource.setSchemaObject(tableObject);
|
||||
}
|
||||
return tableObject;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
if (tableSource instanceof SQLJoinTableSource) {
|
||||
SQLJoinTableSource join = (SQLJoinTableSource) tableSource;
|
||||
SQLTableSource left = join.getLeft();
|
||||
|
||||
SchemaObject tableObject = findTable(left, alias);
|
||||
if (tableObject != null) {
|
||||
return tableObject;
|
||||
}
|
||||
|
||||
SQLTableSource right = join.getRight();
|
||||
tableObject = findTable(right, alias);
|
||||
return tableObject;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public SQLColumnDefinition findColumn(SQLTableSource tableSource, SQLSelectItem selectItem) {
|
||||
if (selectItem == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return findColumn(tableSource, selectItem.getExpr());
|
||||
}
|
||||
|
||||
public SQLColumnDefinition findColumn(SQLTableSource tableSource, SQLExpr expr) {
|
||||
SchemaObject object = findTable(tableSource, expr);
|
||||
if (object != null) {
|
||||
if (expr instanceof SQLAggregateExpr) {
|
||||
SQLAggregateExpr aggregateExpr = (SQLAggregateExpr) expr;
|
||||
String function = aggregateExpr.getMethodName();
|
||||
if ("min".equalsIgnoreCase(function)
|
||||
|| "max".equalsIgnoreCase(function)) {
|
||||
SQLExpr arg = aggregateExpr.getArguments().get(0);
|
||||
expr = arg;
|
||||
}
|
||||
}
|
||||
|
||||
if (expr instanceof SQLName) {
|
||||
return object.findColumn(((SQLName) expr).getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public SchemaObject findTable(SQLTableSource tableSource, SQLSelectItem selectItem) {
|
||||
if (selectItem == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return findTable(tableSource, selectItem.getExpr());
|
||||
}
|
||||
|
||||
public SchemaObject findTable(SQLTableSource tableSource, SQLExpr expr) {
|
||||
if (expr instanceof SQLAggregateExpr) {
|
||||
SQLAggregateExpr aggregateExpr = (SQLAggregateExpr) expr;
|
||||
String function = aggregateExpr.getMethodName();
|
||||
if ("min".equalsIgnoreCase(function)
|
||||
|| "max".equalsIgnoreCase(function)) {
|
||||
SQLExpr arg = aggregateExpr.getArguments().get(0);
|
||||
return findTable(tableSource, arg);
|
||||
}
|
||||
}
|
||||
|
||||
if (expr instanceof SQLPropertyExpr) {
|
||||
String ownerName = ((SQLPropertyExpr) expr).getOwnernName();
|
||||
return findTable(tableSource, ownerName);
|
||||
}
|
||||
|
||||
if (expr instanceof SQLAllColumnExpr || expr instanceof SQLIdentifierExpr) {
|
||||
if (tableSource instanceof SQLExprTableSource) {
|
||||
return findTable(tableSource, tableSource.computeAlias());
|
||||
}
|
||||
|
||||
if (tableSource instanceof SQLJoinTableSource) {
|
||||
SQLJoinTableSource join = (SQLJoinTableSource) tableSource;
|
||||
|
||||
SchemaObject table = findTable(join.getLeft(), expr);
|
||||
if (table == null) {
|
||||
table = findTable(join.getRight(), expr);
|
||||
}
|
||||
return table;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Map<String, SchemaObject> getTables(SQLTableSource x) {
|
||||
Map<String, SchemaObject> tables = new LinkedHashMap<String, SchemaObject>();
|
||||
computeTables(x, tables);
|
||||
return tables;
|
||||
}
|
||||
|
||||
protected void computeTables(SQLTableSource x, Map<String, SchemaObject> tables) {
|
||||
if (x == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (x instanceof SQLExprTableSource) {
|
||||
SQLExprTableSource exprTableSource = (SQLExprTableSource) x;
|
||||
|
||||
SQLExpr expr = exprTableSource.getExpr();
|
||||
if (expr instanceof SQLIdentifierExpr) {
|
||||
String tableName = ((SQLIdentifierExpr) expr).getName();
|
||||
|
||||
SchemaObject table = exprTableSource.getSchemaObject();
|
||||
if (table == null) {
|
||||
table = findTable(tableName);
|
||||
|
||||
if (table != null) {
|
||||
exprTableSource.setSchemaObject(table);
|
||||
}
|
||||
}
|
||||
|
||||
if (table != null) {
|
||||
tables.put(tableName, table);
|
||||
|
||||
String alias = x.getAlias();
|
||||
if (alias != null && !alias.equalsIgnoreCase(tableName)) {
|
||||
tables.put(alias, table);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (x instanceof SQLJoinTableSource) {
|
||||
SQLJoinTableSource join = (SQLJoinTableSource) x;
|
||||
computeTables(join.getLeft(), tables);
|
||||
computeTables(join.getRight(), tables);
|
||||
}
|
||||
}
|
||||
|
||||
public int getTableCount() {
|
||||
int count = 0;
|
||||
for (SchemaObject object : this.objects.values()) {
|
||||
if (object.getType() == SchemaObjectType.Table) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public Map<String, SchemaObject> getObjects() {
|
||||
return this.objects;
|
||||
}
|
||||
|
||||
public int getViewCount() {
|
||||
int count = 0;
|
||||
for (SchemaObject object : this.objects.values()) {
|
||||
if (object.getType() == SchemaObjectType.View) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@ import com.alibaba.druid.sql.ast.statement.*;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateTableStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitorAdapter;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -36,300 +37,150 @@ import java.util.concurrent.ConcurrentSkipListMap;
|
||||
* Created by wenshao on 03/06/2017.
|
||||
*/
|
||||
public class SchemaRepository {
|
||||
private String name;
|
||||
private Schema defaultSchema;
|
||||
|
||||
private final Map<String, SchemaObject> objects = new ConcurrentSkipListMap<String, SchemaObject>();
|
||||
private Map<String, Schema> schemas = new LinkedHashMap<String, Schema>();
|
||||
|
||||
private final Map<String, SchemaObject> functions = new ConcurrentSkipListMap<String, SchemaObject>();
|
||||
|
||||
private final SchemaVisitor visitor = new SchemaVisitor();
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
public String getDefaultSchemaName() {
|
||||
return getDefaultSchema().getName();
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
public void setDefaultSchema(String name) {
|
||||
if (name == null) {
|
||||
defaultSchema = null;
|
||||
return;
|
||||
}
|
||||
|
||||
String normalizedName = SQLUtils.normalize(name)
|
||||
.toLowerCase();
|
||||
|
||||
Schema defaultSchema = schemas.get(normalizedName);
|
||||
if (defaultSchema != null) {
|
||||
this.defaultSchema = defaultSchema;
|
||||
return;
|
||||
}
|
||||
|
||||
if (defaultSchema == null) {
|
||||
if (this.defaultSchema != null
|
||||
&& this.defaultSchema.getName() == null) {
|
||||
this.defaultSchema.setName(name);
|
||||
|
||||
schemas.put(normalizedName, this.defaultSchema);
|
||||
return;
|
||||
}
|
||||
|
||||
defaultSchema = new Schema(this);
|
||||
defaultSchema.setName(name);
|
||||
schemas.put(normalizedName, defaultSchema);
|
||||
this.defaultSchema = defaultSchema;
|
||||
}
|
||||
}
|
||||
|
||||
public Schema findSchema(String schema) {
|
||||
if (schema == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return schemas.get(
|
||||
SQLUtils.normalize(schema)
|
||||
.toLowerCase());
|
||||
}
|
||||
|
||||
public Schema getDefaultSchema() {
|
||||
if (defaultSchema == null) {
|
||||
defaultSchema = new Schema(this);
|
||||
}
|
||||
|
||||
return defaultSchema;
|
||||
}
|
||||
|
||||
public void setDefaultSchema(Schema schema) {
|
||||
this.defaultSchema = schema;
|
||||
}
|
||||
|
||||
public SchemaObject findTable(String tableName) {
|
||||
String lowerName = tableName.toLowerCase();
|
||||
SchemaObject object = objects.get(lowerName);
|
||||
return getDefaultSchema().findTable(tableName);
|
||||
}
|
||||
|
||||
if (object != null && object.getType() == SchemaObjectType.Table) {
|
||||
public SchemaObject findTableOrView(String tableName) {
|
||||
return findTableOrView(tableName, true);
|
||||
}
|
||||
|
||||
public SchemaObject findTableOrView(String tableName, boolean onlyCurrent) {
|
||||
Schema schema = getDefaultSchema();
|
||||
|
||||
SchemaObject object = schema.findTableOrView(tableName);
|
||||
if (object != null) {
|
||||
return object;
|
||||
}
|
||||
|
||||
for (Schema s : this.schemas.values()) {
|
||||
if (s == schema) {
|
||||
continue;
|
||||
}
|
||||
|
||||
object = schema.findTableOrView(tableName);
|
||||
if (object != null) {
|
||||
return object;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Collection<Schema> getSchemas() {
|
||||
return schemas.values();
|
||||
}
|
||||
|
||||
public SchemaObject findFunction(String functionName) {
|
||||
String lowerName = functionName.toLowerCase();
|
||||
return functions.get(lowerName);
|
||||
return getDefaultSchema().findFunction(functionName);
|
||||
}
|
||||
|
||||
public void acceptDDL(String ddl, String dbType) {
|
||||
List<SQLStatement> stmtList = SQLUtils.parseStatements(ddl, dbType);
|
||||
for (SQLStatement stmt : stmtList) {
|
||||
accept(stmt);
|
||||
}
|
||||
getDefaultSchema().acceptDDL(ddl, dbType);
|
||||
}
|
||||
|
||||
public void accept(SQLStatement stmt) {
|
||||
stmt.accept(visitor);
|
||||
getDefaultSchema().accept(stmt);
|
||||
}
|
||||
|
||||
public boolean isSequence(String name) {
|
||||
SchemaObject object = objects.get(name);
|
||||
return object != null
|
||||
&& object.getType() == SchemaObjectType.Sequence;
|
||||
}
|
||||
|
||||
public class SchemaVisitor extends OracleASTVisitorAdapter {
|
||||
|
||||
public boolean visit(SQLDropSequenceStatement x) {
|
||||
String name = x.getName().getSimpleName();
|
||||
objects.remove(name);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateSequenceStatement x) {
|
||||
String name = x.getName().getSimpleName();
|
||||
SchemaObject object = new SchemaObjectImpl(name, SchemaObjectType.Sequence);
|
||||
|
||||
objects.put(name.toLowerCase(), object);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(OracleCreateTableStatement x) {
|
||||
visit((SQLCreateTableStatement) x);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateTableStatement x) {
|
||||
String name = x.computeName();
|
||||
SchemaObject object = new SchemaObjectImpl(name, SchemaObjectType.Table, x);
|
||||
|
||||
String name_lower = name.toLowerCase();
|
||||
if (objects.containsKey(name_lower)) {
|
||||
return false;
|
||||
}
|
||||
objects.put(name_lower, object);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateIndexStatement x) {
|
||||
String name = x.getName().getSimpleName();
|
||||
SchemaObject object = new SchemaObjectImpl(name, SchemaObjectType.Index);
|
||||
|
||||
objects.put(name.toLowerCase(), object);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateFunctionStatement x) {
|
||||
String name = x.getName().getSimpleName();
|
||||
SchemaObject object = new SchemaObjectImpl(name, SchemaObjectType.Function, x);
|
||||
|
||||
functions.put(name.toLowerCase(), object);
|
||||
|
||||
return false;
|
||||
}
|
||||
return getDefaultSchema().isSequence(name);
|
||||
}
|
||||
|
||||
public SchemaObject findTable(SQLTableSource tableSource, String alias) {
|
||||
if (tableSource instanceof SQLExprTableSource) {
|
||||
if (alias.equalsIgnoreCase(tableSource.computeAlias())) {
|
||||
SQLExprTableSource exprTableSource = (SQLExprTableSource) tableSource;
|
||||
|
||||
SchemaObject tableObject = exprTableSource.getSchemaObject();
|
||||
if (tableObject != null) {
|
||||
return tableObject;
|
||||
}
|
||||
|
||||
SQLExpr expr = exprTableSource.getExpr();
|
||||
if (expr instanceof SQLIdentifierExpr) {
|
||||
String tableName = ((SQLIdentifierExpr) expr).getName();
|
||||
|
||||
tableObject = findTable(tableName);
|
||||
if (tableObject != null) {
|
||||
exprTableSource.setSchemaObject(tableObject);
|
||||
}
|
||||
return tableObject;
|
||||
}
|
||||
|
||||
if (expr instanceof SQLPropertyExpr) {
|
||||
String tableName = ((SQLPropertyExpr) expr).getName();
|
||||
|
||||
tableObject = findTable(tableName);
|
||||
if (tableObject != null) {
|
||||
exprTableSource.setSchemaObject(tableObject);
|
||||
}
|
||||
return tableObject;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
if (tableSource instanceof SQLJoinTableSource) {
|
||||
SQLJoinTableSource join = (SQLJoinTableSource) tableSource;
|
||||
SQLTableSource left = join.getLeft();
|
||||
|
||||
SchemaObject tableObject = findTable(left, alias);
|
||||
if (tableObject != null) {
|
||||
return tableObject;
|
||||
}
|
||||
|
||||
SQLTableSource right = join.getRight();
|
||||
tableObject = findTable(right, alias);
|
||||
return tableObject;
|
||||
}
|
||||
|
||||
return null;
|
||||
return getDefaultSchema().findTable(tableSource, alias);
|
||||
}
|
||||
|
||||
public SQLColumnDefinition findColumn(SQLTableSource tableSource, SQLSelectItem selectItem) {
|
||||
if (selectItem == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return findColumn(tableSource, selectItem.getExpr());
|
||||
return getDefaultSchema().findColumn(tableSource, selectItem);
|
||||
}
|
||||
|
||||
public SQLColumnDefinition findColumn(SQLTableSource tableSource, SQLExpr expr) {
|
||||
SchemaObject object = findTable(tableSource, expr);
|
||||
if (object != null) {
|
||||
if (expr instanceof SQLAggregateExpr) {
|
||||
SQLAggregateExpr aggregateExpr = (SQLAggregateExpr) expr;
|
||||
String function = aggregateExpr.getMethodName();
|
||||
if ("min".equalsIgnoreCase(function)
|
||||
|| "max".equalsIgnoreCase(function)) {
|
||||
SQLExpr arg = aggregateExpr.getArguments().get(0);
|
||||
expr = arg;
|
||||
}
|
||||
}
|
||||
|
||||
if (expr instanceof SQLName) {
|
||||
return object.findColumn(((SQLName) expr).getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return getDefaultSchema().findColumn(tableSource, expr);
|
||||
}
|
||||
|
||||
public SchemaObject findTable(SQLTableSource tableSource, SQLSelectItem selectItem) {
|
||||
if (selectItem == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return findTable(tableSource, selectItem.getExpr());
|
||||
return getDefaultSchema().findTable(tableSource, selectItem);
|
||||
}
|
||||
|
||||
public SchemaObject findTable(SQLTableSource tableSource, SQLExpr expr) {
|
||||
if (expr instanceof SQLAggregateExpr) {
|
||||
SQLAggregateExpr aggregateExpr = (SQLAggregateExpr) expr;
|
||||
String function = aggregateExpr.getMethodName();
|
||||
if ("min".equalsIgnoreCase(function)
|
||||
|| "max".equalsIgnoreCase(function)) {
|
||||
SQLExpr arg = aggregateExpr.getArguments().get(0);
|
||||
return findTable(tableSource, arg);
|
||||
}
|
||||
}
|
||||
|
||||
if (expr instanceof SQLPropertyExpr) {
|
||||
String ownerName = ((SQLPropertyExpr) expr).getOwnernName();
|
||||
return findTable(tableSource, ownerName);
|
||||
}
|
||||
|
||||
if (expr instanceof SQLAllColumnExpr || expr instanceof SQLIdentifierExpr) {
|
||||
if (tableSource instanceof SQLExprTableSource) {
|
||||
return findTable(tableSource, tableSource.computeAlias());
|
||||
}
|
||||
|
||||
if (tableSource instanceof SQLJoinTableSource) {
|
||||
SQLJoinTableSource join = (SQLJoinTableSource) tableSource;
|
||||
|
||||
SchemaObject table = findTable(join.getLeft(), expr);
|
||||
if (table == null) {
|
||||
table = findTable(join.getRight(), expr);
|
||||
}
|
||||
return table;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
return getDefaultSchema().findTable(tableSource, expr);
|
||||
}
|
||||
|
||||
public Map<String, SchemaObject> getTables(SQLTableSource x) {
|
||||
Map<String, SchemaObject> tables = new LinkedHashMap<String, SchemaObject>();
|
||||
computeTables(x, tables);
|
||||
return tables;
|
||||
}
|
||||
|
||||
private void computeTables(SQLTableSource x, Map<String, SchemaObject> tables) {
|
||||
if (x == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (x instanceof SQLExprTableSource) {
|
||||
SQLExprTableSource exprTableSource = (SQLExprTableSource) x;
|
||||
|
||||
SQLExpr expr = exprTableSource.getExpr();
|
||||
if (expr instanceof SQLIdentifierExpr) {
|
||||
String tableName = ((SQLIdentifierExpr) expr).getName();
|
||||
|
||||
SchemaObject table = exprTableSource.getSchemaObject();
|
||||
if (table == null) {
|
||||
table = findTable(tableName);
|
||||
|
||||
if (table != null) {
|
||||
exprTableSource.setSchemaObject(table);
|
||||
}
|
||||
}
|
||||
|
||||
if (table != null) {
|
||||
tables.put(tableName, table);
|
||||
|
||||
String alias = x.getAlias();
|
||||
if (alias != null && !alias.equalsIgnoreCase(tableName)) {
|
||||
tables.put(alias, table);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (x instanceof SQLJoinTableSource) {
|
||||
SQLJoinTableSource join = (SQLJoinTableSource) x;
|
||||
computeTables(join.getLeft(), tables);
|
||||
computeTables(join.getRight(), tables);
|
||||
}
|
||||
return getDefaultSchema().getTables(x);
|
||||
}
|
||||
|
||||
public int getTableCount() {
|
||||
int count = 0;
|
||||
for (SchemaObject object : this.objects.values()) {
|
||||
if (object.getType() == SchemaObjectType.Table) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
return getDefaultSchema().getTableCount();
|
||||
}
|
||||
|
||||
public Map<String, SchemaObject> getObjects() {
|
||||
return this.objects;
|
||||
return getDefaultSchema().getObjects();
|
||||
}
|
||||
|
||||
public int getViewCount() {
|
||||
int count = 0;
|
||||
for (SchemaObject object : this.objects.values()) {
|
||||
if (object.getType() == SchemaObjectType.View) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
return getDefaultSchema().getViewCount();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,7 +134,9 @@ public final class ExportParameterVisitorUtils {
|
||||
}
|
||||
|
||||
public static void exportParameter(final List<Object> parameters, SQLBinaryOpExpr x) {
|
||||
if (x.getLeft() instanceof SQLLiteralExpr && x.getRight() instanceof SQLLiteralExpr && x.getOperator().isRelational()) {
|
||||
if (x.getLeft() instanceof SQLLiteralExpr
|
||||
&& x.getRight() instanceof SQLLiteralExpr
|
||||
&& x.getOperator().isRelational()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -697,15 +697,19 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
return false;
|
||||
}
|
||||
|
||||
if (x.getText() == null) {
|
||||
printChars(x.getText());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void printChars(String text) {
|
||||
if (text == null) {
|
||||
print0(ucase ? "NULL" : "null");
|
||||
} else {
|
||||
print('\'');
|
||||
print0(x.getText().replaceAll("'", "''"));
|
||||
print0(text.replaceAll("'", "''"));
|
||||
print('\'');
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLDataType x) {
|
||||
@@ -884,39 +888,49 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
if (this.parameterized) {
|
||||
List<SQLExpr> targetList = x.getTargetList();
|
||||
|
||||
boolean changed = true;
|
||||
if (targetList.size() == 1 && targetList.get(0) instanceof SQLVariantRefExpr) {
|
||||
changed = false;
|
||||
}
|
||||
|
||||
x.getExpr().accept(this);
|
||||
|
||||
if (x.isNot()) {
|
||||
print(isUppCase() ? " NOT IN (?)" : " not in (?)");
|
||||
} else {
|
||||
print(isUppCase() ? " IN (?)" : " in (?)");
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
incrementReplaceCunt();
|
||||
if(this instanceof ExportParameterVisitor || this.parameters != null) {
|
||||
if (parameterizedMergeInList) {
|
||||
List<Object> subList = new ArrayList<Object>(x.getTargetList().size());
|
||||
for (SQLExpr target : x.getTargetList()) {
|
||||
ExportParameterVisitorUtils.exportParameter(subList, target);
|
||||
}
|
||||
if (subList != null) {
|
||||
parameters.add(subList);
|
||||
}
|
||||
} else {
|
||||
for (SQLExpr target : x.getTargetList()) {
|
||||
ExportParameterVisitorUtils.exportParameter(this.parameters, target);
|
||||
}
|
||||
}
|
||||
boolean allLiteral = true;
|
||||
for (SQLExpr item : targetList) {
|
||||
if (!(item instanceof SQLLiteralExpr || item instanceof SQLVariantRefExpr)) {
|
||||
allLiteral = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
if (allLiteral) {
|
||||
boolean changed = true;
|
||||
if (targetList.size() == 1 && targetList.get(0) instanceof SQLVariantRefExpr) {
|
||||
changed = false;
|
||||
}
|
||||
|
||||
x.getExpr().accept(this);
|
||||
|
||||
if (x.isNot()) {
|
||||
print(isUppCase() ? " NOT IN (?)" : " not in (?)");
|
||||
} else {
|
||||
print(isUppCase() ? " IN (?)" : " in (?)");
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
incrementReplaceCunt();
|
||||
if (this instanceof ExportParameterVisitor || this.parameters != null) {
|
||||
if (parameterizedMergeInList) {
|
||||
List<Object> subList = new ArrayList<Object>(x.getTargetList().size());
|
||||
for (SQLExpr target : x.getTargetList()) {
|
||||
ExportParameterVisitorUtils.exportParameter(subList, target);
|
||||
}
|
||||
if (subList != null) {
|
||||
parameters.add(subList);
|
||||
}
|
||||
} else {
|
||||
for (SQLExpr target : x.getTargetList()) {
|
||||
ExportParameterVisitorUtils.exportParameter(this.parameters, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
x.getExpr().accept(this);
|
||||
@@ -962,19 +976,21 @@ 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();
|
||||
SQLBinaryOperator op = binaryOpExpr.getOperator();
|
||||
if (left instanceof SQLIdentifierExpr
|
||||
&& op == SQLBinaryOperator.Equality) {
|
||||
String name = ((SQLIdentifierExpr) left).getName();
|
||||
if ("rownum".equals(name)) {
|
||||
print(1);
|
||||
return false;
|
||||
SQLObject parent = x.getParent();
|
||||
|
||||
if (val == 1) {
|
||||
if (JdbcConstants.ORACLE.equals(dbType)) {
|
||||
if (parent instanceof SQLBinaryOpExpr) {
|
||||
SQLBinaryOpExpr binaryOpExpr = (SQLBinaryOpExpr) parent;
|
||||
SQLExpr left = binaryOpExpr.getLeft();
|
||||
SQLBinaryOperator op = binaryOpExpr.getOperator();
|
||||
if (left instanceof SQLIdentifierExpr
|
||||
&& op == SQLBinaryOperator.Equality) {
|
||||
String name = ((SQLIdentifierExpr) left).getName();
|
||||
if ("rownum".equals(name)) {
|
||||
print(1);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1015,14 +1031,21 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
SQLExpr param = x.getParameters().get(i);
|
||||
|
||||
if (parameterized) {
|
||||
if (JdbcUtils.ORACLE.equalsIgnoreCase(dbType)) {
|
||||
if (size == 2 && i == 1 && param instanceof SQLCharExpr) {
|
||||
if (size == 2 && i == 1 && param instanceof SQLCharExpr) {
|
||||
if (JdbcUtils.ORACLE.equals(dbType)) {
|
||||
if ("TO_CHAR".equalsIgnoreCase(function)
|
||||
|| "TO_DATE".equalsIgnoreCase(function)) {
|
||||
param.putAttribute(ParameterizedOutputVisitorUtils.ATTR_PARAMS_SKIP, true);
|
||||
printChars(((SQLCharExpr) param).getText());
|
||||
continue;
|
||||
}
|
||||
} else if (JdbcConstants.MYSQL.equals(dbType)) {
|
||||
if ("DATE_FORMAT".equalsIgnoreCase(function)) {
|
||||
printChars(((SQLCharExpr) param).getText());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (param instanceof SQLBinaryOpExpr) {
|
||||
@@ -3427,16 +3450,26 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
if (i != 0 && comment.startsWith("--")) {
|
||||
println();
|
||||
}
|
||||
print0(comment);
|
||||
|
||||
printComment(comment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void printComment(String comment) {
|
||||
if (comment.startsWith("--") && comment.length() > 2 && comment.charAt(2) != ' ') {
|
||||
print0("-- ");
|
||||
print0(comment.substring(2));
|
||||
} else {
|
||||
print0(comment);
|
||||
}
|
||||
}
|
||||
|
||||
protected void printlnComments(List<String> comments) {
|
||||
if (comments != null) {
|
||||
for (int i = 0; i < comments.size(); ++i) {
|
||||
String comment = comments.get(i);
|
||||
print0(comment);
|
||||
printComment(comment);
|
||||
println();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,14 +34,7 @@ import java.sql.ResultSetMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.sql.Types;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author wenshao [szujobs@hotmail.com]
|
||||
@@ -629,6 +622,10 @@ public final class JdbcUtils implements JdbcConstants {
|
||||
}
|
||||
}
|
||||
|
||||
public static void execute(Connection conn, String sql) throws SQLException {
|
||||
execute(conn, sql, Collections.emptyList());
|
||||
}
|
||||
|
||||
public static void execute(Connection conn, String sql, List<Object> parameters) throws SQLException {
|
||||
PreparedStatement stmt = null;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user