public boolean parseStatementListDialect()

in core/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java [1073:1704]


    public boolean parseStatementListDialect(List<SQLStatement> statementList) {
        if (lexer.identifierEquals("PREPARE")) {
            MySqlPrepareStatement stmt = parsePrepare();
            statementList.add(stmt);
            return true;
        }

        if (lexer.identifierEquals("DEALLOCATE")) {
            MysqlDeallocatePrepareStatement stmt = parseDeallocatePrepare();
            statementList.add(stmt);
            return true;
        }

        if (lexer.identifierEquals("LOAD")) {
            SQLStatement stmt = parseLoad();
            statementList.add(stmt);
            return true;
        }

        if (lexer.token() == Token.REPLACE) {
            SQLReplaceStatement stmt = parseReplace();
            statementList.add(stmt);
            return true;
        }

        if (lexer.identifierEquals("START")) {
            SQLStartTransactionStatement stmt = parseStart();
            statementList.add(stmt);
            return true;
        }

        if (lexer.token() == Token.SHOW) {
            SQLStatement stmt = parseShow();
            statementList.add(stmt);
            return true;
        }

        if (lexer.identifierEquals("CLEAR")) {
            lexer.nextToken();

            if (isEnabled(SQLParserFeature.DRDSAsyncDDL) && lexer.identifierEquals("DDL")) {
                // CLEAR DDL CACHE { ALL | <job_id> [ , <job_id> ] ... }
                lexer.nextToken();
                accept(Token.CACHE);

                DrdsClearDDLJobCache stmt = new DrdsClearDDLJobCache();
                if (Token.ALL == lexer.token()) {
                    lexer.nextToken();
                    stmt.setAllJobs(true);
                    statementList.add(stmt);
                    return true;
                } else {
                    while (true) {
                        stmt.addJobId(lexer.integerValue().longValue());
                        accept(Token.LITERAL_INT);
                        if (Token.COMMA == lexer.token()) {
                            lexer.nextToken();
                        } else if (lexer.token() == Token.EOF || lexer.token() == SEMI) {
                            break;
                        } else {
                            throw new ParserException("syntax error, expect job id, actual " + lexer.token() + ", " + lexer.info());
                        }
                    }
                    statementList.add(stmt);
                    return true;
                }
            }

            acceptIdentifier("PLANCACHE");

            statementList.add(new MySqlClearPlanCacheStatement());
            return true;
        }

        if (lexer.identifierEquals("DISABLED")) {
            lexer.nextToken();
            acceptIdentifier("PLANCACHE");

            statementList.add(new MySqlDisabledPlanCacheStatement());
            return true;
        }

        if (lexer.identifierEquals("XA")) {
            lexer.nextToken();
            MySqlXAStatement stmt = new MySqlXAStatement();
            String typeStr = lexer.stringVal();
            stmt.setType(
                    MySqlXAStatement.XAType.of(typeStr)
            );
            lexer.nextToken();

            if (lexer.token() != EOF && lexer.token() != SEMI) {
                SQLExpr xid = exprParser.expr();
                stmt.setId(xid);
            }

            statementList.add(stmt);
            return true;
        }

        if (lexer.token() == Token.EXPLAIN) {
            SQLStatement stmt = this.parseExplain();
            statementList.add(stmt);
            return true;
        }

        if (lexer.identifierEquals(BINLOG)) {
            SQLStatement stmt = parseBinlog();
            statementList.add(stmt);
            return true;
        }

        if (lexer.identifierEquals(RESET)) {
            SQLStatement stmt = parseReset();
            statementList.add(stmt);
            return true;
        }

        if (lexer.token() == Token.ANALYZE) {
            SQLStatement stmt = parseAnalyze();
            statementList.add(stmt);
            return true;
        }

        if (lexer.identifierEquals(FnvHash.Constants.ARCHIVE)) {
            SQLStatement stmt = parseArchive();
            statementList.add(stmt);
            return true;
        }

        if (lexer.identifierEquals(FnvHash.Constants.BACKUP)) {
            SQLStatement stmt = parseBackup();
            statementList.add(stmt);
            return true;
        }

        if (lexer.identifierEquals(FnvHash.Constants.RESTORE)) {
            SQLStatement stmt = parseRestore();
            statementList.add(stmt);
            return true;
        }

        if (lexer.identifierEquals("BUILD")) {
            SQLStatement stmt = parseBuildTable();
            statementList.add(stmt);
            return true;
        }

        if (lexer.identifierEquals("CANCEL")) {
            SQLStatement stmt = parseCancelJob();
            statementList.add(stmt);
            return true;
        }

        if (lexer.identifierEquals(FnvHash.Constants.EXPORT)) {
            lexer.nextToken();
            if (lexer.token() == TABLE) {
                SQLStatement stmt = parseExportTable();
                statementList.add(stmt);
            } else if (lexer.token() == Token.DATABASE) {
                SQLStatement stmt = parseExportDB();
                statementList.add(stmt);
            }
            return true;
        }

        if (lexer.identifierEquals(FnvHash.Constants.IMPORT)) {
            lexer.nextToken();
            if (lexer.token() == TABLE) {
                SQLStatement stmt = parseImportTable();
                statementList.add(stmt);
            } else if (lexer.token() == Token.DATABASE) {
                SQLStatement stmt = parseImportDB();
                statementList.add(stmt);
            }
            return true;
        }

        if (lexer.identifierEquals("SUBMIT")) {
            lexer.nextToken();
            acceptIdentifier("JOB");

            SQLStatement stmt = parseSubmitJob();
            statementList.add(stmt);
            return true;
        }

        if (lexer.identifierEquals(FnvHash.Constants.MIGRATE)) {
            SQLStatement stmt = parseMigrate();
            statementList.add(stmt);
            return true;
        }

        if (lexer.token() == Token.OPTIMIZE) {
            SQLStatement stmt = parseOptimize();
            statementList.add(stmt);
            return true;
        }

        if (lexer.identifierEquals("HELP")) {
            lexer.nextToken();
            MySqlHelpStatement stmt = new MySqlHelpStatement();
            stmt.setContent(this.exprParser.primary());
            statementList.add(stmt);
            return true;
        }

        if (lexer.identifierEquals("FLUSH")) {
            SQLStatement stmt = parseFlush();
            statementList.add(stmt);
            return true;
        }

        if (lexer.identifierEquals(FnvHash.Constants.SYNC)) {
            SQLStatement stmt = parseSync();
            statementList.add(stmt);
            return true;
        }

        if (lexer.identifierEquals(FnvHash.Constants.INIT)) {
            statementList.add(
                    new SQLExprStatement(
                            this.exprParser.expr()));
            return true;
        }

        // DRDS async DDL.
        if (isEnabled(SQLParserFeature.DRDSAsyncDDL) && lexer.identifierEquals(FnvHash.Constants.RECOVER)) {
            // RECOVER DDL {ALL | <job_id> [, <job_id>] ...}
            lexer.nextToken();
            acceptIdentifier("DDL");
            DrdsRecoverDDLJob stmt = new DrdsRecoverDDLJob();
            if (Token.ALL == lexer.token()) {
                lexer.nextToken();
                stmt.setAllJobs(true);
                statementList.add(stmt);
                return true;
            } else {
                while (true) {
                    stmt.addJobId(lexer.integerValue().longValue());
                    accept(Token.LITERAL_INT);
                    if (Token.COMMA == lexer.token()) {
                        lexer.nextToken();
                    } else if (lexer.token() == Token.EOF || lexer.token() == SEMI) {
                        break;
                    } else {
                        throw new ParserException("syntax error, expect job id, actual " + lexer.token() + ", " + lexer.info());
                    }
                }
                statementList.add(stmt);
                return true;
            }
        }

        if (isEnabled(SQLParserFeature.DRDSAsyncDDL) && lexer.identifierEquals(FnvHash.Constants.REMOVE)) {
            // REMOVE DDL { ALL { COMPLETED | PENDING } | <job_id> [, <job_id>] ...}
            lexer.nextToken();
            acceptIdentifier("DDL");
            DrdsRemoveDDLJob stmt = new DrdsRemoveDDLJob();
            if (Token.ALL == lexer.token()) {
                lexer.nextToken();
                if (lexer.identifierEquals("COMPLETED")) {
                    lexer.nextToken();
                    stmt.setAllCompleted(true);
                } else if (lexer.identifierEquals("PENDING")) {
                    lexer.nextToken();
                    stmt.setAllPending(true);
                } else {
                    throw new ParserException("syntax error, expect COMPLETED or PENDING, actual " + lexer.token() + ", " + lexer.info());
                }
            } else {
                while (true) {
                    stmt.addJobId(lexer.integerValue().longValue());
                    accept(Token.LITERAL_INT);
                    if (Token.COMMA == lexer.token()) {
                        lexer.nextToken();
                    } else if (lexer.token() == Token.EOF || lexer.token() == SEMI) {
                        break;
                    } else {
                        throw new ParserException("syntax error, expect job id, actual " + lexer.token() + ", " + lexer.info());
                    }
                }
            }
            statementList.add(stmt);
            return true;
        }

        if (isEnabled(SQLParserFeature.DRDSAsyncDDL) && lexer.identifierEquals("INSPECT")) {
            // INSPECT DDL CACHE
            lexer.nextToken();
            acceptIdentifier("DDL");
            accept(Token.CACHE);
            statementList.add(new DrdsInspectDDLJobCache());
            return true;
        }

        if (isEnabled(SQLParserFeature.DRDSAsyncDDL) && lexer.identifierEquals(FnvHash.Constants.CHANGE)) {
            // CHANGE DDL <job_id> { SKIP | ADD } <group_and_table_name> [ , <group_and_table_name> ] ...
            Lexer.SavePoint mark = lexer.mark();
            lexer.nextToken();
            if (lexer.identifierEquals("DDL")) {
                lexer.nextToken();

                DrdsChangeDDLJob stmt = new DrdsChangeDDLJob();

                stmt.setJobId(lexer.integerValue().longValue());
                accept(Token.LITERAL_INT);

                if (lexer.identifierEquals("SKIP")) {
                    lexer.nextToken();
                    stmt.setSkip(true);
                } else if (lexer.identifierEquals("ADD")) {
                    lexer.nextToken();
                    stmt.setAdd(true);
                } else {
                    throw new ParserException("syntax error, expect SKIP or ADD, actual " + lexer.token() + ", " + lexer.info());
                }

                StringBuilder builder = new StringBuilder();
                while (true) {
                    if (Token.COMMA == lexer.token()) {
                        lexer.nextToken();
                        stmt.addGroupAndTableNameList(builder.toString());
                        builder = new StringBuilder();
                    } else if (lexer.token() == Token.EOF || lexer.token() == SEMI) {
                        stmt.addGroupAndTableNameList(builder.toString());
                        break;
                    } else if (lexer.token() == Token.COLON) {
                        builder.append(':');
                        lexer.nextToken();
                    } else if (lexer.token() == Token.DOT) {
                        builder.append('.');
                        lexer.nextToken();
                    } else {
                        builder.append(lexer.stringVal());
                        lexer.nextToken();
                    }
                }

                statementList.add(stmt);
                return true;
            }
            lexer.reset(mark);
        }

        if (isEnabled(SQLParserFeature.DRDSBaseline) && lexer.identifierEquals("BASELINE")) {
            lexer.nextToken();

            DrdsBaselineStatement stmt = new DrdsBaselineStatement();

            if (Token.EOF == lexer.token() || SEMI == lexer.token() ||
                    lexer.stringVal().isEmpty() || lexer.stringVal().equalsIgnoreCase("BASELINE")) {
                throw new ParserException("syntax error, expect baseline operation, actual " + lexer.token() + ", " + lexer.info());
            }

            stmt.setOperation(lexer.stringVal());

            lexer.setToken(Token.COMMA); // Hack here: Set previous comma to deal with negative number.
            lexer.nextToken();

            if (lexer.identifierEquals(FnvHash.Constants.SQL)) {
                // Parse select.
                lexer.nextToken();

                if (lexer.token() == Token.HINT) {
                    stmt.setHeadHints(this.exprParser.parseHints());
                }

                MySqlSelectParser selectParser = createSQLSelectParser();
                stmt.setSelect(selectParser.select());
            } else {
                // Parse id list.
                while (lexer.token() != Token.EOF && lexer.token() != SEMI) {
                    stmt.addBaselineId(lexer.integerValue().longValue());
                    accept(Token.LITERAL_INT);
                    if (Token.COMMA == lexer.token()) {
                        lexer.nextToken();
                    }
                }
            }

            statementList.add(stmt);
            return true;
        }

        if (lexer.token() == Token.DESC || lexer.identifierEquals(DESCRIBE)) {
            SQLStatement stmt = parseDescribe();
            statementList.add(stmt);
            return true;
        }

        if (lexer.token() == Token.LOCK) {
            lexer.nextToken();
            String val = lexer.stringVal();
            boolean isLockTables = TABLES.equalsIgnoreCase(val) && lexer.token() == Token.IDENTIFIER;
            boolean isLockTable = "TABLE".equalsIgnoreCase(val) && lexer.token() == TABLE;
            if (isLockTables || isLockTable) {
                lexer.nextToken();
            } else {
                setErrorEndPos(lexer.pos());
                throw new ParserException("syntax error, expect TABLES or TABLE, actual " + lexer.token() + ", " + lexer.info());
            }

            MySqlLockTableStatement stmt = new MySqlLockTableStatement();

            for (; ; ) {
                MySqlLockTableStatement.Item item = new MySqlLockTableStatement.Item();

                SQLExprTableSource tableSource = null;
                SQLName tableName = this.exprParser.name();

                if (lexer.token() == Token.AS) {
                    lexer.nextToken();
                    String as = lexer.stringVal();
                    tableSource = new SQLExprTableSource(tableName, as);
                    lexer.nextToken();
                } else {
                    tableSource = new SQLExprTableSource(tableName);
                }
                item.setTableSource(tableSource);
                stmt.getItems().add(item);

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

                if (lexer.identifierEquals(READ)) {
                    lexer.nextToken();
                    if (lexer.identifierEquals(LOCAL)) {
                        lexer.nextToken();
                        item.setLockType(LockType.READ_LOCAL);
                    } else {
                        item.setLockType(LockType.READ);
                    }
                } else if (lexer.identifierEquals(WRITE)) {
                    lexer.nextToken();
                    item.setLockType(LockType.WRITE);
                } else if (lexer.identifierEquals(FnvHash.Constants.LOW_PRIORITY)) {
                    lexer.nextToken();
                    acceptIdentifier(WRITE);
                    lexer.nextToken();
                    item.setLockType(LockType.LOW_PRIORITY_WRITE);
                } else {
                    throw new ParserException(
                            "syntax error, expect READ or WRITE OR AS, actual " + lexer.token() + ", " + lexer.info());
                }

                if (lexer.token() == Token.HINT) {
                    item.setHints(this.exprParser.parseHints());
                }

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

            statementList.add(stmt);
            return true;
        }

        if (lexer.identifierEquals("UNLOCK")) {
            lexer.nextToken();
            String val = lexer.stringVal();
            boolean isUnLockTables = TABLES.equalsIgnoreCase(val) && lexer.token() == Token.IDENTIFIER;
            boolean isUnLockTable = "TABLE".equalsIgnoreCase(val) && lexer.token() == TABLE;
            statementList.add(new MySqlUnlockTablesStatement());
            if (isUnLockTables || isUnLockTable) {
                lexer.nextToken();
            } else {
                setErrorEndPos(lexer.pos());
                throw new ParserException("syntax error, expect TABLES or TABLE, actual " + lexer.token() + ", " + lexer.info());
            }
            return true;
        }

        if (lexer.identifierEquals(FnvHash.Constants.CHECKSUM)) {
            statementList.add(this.parseChecksum());
            return true;
        }

        if (lexer.token() == Token.HINT) {
            List<SQLCommentHint> hints = this.exprParser.parseHints();

            boolean tddlHints = false;
            boolean accept = false;

            boolean acceptHint = false;
            switch (lexer.token()) {
                case SELECT:
                case WITH:
                case DELETE:
                case UPDATE:
                case INSERT:
                case SHOW:
                case REPLACE:
                case TRUNCATE:
                case DROP:
                case ALTER:
                case CREATE:
                case CHECK:
                case SET:
                case DESC:
                case OPTIMIZE:
                case ANALYZE:
                case KILL:
                case EXPLAIN:
                case LPAREN:
                    acceptHint = true;
                    break;
                case IDENTIFIER:
                    acceptHint = lexer.hashLCase() == FnvHash.Constants.DUMP
                            || lexer.hashLCase() == FnvHash.Constants.RENAME
                            || lexer.hashLCase() == FnvHash.Constants.DESCRIBE;
                    break;
                default:
                    break;
            }
            if (hints.size() >= 1
                    && statementList.isEmpty()
                    && acceptHint) {
                SQLCommentHint hint = hints.get(0);
                String hintText = hint.getText().toUpperCase();
                if (hintText.startsWith("+TDDL")
                        || hintText.startsWith("+ TDDL")
                        || hintText.startsWith("TDDL")
                        || hintText.startsWith("!TDDL")) {
                    tddlHints = true;
                } else if (hintText.startsWith("+")) {
                    accept = true;
                }
            }

            if (tddlHints) {
                SQLStatementImpl stmt = (SQLStatementImpl) this.parseStatement();
                stmt.setHeadHints(hints);
                statementList.add(stmt);
                return true;
            } else if (accept) {
                SQLStatementImpl stmt = (SQLStatementImpl) this.parseStatement();
                stmt.setHeadHints(hints);
                statementList.add(stmt);
                return true;
            }

            MySqlHintStatement stmt = new MySqlHintStatement();
            stmt.setHints(hints);

            statementList.add(stmt);
            return true;
        }

        if (lexer.token() == Token.BEGIN) {
            Lexer.SavePoint mark = lexer.mark();
            lexer.nextToken();
            if (lexer.token() == SEMI || lexer.token() == Token.EOF || lexer.token() == Token.IDENTIFIER) {
                lexer.reset(mark);
                statementList.add(this.parseTiDBBeginStatment());
                return true;
            } else {
                lexer.reset(mark);
            }
            statementList.add(this.parseBlock());
            return true;
        }

        if (lexer.identifierEquals(FnvHash.Constants.ADD)) {
            statementList.add(parseAddManageInstanceGroup());
            return true;
        }

        if (lexer.token() == Token.IDENTIFIER) {
            String label = lexer.stringVal();
            Lexer.SavePoint savePoint = lexer.markOut();
            lexer.nextToken();
            if (lexer.token() == Token.VARIANT && lexer.stringVal().equals(":")) {
                lexer.nextToken();
                if (lexer.token() == Token.LOOP) {
                    // parse loop statement
                    statementList.add(this.parseLoop(label));
                } else if (lexer.token() == Token.WHILE) {
                    // parse while statement with label
                    statementList.add(this.parseWhile(label));
                } else if (lexer.token() == Token.BEGIN) {
                    // parse begin-end statement with label
                    SQLBlockStatement block = this.parseBlock(label);
                    statementList.add(block);
                } else if (lexer.token() == Token.REPEAT) {
                    // parse repeat statement with label
                    statementList.add(this.parseRepeat(label));
                }
                return true;
            } else {
                lexer.reset(savePoint);
            }

        }

        if (lexer.token() == Token.CHECK) {
            final Lexer.SavePoint mark = lexer.mark();
            lexer.nextToken();

            if (lexer.token() == TABLE) {
                lexer.nextToken();

                MySqlCheckTableStatement stmt = new MySqlCheckTableStatement();
                for (; ; ) {
                    SQLName table = this.exprParser.name();
                    stmt.addTable(new SQLExprTableSource(table));

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

                    break;
                }
                statementList.add(stmt);
            }
            return true;
        }
        String strVal = lexer.stringVal();
        if (strVal.equalsIgnoreCase("SPLIT")) {
            TidbSplitTableStatement stmt = this.parseTiDBSplitTableStatement();
            statementList.add(stmt);
            return true;
        }

        return false;
    }