public void parseStatementList()

in core/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java [126:709]


    public void parseStatementList(List<SQLStatement> statementList, int max, SQLObject parent) {
        if (lexer.token == Token.SELECT) {
            String[] words = lexer.text.split("\\s+");
            if (words.length == 2
                    && "select".equalsIgnoreCase(words[0])
                    && "@@session.tx_read_only".equalsIgnoreCase(words[1])) {
                SQLSelect select = new SQLSelect();
                MySqlSelectQueryBlock queryBlock = new MySqlSelectQueryBlock();
                queryBlock.addSelectItem(new SQLPropertyExpr(new SQLVariantRefExpr("@@session"), "tx_read_only"));
                select.setQuery(queryBlock);

                SQLSelectStatement stmt = new SQLSelectStatement(select);
                statementList.add(stmt);

                lexer.reset(29, '\u001A', Token.EOF);
                return;
            }
        }

        boolean semi = false;
        for (int i = 0; ; i++) {
            if (max != -1) {
                if (statementList.size() >= max) {
                    return;
                }
            }
            while (lexer.token == MULTI_LINE_COMMENT || lexer.token == LINE_COMMENT) {
                lexer.nextToken();
            }

            switch (lexer.token) {
                case EOF:
                case END:
                case UNTIL:
                case ELSE:
                case WHEN:
                case EXCEPTION:
                    if (lexer.isKeepComments() && lexer.hasComment() && !statementList.isEmpty()) {
                        SQLStatement stmt = statementList.get(statementList.size() - 1);
                        stmt.addAfterComment(lexer.readAndResetComments());
                    }
                    if (END == lexer.token && dialectFeatureEnabled(ParseStatementListWhen)) {
                        Lexer.SavePoint savePoint = lexer.mark();
                        lexer.nextToken();
                        if (lexer.token == Token.IF) {
                            lexer.reset(savePoint);
                            return;
                        }

                        if (parent instanceof SQLBlockStatement) {
                            lexer.reset(savePoint);
                            return;
                        }

                        lexer.reset(savePoint);
                        SQLStatement stmt = parseEnd();
                        stmt.setParent(parent);
                        statementList.add(stmt);
                        continue;
                    }
                    return;
                case ELSEIF:
                    if (parent instanceof SQLIfStatement) {
                        return;
                    }
                    break;
                case SEMI: {
                    char ch = lexer.ch;
                    lexer.nextToken();

                    if (statementList.size() > 0) {
                        SQLStatement lastStmt = statementList.get(statementList.size() - 1);
                        lastStmt.setAfterSemi(true);

                        if (lexer.isKeepComments()) {
                            if (ch == '\n'
                                    && lexer.getComments() != null
                                    && !lexer.getComments().isEmpty()
                                    && !(lastStmt instanceof SQLSetStatement)
                            ) {
                                lexer.getComments().add(0, new String("\n"));
                            }
                            lastStmt.addAfterComment(lexer.readAndResetComments());
                        }
                    }

                    semi = true;

                    continue;
                }
                case WITH: {
                    SQLStatement stmt = parseWith();
                    stmt.setParent(parent);
                    statementList.add(stmt);
                    continue;
                }
                case SELECT: {
                    MySqlHintStatement hintStatement = null;
                    if (i == 1
                            && statementList.size() > 0
                            && statementList.get(statementList.size() - i) instanceof MySqlHintStatement) {
                        hintStatement = (MySqlHintStatement) statementList.get(statementList.size() - i);
                    } else if (i > 0 && dialectFeatureEnabled(ParseStatementListSelectUnsupportedSyntax) && !semi
                            && !(statementList.size() > 0 && statementList.get(statementList.size() - i).isAfterSemi())
                    ) {
                        throw new ParserException("syntax error. " + lexer.info());
                    }
                    SQLStatement stmt = parseSelect();
                    stmt.setParent(parent);
                    if (hintStatement != null && stmt instanceof SQLStatementImpl) {
                        SQLStatementImpl stmtImpl = (SQLStatementImpl) stmt;
                        List<SQLCommentHint> hints = stmtImpl.getHeadHintsDirect();
                        if (hints == null) {
                            stmtImpl.setHeadHints(hintStatement.getHints());
                        } else {
                            hints.addAll(hintStatement.getHints());
                        }
                        statementList.set(statementList.size() - 1, stmt);
                    } else {
                        statementList.add(stmt);
                    }
                    semi = false;
                    continue;
                }
                case UPDATE: {
                    //FOR ADS
                    Lexer.SavePoint savePoint = lexer.mark();
                    lexer.nextToken();
                    if (dialectFeatureEnabled(ParseStatementListUpdatePlanCache) && lexer.identifierEquals("PLANCACHE")) {
                        lexer.nextToken();
                        if (lexer.token == Token.SELECT) {
                            MySqlUpdatePlanCacheStatement stmt = new MySqlUpdatePlanCacheStatement();

                            SQLSelect fromSelect = createSQLSelectParser().select();
                            accept(Token.TO);
                            SQLSelect toSelect = createSQLSelectParser().select();

                            stmt.setFormSelect(fromSelect);
                            stmt.setToSelect(toSelect);

                            statementList.add(stmt);
                            continue;
                        }
                    }

                    lexer.reset(savePoint);
                    SQLStatement stmt = parseUpdateStatement();
                    stmt.setParent(parent);
                    statementList.add(stmt);
                    continue;
                }
                case CREATE: {
                    List<String> comments = null;
                    if (lexer.isKeepComments() && lexer.hasComment()) {
                        comments = lexer.readAndResetComments();
                    }
                    SQLStatement stmt = parseCreate();
                    stmt.addBeforeComment(comments);
                    stmt.setParent(parent);
                    statementList.add(stmt);
                    continue;
                }
                case INSERT: {
                    SQLStatement stmt = parseInsert();
                    stmt.setParent(parent);
                    statementList.add(stmt);
                    continue;
                }
                case DELETE: {
                    SQLStatement stmt = parseDeleteStatement();
                    stmt.setParent(parent);
                    statementList.add(stmt);
                    continue;
                }
                case GET: {
                    SQLStatement stmt = parseGetDiagnosticsStatement();
                    stmt.setParent(parent);
                    statementList.add(stmt);
                    continue;
                }
                case EXPLAIN: {
                    if (lexer.keepSourceLocation) {
                        lexer.computeRowAndColumn();
                    }
                    int sourceLine = lexer.posLine;
                    int sourceColumn = lexer.posColumn;

                    //FOR ADS
                    Lexer.SavePoint savePoint = lexer.mark();
                    lexer.nextToken();

                    if (lexer.identifierEquals("PLANCACHE")) {
                        lexer.nextToken();
                        MySqlExplainPlanCacheStatement stmt = new MySqlExplainPlanCacheStatement();
                        stmt.setSource(sourceLine, sourceColumn);
                        statementList.add(stmt);
//                    } else if(lexer.token ==  Token.ANALYZE) {
//                        lexer.nextToken();
//
//                        SQLExplainAnalyzeStatement stmt = new SQLExplainAnalyzeStatement();
//                        stmt.setSelect(createSQLSelectParser().select());
//                        statementList.add(stmt);
                    } else {
                        lexer.reset(savePoint);
                        SQLExplainStatement stmt = parseExplain();
                        stmt.setSource(sourceLine, sourceColumn);
                        stmt.setParent(parent);
                        statementList.add(stmt);
                    }
                    continue;
                }
                case SET: {
                    SQLStatement stmt = parseSet();
                    stmt.setParent(parent);
                    statementList.add(stmt);
                    continue;
                }
                case ALTER: {
                    SQLStatement stmt = parseAlter();
                    stmt.setParent(parent);
                    statementList.add(stmt);
                    continue;
                }
                case TRUNCATE: {
                    SQLStatement stmt = parseTruncate();
                    stmt.setParent(parent);
                    statementList.add(stmt);
                    continue;
                }
                case USE: {
                    SQLStatement stmt = parseUse();
                    stmt.setParent(parent);
                    statementList.add(stmt);
                    continue;
                }
                case GRANT: {
                    SQLStatement stmt = parseGrant();
                    stmt.setParent(parent);
                    statementList.add(stmt);
                    continue;
                }
                case REVOKE: {
                    SQLStatement stmt = parseRevoke();
                    stmt.setParent(parent);
                    statementList.add(stmt);
                    continue;
                }
                case SHOW: {
                    SQLStatement stmt = parseShow();
                    stmt.setParent(parent);
                    statementList.add(stmt);
                    continue;
                }
                case MERGE: {
                    SQLStatement stmt = parseMerge();
                    stmt.setParent(parent);
                    statementList.add(stmt);
                    continue;
                }
                case REPEAT: {
                    SQLStatement stmt = parseRepeat();
                    stmt.setParent(parent);
                    statementList.add(stmt);
                    continue;
                }
                case DECLARE: {
                    SQLStatement stmt = parseDeclare();
                    stmt.setParent(parent);
                    statementList.add(stmt);
                    continue;
                }
                case WHILE: {
                    SQLStatement stmt = parseWhile();
                    stmt.setParent(parent);
                    statementList.add(stmt);
                    continue;
                }
                case IF: {
                    SQLStatement stmt = parseIf();
                    stmt.setParent(parent);
                    statementList.add(stmt);
                    continue;
                }
                case CASE: {
                    SQLStatement stmt = parseCase();
                    stmt.setParent(parent);
                    statementList.add(stmt);
                    continue;
                }
                case OPEN: {
                    SQLStatement stmt = parseOpen();
                    stmt.setParent(parent);
                    statementList.add(stmt);
                    continue;
                }
                case FETCH: {
                    SQLStatement stmt = parseFetch();
                    stmt.setParent(parent);
                    statementList.add(stmt);
                    continue;
                }
                case DROP: {
                    SQLStatement stmt = parseDrop();
                    stmt.setParent(parent);
                    statementList.add(stmt);
                    continue;
                }
                case COMMENT: {
                    SQLStatement stmt = parseComment();
                    stmt.setParent(parent);
                    statementList.add(stmt);
                    continue;
                }
                case KILL: {
                    SQLStatement stmt = parseKill();
                    stmt.setParent(parent);
                    statementList.add(stmt);
                    continue;
                }
                case CLOSE: {
                    SQLStatement stmt = parseClose();
                    stmt.setParent(parent);
                    statementList.add(stmt);
                    continue;
                }
                case RETURN: {
                    SQLStatement stmt = parseReturn();
                    stmt.setParent(parent);
                    statementList.add(stmt);
                    continue;
                }
                case UPSERT: {
                    SQLStatement stmt = parseUpsert();
                    stmt.setParent(parent);
                    statementList.add(stmt);
                    continue;
                }
                case LEAVE: {
                    SQLStatement stmt = parseLeave();
                    stmt.setParent(parent);
                    statementList.add(stmt);
                    continue;
                }
                case CACHE: {
                    SQLStatement stmt = parseCache();
                    stmt.setParent(parent);
                    statementList.add(stmt);
                    continue;
                }
                default:
                    break;
            }

            if (lexer.token == Token.LBRACE || lexer.identifierEquals("CALL")) {
                SQLCallStatement stmt = parseCall();
                statementList.add(stmt);
                continue;
            }

            if (lexer.identifierEquals("UPSERT")) {
                SQLStatement stmt = parseUpsert();
                statementList.add(stmt);
                continue;
            }

            if (lexer.identifierEquals("LIST")) {
                Lexer.SavePoint mark = lexer.mark();

                SQLStatement stmt = parseList();
                if (stmt != null) {
                    statementList.add(stmt);
                    continue;
                } else {
                    lexer.reset(mark);
                }
            }

            if (lexer.identifierEquals("RENAME")) {
                SQLStatement stmt = parseRename();
                statementList.add(stmt);
                continue;
            }

            if (lexer.identifierEquals("RELEASE")) {
                SQLStatement stmt = parseReleaseSavePoint();
                statementList.add(stmt);
                continue;
            }

            if (lexer.identifierEquals("SAVEPOINT")) {
                SQLStatement stmt = parseSavePoint();
                statementList.add(stmt);
                continue;
            }

            if (lexer.identifierEquals("REFRESH")) {
                SQLStatement stmt = parseRefresh();
                statementList.add(stmt);
                continue;
            }

            if (lexer.identifierEquals("SETPROJECT")) {
                SQLStatement stmt = parseSet();
                statementList.add(stmt);
                continue;
            }

            if (lexer.identifierEquals(FnvHash.Constants.COPY)) {
                SQLStatement stmt = parseCopy();
                statementList.add(stmt);
                continue;
            }

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

            if (lexer.identifierEquals("ROLLBACK")) {
                SQLStatement stmt = parseRollback();
                statementList.add(stmt);

                if (parent instanceof SQLBlockStatement
                        && dialectFeatureEnabled(ParseStatementListRollbackReturn)) {
                    return;
                }

                continue;
            }

            if (lexer.identifierEquals("DUMP")) {
                SQLStatement stmt = parseDump();
                statementList.add(stmt);

                continue;
            }

            if (lexer.identifierEquals(FnvHash.Constants.COMMIT)) {
                SQLStatement stmt = parseCommit();

                statementList.add(stmt);

                if (parent instanceof SQLBlockStatement
                        && dialectFeatureEnabled(ParseStatementListCommitReturn)) {
                    return;
                }

                continue;
            }

            if (lexer.identifierEquals(FnvHash.Constants.RETURN)) {
                SQLStatement stmt = parseReturn();
                statementList.add(stmt);
                continue;
            }

            if (lexer.identifierEquals(FnvHash.Constants.PURGE)) {
                SQLStatement stmt = parsePurge();
                statementList.add(stmt);
                continue;
            }

            if (lexer.identifierEquals(FnvHash.Constants.FLASHBACK)) {
                SQLStatement stmt = parseFlashback();
                statementList.add(stmt);
                continue;
            }

            if (lexer.identifierEquals(FnvHash.Constants.WHO)) {
                SQLStatement stmt = parseWhoami();
                statementList.add(stmt);
                continue;
            }

            if (lexer.token == Token.FOR) {
                SQLStatement stmt = parseFor();
                statementList.add(stmt);
                stmt.setParent(parent);
                continue;
            }

            if (lexer.token == Token.LPAREN) {
                Lexer.SavePoint savePoint = lexer.markOut();

                int parenCount = 0;
                do {
                    lexer.nextToken();
                    parenCount++;
                } while (lexer.token == Token.LPAREN);

                if (lexer.token == RPAREN && parenCount == 1 && dialectFeatureEnabled(ParseStatementListLparenContinue)) {
                    lexer.nextToken();
                    continue;
                }

                if (lexer.token == Token.SELECT) {
                    lexer.reset(savePoint);
                    SQLStatement stmt = parseSelect();
                    statementList.add(stmt);
                    continue;
                } else {
                    throw new ParserException("TODO " + lexer.info());
                }
            }

            if (lexer.token == Token.VALUES) {
                SQLValuesTableSource values = this.createSQLSelectParser().parseValues();
                SQLSelectStatement stmt = new SQLSelectStatement();
                stmt.setSelect(
                        new SQLSelect(values)
                );
                statementList.add(stmt);
                stmt.setParent(parent);
                continue;
            }

            if (lexer.identifierEquals("OPTIMIZE")) {
                SQLStatement stmt = parseOptimize();
                statementList.add(stmt);
                stmt.setParent(parent);
                continue;
            }

            if (lexer.token == WHILE) {
                SQLStatement stmt = parseWhile();
                statementList.add(stmt);
                stmt.setParent(parent);
                continue;
            }

            if (lexer.token == LOOP) {
                SQLStatement stmt = parseLoop();
                statementList.add(stmt);
                stmt.setParent(parent);
                continue;
            }

            if (lexer.token == CONTINUE) {
                SQLStatement stmt = parseContinue();
                statementList.add(stmt);
                stmt.setParent(parent);
                continue;
            }

            if (lexer.token == LEAVE) {
                SQLStatement stmt = parseLeave();
                statementList.add(stmt);
                stmt.setParent(parent);
                continue;
            }

            if (lexer.identifierEquals("EXECUTE")) {
                SQLStatement stmt = parseExecute();
                statementList.add(stmt);
                stmt.setParent(parent);
                continue;
            }

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

            int size = statementList.size();
            if (parseStatementListDialect(statementList)) {
                if (parent != null) {
                    for (int j = size; j < statementList.size(); ++j) {
                        SQLStatement dialectStmt = statementList.get(j);
                        dialectStmt.setParent(parent);
                    }
                }

                continue;
            }

            // throw new ParserException("syntax error, " + lexer.token + " "
            // + lexer.stringVal() + ", pos "
            // + lexer.pos());
            throw new ParserException(UNSUPPORT_TOKEN_MSG_PREFIX + lexer.info());
        }

    }