in core/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java [3666:4009]
public SQLExpr relationalRest(SQLExpr expr) {
final SQLExpr initExpr = expr;
SQLExpr rightExp = null;
Token token = lexer.token;
switch (token) {
case EQ: {
lexer.nextToken();
try {
rightExp = bitOr();
} catch (EOFParserException e) {
throw new ParserException("EOF, " + expr + "=", e);
}
if (lexer.token == Token.COLONEQ) {
lexer.nextToken();
SQLExpr colonExpr = expr();
rightExp = new SQLBinaryOpExpr(rightExp, SQLBinaryOperator.Assignment, colonExpr, dbType);
}
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Equality, rightExp, dbType);
}
break;
case IS: {
lexer.nextTokenNotOrNull();
SQLBinaryOperator op;
if (lexer.token == Token.NOT) {
op = SQLBinaryOperator.IsNot;
lexer.nextTokenNotOrNull();
} else {
op = SQLBinaryOperator.Is;
}
if (lexer.identifierEquals(FnvHash.Constants.JSON)) {
lexer.nextToken();
String name = "JSON";
if (lexer.identifierEquals(FnvHash.Constants.VALUE)) {
lexer.nextToken();
name = "JSON VALUE";
} else if (lexer.identifierEquals(FnvHash.Constants.OBJECT)) {
lexer.nextToken();
name = "JSON OBJECT";
} else if (lexer.identifierEquals(FnvHash.Constants.ARRAY)) {
lexer.nextToken();
name = "JSON ARRAY";
} else if (lexer.identifierEquals(FnvHash.Constants.SCALAR)) {
lexer.nextToken();
name = "JSON SCALAR";
}
rightExp = new SQLIdentifierExpr(name);
} else if (lexer.token == Token.DISTINCT) {
lexer.nextToken();
accept(Token.FROM);
if (op == SQLBinaryOperator.Is) {
op = SQLBinaryOperator.IsDistinctFrom;
} else {
op = SQLBinaryOperator.IsNotDistinctFrom;
}
rightExp = bitOr();
} else {
rightExp = primary();
}
expr = new SQLBinaryOpExpr(expr, op, rightExp, dbType);
}
break;
case EQGT: {
lexer.nextToken();
rightExp = expr();
String argumentName = ((SQLIdentifierExpr) expr).getName();
expr = new OracleArgumentExpr(argumentName, rightExp);
}
break;
case BANGEQ:
case CARETEQ: {
lexer.nextToken();
rightExp = bitOr();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotEqual, rightExp, dbType);
}
break;
case COLONEQ: {
lexer.nextToken();
rightExp = expr();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Assignment, rightExp, dbType);
}
break;
case LT: {
SQLBinaryOperator op = SQLBinaryOperator.LessThan;
lexer.nextToken();
if (lexer.token == Token.EQ) {
lexer.nextToken();
op = SQLBinaryOperator.LessThanOrEqual;
} else if (lexer.token == Token.LT) {
lexer.nextToken();
op = SQLBinaryOperator.LeftShift;
rightExp = additive();
}
if (rightExp == null) {
rightExp = bitOr();
}
expr = new SQLBinaryOpExpr(expr, op, rightExp, getDbType());
}
break;
case LTEQ:
lexer.nextToken();
rightExp = bitOr();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.LessThanOrEqual, rightExp, getDbType());
break;
case LTLTLT:
lexer.nextToken();
rightExp = bitOr();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.LeftShiftUnsigned, rightExp, getDbType());
break;
case LTEQGT: {
lexer.nextToken();
rightExp = bitOr();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.LessThanOrEqualOrGreaterThan, rightExp, getDbType());
}
break;
case GT: {
SQLBinaryOperator op = SQLBinaryOperator.GreaterThan;
lexer.nextToken();
if (lexer.token == Token.EQ) {
lexer.nextToken();
op = SQLBinaryOperator.GreaterThanOrEqual;
}
if (lexer.token == Token.GT) {
lexer.nextToken();
op = SQLBinaryOperator.RightShift;
rightExp = additive();
} else if (lexer.token == Token.GTGT) {
lexer.nextToken();
op = SQLBinaryOperator.RightShiftUnsigned;
rightExp = additive();
}
if (rightExp == null) {
rightExp = bitOr();
}
expr = new SQLBinaryOpExpr(expr, op, rightExp, dbType);
}
break;
case GTEQ: {
lexer.nextToken();
rightExp = bitOr();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.GreaterThanOrEqual, rightExp, dbType);
}
break;
case BANGLT: {
lexer.nextToken();
rightExp = bitOr();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotLessThan, rightExp, dbType);
}
break;
case BANGGT:
lexer.nextToken();
rightExp = bitOr();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotGreaterThan, rightExp, dbType);
break;
case LTGT:
lexer.nextToken();
rightExp = bitOr();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.LessThanOrGreater, rightExp, dbType);
break;
case LIKE: {
Lexer.SavePoint mark = lexer.mark();
lexer.nextTokenValue();
if (lexer.token == Token.COMMA) {
lexer.reset(mark);
return expr;
}
rightExp = bitOr();
if (rightExp.getClass() == SQLIdentifierExpr.class) {
String name = ((SQLIdentifierExpr) rightExp).getName();
int length = name.length();
if (length > 1
&& name.charAt(0) == name.charAt(length - 1)
&& name.charAt(0) != '`'
) {
rightExp = new SQLCharExpr(name.substring(1, length - 1));
}
}
// rightExp = relationalRest(rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Like, rightExp, dbType);
if (lexer.token == Token.ESCAPE) {
lexer.nextToken();
rightExp = primary();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Escape, rightExp, dbType);
}
break;
}
case ILIKE:
lexer.nextToken();
rightExp = bitOr();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.ILike, rightExp, dbType);
break;
case MONKEYS_AT_AT:
lexer.nextToken();
rightExp = bitOr();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.AT_AT, rightExp, dbType);
break;
case MONKEYS_AT_GT:
lexer.nextToken();
rightExp = bitOr();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Array_Contains, rightExp, dbType);
break;
case LT_MONKEYS_AT:
lexer.nextToken();
rightExp = bitOr();
rightExp = relationalRest(rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Array_ContainedBy, rightExp, dbType);
break;
case QUES:
expr = relationalRestQues(expr);
break;
case NOT:
lexer.nextToken();
expr = notRationalRest(expr, false);
break;
case BANG:
expr = relationalRestBang(expr);
break;
case BETWEEN:
lexer.nextToken();
SQLExpr beginExpr = relational();
accept(Token.AND);
SQLExpr endExpr = relational();
expr = new SQLBetweenExpr(expr, beginExpr, endExpr);
parseQueryPlanHint(expr);
break;
case IN:
case CONTAINS:
case GLOBAL:
expr = inRest(expr);
break;
case EQEQ:
expr = relationalRestEqeq(expr);
break;
case TILDE:
expr = relationalRestTilde(expr);
break;
case TILDE_STAR:
expr = relationalRestTildeStar(expr);
break;
case BANG_TILDE:
expr = relationalRestBangTilde(expr);
break;
case BANG_TILDE_STAR:
expr = relationalRestBangTildeStar(expr);
break;
case TILDE_EQ:
expr = relationalRestTildeEq(expr);
break;
case RLIKE: {
Lexer.SavePoint mark = lexer.mark();
lexer.nextToken();
switch (lexer.token) {
case COMMA:
lexer.reset(mark);
break;
default:
rightExp = bitOr();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.RLike, rightExp, dbType);
break;
}
break;
}
case IDENTIFIER:
long hash = lexer.hashLCase;
if (hash == FnvHash.Constants.SOUNDS) {
lexer.nextToken();
accept(Token.LIKE);
rightExp = bitOr();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.SoudsLike, rightExp, dbType);
} else if (hash == FnvHash.Constants.REGEXP) {
lexer.nextToken();
rightExp = bitOr();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.RegExp, rightExp, dbType);
} else if (hash == FnvHash.Constants.SIMILAR) {
expr = relationalRestIdentifierSimilar(expr);
} else {
return expr;
}
break;
default:
return expr;
}
if (expr == initExpr) {
return expr;
}
switch (lexer.token) {
case BETWEEN:
case IS:
case EQ:
case EQEQ:
case IN:
case CONTAINS:
case BANG_TILDE_STAR:
case TILDE_EQ:
case LT:
case LTEQ:
case LTEQGT:
case GT:
case GTEQ:
case LTGT:
case BANGEQ:
case LIKE:
case NOT:
expr = relationalRest(expr);
break;
default:
break;
}
return expr;
}