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:
@@ -17,4 +17,6 @@ package com.alibaba.druid.sql.ast;
|
||||
|
||||
public interface SQLExpr extends SQLObject, Cloneable {
|
||||
SQLExpr clone();
|
||||
|
||||
SQLDataType computeDataType();
|
||||
}
|
||||
|
||||
@@ -28,4 +28,8 @@ public abstract class SQLExprImpl extends SQLObjectImpl implements SQLExpr {
|
||||
public SQLExpr clone() {
|
||||
throw new UnsupportedOperationException(this.getClass().getName());
|
||||
}
|
||||
|
||||
public SQLDataType computeDataType() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,4 +211,8 @@ public abstract class SQLObjectImpl implements SQLObject {
|
||||
public SQLObject clone() {
|
||||
throw new UnsupportedOperationException(this.getClass().getName());
|
||||
}
|
||||
|
||||
public SQLDataType computeDataType() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,11 +20,7 @@ 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.SQLKeep;
|
||||
import com.alibaba.druid.sql.ast.SQLOrderBy;
|
||||
import com.alibaba.druid.sql.ast.SQLOver;
|
||||
import com.alibaba.druid.sql.ast.*;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class SQLAggregateExpr extends SQLExprImpl implements Serializable {
|
||||
@@ -206,4 +202,25 @@ public class SQLAggregateExpr extends SQLExprImpl implements Serializable {
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
public SQLDataType computeDataType() {
|
||||
if ("count".equals(methodName)
|
||||
|| "row_number".equals(methodName)) {
|
||||
return SQLIntegerExpr.DEFAULT_DATA_TYPE;
|
||||
}
|
||||
|
||||
if (arguments.size() > 0) {
|
||||
SQLDataType dataType = arguments.get(0).computeDataType();
|
||||
if (dataType != null) {
|
||||
return dataType;
|
||||
}
|
||||
}
|
||||
|
||||
if ("wm_conat".equals(methodName)
|
||||
|| "group_concat".equals(methodName)) {
|
||||
return SQLCharExpr.DEFAULT_DATA_TYPE;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,10 +15,15 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.ast.expr;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLDataType;
|
||||
import com.alibaba.druid.sql.ast.SQLExprImpl;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelect;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectItem;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SQLAnyExpr extends SQLExprImpl {
|
||||
|
||||
public SQLSelect subQuery;
|
||||
@@ -82,4 +87,22 @@ public class SQLAnyExpr extends SQLExprImpl {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public SQLDataType computeDataType() {
|
||||
if (subQuery == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
SQLSelectQueryBlock queryBlock = subQuery.getFirstQueryBlock();
|
||||
if (queryBlock == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<SQLSelectItem> selectList = queryBlock.getSelectList();
|
||||
if (selectList.size() == 1) {
|
||||
return selectList.get(0).computeDataType();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.alibaba.druid.sql.ast.expr;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLDataType;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLExprImpl;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
@@ -143,4 +144,8 @@ public class SQLBetweenExpr extends SQLExprImpl implements Serializable {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public SQLDataType computeDataType() {
|
||||
return SQLBooleanExpr.DEFAULT_DATA_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,10 +20,7 @@ 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.SQLObject;
|
||||
import com.alibaba.druid.sql.ast.SQLReplaceable;
|
||||
import com.alibaba.druid.sql.ast.*;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
import com.alibaba.druid.util.Utils;
|
||||
|
||||
@@ -429,4 +426,30 @@ public class SQLBinaryOpExpr extends SQLExprImpl implements SQLReplaceable, Seri
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public SQLDataType computeDataType() {
|
||||
if (operator != null && operator.isRelational()) {
|
||||
return SQLBooleanExpr.DEFAULT_DATA_TYPE;
|
||||
}
|
||||
|
||||
SQLDataType leftDataType = null, rightDataType = null;
|
||||
if (left != null) {
|
||||
leftDataType = left.computeDataType();
|
||||
}
|
||||
if (right != null) {
|
||||
rightDataType = right.computeDataType();
|
||||
}
|
||||
|
||||
if (operator == SQLBinaryOperator.Concat) {
|
||||
if (leftDataType != null) {
|
||||
return leftDataType;
|
||||
}
|
||||
if (rightDataType != null) {
|
||||
return rightDataType;
|
||||
}
|
||||
return SQLCharExpr.DEFAULT_DATA_TYPE;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,6 +138,8 @@ public enum SQLBinaryOperator {
|
||||
case NotRLike:
|
||||
case RegExp:
|
||||
case NotRegExp:
|
||||
case Is:
|
||||
case IsNot:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
||||
@@ -15,11 +15,14 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.ast.expr;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLDataType;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
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 static final SQLDataType DEFAULT_DATA_TYPE = new SQLCharacterDataType("boolean");
|
||||
|
||||
private boolean value;
|
||||
|
||||
@@ -77,4 +80,7 @@ public class SQLBooleanExpr extends SQLExprImpl implements SQLExpr, SQLLiteralEx
|
||||
return true;
|
||||
}
|
||||
|
||||
public SQLDataType computeDataType() {
|
||||
return DEFAULT_DATA_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,10 +19,7 @@ import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLExprImpl;
|
||||
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.visitor.SQLASTVisitor;
|
||||
|
||||
public class SQLCaseExpr extends SQLExprImpl implements SQLReplaceable, Serializable {
|
||||
@@ -255,4 +252,22 @@ public class SQLCaseExpr extends SQLExprImpl implements SQLReplaceable, Serializ
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
public SQLDataType computeDataType() {
|
||||
for (Item item : items) {
|
||||
SQLExpr expr = item.getValueExpr();
|
||||
if (expr != null) {
|
||||
SQLDataType dataType = expr.computeDataType();
|
||||
if (dataType != null) {
|
||||
return dataType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(elseExpr != null) {
|
||||
return elseExpr.computeDataType();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,4 +94,7 @@ public class SQLCastExpr extends SQLExprImpl {
|
||||
return true;
|
||||
}
|
||||
|
||||
public SQLDataType computeDataType() {
|
||||
return dataType;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
package com.alibaba.druid.sql.ast.expr;
|
||||
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLDataType;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLCharacterDataType;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class SQLCharExpr extends SQLTextLiteralExpr implements SQLValuableExpr{
|
||||
public static final SQLDataType DEFAULT_DATA_TYPE = new SQLCharacterDataType("varchar");
|
||||
|
||||
public SQLCharExpr(){
|
||||
|
||||
@@ -55,4 +58,8 @@ public class SQLCharExpr extends SQLTextLiteralExpr implements SQLValuableExpr{
|
||||
public SQLCharExpr clone() {
|
||||
return new SQLCharExpr(this.text);
|
||||
}
|
||||
|
||||
public SQLDataType computeDataType() {
|
||||
return DEFAULT_DATA_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,12 +15,15 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.ast.expr;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLDataType;
|
||||
import com.alibaba.druid.sql.ast.SQLExprImpl;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLCharacterDataType;
|
||||
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 static final SQLDataType DEFAULT_DATA_TYPE = new SQLCharacterDataType("date");
|
||||
|
||||
private String literal;
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.alibaba.druid.sql.ast.expr;
|
||||
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLDataType;
|
||||
import com.alibaba.druid.sql.ast.SQLExprImpl;
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
|
||||
@@ -147,4 +148,12 @@ public class SQLIdentifierExpr extends SQLExprImpl implements SQLName {
|
||||
public void setResolvedColumn(SQLColumnDefinition resolvedColumn) {
|
||||
this.resolvedColumn = resolvedColumn;
|
||||
}
|
||||
|
||||
public SQLDataType computeDataType() {
|
||||
if (resolvedColumn != null) {
|
||||
return resolvedColumn.getDataType();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import java.io.Serializable;
|
||||
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.SQLExprImpl;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
@@ -121,4 +122,8 @@ public class SQLInListExpr extends SQLExprImpl implements Serializable {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public SQLDataType computeDataType() {
|
||||
return SQLBooleanExpr.DEFAULT_DATA_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.alibaba.druid.sql.ast.expr;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLDataType;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLExprImpl;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelect;
|
||||
@@ -125,4 +126,7 @@ public class SQLInSubQueryExpr extends SQLExprImpl implements Serializable {
|
||||
return true;
|
||||
}
|
||||
|
||||
public SQLDataType computeDataType() {
|
||||
return SQLBooleanExpr.DEFAULT_DATA_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,9 +15,12 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.ast.expr;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLDataType;
|
||||
import com.alibaba.druid.sql.ast.SQLDataTypeImpl;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class SQLIntegerExpr extends SQLNumericLiteralExpr implements SQLValuableExpr{
|
||||
public static final SQLDataType DEFAULT_DATA_TYPE = new SQLDataTypeImpl("bigint");
|
||||
|
||||
private Number number;
|
||||
|
||||
@@ -86,4 +89,8 @@ public class SQLIntegerExpr extends SQLNumericLiteralExpr implements SQLValuable
|
||||
public SQLIntegerExpr clone() {
|
||||
return new SQLIntegerExpr(this.number);
|
||||
}
|
||||
|
||||
public SQLDataType computeDataType() {
|
||||
return DEFAULT_DATA_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,9 +15,12 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.ast.expr;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLDataType;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLCharacterDataType;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class SQLNCharExpr extends SQLTextLiteralExpr {
|
||||
private static SQLDataType defaultDataType = new SQLCharacterDataType("nvarchar");
|
||||
|
||||
public SQLNCharExpr(){
|
||||
|
||||
@@ -46,4 +49,8 @@ public class SQLNCharExpr extends SQLTextLiteralExpr {
|
||||
public SQLNCharExpr clone() {
|
||||
return new SQLNCharExpr(text);
|
||||
}
|
||||
|
||||
public SQLDataType computeDataType() {
|
||||
return defaultDataType;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.alibaba.druid.sql.ast.expr;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLDataType;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLExprImpl;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
@@ -94,4 +95,8 @@ public class SQLNotExpr extends SQLExprImpl implements Serializable {
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
public SQLDataType computeDataType() {
|
||||
return SQLBooleanExpr.DEFAULT_DATA_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,9 +15,12 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.ast.expr;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLDataType;
|
||||
import com.alibaba.druid.sql.ast.SQLDataTypeImpl;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class SQLNumberExpr extends SQLNumericLiteralExpr {
|
||||
private static SQLDataType defaultDataType = new SQLDataTypeImpl("number");
|
||||
|
||||
private Number number;
|
||||
|
||||
@@ -80,4 +83,8 @@ public class SQLNumberExpr extends SQLNumericLiteralExpr {
|
||||
public SQLNumberExpr clone() {
|
||||
return new SQLNumberExpr(number);
|
||||
}
|
||||
|
||||
public SQLDataType computeDataType() {
|
||||
return defaultDataType;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.alibaba.druid.sql.ast.expr;
|
||||
|
||||
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.SQLExprImpl;
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
@@ -164,4 +165,12 @@ public class SQLPropertyExpr extends SQLExprImpl implements SQLName {
|
||||
public void setResolvedColumn(SQLColumnDefinition resolvedColumn) {
|
||||
this.resolvedColumn = resolvedColumn;
|
||||
}
|
||||
|
||||
public SQLDataType computeDataType() {
|
||||
if (resolvedColumn != null) {
|
||||
return resolvedColumn.getDataType();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,9 +16,13 @@
|
||||
package com.alibaba.druid.sql.ast.expr;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLDataType;
|
||||
import com.alibaba.druid.sql.ast.SQLExprImpl;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelect;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectItem;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class SQLQueryExpr extends SQLExprImpl implements Serializable {
|
||||
@@ -97,4 +101,22 @@ public class SQLQueryExpr extends SQLExprImpl implements Serializable {
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
public SQLDataType computeDataType() {
|
||||
if (subQuery == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
SQLSelectQueryBlock queryBlock = subQuery.getFirstQueryBlock();
|
||||
if (queryBlock == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<SQLSelectItem> selectList = queryBlock.getSelectList();
|
||||
if (selectList.size() == 1) {
|
||||
return selectList.get(0).computeDataType();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,10 +15,15 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.ast.expr;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLDataType;
|
||||
import com.alibaba.druid.sql.ast.SQLExprImpl;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelect;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectItem;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SQLSomeExpr extends SQLExprImpl {
|
||||
|
||||
public SQLSelect subQuery;
|
||||
@@ -82,4 +87,22 @@ public class SQLSomeExpr extends SQLExprImpl {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public SQLDataType computeDataType() {
|
||||
if (subQuery == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
SQLSelectQueryBlock queryBlock = subQuery.getFirstQueryBlock();
|
||||
if (queryBlock == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<SQLSelectItem> selectList = queryBlock.getSelectList();
|
||||
if (selectList.size() == 1) {
|
||||
return selectList.get(0).computeDataType();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package com.alibaba.druid.sql.ast.expr;
|
||||
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLDataType;
|
||||
import com.alibaba.druid.sql.ast.SQLExprImpl;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLCharacterDataType;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
/*
|
||||
@@ -20,6 +22,7 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
* limitations under the License.
|
||||
*/
|
||||
public class SQLTimestampExpr extends SQLExprImpl {
|
||||
public static final SQLDataType DEFAULT_DATA_TYPE = new SQLCharacterDataType("datetime");
|
||||
|
||||
protected String literal;
|
||||
protected String timeZone;
|
||||
@@ -105,4 +108,8 @@ public class SQLTimestampExpr extends SQLExprImpl {
|
||||
public String toString() {
|
||||
return SQLUtils.toSQLString(this, null);
|
||||
}
|
||||
|
||||
public SQLDataType computeDataType() {
|
||||
return DEFAULT_DATA_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ 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.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
|
||||
import com.alibaba.druid.sql.repository.SchemaObject;
|
||||
@@ -171,4 +172,17 @@ public class SQLExprTableSource extends SQLTableSourceImpl {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public SQLColumnDefinition findColumn(String columnName) {
|
||||
if (schemaObject == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
SQLStatement stmt = schemaObject.getStatement();
|
||||
if (stmt instanceof SQLCreateTableStatement) {
|
||||
SQLCreateTableStatement createTableStmt = (SQLCreateTableStatement) stmt;
|
||||
return createTableStmt.findColumn(columnName);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.util.List;
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLReplaceable;
|
||||
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.SQLIdentifierExpr;
|
||||
@@ -368,4 +369,19 @@ public class SQLJoinTableSource extends SQLTableSourceImpl implements SQLReplace
|
||||
return false;
|
||||
}
|
||||
|
||||
public SQLColumnDefinition findColumn(String columnName) {
|
||||
if (left != null) {
|
||||
SQLColumnDefinition column = left.findColumn(columnName);
|
||||
if (column != null) {
|
||||
return column;
|
||||
}
|
||||
}
|
||||
|
||||
if (right != null) {
|
||||
return right.findColumn(columnName);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -272,4 +272,15 @@ public class SQLSelect extends SQLObjectImpl {
|
||||
this.xmlPath = xmlPath;
|
||||
}
|
||||
|
||||
public SQLSelectQueryBlock getFirstQueryBlock() {
|
||||
if (query instanceof SQLSelectQueryBlock) {
|
||||
return (SQLSelectQueryBlock) query;
|
||||
}
|
||||
|
||||
if (query instanceof SQLUnionQuery) {
|
||||
return ((SQLUnionQuery) query).getFirstQueryBlock();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,23 +82,11 @@ public class SQLSelectItem extends SQLObjectImpl implements SQLReplaceable {
|
||||
}
|
||||
|
||||
public SQLDataType computeDataType() {
|
||||
if (expr instanceof SQLIdentifierExpr) {
|
||||
SQLIdentifierExpr identExpr = (SQLIdentifierExpr) expr;
|
||||
if (identExpr.getResolvedColumn() != null) {
|
||||
return identExpr.getResolvedColumn().getDataType();
|
||||
}
|
||||
if (expr == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (expr instanceof SQLPropertyExpr) {
|
||||
SQLPropertyExpr propertyExpr = (SQLPropertyExpr) expr;
|
||||
if (propertyExpr.getResolvedColumn() != null) {
|
||||
return propertyExpr.getResolvedColumn().getDataType();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
return expr.computeDataType();
|
||||
}
|
||||
|
||||
public String getAlias() {
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.alibaba.druid.sql.ast.*;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
|
||||
import com.alibaba.druid.sql.repository.SchemaObject;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class SQLSelectQueryBlock extends SQLObjectImpl implements SQLSelectQuery, SQLReplaceable {
|
||||
@@ -533,4 +534,18 @@ public class SQLSelectQueryBlock extends SQLObjectImpl implements SQLSelectQuery
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public SQLColumnDefinition computeColumn(SQLIdentifierExpr identExpr) {
|
||||
SQLColumnDefinition column = identExpr.getResolvedColumn();
|
||||
if (column != null) {
|
||||
return column;
|
||||
}
|
||||
|
||||
column = from.findColumn(identExpr.getName());
|
||||
if (column != null) {
|
||||
identExpr.setResolvedColumn(column);
|
||||
}
|
||||
|
||||
return column;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,4 +36,6 @@ public interface SQLTableSource extends SQLObject {
|
||||
|
||||
SQLExpr getFlashback();
|
||||
void setFlashback(SQLExpr flashback);
|
||||
|
||||
SQLColumnDefinition findColumn(String columnName);
|
||||
}
|
||||
|
||||
@@ -94,4 +94,8 @@ public abstract class SQLTableSourceImpl extends SQLObjectImpl implements SQLTab
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public SQLColumnDefinition findColumn(String columnName) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.oracle.ast;
|
||||
|
||||
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.dialect.oracle.visitor.OracleASTVisitor;
|
||||
@@ -36,4 +37,8 @@ public abstract class OracleSQLObjectImpl extends SQLObjectImpl implements Oracl
|
||||
public OracleSQLObject clone() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public SQLDataType computeDataType() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.oracle.ast.expr;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLDataType;
|
||||
import com.alibaba.druid.sql.ast.SQLOver;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
@@ -60,4 +61,8 @@ public class OracleAnalytic extends SQLOver implements OracleExpr {
|
||||
public void setWindowing(OracleAnalyticWindowing windowing) {
|
||||
this.windowing = windowing;
|
||||
}
|
||||
|
||||
public SQLDataType computeDataType() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.oracle.ast.expr;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLDataType;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObjectImpl;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
|
||||
|
||||
@@ -196,14 +196,7 @@ public class Schema {
|
||||
select.accept(
|
||||
repository.createResolveVisitor());
|
||||
|
||||
SQLSelectQuery query = select.getQuery();
|
||||
SQLSelectQueryBlock queryBlock = null;
|
||||
if (query instanceof SQLSelectQueryBlock) {
|
||||
queryBlock = (SQLSelectQueryBlock) query;
|
||||
} else if (query instanceof SQLUnionQuery) {
|
||||
queryBlock = ((SQLUnionQuery) query).getFirstQueryBlock();
|
||||
}
|
||||
|
||||
SQLSelectQueryBlock queryBlock = select.getFirstQueryBlock();
|
||||
if (queryBlock != null) {
|
||||
List<SQLSelectItem> selectList = queryBlock.getSelectList();
|
||||
for (SQLSelectItem selectItem : selectList) {
|
||||
|
||||
@@ -266,32 +266,69 @@ public class SchemaRepository {
|
||||
|
||||
public class MySqlResolveVisitor extends MySqlASTVisitorAdapter {
|
||||
|
||||
public boolean visit(SQLExprTableSource x) {
|
||||
if (x.getSchemaObject() != null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SQLExpr expr = x.getExpr();
|
||||
if (expr instanceof SQLName) {
|
||||
SchemaObject table = findTable((SQLName) expr);
|
||||
if (table != null) {
|
||||
x.setSchemaObject(table);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(MySqlSelectQueryBlock x) {
|
||||
SQLTableSource from = x.getFrom();
|
||||
from.accept(this);
|
||||
|
||||
List<SQLSelectItem> selectList = x.getSelectList();
|
||||
|
||||
List<SQLSelectItem> columns = new ArrayList<SQLSelectItem>();
|
||||
for (int i = selectList.size() - 1; i >= 0; i--) {
|
||||
SQLSelectItem selectItem = selectList.get(i);
|
||||
SQLExpr expr = selectItem.getExpr();
|
||||
if (expr instanceof SQLAllColumnExpr) {
|
||||
SQLTableSource from = x.getFrom();
|
||||
List<SQLSelectItem> columns = new ArrayList<SQLSelectItem>();
|
||||
if (from instanceof SQLExprTableSource) {
|
||||
SchemaObject table = findTable((SQLExprTableSource) from);
|
||||
if (table != null) {
|
||||
SQLCreateTableStatement createTableStmt = (SQLCreateTableStatement) table.getStatement();
|
||||
for (SQLTableElement e : createTableStmt.getTableElementList()) {
|
||||
if (e instanceof SQLColumnDefinition) {
|
||||
SQLColumnDefinition column = (SQLColumnDefinition) e;
|
||||
SQLIdentifierExpr name = (SQLIdentifierExpr) column.getName().clone();
|
||||
name.setResolvedColumn(column);
|
||||
columns.add(new SQLSelectItem(name));
|
||||
}
|
||||
}
|
||||
}
|
||||
extractColumns(from, columns);
|
||||
} else if (expr instanceof SQLPropertyExpr) {
|
||||
SQLPropertyExpr propertyExpr = (SQLPropertyExpr) expr;
|
||||
String ownerName = propertyExpr.getOwnernName();
|
||||
if (propertyExpr.getName().equals("*")) {
|
||||
SQLTableSource tableSource = x.findTableSource(ownerName);
|
||||
extractColumns(tableSource, columns);
|
||||
}
|
||||
|
||||
SQLColumnDefinition column = propertyExpr.getResolvedColumn();
|
||||
if (column != null) {
|
||||
continue;
|
||||
}
|
||||
SQLTableSource tableSource = x.findTableSource(propertyExpr.getOwnernName());
|
||||
if (tableSource != null) {
|
||||
column = tableSource.findColumn(propertyExpr.getName());
|
||||
if (column != null) {
|
||||
propertyExpr.setResolvedColumn(column);
|
||||
}
|
||||
}
|
||||
} else if (expr instanceof SQLIdentifierExpr) {
|
||||
SQLIdentifierExpr identExpr = (SQLIdentifierExpr) expr;
|
||||
SQLColumnDefinition column = identExpr.getResolvedColumn();
|
||||
if (column != null) {
|
||||
continue;
|
||||
}
|
||||
column = from.findColumn(identExpr.getName());
|
||||
if (column != null) {
|
||||
identExpr.setResolvedColumn(column);
|
||||
}
|
||||
}
|
||||
|
||||
if (columns.size() > 0) {
|
||||
for (SQLSelectItem column : columns) {
|
||||
column.setParent(x);
|
||||
}
|
||||
|
||||
selectList.remove(i);
|
||||
selectList.addAll(i, columns);
|
||||
}
|
||||
@@ -301,6 +338,23 @@ public class SchemaRepository {
|
||||
}
|
||||
}
|
||||
|
||||
private void extractColumns(SQLTableSource from, List<SQLSelectItem> columns) {
|
||||
if (from instanceof SQLExprTableSource) {
|
||||
SchemaObject table = findTable((SQLExprTableSource) from);
|
||||
if (table != null) {
|
||||
SQLCreateTableStatement createTableStmt = (SQLCreateTableStatement) table.getStatement();
|
||||
for (SQLTableElement e : createTableStmt.getTableElementList()) {
|
||||
if (e instanceof SQLColumnDefinition) {
|
||||
SQLColumnDefinition column = (SQLColumnDefinition) e;
|
||||
SQLIdentifierExpr name = (SQLIdentifierExpr) column.getName().clone();
|
||||
name.setResolvedColumn(column);
|
||||
columns.add(new SQLSelectItem(name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public SchemaObject findTable(SQLExprTableSource x) {
|
||||
if (x == null) {
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user