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