mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
improved sql parsre.
This commit is contained in:
@@ -37,7 +37,7 @@ public class SQLAggregateExpr extends SQLExprImpl implements Serializable, SQLRe
|
||||
protected SQLKeep keep;
|
||||
protected SQLOver over;
|
||||
protected SQLOrderBy withinGroup;
|
||||
protected boolean ignoreNulls = false;
|
||||
protected Boolean ignoreNulls = false;
|
||||
|
||||
public SQLAggregateExpr(String methodName){
|
||||
this.methodName = methodName;
|
||||
@@ -117,6 +117,10 @@ public class SQLAggregateExpr extends SQLExprImpl implements Serializable, SQLRe
|
||||
}
|
||||
|
||||
public boolean isIgnoreNulls() {
|
||||
return this.ignoreNulls != null && this.ignoreNulls;
|
||||
}
|
||||
|
||||
public Boolean getIgnoreNulls() {
|
||||
return this.ignoreNulls;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,8 +23,9 @@ package com.alibaba.druid.sql.ast.expr;
|
||||
public enum SQLBinaryOperator {
|
||||
Union("UNION", 0),
|
||||
COLLATE("COLLATE", 20),
|
||||
BitwiseXor("^", 50),
|
||||
|
||||
BitwiseXor("^", 50),
|
||||
BitwiseXorEQ("^=", 110),
|
||||
|
||||
Multiply("*", 60),
|
||||
Divide("/", 60),
|
||||
DIV("DIV", 60), // mysql integer division
|
||||
@@ -70,7 +71,7 @@ public enum SQLBinaryOperator {
|
||||
Array_Contains("@>", 110),
|
||||
Array_ContainedBy("<@", 110),
|
||||
SAME_AS("~=", 110),
|
||||
|
||||
|
||||
RLike("RLIKE", 110),
|
||||
NotRLike("NOT RLIKE", 110),
|
||||
|
||||
@@ -149,4 +150,19 @@ public enum SQLBinaryOperator {
|
||||
public boolean isLogical() {
|
||||
return this == BooleanAnd || this == BooleanOr || this == BooleanXor;
|
||||
}
|
||||
|
||||
public boolean isArithmetic() {
|
||||
switch (this) {
|
||||
case Add:
|
||||
case Subtract:
|
||||
case Multiply:
|
||||
case Divide:
|
||||
case DIV:
|
||||
case Modulus:
|
||||
case Mod:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+10
@@ -1025,4 +1025,14 @@ public class OracleToMySqlOutputVisitor extends MySqlOutputVisitor implements Or
|
||||
public void endVisit(OraclePipeRowStatement x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleIsOfTypeExpr x) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OracleIsOfTypeExpr x) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.oracle.ast;
|
||||
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLDataType;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLObjectImpl;
|
||||
@@ -41,4 +42,8 @@ public abstract class OracleSQLObjectImpl extends SQLObjectImpl implements Oracl
|
||||
public SQLDataType computeDataType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return SQLUtils.toOracleString(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,10 +19,14 @@ 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.SQLObject;
|
||||
import com.alibaba.druid.sql.ast.SQLOrderBy;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelect;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObjectImpl;
|
||||
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 ModelClause extends OracleSQLObjectImpl {
|
||||
|
||||
@@ -391,7 +395,7 @@ public class ModelClause extends OracleSQLObjectImpl {
|
||||
|
||||
}
|
||||
|
||||
public static class CellAssignment extends OracleSQLObjectImpl {
|
||||
public static class CellAssignment extends SQLExprImpl implements OracleExpr {
|
||||
|
||||
private SQLExpr measureColumn;
|
||||
private final List<SQLExpr> conditions = new ArrayList<SQLExpr>();
|
||||
@@ -404,8 +408,11 @@ public class ModelClause extends OracleSQLObjectImpl {
|
||||
return measureColumn;
|
||||
}
|
||||
|
||||
public void setMeasureColumn(SQLExpr measureColumn) {
|
||||
this.measureColumn = measureColumn;
|
||||
public void setMeasureColumn(SQLExpr e) {
|
||||
if (e != null) {
|
||||
e.setParent(this);
|
||||
}
|
||||
this.measureColumn = e;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -417,6 +424,46 @@ public class ModelClause extends OracleSQLObjectImpl {
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
CellAssignment that = (CellAssignment) o;
|
||||
|
||||
if (measureColumn != null ? !measureColumn.equals(that.measureColumn) : that.measureColumn != null)
|
||||
return false;
|
||||
return conditions != null ? conditions.equals(that.conditions) : that.conditions == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = measureColumn != null ? measureColumn.hashCode() : 0;
|
||||
result = 31 * result + (conditions != null ? conditions.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void accept0(SQLASTVisitor visitor) {
|
||||
accept0((OracleASTVisitor) visitor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLExpr clone() {
|
||||
CellAssignment x = new CellAssignment();
|
||||
if (measureColumn != null) {
|
||||
x.setMeasureColumn(measureColumn.clone());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SQLObject> getChildren() {
|
||||
List children = new ArrayList();
|
||||
children.add(measureColumn);
|
||||
children.addAll(conditions);
|
||||
return children;
|
||||
}
|
||||
}
|
||||
|
||||
public ModelClause clone() {
|
||||
|
||||
+17
-6
@@ -18,6 +18,7 @@ package com.alibaba.druid.sql.dialect.oracle.ast.expr;
|
||||
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.expr.SQLIntegerExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
@@ -29,10 +30,10 @@ public class OracleIntervalExpr extends SQLExprImpl implements SQLLiteralExpr, O
|
||||
|
||||
private SQLExpr value;
|
||||
private OracleIntervalType type;
|
||||
private Integer precision;
|
||||
private SQLExpr precision;
|
||||
private Integer factionalSecondsPrecision;
|
||||
private OracleIntervalType toType;
|
||||
private Integer toFactionalSecondsPrecision;
|
||||
private SQLExpr toFactionalSecondsPrecision;
|
||||
|
||||
public OracleIntervalExpr(){
|
||||
|
||||
@@ -72,11 +73,18 @@ public class OracleIntervalExpr extends SQLExprImpl implements SQLLiteralExpr, O
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Integer getPrecision() {
|
||||
public SQLExpr getPrecision() {
|
||||
return this.precision;
|
||||
}
|
||||
|
||||
public void setPrecision(Integer precision) {
|
||||
this.setPrecision(new SQLIntegerExpr(precision));
|
||||
}
|
||||
|
||||
public void setPrecision(SQLExpr precision) {
|
||||
if (precision != null) {
|
||||
precision.setParent(this);
|
||||
}
|
||||
this.precision = precision;
|
||||
}
|
||||
|
||||
@@ -96,12 +104,15 @@ public class OracleIntervalExpr extends SQLExprImpl implements SQLLiteralExpr, O
|
||||
this.toType = toType;
|
||||
}
|
||||
|
||||
public Integer getToFactionalSecondsPrecision() {
|
||||
public SQLExpr getToFactionalSecondsPrecision() {
|
||||
return this.toFactionalSecondsPrecision;
|
||||
}
|
||||
|
||||
public void setToFactionalSecondsPrecision(Integer toFactionalSecondsPrecision) {
|
||||
this.toFactionalSecondsPrecision = toFactionalSecondsPrecision;
|
||||
public void setToFactionalSecondsPrecision(SQLExpr x) {
|
||||
if (x != null) {
|
||||
x.setParent(this);
|
||||
}
|
||||
this.toFactionalSecondsPrecision = x;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright 1999-2017 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.oracle.ast.expr;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLExprImpl;
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.SQLObject;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class OracleIsOfTypeExpr extends SQLExprImpl implements OracleExpr {
|
||||
private SQLExpr expr;
|
||||
private List<SQLExpr> types = new ArrayList<SQLExpr>();
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
OracleIsOfTypeExpr that = (OracleIsOfTypeExpr) o;
|
||||
|
||||
if (expr != null ? !expr.equals(that.expr) : that.expr != null) return false;
|
||||
return types != null ? types.equals(that.types) : that.types == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = expr != null ? expr.hashCode() : 0;
|
||||
result = 31 * result + (types != null ? types.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void accept0(SQLASTVisitor visitor) {
|
||||
accept0((OracleASTVisitor) visitor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept0(OracleASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, expr);
|
||||
acceptChild(visitor, types);
|
||||
}
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLExpr clone() {
|
||||
OracleIsOfTypeExpr x = new OracleIsOfTypeExpr();
|
||||
if (expr != null) {
|
||||
x.setExpr(expr);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SQLObject> getChildren() {
|
||||
List children = new ArrayList<SQLExpr>();
|
||||
if (expr != null) {
|
||||
children.add(expr);
|
||||
}
|
||||
children.addAll(types);
|
||||
return children;
|
||||
}
|
||||
|
||||
public SQLExpr getExpr() {
|
||||
return expr;
|
||||
}
|
||||
|
||||
public void setExpr(SQLExpr expr) {
|
||||
if (expr != null) {
|
||||
expr.setParent(this);
|
||||
}
|
||||
this.expr = expr;
|
||||
}
|
||||
|
||||
public List<SQLExpr> getTypes() {
|
||||
return types;
|
||||
}
|
||||
}
|
||||
@@ -92,6 +92,9 @@ public class OracleSelectPivot extends OracleSelectPivotBase {
|
||||
}
|
||||
|
||||
public void setExpr(SQLExpr expr) {
|
||||
if (expr != null) {
|
||||
expr.setParent(this);
|
||||
}
|
||||
this.expr = expr;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,21 +20,7 @@ import java.util.Arrays;
|
||||
|
||||
import com.alibaba.druid.sql.ast.*;
|
||||
import com.alibaba.druid.sql.ast.SQLKeep.DenseRank;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLAggregateExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLAggregateOption;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLNumericLiteralExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLSequenceExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLTimestampExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLUnaryExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLUnaryOperator;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.*;
|
||||
import com.alibaba.druid.sql.ast.statement.*;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalDay;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalYear;
|
||||
@@ -592,6 +578,17 @@ public class OracleExprParser extends SQLExprParser {
|
||||
|
||||
expr = dblink;
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.LBRACKET) {
|
||||
SQLArrayExpr arrayExpr = new SQLArrayExpr();
|
||||
arrayExpr.setExpr(expr);
|
||||
lexer.nextToken();
|
||||
this.exprList(arrayExpr.getValues(), arrayExpr);
|
||||
accept(Token.RBRACKET);
|
||||
expr = arrayExpr;
|
||||
|
||||
expr = primaryRest(expr);
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals("DAY") || lexer.identifierEquals("YEAR")) {
|
||||
Lexer.SavePoint savePoint = lexer.mark();
|
||||
@@ -743,6 +740,10 @@ public class OracleExprParser extends SQLExprParser {
|
||||
lexer.nextToken();
|
||||
acceptIdentifier("NULLS");
|
||||
aggregateExpr.setIgnoreNulls(true);
|
||||
} else if (lexer.identifierEquals(FnvHash.Constants.RESPECT)) {
|
||||
lexer.nextToken();
|
||||
acceptIdentifier("NULLS");
|
||||
aggregateExpr.setIgnoreNulls(false);
|
||||
}
|
||||
|
||||
accept(Token.RPAREN);
|
||||
@@ -873,10 +874,15 @@ public class OracleExprParser extends SQLExprParser {
|
||||
accept(Token.INTERVAL);
|
||||
|
||||
OracleIntervalExpr interval = new OracleIntervalExpr();
|
||||
if (lexer.token() != Token.LITERAL_CHARS) {
|
||||
|
||||
if (lexer.token() == Token.LITERAL_CHARS) {
|
||||
interval.setValue(new SQLCharExpr(lexer.stringVal()));
|
||||
} else if (lexer.token() == Token.VARIANT) {
|
||||
interval.setValue(new SQLVariantRefExpr(lexer.stringVal()));
|
||||
} else {
|
||||
return new SQLIdentifierExpr("INTERVAL");
|
||||
}
|
||||
interval.setValue(new SQLCharExpr(lexer.stringVal()));
|
||||
|
||||
lexer.nextToken();
|
||||
|
||||
OracleIntervalType type;
|
||||
@@ -906,12 +912,11 @@ public class OracleExprParser extends SQLExprParser {
|
||||
|
||||
if (lexer.token() == Token.LPAREN) {
|
||||
lexer.nextToken();
|
||||
if (lexer.token() != Token.LITERAL_INT) {
|
||||
if (lexer.token() != Token.LITERAL_INT && lexer.token() != Token.VARIANT) {
|
||||
throw new ParserException("syntax error. " + lexer.info());
|
||||
}
|
||||
interval.setPrecision(lexer.integerValue().intValue());
|
||||
lexer.nextToken();
|
||||
|
||||
interval.setPrecision(this.primary());
|
||||
|
||||
if (lexer.token() == Token.COMMA) {
|
||||
lexer.nextToken();
|
||||
if (lexer.token() != Token.LITERAL_INT) {
|
||||
@@ -930,11 +935,10 @@ public class OracleExprParser extends SQLExprParser {
|
||||
interval.setToType(OracleIntervalType.SECOND);
|
||||
if (lexer.token() == Token.LPAREN) {
|
||||
lexer.nextToken();
|
||||
if (lexer.token() != Token.LITERAL_INT) {
|
||||
if (lexer.token() != Token.LITERAL_INT && lexer.token() != Token.VARIANT) {
|
||||
throw new ParserException("syntax error. " + lexer.info());
|
||||
}
|
||||
interval.setToFactionalSecondsPrecision(lexer.integerValue().intValue());
|
||||
lexer.nextToken();
|
||||
interval.setToFactionalSecondsPrecision(primary());
|
||||
accept(Token.RPAREN);
|
||||
}
|
||||
} else {
|
||||
@@ -958,6 +962,41 @@ public class OracleExprParser extends SQLExprParser {
|
||||
lexer.nextToken();
|
||||
accept(Token.SET);
|
||||
expr = new OracleIsSetExpr(expr);
|
||||
} else if (lexer.token() == Token.OF) {
|
||||
lexer.nextToken();
|
||||
|
||||
if (lexer.identifierEquals(FnvHash.Constants.TYPE)) {
|
||||
lexer.nextToken();
|
||||
}
|
||||
|
||||
OracleIsOfTypeExpr isOf = new OracleIsOfTypeExpr();
|
||||
isOf.setExpr(expr);
|
||||
accept(Token.LPAREN);
|
||||
|
||||
for (;;) {
|
||||
boolean only = lexer.identifierEquals(FnvHash.Constants.ONLY);
|
||||
if (only) {
|
||||
lexer.nextToken();
|
||||
}
|
||||
|
||||
SQLExpr type = this.name();
|
||||
if (only) {
|
||||
type.putAttribute("ONLY", true);
|
||||
}
|
||||
|
||||
type.setParent(isOf);
|
||||
isOf.getTypes().add(type);
|
||||
|
||||
if (lexer.token() == Token.COMMA) {
|
||||
lexer.nextToken();
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
accept(Token.RPAREN);
|
||||
|
||||
expr = isOf;
|
||||
} else {
|
||||
SQLExpr rightExpr = primary();
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Is, rightExpr, getDbType());
|
||||
|
||||
@@ -144,7 +144,8 @@ public class OracleLexer extends Lexer {
|
||||
}
|
||||
|
||||
public void scanVariable() {
|
||||
if (ch != ':' && ch != '#' && ch != '$') {
|
||||
final char c0 = ch;
|
||||
if (c0 != ':' && c0 != '#' && c0 != '$') {
|
||||
throw new ParserException("illegal variable. " + info());
|
||||
}
|
||||
|
||||
@@ -154,25 +155,46 @@ public class OracleLexer extends Lexer {
|
||||
|
||||
boolean quoteFlag = false;
|
||||
boolean mybatisFlag = false;
|
||||
if (charAt(pos + 1) == '"') {
|
||||
|
||||
char c1 = charAt(pos + 1);
|
||||
if (c0 == ':' && c1 == ' ') {
|
||||
pos++;
|
||||
bufPos = 2;
|
||||
c1 = charAt(pos + 1);
|
||||
}
|
||||
|
||||
if (c1 == '"') {
|
||||
pos++;
|
||||
bufPos++;
|
||||
quoteFlag = true;
|
||||
} else if (charAt(pos + 1) == '{') {
|
||||
} else if (c1 == '{') {
|
||||
pos++;
|
||||
bufPos++;
|
||||
mybatisFlag = true;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
ch = charAt(++pos);
|
||||
if (c0 == ':' && c1 >= '0' && c1 <= '9') {
|
||||
for (; ; ) {
|
||||
ch = charAt(++pos);
|
||||
|
||||
if (!isIdentifierChar(ch)) {
|
||||
break;
|
||||
if (ch < '0' || ch > '9') {
|
||||
break;
|
||||
}
|
||||
|
||||
bufPos++;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
for (; ; ) {
|
||||
ch = charAt(++pos);
|
||||
|
||||
bufPos++;
|
||||
continue;
|
||||
if (!isIdentifierChar(ch)) {
|
||||
break;
|
||||
}
|
||||
|
||||
bufPos++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (quoteFlag) {
|
||||
|
||||
@@ -48,6 +48,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectTableReference;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectTableSource;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectUnPivot;
|
||||
import com.alibaba.druid.sql.parser.*;
|
||||
import com.alibaba.druid.util.FnvHash;
|
||||
|
||||
public class OracleSelectParser extends SQLSelectParser {
|
||||
|
||||
@@ -204,8 +205,16 @@ public class OracleSelectParser extends SQLSelectParser {
|
||||
throw new ParserException("syntax erorr : " + lexer.token());
|
||||
}
|
||||
|
||||
searchClause.setType(SearchClause.Type.valueOf(lexer.stringVal()));
|
||||
lexer.nextToken();
|
||||
if (lexer.identifierEquals(FnvHash.Constants.DEPTH)) {
|
||||
lexer.nextToken();
|
||||
searchClause.setType(SearchClause.Type.DEPTH);
|
||||
} else if (lexer.identifierEquals(FnvHash.Constants.BREADTH)) {
|
||||
lexer.nextToken();
|
||||
searchClause.setType(SearchClause.Type.BREADTH);
|
||||
} else {
|
||||
searchClause.setType(SearchClause.Type.valueOf(lexer.stringVal().toUpperCase()));
|
||||
lexer.nextToken();
|
||||
}
|
||||
|
||||
acceptIdentifier("FIRST");
|
||||
accept(Token.BY);
|
||||
@@ -522,9 +531,16 @@ public class OracleSelectParser extends SQLSelectParser {
|
||||
item.setCellAssignment(parseCellAssignment());
|
||||
item.setOrderBy(this.parseOrderBy());
|
||||
accept(Token.EQ);
|
||||
item.setExpr(expr());
|
||||
|
||||
SQLExpr expr = this.expr();
|
||||
item.setExpr(expr);
|
||||
|
||||
modelRulesClause.getCellAssignmentItems().add(item);
|
||||
|
||||
if (lexer.token() == Token.COMMA) {
|
||||
lexer.nextToken();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
mainModel.setModelRulesClause(modelRulesClause);
|
||||
@@ -533,7 +549,7 @@ public class OracleSelectParser extends SQLSelectParser {
|
||||
private CellAssignment parseCellAssignment() {
|
||||
CellAssignment cellAssignment = new CellAssignment();
|
||||
|
||||
cellAssignment.setMeasureColumn(expr());
|
||||
cellAssignment.setMeasureColumn(this.exprParser.name());
|
||||
accept(Token.LBRACKET);
|
||||
this.exprParser.exprList(cellAssignment.getConditions(), cellAssignment);
|
||||
accept(Token.RBRACKET);
|
||||
@@ -609,6 +625,7 @@ public class OracleSelectParser extends SQLSelectParser {
|
||||
} else if (lexer.token() == Token.IDENTIFIER) {
|
||||
SQLTableSource identTable = parseTableSource();
|
||||
accept(Token.RPAREN);
|
||||
parsePivot((OracleSelectTableSource) identTable);
|
||||
return identTable;
|
||||
} else {
|
||||
throw new ParserException("TODO :" + lexer.info());
|
||||
@@ -688,6 +705,11 @@ public class OracleSelectParser extends SQLSelectParser {
|
||||
lexer.nextToken();
|
||||
partition.setPartition(exprParser.name());
|
||||
accept(Token.RPAREN);
|
||||
} else if (lexer.token() == Token.BY) {
|
||||
lexer.nextToken();
|
||||
accept(Token.LPAREN);
|
||||
partition.setPartition(exprParser.name());
|
||||
accept(Token.RPAREN);
|
||||
} else {
|
||||
accept(Token.FOR);
|
||||
accept(Token.LPAREN);
|
||||
@@ -861,6 +883,14 @@ public class OracleSelectParser extends SQLSelectParser {
|
||||
if (lexer.token() == Token.ON) {
|
||||
lexer.nextToken();
|
||||
join.setCondition(this.exprParser.expr());
|
||||
|
||||
if (lexer.token() == Token.ON
|
||||
&& tableSource instanceof SQLJoinTableSource
|
||||
&& ((SQLJoinTableSource) tableSource).getCondition() == null) {
|
||||
lexer.nextToken();
|
||||
SQLExpr leftCondidition = this.exprParser.expr();
|
||||
((SQLJoinTableSource) tableSource).setCondition(leftCondidition);
|
||||
}
|
||||
} else if (lexer.token() == Token.USING) {
|
||||
lexer.nextToken();
|
||||
accept(Token.LPAREN);
|
||||
@@ -868,6 +898,8 @@ public class OracleSelectParser extends SQLSelectParser {
|
||||
accept(Token.RPAREN);
|
||||
}
|
||||
|
||||
parsePivot(join);
|
||||
|
||||
return parseTableSourceRest(join);
|
||||
}
|
||||
|
||||
@@ -921,25 +953,28 @@ public class OracleSelectParser extends SQLSelectParser {
|
||||
|
||||
accept(Token.IN);
|
||||
accept(Token.LPAREN);
|
||||
if (lexer.token() == (Token.LPAREN)) {
|
||||
throw new ParserException("TODO. " + lexer.info());
|
||||
}
|
||||
// if (lexer.token() == (Token.LPAREN)) {
|
||||
// throw new ParserException("TODO. " + lexer.info());
|
||||
// }
|
||||
|
||||
if (lexer.token() == (Token.SELECT)) {
|
||||
throw new ParserException("TODO. " + lexer.info());
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
SQLExpr expr = this.exprParser.expr();
|
||||
item = new OracleSelectPivot.Item();
|
||||
item.setExpr(this.exprParser.expr());
|
||||
item.setAlias(as());
|
||||
item.setExpr(expr);
|
||||
pivot.getPivotIn().add(item);
|
||||
} else {
|
||||
for (; ; ) {
|
||||
item = new OracleSelectPivot.Item();
|
||||
item.setExpr(this.exprParser.expr());
|
||||
item.setAlias(as());
|
||||
pivot.getPivotIn().add(item);
|
||||
|
||||
if (lexer.token() != Token.COMMA) {
|
||||
break;
|
||||
if (lexer.token() != Token.COMMA) {
|
||||
break;
|
||||
}
|
||||
|
||||
lexer.nextToken();
|
||||
}
|
||||
|
||||
lexer.nextToken();
|
||||
}
|
||||
|
||||
accept(Token.RPAREN);
|
||||
|
||||
+4
-1
@@ -1381,7 +1381,10 @@ public class OracleStatementParser extends SQLStatementParser {
|
||||
stmt.addItem(item);
|
||||
|
||||
accept(Token.RPAREN);
|
||||
} else if (lexer.token() == Token.CONSTRAINT) {
|
||||
} else if (lexer.token() == Token.CONSTRAINT
|
||||
|| lexer.token() == Token.FOREIGN
|
||||
|| lexer.token() == Token.PRIMARY
|
||||
|| lexer.token() == Token.UNIQUE) {
|
||||
OracleConstraint constraint = ((OracleExprParser) this.exprParser).parseConstaint();
|
||||
SQLAlterTableAddConstraint item = new SQLAlterTableAddConstraint();
|
||||
constraint.setParent(item);
|
||||
|
||||
@@ -437,4 +437,8 @@ public interface OracleASTVisitor extends SQLASTVisitor {
|
||||
boolean visit(OraclePipeRowStatement x);
|
||||
|
||||
void endVisit(OraclePipeRowStatement x);
|
||||
|
||||
boolean visit(OracleIsOfTypeExpr x);
|
||||
|
||||
void endVisit(OracleIsOfTypeExpr x);
|
||||
}
|
||||
|
||||
+10
@@ -1083,4 +1083,14 @@ public class OracleASTVisitorAdapter extends SQLASTVisitorAdapter implements Ora
|
||||
public void endVisit(OraclePipeRowStatement x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleIsOfTypeExpr x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OracleIsOfTypeExpr x) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+37
-4
@@ -187,7 +187,7 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
|
||||
|
||||
if (x.getPrecision() != null) {
|
||||
print('(');
|
||||
print(x.getPrecision().intValue());
|
||||
printExpr(x.getPrecision());
|
||||
if (x.getFactionalSecondsPrecision() != null) {
|
||||
print0(", ");
|
||||
print(x.getFactionalSecondsPrecision().intValue());
|
||||
@@ -200,7 +200,7 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
|
||||
print0(x.getToType().name());
|
||||
if (x.getToFactionalSecondsPrecision() != null) {
|
||||
print('(');
|
||||
print(x.getToFactionalSecondsPrecision().intValue());
|
||||
printExpr(x.getToFactionalSecondsPrecision());
|
||||
print(')');
|
||||
}
|
||||
}
|
||||
@@ -297,6 +297,12 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
|
||||
printFlashback(x.getFlashback());
|
||||
}
|
||||
|
||||
OracleSelectPivotBase pivot = x.getPivot();
|
||||
if (pivot != null) {
|
||||
println();
|
||||
pivot.accept(this);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -471,9 +477,10 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
|
||||
println();
|
||||
print(')');
|
||||
|
||||
if (x.getPivot() != null) {
|
||||
OracleSelectPivotBase pivot = x.getPivot();
|
||||
if (pivot != null) {
|
||||
println();
|
||||
x.getPivot().accept(this);
|
||||
pivot.accept(this);
|
||||
}
|
||||
|
||||
printFlashback(x.getFlashback());
|
||||
@@ -3341,4 +3348,30 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
|
||||
public void endVisit(OraclePipeRowStatement x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleIsOfTypeExpr x) {
|
||||
printExpr(x.getExpr());
|
||||
print0(ucase ? " IS OF TYPE (" : " is of type (");
|
||||
|
||||
List<SQLExpr> types = x.getTypes();
|
||||
for (int i = 0, size = types.size(); i < size; ++i) {
|
||||
if (i != 0) {
|
||||
print0(", ");
|
||||
}
|
||||
SQLExpr type = types.get(i);
|
||||
if (Boolean.TRUE == type.getAttribute("ONLY")) {
|
||||
print0(ucase ? "ONLY " : "only ");
|
||||
}
|
||||
type.accept(this);
|
||||
}
|
||||
|
||||
print(')');
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OracleIsOfTypeExpr x) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+10
@@ -1375,4 +1375,14 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
|
||||
public void endVisit(OraclePipeRowStatement x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleIsOfTypeExpr x) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OracleIsOfTypeExpr x) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,12 @@ public class PGTypeCastExpr extends SQLCastExpr implements PGExpr {
|
||||
|
||||
@Override
|
||||
protected void accept0(SQLASTVisitor visitor) {
|
||||
accept0((PGASTVisitor) visitor);
|
||||
if (visitor instanceof PGASTVisitor) {
|
||||
accept0((PGASTVisitor) visitor);
|
||||
return;
|
||||
}
|
||||
|
||||
super.accept0(visitor);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
|
||||
+6
-1
@@ -38,7 +38,12 @@ public class PGUpdateStatement extends SQLUpdateStatement implements PGSQLStatem
|
||||
}
|
||||
|
||||
protected void accept0(SQLASTVisitor visitor) {
|
||||
accept0((PGASTVisitor) visitor);
|
||||
if (visitor instanceof PGASTVisitor) {
|
||||
accept0((PGASTVisitor) visitor);
|
||||
return;
|
||||
}
|
||||
|
||||
super.accept0(visitor);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+74
@@ -31,6 +31,8 @@ import com.alibaba.druid.sql.parser.Lexer;
|
||||
import com.alibaba.druid.sql.parser.ParserException;
|
||||
import com.alibaba.druid.sql.parser.SQLStatementParser;
|
||||
import com.alibaba.druid.sql.parser.Token;
|
||||
import com.alibaba.druid.util.FnvHash;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -393,5 +395,77 @@ public class PGSQLStatementParser extends SQLStatementParser {
|
||||
return stmt;
|
||||
}
|
||||
|
||||
public SQLCreateSequenceStatement parseCreateSequence(boolean acceptCreate) {
|
||||
if (acceptCreate) {
|
||||
accept(Token.CREATE);
|
||||
}
|
||||
|
||||
accept(Token.SEQUENCE);
|
||||
|
||||
SQLCreateSequenceStatement stmt = new SQLCreateSequenceStatement();
|
||||
stmt.setDbType(dbType);
|
||||
stmt.setName(this.exprParser.name());
|
||||
|
||||
for (;;) {
|
||||
if (lexer.token() == Token.START) {
|
||||
lexer.nextToken();
|
||||
accept(Token.WITH);
|
||||
stmt.setStartWith(this.exprParser.expr());
|
||||
continue;
|
||||
} else if (lexer.identifierEquals("INCREMENT")) {
|
||||
lexer.nextToken();
|
||||
accept(Token.BY);
|
||||
stmt.setIncrementBy(this.exprParser.expr());
|
||||
continue;
|
||||
} else if (lexer.token() == Token.CACHE || lexer.identifierEquals(FnvHash.Constants.CACHE)) {
|
||||
lexer.nextToken();
|
||||
stmt.setCache(Boolean.TRUE);
|
||||
|
||||
if (lexer.token() == Token.LITERAL_INT) {
|
||||
stmt.setCacheValue(this.exprParser.primary());
|
||||
}
|
||||
continue;
|
||||
} else if (lexer.token() == Token.NOCACHE) {
|
||||
lexer.nextToken();
|
||||
stmt.setCache(Boolean.FALSE);
|
||||
continue;
|
||||
} else if (lexer.token() == Token.ORDER) {
|
||||
lexer.nextToken();
|
||||
stmt.setOrder(Boolean.TRUE);
|
||||
continue;
|
||||
} else if (lexer.identifierEquals("NOORDER")) {
|
||||
lexer.nextToken();
|
||||
stmt.setOrder(Boolean.FALSE);
|
||||
continue;
|
||||
} else if (lexer.identifierEquals("CYCLE")) {
|
||||
lexer.nextToken();
|
||||
stmt.setCycle(Boolean.TRUE);
|
||||
continue;
|
||||
} else if (lexer.identifierEquals("NOCYCLE")) {
|
||||
lexer.nextToken();
|
||||
stmt.setCycle(Boolean.FALSE);
|
||||
continue;
|
||||
} else if (lexer.identifierEquals("MINVALUE")) {
|
||||
lexer.nextToken();
|
||||
stmt.setMinValue(this.exprParser.expr());
|
||||
continue;
|
||||
} else if (lexer.identifierEquals("MAXVALUE")) {
|
||||
lexer.nextToken();
|
||||
stmt.setMaxValue(this.exprParser.expr());
|
||||
continue;
|
||||
} else if (lexer.identifierEquals("NOMAXVALUE")) {
|
||||
lexer.nextToken();
|
||||
stmt.setNoMaxValue(true);
|
||||
continue;
|
||||
} else if (lexer.identifierEquals("NOMINVALUE")) {
|
||||
lexer.nextToken();
|
||||
stmt.setNoMinValue(true);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return stmt;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+27
-2
@@ -1082,7 +1082,7 @@ public class PGOutputVisitor extends SQLASTOutputVisitor implements PGASTVisitor
|
||||
|
||||
if (x.getPrecision() != null) {
|
||||
print('(');
|
||||
print(x.getPrecision().intValue());
|
||||
printExpr(x.getPrecision());
|
||||
if (x.getFactionalSecondsPrecision() != null) {
|
||||
print0(", ");
|
||||
print(x.getFactionalSecondsPrecision().intValue());
|
||||
@@ -1095,7 +1095,7 @@ public class PGOutputVisitor extends SQLASTOutputVisitor implements PGASTVisitor
|
||||
print0(x.getToType().name());
|
||||
if (x.getToFactionalSecondsPrecision() != null) {
|
||||
print('(');
|
||||
print(x.getToFactionalSecondsPrecision().intValue());
|
||||
printExpr(x.getToFactionalSecondsPrecision());
|
||||
print(')');
|
||||
}
|
||||
}
|
||||
@@ -2770,4 +2770,29 @@ public class PGOutputVisitor extends SQLASTOutputVisitor implements PGASTVisitor
|
||||
x.getExpr().accept(this);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleIsOfTypeExpr x) {
|
||||
printExpr(x.getExpr());
|
||||
print0(ucase ? " IS OF TYPE (" : " is of type (");
|
||||
|
||||
List<SQLExpr> types = x.getTypes();
|
||||
for (int i = 0, size = types.size(); i < size; ++i) {
|
||||
if (i != 0) {
|
||||
print0(", ");
|
||||
}
|
||||
SQLExpr type = types.get(i);
|
||||
if (Boolean.TRUE == type.getAttribute("ONLY")) {
|
||||
print0(ucase ? "ONLY " : "only ");
|
||||
}
|
||||
type.accept(this);
|
||||
}
|
||||
|
||||
print(')');
|
||||
return false;
|
||||
}
|
||||
|
||||
public void endVisit(OracleIsOfTypeExpr x) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -866,7 +866,40 @@ public class Lexer {
|
||||
scanChar();
|
||||
token = Token.LT_SUB_GT;
|
||||
} else {
|
||||
token = Token.LT;
|
||||
if (ch == ' ') {
|
||||
char c1 = charAt(pos + 1);
|
||||
if (c1 == '=') {
|
||||
scanChar();
|
||||
scanChar();
|
||||
if (ch == '>') {
|
||||
token = Token.LTEQGT;
|
||||
scanChar();
|
||||
} else {
|
||||
token = Token.LTEQ;
|
||||
}
|
||||
} else if (c1 == '>') {
|
||||
scanChar();
|
||||
scanChar();
|
||||
token = Token.LTGT;
|
||||
} else if (c1 == '<') {
|
||||
scanChar();
|
||||
scanChar();
|
||||
token = Token.LTLT;
|
||||
} else if (c1 == '@') {
|
||||
scanChar();
|
||||
scanChar();
|
||||
token = Token.LT_MONKEYS_AT;
|
||||
} else if (c1 == '-' && charAt(pos + 2) == '>') {
|
||||
scanChar();
|
||||
scanChar();
|
||||
scanChar();
|
||||
token = Token.LT_SUB_GT;
|
||||
} else {
|
||||
token = Token.LT;
|
||||
}
|
||||
} else {
|
||||
token = Token.LT;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '!':
|
||||
|
||||
@@ -24,26 +24,7 @@ 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;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLNullConstraint;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLAssignItem;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLCharacterDataType;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLCheck;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLColumnCheck;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLColumnPrimaryKey;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLColumnReference;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLColumnUniqueKey;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLConstraint;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLForeignKeyConstraint;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLForeignKeyImpl;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLPrimaryKey;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLPrimaryKeyImpl;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelect;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectItem;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUnique;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem;
|
||||
import com.alibaba.druid.sql.ast.statement.*;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleArgumentExpr;
|
||||
import com.alibaba.druid.util.FnvHash;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
@@ -140,8 +121,15 @@ public class SQLExprParser extends SQLParser {
|
||||
switch (token) {
|
||||
case CARET: {
|
||||
lexer.nextToken();
|
||||
SQLBinaryOperator op;
|
||||
if (lexer.token == Token.EQ) {
|
||||
lexer.nextToken();
|
||||
op = SQLBinaryOperator.BitwiseXorEQ;
|
||||
} else {
|
||||
op = SQLBinaryOperator.BitwiseXor;
|
||||
}
|
||||
SQLExpr rightExp = primary();
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BitwiseXor, rightExp, dbType);
|
||||
expr = new SQLBinaryOpExpr(expr, op, rightExp, dbType);
|
||||
expr = bitXorRest(expr);
|
||||
break;
|
||||
}
|
||||
@@ -303,6 +291,13 @@ public class SQLExprParser extends SQLParser {
|
||||
}
|
||||
|
||||
accept(Token.RPAREN);
|
||||
|
||||
if (lexer.token == Token.UNION && sqlExpr instanceof SQLQueryExpr) {
|
||||
SQLQueryExpr queryExpr = (SQLQueryExpr) sqlExpr;
|
||||
|
||||
SQLSelectQuery query = this.createSelectParser().queryRest(queryExpr.getSubQuery().getQuery());
|
||||
queryExpr.getSubQuery().setQuery(query);
|
||||
}
|
||||
break;
|
||||
case INSERT:
|
||||
lexer.nextToken();
|
||||
@@ -707,6 +702,18 @@ public class SQLExprParser extends SQLParser {
|
||||
sqlExpr = new SQLBinaryExpr(strVal);
|
||||
break;
|
||||
}
|
||||
case SET: {
|
||||
Lexer.SavePoint savePoint = lexer.mark();
|
||||
lexer.nextToken();
|
||||
if (lexer.token() == Token.LPAREN) {
|
||||
sqlExpr = new SQLIdentifierExpr("SET");
|
||||
} else {
|
||||
lexer.reset(savePoint);
|
||||
throw new ParserException("ERROR. " + lexer.info());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
throw new ParserException("ERROR. " + lexer.info());
|
||||
}
|
||||
@@ -844,37 +851,37 @@ public class SQLExprParser extends SQLParser {
|
||||
&& "GROUPING".equalsIgnoreCase(((SQLIdentifierExpr) expr).getName())) {
|
||||
SQLGroupingSetExpr groupingSets = new SQLGroupingSetExpr();
|
||||
lexer.nextToken();
|
||||
|
||||
|
||||
accept(Token.LPAREN);
|
||||
|
||||
for (;;) {
|
||||
|
||||
for (; ; ) {
|
||||
SQLExpr item;
|
||||
if (lexer.token == Token.LPAREN) {
|
||||
lexer.nextToken();
|
||||
|
||||
|
||||
SQLListExpr listExpr = new SQLListExpr();
|
||||
this.exprList(listExpr.getItems(), listExpr);
|
||||
item = listExpr;
|
||||
|
||||
|
||||
accept(Token.RPAREN);
|
||||
} else {
|
||||
item = this.expr();
|
||||
}
|
||||
|
||||
|
||||
item.setParent(groupingSets);
|
||||
groupingSets.addParameter(item);
|
||||
|
||||
|
||||
if (lexer.token == Token.RPAREN) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
accept(Token.COMMA);
|
||||
}
|
||||
|
||||
this.exprList(groupingSets.getParameters(), groupingSets);
|
||||
|
||||
accept(Token.RPAREN);
|
||||
|
||||
|
||||
return groupingSets;
|
||||
} else {
|
||||
if (lexer.token == Token.LPAREN) {
|
||||
@@ -992,7 +999,13 @@ public class SQLExprParser extends SQLParser {
|
||||
|
||||
if (lexer.token == Token.USING || lexer.identifierEquals(FnvHash.Constants.USING)) {
|
||||
lexer.nextToken();
|
||||
SQLExpr using = this.primary();
|
||||
SQLExpr using;
|
||||
if (lexer.token == Token.STAR) {
|
||||
lexer.nextToken();
|
||||
using = new SQLAllColumnExpr();
|
||||
} else {
|
||||
using = this.primary();
|
||||
}
|
||||
methodInvokeExpr.setUsing(using);
|
||||
}
|
||||
|
||||
@@ -1542,8 +1555,13 @@ public class SQLExprParser extends SQLParser {
|
||||
public final SQLExpr bitOrRest(SQLExpr expr) {
|
||||
while (lexer.token == Token.BAR) {
|
||||
lexer.nextToken();
|
||||
SQLBinaryOperator op = SQLBinaryOperator.BitwiseOr;
|
||||
if (lexer.token == Token.BAR) {
|
||||
lexer.nextToken();
|
||||
op = SQLBinaryOperator.Concat;
|
||||
}
|
||||
SQLExpr rightExp = bitAnd();
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BitwiseOr, rightExp, getDbType());
|
||||
expr = new SQLBinaryOpExpr(expr, op, rightExp, getDbType());
|
||||
expr = bitAndRest(expr);
|
||||
}
|
||||
return expr;
|
||||
|
||||
@@ -1897,6 +1897,11 @@ public class SQLStatementParser extends SQLParser {
|
||||
return parseCreateType();
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals(FnvHash.Constants.PUBLIC)) {
|
||||
lexer.reset(markBp, markChar, Token.CREATE);
|
||||
return parseCreateSynonym();
|
||||
}
|
||||
|
||||
// lexer.reset(mark_bp, mark_ch, Token.CREATE);
|
||||
throw new ParserException("TODO " + lexer.info());
|
||||
} else if (token == Token.DATABASE) {
|
||||
@@ -2726,82 +2731,90 @@ public class SQLStatementParser extends SQLParser {
|
||||
accept(Token.ON);
|
||||
stmt.setOn(exprParser.expr());
|
||||
|
||||
boolean insertFlag = false;
|
||||
if (lexer.token == Token.WHEN) {
|
||||
lexer.nextToken();
|
||||
if (lexer.token == Token.MATCHED) {
|
||||
SQLMergeStatement.MergeUpdateClause updateClause = new SQLMergeStatement.MergeUpdateClause();
|
||||
for (;;) {
|
||||
boolean insertFlag = false;
|
||||
if (lexer.token == Token.WHEN) {
|
||||
lexer.nextToken();
|
||||
accept(Token.THEN);
|
||||
accept(Token.UPDATE);
|
||||
accept(Token.SET);
|
||||
if (lexer.token == Token.MATCHED) {
|
||||
SQLMergeStatement.MergeUpdateClause updateClause = new SQLMergeStatement.MergeUpdateClause();
|
||||
lexer.nextToken();
|
||||
accept(Token.THEN);
|
||||
accept(Token.UPDATE);
|
||||
accept(Token.SET);
|
||||
|
||||
for (;;) {
|
||||
SQLUpdateSetItem item = this.exprParser.parseUpdateSetItem();
|
||||
for (; ; ) {
|
||||
SQLUpdateSetItem item = this.exprParser.parseUpdateSetItem();
|
||||
|
||||
updateClause.addItem(item);
|
||||
item.setParent(updateClause);
|
||||
updateClause.addItem(item);
|
||||
item.setParent(updateClause);
|
||||
|
||||
if (lexer.token == (Token.COMMA)) {
|
||||
lexer.nextToken();
|
||||
continue;
|
||||
if (lexer.token == (Token.COMMA)) {
|
||||
lexer.nextToken();
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
if (lexer.token == Token.WHERE) {
|
||||
lexer.nextToken();
|
||||
updateClause.setWhere(exprParser.expr());
|
||||
}
|
||||
|
||||
if (lexer.token == Token.DELETE) {
|
||||
lexer.nextToken();
|
||||
accept(Token.WHERE);
|
||||
updateClause.setWhere(exprParser.expr());
|
||||
}
|
||||
|
||||
stmt.setUpdateClause(updateClause);
|
||||
} else if (lexer.token == Token.NOT) {
|
||||
lexer.nextToken();
|
||||
insertFlag = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!insertFlag) {
|
||||
if (lexer.token == Token.WHEN) {
|
||||
lexer.nextToken();
|
||||
}
|
||||
|
||||
if (lexer.token == Token.NOT) {
|
||||
lexer.nextToken();
|
||||
insertFlag = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (insertFlag) {
|
||||
SQLMergeStatement.MergeInsertClause insertClause = new SQLMergeStatement.MergeInsertClause();
|
||||
|
||||
accept(Token.MATCHED);
|
||||
accept(Token.THEN);
|
||||
accept(Token.INSERT);
|
||||
|
||||
if (lexer.token == Token.LPAREN) {
|
||||
accept(Token.LPAREN);
|
||||
exprParser.exprList(insertClause.getColumns(), insertClause);
|
||||
accept(Token.RPAREN);
|
||||
}
|
||||
accept(Token.VALUES);
|
||||
accept(Token.LPAREN);
|
||||
exprParser.exprList(insertClause.getValues(), insertClause);
|
||||
accept(Token.RPAREN);
|
||||
|
||||
if (lexer.token == Token.WHERE) {
|
||||
lexer.nextToken();
|
||||
updateClause.setWhere(exprParser.expr());
|
||||
insertClause.setWhere(exprParser.expr());
|
||||
}
|
||||
|
||||
if (lexer.token == Token.DELETE) {
|
||||
lexer.nextToken();
|
||||
accept(Token.WHERE);
|
||||
updateClause.setWhere(exprParser.expr());
|
||||
}
|
||||
|
||||
stmt.setUpdateClause(updateClause);
|
||||
} else if (lexer.token == Token.NOT) {
|
||||
lexer.nextToken();
|
||||
insertFlag = true;
|
||||
stmt.setInsertClause(insertClause);
|
||||
}
|
||||
}
|
||||
|
||||
if (!insertFlag) {
|
||||
if (lexer.token == Token.WHEN) {
|
||||
lexer.nextToken();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lexer.token == Token.NOT) {
|
||||
lexer.nextToken();
|
||||
insertFlag = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (insertFlag) {
|
||||
SQLMergeStatement.MergeInsertClause insertClause = new SQLMergeStatement.MergeInsertClause();
|
||||
|
||||
accept(Token.MATCHED);
|
||||
accept(Token.THEN);
|
||||
accept(Token.INSERT);
|
||||
|
||||
if (lexer.token == Token.LPAREN) {
|
||||
accept(Token.LPAREN);
|
||||
exprParser.exprList(insertClause.getColumns(), insertClause);
|
||||
accept(Token.RPAREN);
|
||||
}
|
||||
accept(Token.VALUES);
|
||||
accept(Token.LPAREN);
|
||||
exprParser.exprList(insertClause.getValues(), insertClause);
|
||||
accept(Token.RPAREN);
|
||||
|
||||
if (lexer.token == Token.WHERE) {
|
||||
lexer.nextToken();
|
||||
insertClause.setWhere(exprParser.expr());
|
||||
}
|
||||
|
||||
stmt.setInsertClause(insertClause);
|
||||
break;
|
||||
}
|
||||
|
||||
SQLErrorLoggingClause errorClause = parseErrorLoggingClause();
|
||||
|
||||
@@ -41,6 +41,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleCursorExpr;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleDatetimeExpr;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreatePackageStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleForStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectPivot;
|
||||
import com.alibaba.druid.sql.dialect.oracle.parser.OracleFunctionDataType;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
import com.alibaba.druid.util.JdbcUtils;
|
||||
@@ -1597,8 +1598,9 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
visit(subQuery);
|
||||
print(')');
|
||||
println();
|
||||
} else if (parent instanceof SQLStatement
|
||||
&& !(parent instanceof OracleForStatement)) {
|
||||
} else if ((parent instanceof SQLStatement
|
||||
&& !(parent instanceof OracleForStatement))
|
||||
|| parent instanceof OracleSelectPivot.Item) {
|
||||
this.indentCount++;
|
||||
|
||||
println();
|
||||
@@ -4973,7 +4975,11 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
}
|
||||
|
||||
if (x.isNoMaxValue()) {
|
||||
print0(ucase ? " NOMAXVALUE" : " nomaxvalue");
|
||||
if (JdbcConstants.POSTGRESQL.equals(dbType)) {
|
||||
print0(ucase ? " NO MAXVALUE" : " no maxvalue");
|
||||
} else {
|
||||
print0(ucase ? " NOMAXVALUE" : " nomaxvalue");
|
||||
}
|
||||
}
|
||||
|
||||
if (x.getMinValue() != null) {
|
||||
@@ -4982,14 +4988,22 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
}
|
||||
|
||||
if (x.isNoMinValue()) {
|
||||
print0(ucase ? " NOMINVALUE" : " nominvalue");
|
||||
if (JdbcConstants.POSTGRESQL.equals(dbType)) {
|
||||
print0(ucase ? " NO MINVALUE" : " no minvalue");
|
||||
} else {
|
||||
print0(ucase ? " NOMINVALUE" : " nominvalue");
|
||||
}
|
||||
}
|
||||
|
||||
if (x.getCycle() != null) {
|
||||
if (x.getCycle().booleanValue()) {
|
||||
print0(ucase ? " CYCLE" : " cycle");
|
||||
} else {
|
||||
print0(ucase ? " NOCYCLE" : " nocycle");
|
||||
if (JdbcConstants.POSTGRESQL.equals(dbType)) {
|
||||
print0(ucase ? " NO CYCLE" : " no cycle");
|
||||
} else {
|
||||
print0(ucase ? " NOCYCLE" : " nocycle");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -306,6 +306,7 @@ public final class FnvHash {
|
||||
long SQL_SMALL_RESULT = fnv1a_64_lower("SQL_SMALL_RESULT");
|
||||
long SQL_BIG_RESULT = fnv1a_64_lower("SQL_BIG_RESULT");
|
||||
long SQL_BUFFER_RESULT = fnv1a_64_lower("SQL_BUFFER_RESULT");
|
||||
long CACHE = fnv1a_64_lower("CACHE");
|
||||
long SQL_CACHE = fnv1a_64_lower("SQL_CACHE");
|
||||
long SQL_NO_CACHE = fnv1a_64_lower("SQL_NO_CACHE");
|
||||
long SQL_CALC_FOUND_ROWS = fnv1a_64_lower("SQL_CALC_FOUND_ROWS");
|
||||
@@ -439,6 +440,7 @@ public final class FnvHash {
|
||||
long FOLLOWING = fnv1a_64_lower("FOLLOWING");
|
||||
long UNBOUNDED = fnv1a_64_lower("UNBOUNDED");
|
||||
long SIBLINGS = fnv1a_64_lower("SIBLINGS");
|
||||
long RESPECT = fnv1a_64_lower("RESPECT");
|
||||
long NULLS = fnv1a_64_lower("NULLS");
|
||||
long FIRST = fnv1a_64_lower("FIRST");
|
||||
long LAST = fnv1a_64_lower("LAST");
|
||||
@@ -511,6 +513,7 @@ public final class FnvHash {
|
||||
long TRUNC = fnv1a_64_lower("TRUNC");
|
||||
long SYSTIMESTAMP = fnv1a_64_lower("SYSTIMESTAMP");
|
||||
long TYPE = fnv1a_64_lower("TYPE");
|
||||
long ONLY = fnv1a_64_lower("ONLY");
|
||||
long MEMBER = fnv1a_64_lower("MEMBER");
|
||||
long STATIC = fnv1a_64_lower("STATIC");
|
||||
long UNSUPPORTED = fnv1a_64_lower("UNSUPPORTED");
|
||||
@@ -524,5 +527,8 @@ public final class FnvHash {
|
||||
long COMPRESS = fnv1a_64_lower("COMPRESS");
|
||||
long YES = fnv1a_64_lower("YES");
|
||||
long WMSYS = fnv1a_64_lower("WMSYS");
|
||||
|
||||
long DEPTH = fnv1a_64_lower("DEPTH");
|
||||
long BREADTH = fnv1a_64_lower("BREADTH");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user