public SQLExpr primary()

in core/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlExprParser.java [915:1286]


    public SQLExpr primary() {
        final Token tok = lexer.token();
        switch (tok) {
            case IDENTIFIER:
                final long hash_lower = lexer.hashLCase();
                Lexer.SavePoint savePoint = lexer.mark();

                if (hash_lower == FnvHash.Constants.OUTLINE) {
                    lexer.nextToken();
                    try {
                        SQLExpr file = primary();
                        SQLExpr expr = new MySqlOutFileExpr(file);

                        return primaryRest(expr);
                    } catch (ParserException e) {
                        lexer.reset(savePoint);
                    }
                }

                String strVal = lexer.stringVal();

                boolean quoteStart = strVal.length() > 0 && (strVal.charAt(0) == '`' || strVal.charAt(0) == '"');

                if (!quoteStart) {
                    // Allow function in order by when not start with '`'.
                    setAllowIdentifierMethod(true);
                }

                SQLCurrentTimeExpr currentTimeExpr = null;
                if (hash_lower == FnvHash.Constants.CURRENT_TIME && !quoteStart) {
                    currentTimeExpr = new SQLCurrentTimeExpr(SQLCurrentTimeExpr.Type.CURRENT_TIME);
                } else if (hash_lower == FnvHash.Constants.CURRENT_TIMESTAMP && !quoteStart) {
                    currentTimeExpr = new SQLCurrentTimeExpr(SQLCurrentTimeExpr.Type.CURRENT_TIMESTAMP);
                } else if (hash_lower == FnvHash.Constants.CURRENT_DATE && !quoteStart) {
                    currentTimeExpr = new SQLCurrentTimeExpr(SQLCurrentTimeExpr.Type.CURRENT_DATE);
                } else if (hash_lower == FnvHash.Constants.CURDATE && !quoteStart) {
                    currentTimeExpr = new SQLCurrentTimeExpr(SQLCurrentTimeExpr.Type.CURDATE);
                } else if (hash_lower == FnvHash.Constants.LOCALTIME && !quoteStart) {
                    currentTimeExpr = new SQLCurrentTimeExpr(SQLCurrentTimeExpr.Type.LOCALTIME);
                } else if (hash_lower == FnvHash.Constants.LOCALTIMESTAMP && !quoteStart) {
                    currentTimeExpr = new SQLCurrentTimeExpr(SQLCurrentTimeExpr.Type.LOCALTIMESTAMP);
                } else if (hash_lower == FnvHash.Constants.JSON_TABLE) {
                    if (lexer.identifierEquals("JSON_TABLE")) {
                        lexer.nextToken();
                        accept(Token.LPAREN);

                        MySqlJSONTableExpr jsonTable = new MySqlJSONTableExpr();
                        jsonTable.setExpr(
                                this.expr());
                        accept(Token.COMMA);
                        jsonTable.setPath(
                                this.expr());
                        acceptIdentifier("COLUMNS");
                        accept(Token.LPAREN);
                        for (; lexer.token() != Token.RPAREN; ) {
                            jsonTable.addColumn(
                                    parseJsonTableColumn());

                            if (lexer.token() == Token.COMMA) {
                                lexer.nextToken();
                                continue;
                            }
                            break;
                        }
                        accept(Token.RPAREN);

                        accept(Token.RPAREN);
                        return jsonTable;
                    }
                } else if ((hash_lower == FnvHash.Constants._LATIN1) && !quoteStart) {
                    lexer.nextToken();

                    String hexString;
                    if (lexer.identifierEquals(FnvHash.Constants.X)) {
                        lexer.nextToken();
                        hexString = lexer.stringVal();
                        lexer.nextToken();
                    } else if (lexer.token() == Token.LITERAL_CHARS) {
                        hexString = null;
                    } else {
                        hexString = lexer.hexString();
                        lexer.nextToken();
                    }

                    SQLExpr charExpr;
                    if (hexString == null) {
                        String str = lexer.stringVal();
                        lexer.nextToken();

                        String collate = null;
                        if (lexer.identifierEquals(FnvHash.Constants.COLLATE)) {
                            lexer.nextToken();
                            collate = lexer.stringVal();
                            if (lexer.token() == Token.LITERAL_CHARS) {
                                lexer.nextToken();
                            } else {
                                accept(Token.IDENTIFIER);
                            }
                        }

                        charExpr = new MySqlCharExpr(str, "_latin1", collate);
                    } else {
                        charExpr = new MySqlCharExpr(hexString, "_latin1");
                    }

                    return primaryRest(charExpr);
                } else if ((hash_lower == FnvHash.Constants._UTF8 || hash_lower == FnvHash.Constants._UTF8MB4)
                        && !quoteStart) {
                    lexer.nextToken();

                    String hexString;
                    if (lexer.identifierEquals(FnvHash.Constants.X)) {
                        lexer.nextToken();
                        hexString = lexer.stringVal();
                        lexer.nextToken();
                    } else if (lexer.token() == Token.LITERAL_CHARS) {
                        hexString = null;
                    } else {
                        hexString = lexer.hexString();
                        lexer.nextToken();
                    }

                    SQLExpr charExpr;
                    if (hexString == null) {
                        String str = lexer.stringVal();
                        lexer.nextToken();

                        String collate = null;
                        if (lexer.identifierEquals(FnvHash.Constants.COLLATE)) {
                            lexer.nextToken();
                            collate = lexer.stringVal();
                            if (lexer.token() == Token.LITERAL_CHARS) {
                                lexer.nextToken();
                            } else {
                                accept(Token.IDENTIFIER);
                            }
                        }
                        String charset = hash_lower == FnvHash.Constants._UTF8 ? "_utf8" : "_utf8mb4";
                        charExpr = new MySqlCharExpr(str, charset, collate);
                    } else {
                        String str = MySqlUtils.utf8(hexString);
                        charExpr = new SQLCharExpr(str);
                    }

                    return primaryRest(charExpr);
                } else if ((hash_lower == FnvHash.Constants._UTF16 || hash_lower == FnvHash.Constants._UCS2)
                        && !quoteStart) {
                    lexer.nextToken();

                    String hexString;
                    if (lexer.identifierEquals(FnvHash.Constants.X)) {
                        lexer.nextToken();
                        hexString = lexer.stringVal();
                        lexer.nextToken();
                    } else if (lexer.token() == Token.LITERAL_CHARS) {
                        hexString = null;
                    } else {
                        hexString = lexer.hexString();
                        lexer.nextToken();
                    }

                    SQLCharExpr charExpr;
                    if (hexString == null) {
                        String str = lexer.stringVal();
                        lexer.nextToken();
                        charExpr = new MySqlCharExpr(str, "_utf16");
                    } else {
                        charExpr = new SQLCharExpr(MySqlUtils.utf16(hexString));
                    }

                    return primaryRest(charExpr);
                } else if ((hash_lower == FnvHash.Constants._UTF16LE)
                        && !quoteStart) {
                    lexer.nextToken();

                    String hexString;
                    if (lexer.identifierEquals(FnvHash.Constants.X)) {
                        lexer.nextToken();
                        hexString = lexer.stringVal();
                        lexer.nextToken();
                    } else if (lexer.token() == Token.LITERAL_CHARS) {
                        hexString = null;
                    } else {
                        hexString = lexer.hexString();
                        lexer.nextToken();
                    }

                    SQLCharExpr charExpr;
                    if (hexString == null) {
                        String str = lexer.stringVal();
                        lexer.nextToken();
                        charExpr = new MySqlCharExpr(str, "_utf16le");
                    } else {
                        charExpr = new MySqlCharExpr(hexString, "_utf16le");
                    }

                    return primaryRest(charExpr);
                } else if (hash_lower == FnvHash.Constants._UTF32 && !quoteStart) {
                    lexer.nextToken();

                    String hexString;
                    if (lexer.identifierEquals(FnvHash.Constants.X)) {
                        lexer.nextToken();
                        hexString = lexer.stringVal();
                        lexer.nextToken();
                    } else if (lexer.token() == Token.LITERAL_CHARS) {
                        hexString = null;
                    } else {
                        hexString = lexer.hexString();
                        lexer.nextToken();
                    }

                    SQLCharExpr charExpr;
                    if (hexString == null) {
                        String str = lexer.stringVal();
                        lexer.nextToken();
                        charExpr = new MySqlCharExpr(str, "_utf32");
                    } else {
                        charExpr = new SQLCharExpr(MySqlUtils.utf32(hexString));
                    }

                    return primaryRest(charExpr);
                } else if (hash_lower == FnvHash.Constants._GBK && !quoteStart) {
                    lexer.nextToken();

                    String hexString;
                    if (lexer.identifierEquals(FnvHash.Constants.X)) {
                        lexer.nextToken();
                        hexString = lexer.stringVal();
                        lexer.nextToken();
                    } else if (lexer.token() == Token.LITERAL_CHARS) {
                        hexString = null;
                    } else {
                        hexString = lexer.hexString();
                        lexer.nextToken();
                    }

                    SQLCharExpr charExpr;
                    if (hexString == null) {
                        String str = lexer.stringVal();
                        lexer.nextToken();
                        charExpr = new MySqlCharExpr(str, "_gbk");
                    } else {
                        charExpr = new SQLCharExpr(MySqlUtils.gbk(hexString));
                    }

                    return primaryRest(charExpr);
                } else if (hash_lower == FnvHash.Constants._UJIS && !quoteStart) {
                    lexer.nextToken();

                    String hexString;
                    if (lexer.identifierEquals(FnvHash.Constants.X)) {
                        lexer.nextToken();
                        hexString = lexer.stringVal();
                        lexer.nextToken();
                    } else if (lexer.token() == Token.LITERAL_CHARS) {
                        hexString = null;
                    } else {
                        hexString = lexer.hexString();
                        lexer.nextToken();
                    }

                    SQLCharExpr charExpr;
                    if (hexString == null) {
                        String str = lexer.stringVal();
                        lexer.nextToken();
                        charExpr = new MySqlCharExpr(str, "_ujis");
                    } else {
                        charExpr = new MySqlCharExpr(hexString, "_ujis");
                    }

                    return primaryRest(charExpr);
                } else if (hash_lower == FnvHash.Constants._BIG5 && !quoteStart) {
                    lexer.nextToken();

                    String hexString;
                    if (lexer.identifierEquals(FnvHash.Constants.X)) {
                        lexer.nextToken();
                        hexString = lexer.stringVal();
                        lexer.nextToken();
                    } else if (lexer.token() == Token.LITERAL_CHARS) {
                        hexString = null;
                    } else {
                        hexString = lexer.hexString();
                        lexer.nextToken();
                    }

                    SQLCharExpr charExpr;
                    if (hexString == null) {
                        String str = lexer.stringVal();
                        lexer.nextToken();
                        charExpr = new MySqlCharExpr(str, "_big5");
                    } else {
                        charExpr = new SQLCharExpr(MySqlUtils.big5(hexString));
                    }

                    return primaryRest(charExpr);
                } else if (hash_lower == FnvHash.Constants.CURRENT_USER && isEnabled(SQLParserFeature.EnableCurrentUserExpr)) {
                    lexer.nextToken();
                    return primaryRest(
                            new SQLCurrentUserExpr());
                } else if (hash_lower == -5808529385363204345L && lexer.charAt(lexer.pos()) == '\'') { // hex
                    lexer.nextToken();
                    SQLHexExpr hex = new SQLHexExpr(lexer.stringVal());
                    lexer.nextToken();
                    return primaryRest(hex);
                }

                if (currentTimeExpr != null) {
                    String methodName = lexer.stringVal();
                    lexer.nextToken();

                    if (lexer.token() == Token.LPAREN) {
                        lexer.nextToken();
                        if (lexer.token() == Token.LPAREN) {
                            lexer.nextToken();
                        } else {
                            return primaryRest(
                                    methodRest(new SQLIdentifierExpr(methodName), false)
                            );
                        }
                    }

                    return primaryRest(currentTimeExpr);
                }

                return super.primary();
            case VARIANT:
                SQLVariantRefExpr varRefExpr = new SQLVariantRefExpr(lexer.stringVal());
                lexer.nextToken();
                if (varRefExpr.getName().equalsIgnoreCase("@@global")) {
                    accept(Token.DOT);
                    varRefExpr = new SQLVariantRefExpr(lexer.stringVal(), true);
                    lexer.nextToken();
                } else 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();
                }
                return primaryRest(varRefExpr);
            case VALUES:
                lexer.nextToken();

                if (lexer.token() != Token.LPAREN) {
                    SQLExpr expr = primary();
                    SQLValuesQuery values = new SQLValuesQuery();
                    values.addValue(new SQLListExpr(expr));
                    return new SQLQueryExpr(new SQLSelect(values));
                }
                return this.methodRest(new SQLIdentifierExpr("VALUES"), true);
            case BINARY:
                lexer.nextToken();
                if (lexer.token() == Token.COMMA || lexer.token() == Token.SEMI || lexer.token() == Token.EOF) {
                    return new SQLIdentifierExpr("BINARY");
                } else {
                    SQLUnaryExpr binaryExpr = new SQLUnaryExpr(SQLUnaryOperator.BINARY, primary());
                    return primaryRest(binaryExpr);
                }
            default:
                if (lexer.token() == Token.WITH) {
                    SQLQueryExpr queryExpr = new SQLQueryExpr(
                        createSelectParser()
                            .select());
                    return queryExpr;
                }

                return super.primary();
        }

    }