public SQLExpr relationalRest()

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;
    }