Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
studio.raptor.sqlparser.parser.SQLExprParser Maven / Gradle / Ivy
/*
* 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 studio.raptor.sqlparser.parser;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import studio.raptor.sqlparser.ast.SQLCommentHint;
import studio.raptor.sqlparser.ast.SQLDataType;
import studio.raptor.sqlparser.ast.SQLDataTypeImpl;
import studio.raptor.sqlparser.ast.SQLExpr;
import studio.raptor.sqlparser.ast.SQLLimit;
import studio.raptor.sqlparser.ast.SQLName;
import studio.raptor.sqlparser.ast.SQLObject;
import studio.raptor.sqlparser.ast.SQLOrderBy;
import studio.raptor.sqlparser.ast.SQLOrderingSpecification;
import studio.raptor.sqlparser.ast.SQLOver;
import studio.raptor.sqlparser.ast.SQLPartitionValue;
import studio.raptor.sqlparser.ast.expr.SQLAggregateExpr;
import studio.raptor.sqlparser.ast.expr.SQLAggregateOption;
import studio.raptor.sqlparser.ast.expr.SQLAllColumnExpr;
import studio.raptor.sqlparser.ast.expr.SQLAllExpr;
import studio.raptor.sqlparser.ast.expr.SQLAnyExpr;
import studio.raptor.sqlparser.ast.expr.SQLBetweenExpr;
import studio.raptor.sqlparser.ast.expr.SQLBinaryOpExpr;
import studio.raptor.sqlparser.ast.expr.SQLBinaryOperator;
import studio.raptor.sqlparser.ast.expr.SQLBooleanExpr;
import studio.raptor.sqlparser.ast.expr.SQLCaseExpr;
import studio.raptor.sqlparser.ast.expr.SQLCastExpr;
import studio.raptor.sqlparser.ast.expr.SQLCharExpr;
import studio.raptor.sqlparser.ast.expr.SQLCurrentOfCursorExpr;
import studio.raptor.sqlparser.ast.expr.SQLDateExpr;
import studio.raptor.sqlparser.ast.expr.SQLDefaultExpr;
import studio.raptor.sqlparser.ast.expr.SQLExistsExpr;
import studio.raptor.sqlparser.ast.expr.SQLGroupingSetExpr;
import studio.raptor.sqlparser.ast.expr.SQLHexExpr;
import studio.raptor.sqlparser.ast.expr.SQLIdentifierExpr;
import studio.raptor.sqlparser.ast.expr.SQLInListExpr;
import studio.raptor.sqlparser.ast.expr.SQLInSubQueryExpr;
import studio.raptor.sqlparser.ast.expr.SQLIntegerExpr;
import studio.raptor.sqlparser.ast.expr.SQLListExpr;
import studio.raptor.sqlparser.ast.expr.SQLMethodInvokeExpr;
import studio.raptor.sqlparser.ast.expr.SQLNCharExpr;
import studio.raptor.sqlparser.ast.expr.SQLNotExpr;
import studio.raptor.sqlparser.ast.expr.SQLNullExpr;
import studio.raptor.sqlparser.ast.expr.SQLNumberExpr;
import studio.raptor.sqlparser.ast.expr.SQLPropertyExpr;
import studio.raptor.sqlparser.ast.expr.SQLQueryExpr;
import studio.raptor.sqlparser.ast.expr.SQLSequenceExpr;
import studio.raptor.sqlparser.ast.expr.SQLSomeExpr;
import studio.raptor.sqlparser.ast.expr.SQLUnaryExpr;
import studio.raptor.sqlparser.ast.expr.SQLUnaryOperator;
import studio.raptor.sqlparser.ast.expr.SQLVariantRefExpr;
import studio.raptor.sqlparser.ast.statement.SQLAssignItem;
import studio.raptor.sqlparser.ast.statement.SQLCharacterDataType;
import studio.raptor.sqlparser.ast.statement.SQLCheck;
import studio.raptor.sqlparser.ast.statement.SQLColumnCheck;
import studio.raptor.sqlparser.ast.statement.SQLColumnDefinition;
import studio.raptor.sqlparser.ast.statement.SQLColumnPrimaryKey;
import studio.raptor.sqlparser.ast.statement.SQLColumnReference;
import studio.raptor.sqlparser.ast.statement.SQLColumnUniqueKey;
import studio.raptor.sqlparser.ast.statement.SQLConstraint;
import studio.raptor.sqlparser.ast.statement.SQLForeignKeyConstraint;
import studio.raptor.sqlparser.ast.statement.SQLForeignKeyImpl;
import studio.raptor.sqlparser.ast.statement.SQLNotNullConstraint;
import studio.raptor.sqlparser.ast.statement.SQLNullConstraint;
import studio.raptor.sqlparser.ast.statement.SQLPrimaryKey;
import studio.raptor.sqlparser.ast.statement.SQLPrimaryKeyImpl;
import studio.raptor.sqlparser.ast.statement.SQLSelect;
import studio.raptor.sqlparser.ast.statement.SQLSelectItem;
import studio.raptor.sqlparser.ast.statement.SQLSelectOrderByItem;
import studio.raptor.sqlparser.ast.statement.SQLUnique;
import studio.raptor.sqlparser.ast.statement.SQLUpdateSetItem;
import studio.raptor.sqlparser.util.JdbcConstants;
public class SQLExprParser extends SQLParser {
public final static String[] AGGREGATE_FUNCTIONS = {"AVG", "COUNT", "MAX", "MIN", "STDDEV",
"SUM"};
protected String[] aggregateFunctions = AGGREGATE_FUNCTIONS;
public SQLExprParser(String sql) {
super(sql);
}
public SQLExprParser(String sql, String dbType) {
super(sql, dbType);
}
public SQLExprParser(Lexer lexer) {
super(lexer);
}
public SQLExprParser(Lexer lexer, String dbType) {
super(lexer, dbType);
}
protected static boolean isIdent(SQLExpr expr, String name) {
if (expr instanceof SQLIdentifierExpr) {
SQLIdentifierExpr identExpr = (SQLIdentifierExpr) expr;
return identExpr.getName().equalsIgnoreCase(name);
}
return false;
}
public SQLExpr expr() {
if (lexer.token() == Token.STAR) {
lexer.nextToken();
SQLExpr expr = new SQLAllColumnExpr();
if (lexer.token() == Token.DOT) {
lexer.nextToken();
accept(Token.STAR);
return new SQLPropertyExpr(expr, "*");
}
return expr;
}
SQLExpr expr = primary();
if (lexer.token() == Token.COMMA) {
return expr;
}
return exprRest(expr);
}
public SQLExpr exprRest(SQLExpr expr) {
expr = bitXorRest(expr);
expr = multiplicativeRest(expr);
expr = additiveRest(expr);
expr = shiftRest(expr);
expr = bitAndRest(expr);
expr = bitOrRest(expr);
expr = inRest(expr);
expr = relationalRest(expr);
expr = equalityRest(expr);
expr = andRest(expr);
expr = orRest(expr);
return expr;
}
public final SQLExpr bitXor() {
SQLExpr expr = primary();
return bitXorRest(expr);
}
public SQLExpr bitXorRest(SQLExpr expr) {
Token token = lexer.token;
if (token == Token.CARET) {
lexer.nextToken();
SQLExpr rightExp = primary();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BitwiseXor, rightExp, getDbType());
expr = bitXorRest(expr);
} else if (token == Token.SUBGT) {
lexer.nextToken();
SQLExpr rightExp = primary();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.SubGt, rightExp, getDbType());
expr = bitXorRest(expr);
} else if (token == Token.SUBGTGT) {
lexer.nextToken();
SQLExpr rightExp = primary();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.SubGtGt, rightExp, getDbType());
expr = bitXorRest(expr);
} else if (token == Token.POUNDGT) {
lexer.nextToken();
SQLExpr rightExp = primary();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.PoundGt, rightExp, getDbType());
expr = bitXorRest(expr);
} else if (token == Token.POUNDGTGT) {
lexer.nextToken();
SQLExpr rightExp = primary();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.PoundGtGt, rightExp, getDbType());
expr = bitXorRest(expr);
} else if (token == Token.QUESQUES) {
lexer.nextToken();
SQLExpr rightExp = primary();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.QuesQues, rightExp, getDbType());
expr = bitXorRest(expr);
} else if (token == Token.QUESBAR) {
lexer.nextToken();
SQLExpr rightExp = primary();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.QuesBar, rightExp, getDbType());
expr = bitXorRest(expr);
} else if (token == Token.QUESAMP) {
lexer.nextToken();
SQLExpr rightExp = primary();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.QuesAmp, rightExp, getDbType());
expr = bitXorRest(expr);
}
return expr;
}
public final SQLExpr multiplicative() {
SQLExpr expr = bitXor();
return multiplicativeRest(expr);
}
public SQLExpr multiplicativeRest(SQLExpr expr) {
final Token token = lexer.token();
if (token == Token.STAR) {
lexer.nextToken();
SQLExpr rightExp = bitXor();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Multiply, rightExp, getDbType());
expr = multiplicativeRest(expr);
} else if (token == Token.SLASH) {
lexer.nextToken();
SQLExpr rightExp = bitXor();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Divide, rightExp, getDbType());
expr = multiplicativeRest(expr);
} else if (token == Token.PERCENT) {
lexer.nextToken();
SQLExpr rightExp = bitXor();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Modulus, rightExp, getDbType());
expr = multiplicativeRest(expr);
}
return expr;
}
public SQLIntegerExpr integerExpr() {
SQLIntegerExpr intExpr = new SQLIntegerExpr(lexer.integerValue());
accept(Token.LITERAL_INT);
return intExpr;
}
public SQLExpr primary() {
List beforeComments = null;
if (lexer.isKeepComments() && lexer.hasComment()) {
beforeComments = lexer.readAndResetComments();
}
SQLExpr sqlExpr = null;
final Token tok = lexer.token();
switch (tok) {
case LPAREN:
lexer.nextToken();
sqlExpr = expr();
if (lexer.token() == Token.COMMA) {
SQLListExpr listExpr = new SQLListExpr();
listExpr.addItem(sqlExpr);
do {
lexer.nextToken();
listExpr.addItem(expr());
} while (lexer.token() == Token.COMMA);
sqlExpr = listExpr;
}
accept(Token.RPAREN);
break;
case INSERT:
lexer.nextToken();
if (lexer.token() != Token.LPAREN) {
throw new ParserException("syntax error");
}
sqlExpr = new SQLIdentifierExpr("INSERT");
break;
case IDENTIFIER:
String ident = lexer.stringVal();
lexer.nextToken();
if ("DATE".equalsIgnoreCase(ident)
&& lexer.token() == Token.LITERAL_CHARS
&& (JdbcConstants.ORACLE.equals(getDbType())
|| JdbcConstants.POSTGRESQL.equals(getDbType()))) {
String literal = lexer.stringVal();
lexer.nextToken();
SQLDateExpr dateExpr = new SQLDateExpr();
dateExpr.setLiteral(literal);
sqlExpr = dateExpr;
} else {
sqlExpr = new SQLIdentifierExpr(ident);
}
break;
case NEW:
throw new ParserException("TODO");
case LITERAL_INT:
sqlExpr = new SQLIntegerExpr(lexer.integerValue());
lexer.nextToken();
break;
case LITERAL_FLOAT:
sqlExpr = new SQLNumberExpr(lexer.decimalValue());
lexer.nextToken();
break;
case LITERAL_CHARS:
sqlExpr = new SQLCharExpr(lexer.stringVal());
lexer.nextToken();
break;
case LITERAL_NCHARS:
sqlExpr = new SQLNCharExpr(lexer.stringVal());
lexer.nextToken();
break;
case VARIANT:
SQLVariantRefExpr varRefExpr = new SQLVariantRefExpr(lexer.stringVal());
lexer.nextToken();
if (varRefExpr.getName().equals("@") && lexer.token() == Token.LITERAL_CHARS) {
varRefExpr.setName("@'" + lexer.stringVal() + "'");
lexer.nextToken();
} else if (varRefExpr.getName().equals("@@") && lexer.token() == Token.LITERAL_CHARS) {
varRefExpr.setName("@@'" + lexer.stringVal() + "'");
lexer.nextToken();
}
sqlExpr = varRefExpr;
break;
case DEFAULT:
sqlExpr = new SQLDefaultExpr();
lexer.nextToken();
break;
case DUAL:
case KEY:
case DISTINCT:
case LIMIT:
case SCHEMA:
case COLUMN:
case IF:
case END:
case COMMENT:
case COMPUTE:
case ENABLE:
case DISABLE:
case INITIALLY:
case SEQUENCE:
case USER:
case EXPLAIN:
case WITH:
case GRANT:
case REPLACE:
case INDEX:
case MODEL:
case PCTFREE:
case INITRANS:
case MAXTRANS:
case SEGMENT:
case CREATION:
case IMMEDIATE:
case DEFERRED:
case STORAGE:
case NEXT:
case MINEXTENTS:
case MAXEXTENTS:
case MAXSIZE:
case PCTINCREASE:
case FLASH_CACHE:
case CELL_FLASH_CACHE:
case KEEP:
case NONE:
case LOB:
case STORE:
case ROW:
case CHUNK:
case CACHE:
case NOCACHE:
case LOGGING:
case NOCOMPRESS:
case KEEP_DUPLICATES:
case EXCEPTIONS:
case PURGE:
case FULL:
case TO:
case IDENTIFIED:
case PASSWORD:
case BINARY:
case WINDOW:
case OFFSET:
case SHARE:
case START:
case CONNECT:
case MATCHED:
case ERRORS:
case REJECT:
case UNLIMITED:
case BEGIN:
case EXCLUSIVE:
case MODE:
case ADVISE:
case VIEW:
case ESCAPE:
case OVER:
case ORDER:
case CONSTRAINT:
case TYPE:
case OPEN:
case REPEAT:
case TABLE:
case TRUNCATE:
case EXCEPTION:
case FUNCTION:
case IDENTITY:
case EXTRACT:
sqlExpr = new SQLIdentifierExpr(lexer.stringVal());
lexer.nextToken();
break;
case CASE:
SQLCaseExpr caseExpr = new SQLCaseExpr();
lexer.nextToken();
if (lexer.token() != Token.WHEN) {
caseExpr.setValueExpr(expr());
}
accept(Token.WHEN);
SQLExpr testExpr = expr();
accept(Token.THEN);
SQLExpr valueExpr = expr();
SQLCaseExpr.Item caseItem = new SQLCaseExpr.Item(testExpr, valueExpr);
caseExpr.addItem(caseItem);
while (lexer.token() == Token.WHEN) {
lexer.nextToken();
testExpr = expr();
accept(Token.THEN);
valueExpr = expr();
caseItem = new SQLCaseExpr.Item(testExpr, valueExpr);
caseExpr.addItem(caseItem);
}
if (lexer.token() == Token.ELSE) {
lexer.nextToken();
caseExpr.setElseExpr(expr());
}
accept(Token.END);
sqlExpr = caseExpr;
break;
case EXISTS:
lexer.nextToken();
accept(Token.LPAREN);
sqlExpr = new SQLExistsExpr(createSelectParser().select());
accept(Token.RPAREN);
break;
case NOT:
lexer.nextToken();
if (lexer.token() == Token.EXISTS) {
lexer.nextToken();
accept(Token.LPAREN);
sqlExpr = new SQLExistsExpr(createSelectParser().select(), true);
accept(Token.RPAREN);
} else if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
SQLExpr notTarget = expr();
accept(Token.RPAREN);
notTarget = relationalRest(notTarget);
sqlExpr = new SQLNotExpr(notTarget);
return primaryRest(sqlExpr);
} else {
SQLExpr restExpr = relational();
sqlExpr = new SQLNotExpr(restExpr);
}
break;
case SELECT:
SQLQueryExpr queryExpr = new SQLQueryExpr(
createSelectParser()
.select());
sqlExpr = queryExpr;
break;
case CAST:
lexer.nextToken();
accept(Token.LPAREN);
SQLCastExpr cast = new SQLCastExpr();
cast.setExpr(expr());
accept(Token.AS);
cast.setDataType(parseDataType());
accept(Token.RPAREN);
sqlExpr = cast;
break;
case SUB:
lexer.nextToken();
switch (lexer.token()) {
case LITERAL_INT:
Number integerValue = lexer.integerValue();
if (integerValue instanceof Integer) {
int intVal = ((Integer) integerValue).intValue();
if (intVal == Integer.MIN_VALUE) {
integerValue = Long.valueOf(((long) intVal) * -1);
} else {
integerValue = Integer.valueOf(intVal * -1);
}
} else if (integerValue instanceof Long) {
long longVal = ((Long) integerValue).longValue();
if (longVal == 2147483648L) {
integerValue = Integer.valueOf((int) (((long) longVal) * -1));
} else {
integerValue = Long.valueOf(longVal * -1);
}
} else {
integerValue = ((BigInteger) integerValue).negate();
}
sqlExpr = new SQLIntegerExpr(integerValue);
lexer.nextToken();
break;
case LITERAL_FLOAT:
sqlExpr = new SQLNumberExpr(lexer.decimalValue().negate());
lexer.nextToken();
break;
case IDENTIFIER: // 当负号后面为字段的情况
sqlExpr = new SQLIdentifierExpr(lexer.stringVal());
lexer.nextToken();
if (lexer.token() == Token.LPAREN || lexer.token() == Token.LBRACKET) {
sqlExpr = primaryRest(sqlExpr);
}
sqlExpr = new SQLUnaryExpr(SQLUnaryOperator.Negative, sqlExpr);
break;
case QUES: {
SQLVariantRefExpr variantRefExpr = new SQLVariantRefExpr("?");
variantRefExpr.setIndex(lexer.nextVarIndex());
sqlExpr = new SQLUnaryExpr(SQLUnaryOperator.Negative, variantRefExpr);
lexer.nextToken();
break;
}
case LPAREN:
lexer.nextToken();
sqlExpr = expr();
accept(Token.RPAREN);
sqlExpr = new SQLUnaryExpr(SQLUnaryOperator.Negative, sqlExpr);
break;
default:
throw new ParserException("TODO : " + lexer.token());
}
break;
case PLUS:
lexer.nextToken();
switch (lexer.token()) {
case LITERAL_INT:
sqlExpr = new SQLIntegerExpr(lexer.integerValue());
lexer.nextToken();
break;
case LITERAL_FLOAT:
sqlExpr = new SQLNumberExpr(lexer.decimalValue());
lexer.nextToken();
break;
case IDENTIFIER: // 当+号后面为字段的情况
sqlExpr = new SQLIdentifierExpr(lexer.stringVal());
sqlExpr = new SQLUnaryExpr(SQLUnaryOperator.Plus, sqlExpr);
lexer.nextToken();
break;
case LPAREN:
lexer.nextToken();
sqlExpr = expr();
accept(Token.RPAREN);
sqlExpr = new SQLUnaryExpr(SQLUnaryOperator.Plus, sqlExpr);
break;
default:
throw new ParserException("TODO");
}
break;
case TILDE:
lexer.nextToken();
SQLExpr unaryValueExpr = expr();
SQLUnaryExpr unary = new SQLUnaryExpr(SQLUnaryOperator.Compl, unaryValueExpr);
sqlExpr = unary;
break;
case QUES:
lexer.nextToken();
SQLVariantRefExpr quesVarRefExpr = new SQLVariantRefExpr("?");
quesVarRefExpr.setIndex(lexer.nextVarIndex());
sqlExpr = quesVarRefExpr;
break;
case LEFT:
sqlExpr = new SQLIdentifierExpr("LEFT");
lexer.nextToken();
break;
case RIGHT:
sqlExpr = new SQLIdentifierExpr("RIGHT");
lexer.nextToken();
break;
case DATABASE:
sqlExpr = new SQLIdentifierExpr("DATABASE");
lexer.nextToken();
break;
case LOCK:
sqlExpr = new SQLIdentifierExpr("LOCK");
lexer.nextToken();
break;
case NULL:
sqlExpr = new SQLNullExpr();
lexer.nextToken();
break;
case BANG:
lexer.nextToken();
SQLExpr bangExpr = primary();
sqlExpr = new SQLUnaryExpr(SQLUnaryOperator.Not, bangExpr);
break;
case LITERAL_HEX:
String hex = lexer.hexString();
sqlExpr = new SQLHexExpr(hex);
lexer.nextToken();
break;
case INTERVAL:
sqlExpr = parseInterval();
break;
case COLON:
lexer.nextToken();
if (lexer.token == Token.LITERAL_ALIAS) {
sqlExpr = new SQLVariantRefExpr(":\"" + lexer.stringVal() + "\"");
lexer.nextToken();
}
break;
case ANY:
sqlExpr = parseAny();
break;
case SOME:
sqlExpr = parseSome();
break;
case ALL:
sqlExpr = parseAll();
break;
case LITERAL_ALIAS:
sqlExpr = parseAliasExpr(lexer.stringVal());
lexer.nextToken();
break;
case EOF:
throw new EOFParserException();
case TRUE:
lexer.nextToken();
sqlExpr = new SQLBooleanExpr(true);
break;
case FALSE:
lexer.nextToken();
sqlExpr = new SQLBooleanExpr(false);
break;
default:
throw new ParserException("ERROR. token : " + tok + ", pos : " + lexer.pos());
}
SQLExpr expr = primaryRest(sqlExpr);
if (beforeComments != null) {
expr.addBeforeComment(beforeComments);
}
return expr;
}
protected SQLExpr parseAll() {
SQLExpr sqlExpr;
lexer.nextToken();
SQLAllExpr allExpr = new SQLAllExpr();
accept(Token.LPAREN);
SQLSelect allSubQuery = createSelectParser().select();
allExpr.setSubQuery(allSubQuery);
accept(Token.RPAREN);
allSubQuery.setParent(allExpr);
sqlExpr = allExpr;
return sqlExpr;
}
protected SQLExpr parseSome() {
SQLExpr sqlExpr;
lexer.nextToken();
SQLSomeExpr someExpr = new SQLSomeExpr();
accept(Token.LPAREN);
SQLSelect someSubQuery = createSelectParser().select();
someExpr.setSubQuery(someSubQuery);
accept(Token.RPAREN);
someSubQuery.setParent(someExpr);
sqlExpr = someExpr;
return sqlExpr;
}
protected SQLExpr parseAny() {
SQLExpr sqlExpr;
lexer.nextToken();
if (lexer.token() == Token.LPAREN) {
accept(Token.LPAREN);
if (lexer.token() == Token.IDENTIFIER) {
SQLExpr expr = this.expr();
SQLMethodInvokeExpr methodInvokeExpr = new SQLMethodInvokeExpr("ANY");
methodInvokeExpr.addParameter(expr);
accept(Token.RPAREN);
return methodInvokeExpr;
}
SQLAnyExpr anyExpr = new SQLAnyExpr();
SQLSelect anySubQuery = createSelectParser().select();
anyExpr.setSubQuery(anySubQuery);
accept(Token.RPAREN);
anySubQuery.setParent(anyExpr);
sqlExpr = anyExpr;
} else {
sqlExpr = new SQLIdentifierExpr("ANY");
}
return sqlExpr;
}
protected SQLExpr parseAliasExpr(String alias) {
return new SQLIdentifierExpr('"' + alias + '"');
}
protected SQLExpr parseInterval() {
throw new ParserException("TODO");
}
public SQLSelectParser createSelectParser() {
return new SQLSelectParser(this);
}
public SQLExpr primaryRest(SQLExpr expr) {
if (expr == null) {
throw new IllegalArgumentException("expr");
}
Token token = lexer.token;
if (token == Token.OF) {
if (expr instanceof SQLIdentifierExpr) {
String name = ((SQLIdentifierExpr) expr).getName();
if ("CURRENT".equalsIgnoreCase(name)) {
lexer.nextToken();
SQLName cursorName = this.name();
return new SQLCurrentOfCursorExpr(cursorName);
}
}
} else if (token == Token.FOR) {
if (expr instanceof SQLIdentifierExpr) {
SQLIdentifierExpr idenExpr = (SQLIdentifierExpr) expr;
String name = idenExpr.getName();
if ("NEXTVAL".equalsIgnoreCase(name)) {
lexer.nextToken();
SQLName seqName = this.name();
SQLSequenceExpr seqExpr = new SQLSequenceExpr(seqName, SQLSequenceExpr.Function.NextVal);
return seqExpr;
} else if ("CURRVAL".equalsIgnoreCase(name)) {
lexer.nextToken();
SQLName seqName = this.name();
SQLSequenceExpr seqExpr = new SQLSequenceExpr(seqName, SQLSequenceExpr.Function.CurrVal);
return seqExpr;
} else if ("PREVVAL".equalsIgnoreCase(name)) {
lexer.nextToken();
SQLName seqName = this.name();
SQLSequenceExpr seqExpr = new SQLSequenceExpr(seqName, SQLSequenceExpr.Function.PrevVal);
return seqExpr;
}
}
}
if (token == Token.DOT) {
lexer.nextToken();
if (expr instanceof SQLCharExpr) {
String text = ((SQLCharExpr) expr).getText();
expr = new SQLIdentifierExpr(text);
}
expr = dotRest(expr);
return primaryRest(expr);
} else if (identifierEquals("SETS") //
&& expr.getClass() == SQLIdentifierExpr.class //
&& "GROUPING".equalsIgnoreCase(((SQLIdentifierExpr) expr).getName())) {
SQLGroupingSetExpr groupingSets = new SQLGroupingSetExpr();
lexer.nextToken();
accept(Token.LPAREN);
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) {
return methodRest(expr, true);
}
}
return expr;
}
protected SQLExpr methodRest(SQLExpr expr, boolean acceptLPAREN) {
if (acceptLPAREN) {
accept(Token.LPAREN);
}
if (expr instanceof SQLName || expr instanceof SQLDefaultExpr || expr instanceof SQLCharExpr) {
boolean distinct = false;
if (lexer.token() == Token.DISTINCT) {
lexer.nextToken();
distinct = true;
}
String methodName;
SQLMethodInvokeExpr methodInvokeExpr;
if (expr instanceof SQLPropertyExpr) {
methodName = ((SQLPropertyExpr) expr).getName();
methodInvokeExpr = new SQLMethodInvokeExpr(methodName);
methodInvokeExpr.setOwner(((SQLPropertyExpr) expr).getOwner());
} else {
methodName = expr.toString();
methodInvokeExpr = new SQLMethodInvokeExpr(methodName);
}
if (isAggreateFunction(methodName)) {
SQLAggregateExpr aggregateExpr = parseAggregateExpr(methodName);
if (distinct) {
aggregateExpr.setOption(SQLAggregateOption.DISTINCT);
}
return aggregateExpr;
}
if (lexer.token() != Token.RPAREN) {
exprList(methodInvokeExpr.getParameters(), methodInvokeExpr);
}
if (lexer.token() == Token.FROM) {
lexer.nextToken();
SQLExpr from = this.expr();
methodInvokeExpr.setFrom(from);
}
accept(Token.RPAREN);
if (lexer.token() == Token.OVER) {
SQLAggregateExpr aggregateExpr = new SQLAggregateExpr(methodName);
aggregateExpr.getArguments().addAll(methodInvokeExpr.getParameters());
over(aggregateExpr);
return primaryRest(aggregateExpr);
}
return primaryRest(methodInvokeExpr);
}
throw new ParserException("not support token:" + lexer.token());
}
protected SQLExpr dotRest(SQLExpr expr) {
if (lexer.token() == Token.STAR) {
lexer.nextToken();
expr = new SQLPropertyExpr(expr, "*");
} else {
String name;
if (lexer.token() == Token.IDENTIFIER || lexer.token() == Token.LITERAL_CHARS
|| lexer.token() == Token.LITERAL_ALIAS) {
name = lexer.stringVal();
lexer.nextToken();
} else if (lexer.getKeywods().containsValue(lexer.token())) {
name = lexer.stringVal();
lexer.nextToken();
} else {
throw new ParserException("error : " + lexer.stringVal());
}
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
SQLMethodInvokeExpr methodInvokeExpr = new SQLMethodInvokeExpr(name);
methodInvokeExpr.setOwner(expr);
if (lexer.token() == Token.RPAREN) {
lexer.nextToken();
} else {
if (lexer.token() == Token.PLUS) {
methodInvokeExpr.addParameter(new SQLIdentifierExpr("+"));
lexer.nextToken();
} else {
exprList(methodInvokeExpr.getParameters(), methodInvokeExpr);
}
accept(Token.RPAREN);
}
expr = methodInvokeExpr;
} else {
expr = new SQLPropertyExpr(expr, name);
}
}
expr = primaryRest(expr);
return expr;
}
public final SQLExpr groupComparisionRest(SQLExpr expr) {
return expr;
}
public final void names(Collection exprCol) {
names(exprCol, null);
}
public final void names(Collection exprCol, SQLObject parent) {
if (lexer.token() == Token.RBRACE) {
return;
}
if (lexer.token() == Token.EOF) {
return;
}
SQLName name = name();
name.setParent(parent);
exprCol.add(name);
while (lexer.token() == Token.COMMA) {
lexer.nextToken();
name = name();
name.setParent(parent);
exprCol.add(name);
}
}
@Deprecated
public final void exprList(Collection exprCol) {
exprList(exprCol, null);
}
public final void exprList(Collection exprCol, SQLObject parent) {
if (lexer.token() == Token.RPAREN || lexer.token() == Token.RBRACKET) {
return;
}
if (lexer.token() == Token.EOF) {
return;
}
SQLExpr expr = expr();
expr.setParent(parent);
exprCol.add(expr);
while (lexer.token() == Token.COMMA) {
lexer.nextToken();
expr = expr();
expr.setParent(parent);
exprCol.add(expr);
}
}
public SQLName name() {
String identName;
if (lexer.token() == Token.LITERAL_ALIAS) {
identName = '"' + lexer.stringVal() + '"';
lexer.nextToken();
} else if (lexer.token() == Token.IDENTIFIER) {
identName = lexer.stringVal();
lexer.nextToken();
} else if (lexer.token() == Token.LITERAL_CHARS) {
identName = '\'' + lexer.stringVal() + '\'';
lexer.nextToken();
} else if (lexer.token() == Token.VARIANT) {
identName = lexer.stringVal();
lexer.nextToken();
} else {
switch (lexer.token()) {
case MODEL:
case PCTFREE:
case INITRANS:
case MAXTRANS:
case SEGMENT:
case CREATION:
case IMMEDIATE:
case DEFERRED:
case STORAGE:
case NEXT:
case MINEXTENTS:
case MAXEXTENTS:
case MAXSIZE:
case PCTINCREASE:
case FLASH_CACHE:
case CELL_FLASH_CACHE:
case KEEP:
case NONE:
case LOB:
case STORE:
case ROW:
case CHUNK:
case CACHE:
case NOCACHE:
case LOGGING:
case NOCOMPRESS:
case KEEP_DUPLICATES:
case EXCEPTIONS:
case PURGE:
case INITIALLY:
case END:
case COMMENT:
case ENABLE:
case DISABLE:
case SEQUENCE:
case USER:
case ANALYZE:
case OPTIMIZE:
case GRANT:
case REVOKE:
// binary有很多含义,lexer识别了这个token,实际上应该当做普通IDENTIFIER
case BINARY:
case OVER:
case ORDER:
identName = lexer.stringVal();
lexer.nextToken();
break;
default:
throw new ParserException("error " + lexer.token());
}
}
SQLName name = new SQLIdentifierExpr(identName);
name = nameRest(name);
return name;
}
public SQLName nameRest(SQLName name) {
if (lexer.token() == Token.DOT) {
lexer.nextToken();
if (lexer.token() == Token.KEY) {
name = new SQLPropertyExpr(name, "KEY");
lexer.nextToken();
return name;
}
if (lexer.token() != Token.LITERAL_ALIAS && lexer.token() != Token.IDENTIFIER
&& (!lexer.getKeywods().containsValue(lexer.token()))) {
throw new ParserException("error, " + lexer.token());
}
if (lexer.token() == Token.LITERAL_ALIAS) {
name = new SQLPropertyExpr(name, '"' + lexer.stringVal() + '"');
} else {
name = new SQLPropertyExpr(name, lexer.stringVal());
}
lexer.nextToken();
name = nameRest(name);
}
return name;
}
public boolean isAggreateFunction(String word) {
for (int i = 0; i < aggregateFunctions.length; ++i) {
if (aggregateFunctions[i].compareToIgnoreCase(word) == 0) {
return true;
}
}
return false;
}
protected SQLAggregateExpr parseAggregateExpr(String methodName) {
methodName = methodName.toUpperCase();
SQLAggregateExpr aggregateExpr;
if (lexer.token() == Token.ALL) {
aggregateExpr = new SQLAggregateExpr(methodName, SQLAggregateOption.ALL);
lexer.nextToken();
} else if (lexer.token() == Token.DISTINCT) {
aggregateExpr = new SQLAggregateExpr(methodName, SQLAggregateOption.DISTINCT);
lexer.nextToken();
} else if (identifierEquals("DEDUPLICATION")) { // just for nut
aggregateExpr = new SQLAggregateExpr(methodName, SQLAggregateOption.DEDUPLICATION);
lexer.nextToken();
} else {
aggregateExpr = new SQLAggregateExpr(methodName);
}
exprList(aggregateExpr.getArguments(), aggregateExpr);
parseAggregateExprRest(aggregateExpr);
accept(Token.RPAREN);
if (lexer.token() == Token.OVER) {
over(aggregateExpr);
}
return aggregateExpr;
}
protected void over(SQLAggregateExpr aggregateExpr) {
lexer.nextToken();
SQLOver over = new SQLOver();
accept(Token.LPAREN);
if (lexer.token() == Token.PARTITION || identifierEquals("PARTITION")) {
lexer.nextToken();
accept(Token.BY);
if (lexer.token() == (Token.LPAREN)) {
lexer.nextToken();
exprList(over.getPartitionBy(), over);
accept(Token.RPAREN);
} else {
exprList(over.getPartitionBy(), over);
}
}
over.setOrderBy(parseOrderBy());
if (lexer.token() == Token.OF) {
lexer.nextToken();
SQLExpr of = this.expr();
over.setOf(of);
}
SQLOver.WindowingType windowingType = null;
if (identifierEquals("ROWS")) {
windowingType = SQLOver.WindowingType.ROWS;
} else if (identifierEquals("RANGE")) {
windowingType = SQLOver.WindowingType.RANGE;
}
if (windowingType != null) {
over.setWindowingType(windowingType);
lexer.nextToken();
if (lexer.token == Token.BETWEEN) {
lexer.nextToken();
SQLIntegerExpr rowsBegin = (SQLIntegerExpr) this.primary();
over.setWindowingBetweenBegin(rowsBegin);
if (identifierEquals("PRECEDING")) {
over.setWindowingBetweenBeginPreceding(true);
lexer.nextToken();
} else if (identifierEquals("FOLLOWING")) {
over.setWindowingBetweenBeginFollowing(true);
lexer.nextToken();
}
accept(Token.AND);
SQLIntegerExpr betweenEnd = (SQLIntegerExpr) this.primary();
over.setWindowingBetweenEnd(betweenEnd);
if (identifierEquals("PRECEDING")) {
over.setWindowingBetweenEndPreceding(true);
lexer.nextToken();
} else if (identifierEquals("FOLLOWING")) {
over.setWindowingBetweenEndFollowing(true);
lexer.nextToken();
}
} else {
if (identifierEquals("CURRENT")) {
lexer.nextToken();
acceptIdentifier("ROW");
over.setWindowing(new SQLIdentifierExpr("CURRENT ROW"));
} else if (identifierEquals("UNBOUNDED")) {
lexer.nextToken();
over.setWindowing(new SQLIdentifierExpr("UNBOUNDED"));
if (identifierEquals("PRECEDING")) {
over.setWindowingPreceding(true);
lexer.nextToken();
} else if (identifierEquals("FOLLOWING")) {
over.setWindowingFollowing(true);
lexer.nextToken();
}
} else {
SQLIntegerExpr rowsExpr = (SQLIntegerExpr) this.primary();
over.setWindowing(rowsExpr);
if (identifierEquals("PRECEDING")) {
over.setWindowingPreceding(true);
lexer.nextToken();
} else if (identifierEquals("FOLLOWING")) {
over.setWindowingFollowing(true);
lexer.nextToken();
}
}
}
}
accept(Token.RPAREN);
aggregateExpr.setOver(over);
}
protected SQLAggregateExpr parseAggregateExprRest(SQLAggregateExpr aggregateExpr) {
return aggregateExpr;
}
public SQLOrderBy parseOrderBy() {
if (lexer.token() == Token.ORDER) {
SQLOrderBy orderBy = new SQLOrderBy();
lexer.nextToken();
if (identifierEquals("SIBLINGS")) {
lexer.nextToken();
orderBy.setSibings(true);
}
accept(Token.BY);
orderBy.addItem(parseSelectOrderByItem());
while (lexer.token() == Token.COMMA) {
lexer.nextToken();
orderBy.addItem(parseSelectOrderByItem());
}
return orderBy;
}
return null;
}
public SQLSelectOrderByItem parseSelectOrderByItem() {
SQLSelectOrderByItem item = new SQLSelectOrderByItem();
item.setExpr(expr());
if (lexer.token() == Token.ASC) {
lexer.nextToken();
item.setType(SQLOrderingSpecification.ASC);
} else if (lexer.token() == Token.DESC) {
lexer.nextToken();
item.setType(SQLOrderingSpecification.DESC);
}
if (identifierEquals("NULLS")) {
lexer.nextToken();
if (identifierEquals("FIRST")) {
lexer.nextToken();
item.setNullsOrderType(SQLSelectOrderByItem.NullsOrderType.NullsFirst);
} else if (identifierEquals("LAST")) {
lexer.nextToken();
item.setNullsOrderType(SQLSelectOrderByItem.NullsOrderType.NullsLast);
} else {
throw new ParserException("TODO " + lexer.token());
}
}
return item;
}
public SQLUpdateSetItem parseUpdateSetItem() {
SQLUpdateSetItem item = new SQLUpdateSetItem();
if (lexer.token() == (Token.LPAREN)) {
lexer.nextToken();
SQLListExpr list = new SQLListExpr();
this.exprList(list.getItems(), list);
accept(Token.RPAREN);
item.setColumn(list);
} else {
item.setColumn(this.primary());
}
if (lexer.token() == Token.COLONEQ) {
lexer.nextToken();
} else {
accept(Token.EQ);
}
item.setValue(this.expr());
return item;
}
public final SQLExpr bitAnd() {
SQLExpr expr = shift();
return bitAndRest(expr);
}
public final SQLExpr bitAndRest(SQLExpr expr) {
while (lexer.token() == Token.AMP) {
lexer.nextToken();
SQLExpr rightExp = shift();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BitwiseAnd, rightExp, getDbType());
}
return expr;
}
public final SQLExpr bitOr() {
SQLExpr expr = bitAnd();
return bitOrRest(expr);
}
public final SQLExpr bitOrRest(SQLExpr expr) {
while (lexer.token() == Token.BAR) {
lexer.nextToken();
SQLExpr rightExp = bitAnd();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BitwiseOr, rightExp, getDbType());
expr = bitAndRest(expr);
}
return expr;
}
public final SQLExpr equality() {
SQLExpr expr = bitOr();
return equalityRest(expr);
}
public SQLExpr equalityRest(SQLExpr expr) {
SQLExpr rightExp;
if (lexer.token() == Token.EQ) {
lexer.nextToken();
try {
rightExp = bitOr();
} catch (EOFParserException e) {
throw new ParserException("EOF, " + expr + "=", e);
}
rightExp = equalityRest(rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Equality, rightExp, getDbType());
} else if (lexer.token() == Token.BANGEQ) {
lexer.nextToken();
rightExp = bitOr();
rightExp = equalityRest(rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotEqual, rightExp, getDbType());
} else if (lexer.token() == Token.COLONEQ) {
lexer.nextToken();
rightExp = expr();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Assignment, rightExp, getDbType());
}
return expr;
}
public final SQLExpr inRest(SQLExpr expr) {
if (lexer.token() == Token.IN) {
lexer.nextToken();
SQLInListExpr inListExpr = new SQLInListExpr(expr);
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
exprList(inListExpr.getTargetList(), inListExpr);
accept(Token.RPAREN);
expr = inListExpr;
} else {
SQLExpr itemExpr = primary();
itemExpr.setParent(inListExpr);
inListExpr.getTargetList().add(itemExpr);
}
expr = inListExpr;
if (inListExpr.getTargetList().size() == 1) {
SQLExpr targetExpr = inListExpr.getTargetList().get(0);
if (targetExpr instanceof SQLQueryExpr) {
SQLInSubQueryExpr inSubQueryExpr = new SQLInSubQueryExpr();
inSubQueryExpr.setExpr(inListExpr.getExpr());
inSubQueryExpr.setSubQuery(((SQLQueryExpr) targetExpr).getSubQuery());
expr = inSubQueryExpr;
}
}
}
return expr;
}
public final SQLExpr additive() {
SQLExpr expr = multiplicative();
return additiveRest(expr);
}
public SQLExpr additiveRest(SQLExpr expr) {
if (lexer.token() == Token.PLUS) {
lexer.nextToken();
SQLExpr rightExp = multiplicative();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Add, rightExp, getDbType());
expr = additiveRest(expr);
} else if (lexer.token() == Token.BARBAR || lexer.token() == Token.CONCAT) {
lexer.nextToken();
SQLExpr rightExp = multiplicative();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Concat, rightExp, getDbType());
expr = additiveRest(expr);
} else if (lexer.token() == Token.SUB) {
lexer.nextToken();
SQLExpr rightExp = multiplicative();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Subtract, rightExp, getDbType());
expr = additiveRest(expr);
}
return expr;
}
public final SQLExpr shift() {
SQLExpr expr = additive();
return shiftRest(expr);
}
public SQLExpr shiftRest(SQLExpr expr) {
if (lexer.token() == Token.LTLT) {
lexer.nextToken();
SQLExpr rightExp = additive();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.LeftShift, rightExp, getDbType());
expr = shiftRest(expr);
} else if (lexer.token() == Token.GTGT) {
lexer.nextToken();
SQLExpr rightExp = additive();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.RightShift, rightExp, getDbType());
expr = shiftRest(expr);
}
return expr;
}
public SQLExpr and() {
SQLExpr expr = relational();
return andRest(expr);
}
public SQLExpr andRest(SQLExpr expr) {
for (; ; ) {
Token token = lexer.token();
if (token == Token.AND || token == Token.AMPAMP) {
if (lexer.isKeepComments() && lexer.hasComment()) {
expr.addAfterComment(lexer.readAndResetComments());
}
lexer.nextToken();
SQLExpr rightExp = relational();
SQLBinaryOperator operator =
token == Token.AMPAMP && JdbcConstants.POSTGRESQL.equals(getDbType()) ?
SQLBinaryOperator.PG_And
: SQLBinaryOperator.BooleanAnd;
expr = new SQLBinaryOpExpr(expr, operator, rightExp, getDbType());
} else {
break;
}
}
return expr;
}
public SQLExpr or() {
SQLExpr expr = and();
return orRest(expr);
}
public SQLExpr orRest(SQLExpr expr) {
for (; ; ) {
if (lexer.token() == Token.OR) {
lexer.nextToken();
SQLExpr rightExp = and();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BooleanOr, rightExp, getDbType());
} else if (lexer.token() == Token.XOR) {
lexer.nextToken();
SQLExpr rightExp = and();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BooleanXor, rightExp, getDbType());
} else {
break;
}
}
return expr;
}
public SQLExpr relational() {
SQLExpr expr = equality();
return relationalRest(expr);
}
public SQLExpr relationalRest(SQLExpr expr) {
SQLExpr rightExp;
if (lexer.token() == Token.LT) {
SQLBinaryOperator op = SQLBinaryOperator.LessThan;
lexer.nextToken();
if (lexer.token() == Token.EQ) {
lexer.nextToken();
op = SQLBinaryOperator.LessThanOrEqual;
}
rightExp = bitOr();
expr = new SQLBinaryOpExpr(expr, op, rightExp, getDbType());
// expr = relationalRest(expr);
} else if (lexer.token() == Token.LTEQ) {
lexer.nextToken();
rightExp = bitOr();
// rightExp = relationalRest(rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.LessThanOrEqual, rightExp, getDbType());
} else if (lexer.token() == Token.LTEQGT) {
lexer.nextToken();
rightExp = bitOr();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.LessThanOrEqualOrGreaterThan, rightExp,
getDbType());
} else if (lexer.token() == Token.GT) {
SQLBinaryOperator op = SQLBinaryOperator.GreaterThan;
lexer.nextToken();
if (lexer.token() == Token.EQ) {
lexer.nextToken();
op = SQLBinaryOperator.GreaterThanOrEqual;
}
rightExp = bitOr();
expr = new SQLBinaryOpExpr(expr, op, rightExp, getDbType());
} else if (lexer.token() == Token.GTEQ) {
lexer.nextToken();
rightExp = bitOr();
// rightExp = relationalRest(rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.GreaterThanOrEqual, rightExp, getDbType());
} else if (lexer.token() == Token.BANGLT) {
lexer.nextToken();
rightExp = bitOr();
// rightExp = relationalRest(rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotLessThan, rightExp, getDbType());
} else if (lexer.token() == Token.BANGGT) {
lexer.nextToken();
rightExp = bitOr();
rightExp = relationalRest(rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotGreaterThan, rightExp, getDbType());
} else if (lexer.token() == Token.LTGT) {
lexer.nextToken();
rightExp = bitOr();
// rightExp = relationalRest(rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.LessThanOrGreater, rightExp, getDbType());
} else if (lexer.token() == Token.LIKE) {
lexer.nextToken();
rightExp = bitOr();
// rightExp = relationalRest(rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Like, rightExp, getDbType());
if (lexer.token() == Token.ESCAPE) {
lexer.nextToken();
rightExp = primary();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Escape, rightExp, getDbType());
}
} else if (identifierEquals("RLIKE")) {
lexer.nextToken();
rightExp = equality();
rightExp = relationalRest(rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.RLike, rightExp, getDbType());
} else if (lexer.token() == Token.ILIKE) {
lexer.nextToken();
rightExp = equality();
rightExp = relationalRest(rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.ILike, rightExp, getDbType());
} else if (lexer.token() == Token.MONKEYS_AT_AT) {
lexer.nextToken();
rightExp = equality();
rightExp = relationalRest(rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.AT_AT, rightExp, getDbType());
} else if (lexer.token() == Token.MONKEYS_AT_GT) {
lexer.nextToken();
rightExp = equality();
rightExp = relationalRest(rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Array_Contains, rightExp, getDbType());
} else if (lexer.token() == Token.LT_MONKEYS_AT) {
lexer.nextToken();
rightExp = equality();
rightExp = relationalRest(rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Array_ContainedBy, rightExp, getDbType());
} else if (lexer.token() == (Token.NOT)) {
lexer.nextToken();
expr = notRationalRest(expr);
} else if (lexer.token() == (Token.BETWEEN)) {
lexer.nextToken();
SQLExpr beginExpr = bitOr();
accept(Token.AND);
SQLExpr endExpr = bitOr();
expr = new SQLBetweenExpr(expr, beginExpr, endExpr);
} else if (lexer.token() == (Token.IS)) {
lexer.nextToken();
if (lexer.token() == (Token.NOT)) {
lexer.nextToken();
SQLExpr rightExpr = primary();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.IsNot, rightExpr, getDbType());
} else {
SQLExpr rightExpr = primary();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Is, rightExpr, getDbType());
}
} else if (lexer.token() == Token.IN) {
expr = inRest(expr);
} else if (JdbcConstants.POSTGRESQL.equals(lexer.dbType)) {
if (identifierEquals("SIMILAR")) {
lexer.nextToken();
accept(Token.TO);
rightExp = equality();
rightExp = relationalRest(rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.SIMILAR_TO, rightExp, getDbType());
} else if (lexer.token() == Token.TILDE) {
lexer.nextToken();
rightExp = equality();
rightExp = relationalRest(rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.POSIX_Regular_Match, rightExp,
getDbType());
} else if (lexer.token() == Token.TILDE_STAR) {
lexer.nextToken();
rightExp = equality();
rightExp = relationalRest(rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.POSIX_Regular_Match_Insensitive,
rightExp, getDbType());
} else if (lexer.token() == Token.BANG_TILDE) {
lexer.nextToken();
rightExp = equality();
rightExp = relationalRest(rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.POSIX_Regular_Not_Match, rightExp,
getDbType());
} else if (lexer.token() == Token.BANG_TILDE_STAR) {
lexer.nextToken();
rightExp = equality();
rightExp = relationalRest(rightExp);
expr = new SQLBinaryOpExpr(expr,
SQLBinaryOperator.POSIX_Regular_Not_Match_POSIX_Regular_Match_Insensitive, rightExp,
getDbType());
} else if (lexer.token() == Token.TILDE_EQ) {
lexer.nextToken();
rightExp = equality();
rightExp = relationalRest(rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.SAME_AS, rightExp, getDbType());
}
}
return expr;
}
public SQLExpr notRationalRest(SQLExpr expr) {
if (lexer.token() == (Token.LIKE)) {
lexer.nextToken();
SQLExpr rightExp = equality();
rightExp = relationalRest(rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotLike, rightExp, getDbType());
if (lexer.token() == Token.ESCAPE) {
lexer.nextToken();
rightExp = expr();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Escape, rightExp, getDbType());
}
} else if (lexer.token() == Token.IN) {
lexer.nextToken();
accept(Token.LPAREN);
SQLInListExpr inListExpr = new SQLInListExpr(expr, true);
exprList(inListExpr.getTargetList(), inListExpr);
expr = inListExpr;
accept(Token.RPAREN);
if (inListExpr.getTargetList().size() == 1) {
SQLExpr targetExpr = inListExpr.getTargetList().get(0);
if (targetExpr instanceof SQLQueryExpr) {
SQLInSubQueryExpr inSubQueryExpr = new SQLInSubQueryExpr();
inSubQueryExpr.setNot(true);
inSubQueryExpr.setExpr(inListExpr.getExpr());
inSubQueryExpr.setSubQuery(((SQLQueryExpr) targetExpr).getSubQuery());
expr = inSubQueryExpr;
}
}
expr = relationalRest(expr);
return expr;
} else if (lexer.token() == (Token.BETWEEN)) {
lexer.nextToken();
SQLExpr beginExpr = bitOr();
accept(Token.AND);
SQLExpr endExpr = bitOr();
expr = new SQLBetweenExpr(expr, true, beginExpr, endExpr);
return expr;
} else if (identifierEquals("RLIKE")) {
lexer.nextToken();
SQLExpr rightExp = primary();
rightExp = relationalRest(rightExp);
return new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotRLike, rightExp, getDbType());
} else if (lexer.token() == Token.ILIKE) {
lexer.nextToken();
SQLExpr rightExp = primary();
rightExp = relationalRest(rightExp);
return new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotILike, rightExp, getDbType());
} else {
throw new ParserException("TODO " + lexer.token());
}
return expr;
}
public SQLDataType parseDataType() {
if (lexer.token() == Token.DEFAULT || lexer.token() == Token.NOT
|| lexer.token() == Token.NULL) {
return null;
}
SQLName typeExpr = name();
String typeName = typeExpr.toString();
if ("long".equalsIgnoreCase(typeName) //
&& identifierEquals("byte") //
&& JdbcConstants.MYSQL.equals(getDbType()) //
) {
typeName += (' ' + lexer.stringVal());
lexer.nextToken();
} else if ("double".equalsIgnoreCase(typeName)
&& JdbcConstants.POSTGRESQL.equals(getDbType()) //
) {
typeName += (' ' + lexer.stringVal());
lexer.nextToken();
}
if (isCharType(typeName)) {
SQLCharacterDataType charType = new SQLCharacterDataType(typeName);
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
SQLExpr arg = this.expr();
arg.setParent(charType);
charType.addArgument(arg);
accept(Token.RPAREN);
}
charType = (SQLCharacterDataType) parseCharTypeRest(charType);
if (lexer.token() == Token.HINT) {
List hints = this.parseHints();
charType.setHints(hints);
}
return charType;
}
if ("character".equalsIgnoreCase(typeName) && "varying".equalsIgnoreCase(lexer.stringVal())) {
typeName += ' ' + lexer.stringVal();
lexer.nextToken();
}
SQLDataType dataType = new SQLDataTypeImpl(typeName);
return parseDataTypeRest(dataType);
}
protected SQLDataType parseDataTypeRest(SQLDataType dataType) {
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
exprList(dataType.getArguments(), dataType);
accept(Token.RPAREN);
}
if (identifierEquals("PRECISION") && dataType.getName().equalsIgnoreCase("DOUBLE")) {
lexer.nextToken();
dataType.setName("DOUBLE PRECISION");
}
return dataType;
}
protected boolean isCharType(String dataTypeName) {
return "char".equalsIgnoreCase(dataTypeName) //
|| "varchar".equalsIgnoreCase(dataTypeName) || "nchar".equalsIgnoreCase(dataTypeName)
|| "nvarchar".equalsIgnoreCase(dataTypeName) || "tinytext".equalsIgnoreCase(dataTypeName)
|| "text".equalsIgnoreCase(dataTypeName) || "mediumtext".equalsIgnoreCase(dataTypeName)
|| "longtext".equalsIgnoreCase(dataTypeName)
//
;
}
protected SQLDataType parseCharTypeRest(SQLCharacterDataType charType) {
if (lexer.token() == Token.BINARY) {
charType.setHasBinary(true);
lexer.nextToken();
}
if (identifierEquals("CHARACTER")) {
lexer.nextToken();
accept(Token.SET);
if (lexer.token() != Token.IDENTIFIER && lexer.token() != Token.LITERAL_CHARS) {
throw new ParserException();
}
charType.setCharSetName(lexer.stringVal());
lexer.nextToken();
}
if (lexer.token() == Token.BINARY) {
charType.setHasBinary(true);
lexer.nextToken();
}
if (lexer.token() == Token.IDENTIFIER) {
if (lexer.stringVal().equalsIgnoreCase("COLLATE")) {
lexer.nextToken();
if (lexer.token() != Token.IDENTIFIER) {
throw new ParserException();
}
charType.setCollate(lexer.stringVal());
lexer.nextToken();
}
}
return charType;
}
public void accept(Token token) {
if (lexer.token() == token) {
lexer.nextToken();
} else {
throw new ParserException("syntax error, expect " + token + ", actual " + lexer.token() + " "
+ lexer.stringVal());
}
}
public SQLColumnDefinition parseColumn() {
SQLColumnDefinition column = createColumnDefinition();
column.setName(name());
if (lexer.token() != Token.SET //
&& lexer.token() != Token.DROP) {
column.setDataType(parseDataType());
}
return parseColumnRest(column);
}
public SQLColumnDefinition createColumnDefinition() {
SQLColumnDefinition column = new SQLColumnDefinition();
return column;
}
public SQLColumnDefinition parseColumnRest(SQLColumnDefinition column) {
if (lexer.token() == Token.DEFAULT) {
lexer.nextToken();
column.setDefaultExpr(bitOr());
return parseColumnRest(column);
}
if (lexer.token() == Token.NOT) {
lexer.nextToken();
accept(Token.NULL);
SQLNotNullConstraint notNull = new SQLNotNullConstraint();
if (lexer.token() == Token.HINT) {
List hints = this.parseHints();
notNull.setHints(hints);
}
column.addConstraint(notNull);
return parseColumnRest(column);
}
if (lexer.token() == Token.NULL) {
lexer.nextToken();
column.getConstraints().add(new SQLNullConstraint());
return parseColumnRest(column);
}
if (lexer.token == Token.PRIMARY) {
lexer.nextToken();
accept(Token.KEY);
column.addConstraint(new SQLColumnPrimaryKey());
return parseColumnRest(column);
}
if (lexer.token == Token.UNIQUE) {
lexer.nextToken();
if (lexer.token() == Token.KEY) {
lexer.nextToken();
}
column.addConstraint(new SQLColumnUniqueKey());
return parseColumnRest(column);
}
if (lexer.token == Token.CONSTRAINT) {
lexer.nextToken();
SQLName name = this.name();
if (lexer.token() == Token.PRIMARY) {
lexer.nextToken();
accept(Token.KEY);
SQLColumnPrimaryKey pk = new SQLColumnPrimaryKey();
pk.setName(name);
column.addConstraint(pk);
return parseColumnRest(column);
}
if (lexer.token() == Token.UNIQUE) {
lexer.nextToken();
SQLColumnUniqueKey uk = new SQLColumnUniqueKey();
uk.setName(name);
column.addConstraint(uk);
return parseColumnRest(column);
}
if (lexer.token() == Token.REFERENCES) {
lexer.nextToken();
SQLColumnReference ref = new SQLColumnReference();
ref.setName(name);
ref.setTable(this.name());
accept(Token.LPAREN);
this.names(ref.getColumns(), ref);
accept(Token.RPAREN);
column.addConstraint(ref);
return parseColumnRest(column);
}
if (lexer.token() == Token.NOT) {
lexer.nextToken();
accept(Token.NULL);
SQLNotNullConstraint notNull = new SQLNotNullConstraint();
notNull.setName(name);
column.addConstraint(notNull);
return parseColumnRest(column);
}
if (lexer.token == Token.CHECK) {
SQLColumnCheck check = parseColumnCheck();
check.setName(name);
check.setParent(column);
column.addConstraint(check);
return parseColumnRest(column);
}
if (lexer.token == Token.DEFAULT) {
lexer.nextToken();
SQLExpr expr = this.expr();
column.setDefaultExpr(expr);
return parseColumnRest(column);
}
throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal());
}
if (lexer.token == Token.CHECK) {
SQLColumnCheck check = parseColumnCheck();
column.addConstraint(check);
return parseColumnRest(column);
}
if (lexer.token() == Token.COMMENT) {
lexer.nextToken();
column.setComment(primary());
return parseColumnRest(column);
}
return column;
}
protected SQLColumnCheck parseColumnCheck() {
lexer.nextToken();
SQLExpr expr = this.expr();
SQLColumnCheck check = new SQLColumnCheck(expr);
if (lexer.token() == Token.DISABLE) {
lexer.nextToken();
check.setEnable(false);
} else if (lexer.token() == Token.ENABLE) {
lexer.nextToken();
check.setEnable(true);
}
return check;
}
public SQLPrimaryKey parsePrimaryKey() {
accept(Token.PRIMARY);
accept(Token.KEY);
SQLPrimaryKeyImpl pk = new SQLPrimaryKeyImpl();
accept(Token.LPAREN);
exprList(pk.getColumns(), pk);
accept(Token.RPAREN);
return pk;
}
public SQLUnique parseUnique() {
accept(Token.UNIQUE);
SQLUnique unique = new SQLUnique();
accept(Token.LPAREN);
exprList(unique.getColumns(), unique);
accept(Token.RPAREN);
return unique;
}
public SQLAssignItem parseAssignItem() {
SQLAssignItem item = new SQLAssignItem();
SQLExpr var = primary();
if (var instanceof SQLIdentifierExpr) {
var = new SQLVariantRefExpr(((SQLIdentifierExpr) var).getName());
}
item.setTarget(var);
if (lexer.token() == Token.COLONEQ) {
lexer.nextToken();
} else {
accept(Token.EQ);
}
if (lexer.token() == Token.ON) {
item.setValue(new SQLIdentifierExpr(lexer.stringVal()));
lexer.nextToken();
} else {
if (lexer.token() == Token.ALL) {
item.setValue(new SQLIdentifierExpr(lexer.stringVal()));
lexer.nextToken();
} else {
SQLExpr expr = expr();
if (lexer.token() == Token.COMMA && JdbcConstants.POSTGRESQL.equals(dbType)) {
SQLListExpr listExpr = new SQLListExpr();
listExpr.addItem(expr);
expr.setParent(listExpr);
do {
lexer.nextToken();
SQLExpr listItem = this.expr();
listItem.setParent(listExpr);
listExpr.addItem(listItem);
} while (lexer.token() == Token.COMMA);
item.setValue(listExpr);
} else {
item.setValue(expr);
}
}
}
return item;
}
public List parseHints() {
List hints = new ArrayList();
parseHints(hints);
return hints;
}
@SuppressWarnings({"unchecked", "rawtypes"})
public void parseHints(List hints) {
if (lexer.token() == Token.HINT) {
hints.add(new SQLCommentHint(lexer.stringVal()));
lexer.nextToken();
}
}
public SQLConstraint parseConstaint() {
SQLName name = null;
if (lexer.token() == Token.CONSTRAINT) {
lexer.nextToken();
name = this.name();
}
SQLConstraint constraint;
if (lexer.token() == Token.PRIMARY) {
constraint = parsePrimaryKey();
} else if (lexer.token() == Token.UNIQUE) {
constraint = parseUnique();
} else if (lexer.token() == Token.FOREIGN) {
constraint = parseForeignKey();
} else if (lexer.token() == Token.CHECK) {
constraint = parseCheck();
} else {
throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal());
}
constraint.setName(name);
return constraint;
}
public SQLCheck parseCheck() {
accept(Token.CHECK);
SQLCheck check = createCheck();
accept(Token.LPAREN);
check.setExpr(this.expr());
accept(Token.RPAREN);
return check;
}
protected SQLCheck createCheck() {
return new SQLCheck();
}
public SQLForeignKeyConstraint parseForeignKey() {
accept(Token.FOREIGN);
accept(Token.KEY);
SQLForeignKeyConstraint fk = createForeignKey();
accept(Token.LPAREN);
this.names(fk.getReferencingColumns());
accept(Token.RPAREN);
accept(Token.REFERENCES);
fk.setReferencedTableName(this.name());
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
this.names(fk.getReferencedColumns(), fk);
accept(Token.RPAREN);
}
return fk;
}
protected SQLForeignKeyConstraint createForeignKey() {
return new SQLForeignKeyImpl();
}
public SQLSelectItem parseSelectItem() {
SQLExpr expr;
boolean connectByRoot = false;
if (lexer.token() == Token.IDENTIFIER) {
String ident = lexer.stringVal();
lexer.nextTokenComma();
if ("CONNECT_BY_ROOT".equalsIgnoreCase(ident)) {
connectByRoot = true;
expr = new SQLIdentifierExpr(lexer.stringVal());
lexer.nextToken();
} else if ("DATE".equalsIgnoreCase(ident)
&& lexer.token() == Token.LITERAL_CHARS
&& (JdbcConstants.ORACLE.equals(getDbType())
|| JdbcConstants.POSTGRESQL.equals(getDbType()))) {
String literal = lexer.stringVal();
lexer.nextToken();
SQLDateExpr dateExpr = new SQLDateExpr();
dateExpr.setLiteral(literal);
expr = dateExpr;
} else {
expr = new SQLIdentifierExpr(ident);
}
if (lexer.token() != Token.COMMA) {
expr = this.primaryRest(expr);
expr = this.exprRest(expr);
}
} else {
expr = expr();
}
final String alias = as();
return new SQLSelectItem(expr, alias, connectByRoot);
}
public SQLExpr parseGroupingSet() {
String tmp = lexer.stringVal();
acceptIdentifier("GROUPING");
SQLGroupingSetExpr expr = new SQLGroupingSetExpr();
if (identifierEquals("SET")) {
lexer.nextToken();
} else {
return new SQLIdentifierExpr(tmp);
}
accept(Token.LPAREN);
this.exprList(expr.getParameters(), expr);
accept(Token.RPAREN);
return expr;
}
public SQLPartitionValue parsePartitionValues() {
if (lexer.token() != Token.VALUES) {
return null;
}
lexer.nextToken();
SQLPartitionValue values = null;
if (lexer.token() == Token.IN) {
lexer.nextToken();
values = new SQLPartitionValue(SQLPartitionValue.Operator.In);
accept(Token.LPAREN);
this.exprList(values.getItems(), values);
accept(Token.RPAREN);
} else if (identifierEquals("LESS")) {
lexer.nextToken();
acceptIdentifier("THAN");
values = new SQLPartitionValue(SQLPartitionValue.Operator.LessThan);
if (identifierEquals("MAXVALUE")) {
SQLIdentifierExpr maxValue = new SQLIdentifierExpr(lexer.stringVal());
lexer.nextToken();
maxValue.setParent(values);
values.addItem(maxValue);
} else {
accept(Token.LPAREN);
this.exprList(values.getItems(), values);
accept(Token.RPAREN);
}
} else if (lexer.token() == Token.LPAREN) {
values = new SQLPartitionValue(SQLPartitionValue.Operator.List);
lexer.nextToken();
this.exprList(values.getItems(), values);
accept(Token.RPAREN);
}
return values;
}
public SQLLimit parseLimit() {
if (lexer.token() == Token.LIMIT) {
lexer.nextToken();
SQLLimit limit = new SQLLimit();
SQLExpr temp = this.expr();
if (lexer.token() == (Token.COMMA)) {
limit.setOffset(temp);
lexer.nextToken();
limit.setRowCount(this.expr());
} else if (identifierEquals("OFFSET")) {
limit.setRowCount(temp);
lexer.nextToken();
limit.setOffset(this.expr());
} else {
limit.setRowCount(temp);
}
return limit;
}
return null;
}
}