Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
studio.raptor.sqlparser.dialect.mysql.parser.MySqlStatementParser Maven / Gradle / Ivy
/*
* Copyright 1999-2017 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package studio.raptor.sqlparser.dialect.mysql.parser;
import java.util.ArrayList;
import java.util.List;
import studio.raptor.sqlparser.ast.SQLCommentHint;
import studio.raptor.sqlparser.ast.SQLDataTypeImpl;
import studio.raptor.sqlparser.ast.SQLDeclareItem;
import studio.raptor.sqlparser.ast.SQLExpr;
import studio.raptor.sqlparser.ast.SQLName;
import studio.raptor.sqlparser.ast.SQLOrderBy;
import studio.raptor.sqlparser.ast.SQLParameter;
import studio.raptor.sqlparser.ast.SQLParameter.ParameterType;
import studio.raptor.sqlparser.ast.SQLPartition;
import studio.raptor.sqlparser.ast.SQLStatement;
import studio.raptor.sqlparser.ast.expr.SQLBinaryOpExpr;
import studio.raptor.sqlparser.ast.expr.SQLBinaryOperator;
import studio.raptor.sqlparser.ast.expr.SQLCharExpr;
import studio.raptor.sqlparser.ast.expr.SQLIdentifierExpr;
import studio.raptor.sqlparser.ast.expr.SQLIntegerExpr;
import studio.raptor.sqlparser.ast.expr.SQLLiteralExpr;
import studio.raptor.sqlparser.ast.expr.SQLNCharExpr;
import studio.raptor.sqlparser.ast.expr.SQLQueryExpr;
import studio.raptor.sqlparser.ast.expr.SQLVariantRefExpr;
import studio.raptor.sqlparser.ast.statement.SQLAlterDatabaseStatement;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableAddColumn;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableAddConstraint;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableAddIndex;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableAddPartition;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableAnalyzePartition;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableCheckPartition;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableCoalescePartition;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableConvertCharSet;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableDisableConstraint;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableDisableKeys;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableDiscardPartition;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableDropColumnItem;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableDropConstraint;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableDropForeignKey;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableDropIndex;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableDropKey;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableDropPartition;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableDropPrimaryKey;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableEnableConstraint;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableEnableKeys;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableImportPartition;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableOptimizePartition;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableReOrganizePartition;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableRebuildPartition;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableRepairPartition;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableStatement;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableTruncatePartition;
import studio.raptor.sqlparser.ast.statement.SQLBlockStatement;
import studio.raptor.sqlparser.ast.statement.SQLColumnDefinition;
import studio.raptor.sqlparser.ast.statement.SQLCreateDatabaseStatement;
import studio.raptor.sqlparser.ast.statement.SQLCreateIndexStatement;
import studio.raptor.sqlparser.ast.statement.SQLCreateProcedureStatement;
import studio.raptor.sqlparser.ast.statement.SQLCreateTableStatement;
import studio.raptor.sqlparser.ast.statement.SQLExprTableSource;
import studio.raptor.sqlparser.ast.statement.SQLIfStatement;
import studio.raptor.sqlparser.ast.statement.SQLInsertStatement;
import studio.raptor.sqlparser.ast.statement.SQLInsertStatement.ValuesClause;
import studio.raptor.sqlparser.ast.statement.SQLLoopStatement;
import studio.raptor.sqlparser.ast.statement.SQLPrimaryKey;
import studio.raptor.sqlparser.ast.statement.SQLSelect;
import studio.raptor.sqlparser.ast.statement.SQLSelectOrderByItem;
import studio.raptor.sqlparser.ast.statement.SQLSelectStatement;
import studio.raptor.sqlparser.ast.statement.SQLSetStatement;
import studio.raptor.sqlparser.ast.statement.SQLShowTablesStatement;
import studio.raptor.sqlparser.ast.statement.SQLStartTransactionStatement;
import studio.raptor.sqlparser.ast.statement.SQLTableSource;
import studio.raptor.sqlparser.ast.statement.SQLUnique;
import studio.raptor.sqlparser.ast.statement.SQLUpdateSetItem;
import studio.raptor.sqlparser.ast.statement.SQLUpdateStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.MysqlForeignKey;
import studio.raptor.sqlparser.dialect.mysql.ast.clause.ConditionValue;
import studio.raptor.sqlparser.dialect.mysql.ast.clause.ConditionValue.ConditionType;
import studio.raptor.sqlparser.dialect.mysql.ast.clause.MySqlCaseStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.clause.MySqlCaseStatement.MySqlWhenStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.clause.MySqlCursorDeclareStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.clause.MySqlDeclareConditionStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.clause.MySqlDeclareHandlerStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.clause.MySqlDeclareStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.clause.MySqlHandlerType;
import studio.raptor.sqlparser.dialect.mysql.ast.clause.MySqlIterateStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.clause.MySqlLeaveStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.clause.MySqlRepeatStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.clause.MySqlSelectIntoStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.clause.MySqlWhileStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.CobarShowStatus;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlAlterTableAlterColumn;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlAlterTableChangeColumn;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlAlterTableCharacter;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlAlterTableDiscardTablespace;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlAlterTableImportTablespace;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlAlterTableModifyColumn;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlAlterTableOption;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlAlterUserStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlAnalyzeStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlBinlogStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlCommitStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlCreateTableStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlCreateUserStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlDeleteStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlExecuteStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlExplainStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlHelpStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlHintStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlInsertStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlKillStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlLoadDataInFileStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlLoadXmlStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlLockTableStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlLockTableStatement.LockType;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlOptimizeStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlPrepareStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlRenameTableStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlReplaceStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlResetStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlRollbackStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlSetCharSetStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlSetNamesStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlSetPasswordStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlSetTransactionStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowAuthorsStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowBinLogEventsStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowBinaryLogsStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowCharacterSetStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowCollationStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowColumnsStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowContributorsStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowCreateDatabaseStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowCreateEventStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowCreateFunctionStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowCreateProcedureStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowCreateTableStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowCreateTriggerStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowCreateViewStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowDatabasesStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowEngineStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowEnginesStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowErrorsStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowEventsStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowFunctionCodeStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowFunctionStatusStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowGrantsStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowIndexesStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowKeysStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowMasterLogsStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowMasterStatusStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowOpenTablesStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowPluginsStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowPrivilegesStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowProcedureCodeStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowProcedureStatusStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowProcessListStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowProfileStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowProfilesStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowRelayLogEventsStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowSlaveHostsStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowSlaveStatusStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowStatusStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowTableStatusStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowTriggersStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowVariantsStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlShowWarningsStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlUnlockTablesStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MySqlUpdateStatement;
import studio.raptor.sqlparser.dialect.mysql.ast.statement.MysqlDeallocatePrepareStatement;
import studio.raptor.sqlparser.parser.Lexer;
import studio.raptor.sqlparser.parser.ParserException;
import studio.raptor.sqlparser.parser.SQLSelectParser;
import studio.raptor.sqlparser.parser.SQLStatementParser;
import studio.raptor.sqlparser.parser.Token;
import studio.raptor.sqlparser.util.JdbcConstants;
public class MySqlStatementParser extends SQLStatementParser {
private static final String AUTO_INCREMENT = "AUTO_INCREMENT";
private static final String COLLATE2 = "COLLATE";
private static final String CHAIN = "CHAIN";
private static final String ENGINES = "ENGINES";
private static final String ENGINE = "ENGINE";
private static final String BINLOG = "BINLOG";
private static final String EVENTS = "EVENTS";
private static final String CHARACTER = "CHARACTER";
private static final String SESSION = "SESSION";
private static final String GLOBAL = "GLOBAL";
private static final String VARIABLES = "VARIABLES";
private static final String ERRORS = "ERRORS";
private static final String STATUS = "STATUS";
private static final String IGNORE = "IGNORE";
private static final String RESET = "RESET";
private static final String DESCRIBE = "DESCRIBE";
private static final String WRITE = "WRITE";
private static final String READ = "READ";
private static final String LOCAL = "LOCAL";
private static final String TABLES = "TABLES";
private static final String TEMPORARY = "TEMPORARY";
private static final String SPATIAL = "SPATIAL";
private static final String FULLTEXT = "FULLTEXT";
private static final String DELAYED = "DELAYED";
private static final String LOW_PRIORITY = "LOW_PRIORITY";
private static final String CONNECTION = "CONNECTION";
private static final String EXTENDED = "EXTENDED";
private static final String PARTITIONS = "PARTITIONS";
private static final String FORMAT = "FORMAT";
private static final String TRADITIONAL = "TRADITIONAL";
private static final String JSON = "JSON";
private int maxIntoClause = -1;
public MySqlStatementParser(String sql) {
super(new MySqlExprParser(sql));
}
public MySqlStatementParser(Lexer lexer) {
super(new MySqlExprParser(lexer));
}
public int getMaxIntoClause() {
return maxIntoClause;
}
public void setMaxIntoClause(int maxIntoClause) {
this.maxIntoClause = maxIntoClause;
}
public SQLCreateTableStatement parseCreateTable() {
MySqlCreateTableParser parser = new MySqlCreateTableParser(this.exprParser);
return parser.parseCrateTable();
}
public SQLStatement parseSelect() {
MySqlSelectParser selectParser = new MySqlSelectParser(this.exprParser);
SQLSelect select = selectParser.select();
if (selectParser.returningFlag) {
return selectParser.updateStmt;
}
return new SQLSelectStatement(select, JdbcConstants.MYSQL);
}
public SQLUpdateStatement parseUpdateStatement() {
return new MySqlSelectParser(this.exprParser).parseUpdateStatment();
}
protected MySqlUpdateStatement createUpdateStatement() {
return new MySqlUpdateStatement();
}
public MySqlDeleteStatement parseDeleteStatement() {
MySqlDeleteStatement deleteStatement = new MySqlDeleteStatement();
if (lexer.token() == Token.DELETE) {
lexer.nextToken();
if (lexer.token() == Token.COMMENT) {
lexer.nextToken();
}
if (lexer.token() == Token.HINT) {
this.getExprParser().parseHints(deleteStatement.getHints());
}
if (identifierEquals(LOW_PRIORITY)) {
deleteStatement.setLowPriority(true);
lexer.nextToken();
}
if (identifierEquals("QUICK")) {
deleteStatement.setQuick(true);
lexer.nextToken();
}
if (identifierEquals(IGNORE)) {
deleteStatement.setIgnore(true);
lexer.nextToken();
}
if (lexer.token() == Token.IDENTIFIER) {
deleteStatement.setTableSource(createSQLSelectParser().parseTableSource());
if (lexer.token() == Token.FROM) {
lexer.nextToken();
SQLTableSource tableSource = createSQLSelectParser().parseTableSource();
deleteStatement.setFrom(tableSource);
}
} else if (lexer.token() == Token.FROM) {
lexer.nextToken();
deleteStatement.setTableSource(createSQLSelectParser().parseTableSource());
} else {
throw new ParserException("syntax error");
}
if (identifierEquals("USING")) {
lexer.nextToken();
SQLTableSource tableSource = createSQLSelectParser().parseTableSource();
deleteStatement.setUsing(tableSource);
}
}
if (lexer.token() == (Token.WHERE)) {
lexer.nextToken();
SQLExpr where = this.exprParser.expr();
deleteStatement.setWhere(where);
}
if (lexer.token() == (Token.ORDER)) {
SQLOrderBy orderBy = exprParser.parseOrderBy();
deleteStatement.setOrderBy(orderBy);
}
deleteStatement.setLimit(this.exprParser.parseLimit());
return deleteStatement;
}
public SQLStatement parseCreate() {
char markChar = lexer.current();
int markBp = lexer.bp();
accept(Token.CREATE);
boolean replace = false;
if (lexer.token() == Token.OR) {
lexer.nextToken();
accept(Token.REPLACE);
replace = true;
}
List hints = this.exprParser.parseHints();
if (lexer.token() == Token.TABLE || identifierEquals(TEMPORARY)) {
if (replace) {
lexer.reset(markBp, markChar, Token.CREATE);
}
MySqlCreateTableParser parser = new MySqlCreateTableParser(this.exprParser);
MySqlCreateTableStatement stmt = parser.parseCrateTable(false);
stmt.setHints(hints);
return stmt;
}
if (lexer.token() == Token.DATABASE) {
if (replace) {
lexer.reset(markBp, markChar, Token.CREATE);
}
return parseCreateDatabase();
}
if (lexer.token() == Token.UNIQUE || lexer.token() == Token.INDEX || identifierEquals(FULLTEXT)
|| identifierEquals(SPATIAL)) {
if (replace) {
lexer.reset(markBp, markChar, Token.CREATE);
}
return parseCreateIndex(false);
}
if (lexer.token() == Token.USER) {
if (replace) {
lexer.reset(markBp, markChar, Token.CREATE);
}
return parseCreateUser();
}
if (lexer.token() == Token.VIEW
|| identifierEquals("ALGORITHM")) {
if (replace) {
lexer.reset(markBp, markChar, Token.CREATE);
}
return parseCreateView();
}
if (lexer.token() == Token.TRIGGER) {
if (replace) {
lexer.reset(markBp, markChar, Token.CREATE);
}
return parseCreateTrigger();
}
// parse create procedure
if (lexer.token() == Token.PROCEDURE || identifierEquals("DEFINER")) {
if (replace) {
lexer.reset(markBp, markChar, Token.CREATE);
}
return parseCreateProcedure();
}
throw new ParserException("TODO " + lexer.info());
}
public SQLStatement parseCreateIndex(boolean acceptCreate) {
if (acceptCreate) {
accept(Token.CREATE);
}
SQLCreateIndexStatement stmt = new SQLCreateIndexStatement();
if (lexer.token() == Token.UNIQUE) {
stmt.setType("UNIQUE");
lexer.nextToken();
} else if (identifierEquals(FULLTEXT)) {
stmt.setType(FULLTEXT);
lexer.nextToken();
} else if (identifierEquals(SPATIAL)) {
stmt.setType(SPATIAL);
lexer.nextToken();
}
accept(Token.INDEX);
stmt.setName(this.exprParser.name());
parseCreateIndexUsing(stmt);
accept(Token.ON);
stmt.setTable(this.exprParser.name());
accept(Token.LPAREN);
for (; ; ) {
SQLSelectOrderByItem item = this.exprParser.parseSelectOrderByItem();
stmt.addItem(item);
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
break;
}
accept(Token.RPAREN);
parseCreateIndexUsing(stmt);
return stmt;
}
private void parseCreateIndexUsing(SQLCreateIndexStatement stmt) {
if (identifierEquals("USING")) {
lexer.nextToken();
if (identifierEquals("BTREE")) {
stmt.setUsing("BTREE");
lexer.nextToken();
} else if (identifierEquals("HASH")) {
stmt.setUsing("HASH");
lexer.nextToken();
} else {
throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal());
}
}
}
public SQLStatement parseCreateUser() {
if (lexer.token() == Token.CREATE) {
lexer.nextToken();
}
accept(Token.USER);
MySqlCreateUserStatement stmt = new MySqlCreateUserStatement();
for (; ; ) {
MySqlCreateUserStatement.UserSpecification userSpec = new MySqlCreateUserStatement.UserSpecification();
SQLExpr expr = exprParser.primary();
userSpec.setUser(expr);
if (lexer.token() == Token.IDENTIFIED) {
lexer.nextToken();
if (lexer.token() == Token.BY) {
lexer.nextToken();
if (identifierEquals("PASSWORD")) {
lexer.nextToken();
userSpec.setPasswordHash(true);
}
SQLCharExpr password = (SQLCharExpr) this.exprParser.expr();
userSpec.setPassword(password);
} else if (lexer.token() == Token.WITH) {
lexer.nextToken();
userSpec.setAuthPlugin(this.exprParser.expr());
}
}
stmt.addUser(userSpec);
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
break;
}
return stmt;
}
public SQLStatement parseKill() {
accept(Token.KILL);
MySqlKillStatement stmt = new MySqlKillStatement();
if (identifierEquals("CONNECTION")) {
stmt.setType(MySqlKillStatement.Type.CONNECTION);
lexer.nextToken();
} else if (identifierEquals("QUERY")) {
stmt.setType(MySqlKillStatement.Type.QUERY);
lexer.nextToken();
} else if (lexer.token() == Token.LITERAL_INT) {
// skip
} else {
throw new ParserException("not support kill type " + lexer.token());
}
this.exprParser.exprList(stmt.getThreadIds(), stmt);
return stmt;
}
public SQLStatement parseBinlog() {
acceptIdentifier("binlog");
MySqlBinlogStatement stmt = new MySqlBinlogStatement();
SQLExpr expr = this.exprParser.expr();
stmt.setExpr(expr);
return stmt;
}
public MySqlAnalyzeStatement parseAnalyze() {
accept(Token.ANALYZE);
accept(Token.TABLE);
MySqlAnalyzeStatement stmt = new MySqlAnalyzeStatement();
List names = new ArrayList();
this.exprParser.names(names, stmt);
for (SQLName name : names) {
stmt.addTableSource(new SQLExprTableSource(name));
}
return stmt;
}
public MySqlOptimizeStatement parseOptimize() {
accept(Token.OPTIMIZE);
accept(Token.TABLE);
MySqlOptimizeStatement stmt = new MySqlOptimizeStatement();
List names = new ArrayList();
this.exprParser.names(names, stmt);
for (SQLName name : names) {
stmt.addTableSource(new SQLExprTableSource(name));
}
return stmt;
}
public SQLStatement parseReset() {
acceptIdentifier(RESET);
MySqlResetStatement stmt = new MySqlResetStatement();
for (; ; ) {
if (lexer.token() == Token.IDENTIFIER) {
if (identifierEquals("QUERY")) {
lexer.nextToken();
accept(Token.CACHE);
stmt.getOptions().add("QUERY CACHE");
} else {
stmt.getOptions().add(lexer.stringVal());
lexer.nextToken();
}
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
}
break;
}
return stmt;
}
public boolean parseStatementListDialect(List statementList) {
if (lexer.token() == Token.KILL) {
SQLStatement stmt = parseKill();
statementList.add(stmt);
return true;
}
if (identifierEquals("PREPARE")) {
MySqlPrepareStatement stmt = parsePrepare();
statementList.add(stmt);
return true;
}
if (identifierEquals("EXECUTE")) {
MySqlExecuteStatement stmt = parseExecute();
statementList.add(stmt);
return true;
}
if (identifierEquals("DEALLOCATE")) {
MysqlDeallocatePrepareStatement stmt = parseDeallocatePrepare();
statementList.add(stmt);
return true;
}
if (identifierEquals("LOAD")) {
SQLStatement stmt = parseLoad();
statementList.add(stmt);
return true;
}
if (lexer.token() == Token.REPLACE) {
MySqlReplaceStatement stmt = parseReplicate();
statementList.add(stmt);
return true;
}
if (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.token() == Token.EXPLAIN) {
SQLStatement stmt = this.parseExplain();
statementList.add(stmt);
return true;
}
if (identifierEquals(BINLOG)) {
SQLStatement stmt = parseBinlog();
statementList.add(stmt);
return true;
}
if (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.token() == Token.OPTIMIZE) {
SQLStatement stmt = parseOptimize();
statementList.add(stmt);
return true;
}
if (identifierEquals("HELP")) {
lexer.nextToken();
MySqlHelpStatement stmt = new MySqlHelpStatement();
stmt.setContent(this.exprParser.primary());
statementList.add(stmt);
return true;
}
if (lexer.token() == Token.DESC || 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() == Token.TABLE;
if (isLockTables || isLockTable) {
lexer.nextToken();
} else {
setErrorEndPos(lexer.pos());
throw new ParserException("syntax error, expect TABLES or TABLE, actual " + lexer.token());
}
MySqlLockTableStatement stmt = new MySqlLockTableStatement();
stmt.setTableSource(this.exprParser.name());
if (identifierEquals(READ)) {
lexer.nextToken();
if (identifierEquals(LOCAL)) {
lexer.nextToken();
stmt.setLockType(LockType.READ_LOCAL);
} else {
stmt.setLockType(LockType.READ);
}
} else if (identifierEquals(WRITE)) {
stmt.setLockType(LockType.WRITE);
} else if (identifierEquals(LOW_PRIORITY)) {
lexer.nextToken();
acceptIdentifier(WRITE);
stmt.setLockType(LockType.LOW_PRIORITY_WRITE);
} else {
throw new ParserException("syntax error, expect READ or WRITE, actual " + lexer.token());
}
if (lexer.token() == Token.HINT) {
stmt.setHints(this.exprParser.parseHints());
}
statementList.add(stmt);
return true;
}
if (identifierEquals("UNLOCK")) {
lexer.nextToken();
String val = lexer.stringVal();
boolean isUnLockTables = TABLES.equalsIgnoreCase(val) && lexer.token() == Token.IDENTIFIER;
boolean isUnLockTable = "TABLE".equalsIgnoreCase(val) && lexer.token() == 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());
}
return true;
}
if (lexer.token() == Token.HINT) {
List hints = this.exprParser.parseHints();
boolean tddlSelectHints = false;
if (hints.size() == 1 && statementList.size() == 0 && lexer.token() == Token.SELECT) {
SQLCommentHint hint = hints.get(0);
String hintText = hint.getText();
if (hintText.startsWith("+TDDL")) {
tddlSelectHints = true;
}
}
if (tddlSelectHints) {
SQLSelectStatement stmt = (SQLSelectStatement) 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) {
statementList.add(this.parseBlock());
return true;
}
return false;
}
public SQLBlockStatement parseBlock() {
SQLBlockStatement block = new SQLBlockStatement();
accept(Token.BEGIN);
parseProcedureStatementList(block.getStatementList());
accept(Token.END);
return block;
}
public MySqlExplainStatement parseDescribe() {
// see https://dev.mysql.com/doc/refman/5.7/en/explain.html
MySqlExplainStatement describe = new MySqlExplainStatement();
// {DESCRIBE | DESC}
if (lexer.token() == Token.DESC || identifierEquals(DESCRIBE)) {
lexer.nextToken();
describe.setDescribe(true);
} else {
throw new ParserException("expect one of {DESCRIBE | DESC} , actual " + lexer.token());
}
return parseExplain(describe);
}
public MySqlExplainStatement parseExplain() {
// see https://dev.mysql.com/doc/refman/5.7/en/explain.html
MySqlExplainStatement explain = new MySqlExplainStatement();
// {EXPLAIN}
if (lexer.token() == Token.EXPLAIN) {
lexer.nextToken();
} else {
throw new ParserException("expect EXPLAIN , actual " + lexer.token());
}
return parseExplain(explain);
}
private MySqlExplainStatement parseExplain(MySqlExplainStatement explain) {
if (lexer.token() == Token.HINT) {
List hints = this.exprParser.parseHints();
explain.setHints(hints);
}
// see https://dev.mysql.com/doc/refman/5.7/en/explain.html
boolean table = false;
if (lexer.token() == Token.IDENTIFIER) {
String stringVal = lexer.stringVal();
if (stringVal.equalsIgnoreCase(EXTENDED)
|| stringVal.equalsIgnoreCase(PARTITIONS)) {
explain.setType(stringVal);
lexer.nextToken();
} else if (stringVal.equalsIgnoreCase(FORMAT)) {
explain.setType(stringVal);
lexer.nextToken();
accept(Token.EQ);
String format = lexer.stringVal();
explain.setFormat(format);
accept(Token.IDENTIFIER);
} else {
explain.setTableName(exprParser.name());
if (lexer.token() == Token.IDENTIFIER) {
explain.setColumnName(exprParser.name());
} else if (lexer.token() == Token.LITERAL_CHARS) {
explain.setWild(exprParser.expr());
}
table = true;
}
}
if (lexer.token() == Token.FOR) {
lexer.nextToken();
acceptIdentifier(CONNECTION);
explain.setConnectionId(exprParser.expr());
} else if (!table) {
explain.setStatement(this.parseStatement());
}
return explain;
}
public SQLStatement parseShow() {
accept(Token.SHOW);
if (lexer.token() == Token.COMMENT) {
lexer.nextToken();
}
boolean full = false;
if (lexer.token() == Token.FULL) {
lexer.nextToken();
full = true;
}
if (identifierEquals("PROCESSLIST")) {
lexer.nextToken();
MySqlShowProcessListStatement stmt = new MySqlShowProcessListStatement();
stmt.setFull(full);
return stmt;
}
if (identifierEquals("COLUMNS") || identifierEquals("FIELDS")) {
lexer.nextToken();
MySqlShowColumnsStatement stmt = parseShowColumns();
stmt.setFull(full);
return stmt;
}
if (identifierEquals("COLUMNS")) {
lexer.nextToken();
MySqlShowColumnsStatement stmt = parseShowColumns();
return stmt;
}
if (identifierEquals(TABLES)) {
lexer.nextToken();
SQLShowTablesStatement stmt = parseShowTabless();
stmt.setFull(full);
return stmt;
}
if (identifierEquals("DATABASES")) {
lexer.nextToken();
MySqlShowDatabasesStatement stmt = parseShowDatabases();
return stmt;
}
if (identifierEquals("WARNINGS")) {
lexer.nextToken();
MySqlShowWarningsStatement stmt = parseShowWarnings();
return stmt;
}
if (identifierEquals("COUNT")) {
lexer.nextToken();
accept(Token.LPAREN);
accept(Token.STAR);
accept(Token.RPAREN);
if (identifierEquals(ERRORS)) {
lexer.nextToken();
MySqlShowErrorsStatement stmt = new MySqlShowErrorsStatement();
stmt.setCount(true);
return stmt;
} else {
acceptIdentifier("WARNINGS");
MySqlShowWarningsStatement stmt = new MySqlShowWarningsStatement();
stmt.setCount(true);
return stmt;
}
}
if (identifierEquals(ERRORS)) {
lexer.nextToken();
MySqlShowErrorsStatement stmt = new MySqlShowErrorsStatement();
stmt.setLimit(this.exprParser.parseLimit());
return stmt;
}
if (identifierEquals(STATUS)) {
lexer.nextToken();
MySqlShowStatusStatement stmt = parseShowStatus();
return stmt;
}
if (identifierEquals(VARIABLES)) {
lexer.nextToken();
MySqlShowVariantsStatement stmt = parseShowVariants();
return stmt;
}
if (identifierEquals(GLOBAL)) {
lexer.nextToken();
if (identifierEquals(STATUS)) {
lexer.nextToken();
MySqlShowStatusStatement stmt = parseShowStatus();
stmt.setGlobal(true);
return stmt;
}
if (identifierEquals(VARIABLES)) {
lexer.nextToken();
MySqlShowVariantsStatement stmt = parseShowVariants();
stmt.setGlobal(true);
return stmt;
}
}
if (identifierEquals(SESSION)) {
lexer.nextToken();
if (identifierEquals(STATUS)) {
lexer.nextToken();
MySqlShowStatusStatement stmt = parseShowStatus();
stmt.setSession(true);
return stmt;
}
if (identifierEquals(VARIABLES)) {
lexer.nextToken();
MySqlShowVariantsStatement stmt = parseShowVariants();
stmt.setSession(true);
return stmt;
}
}
if (identifierEquals("COBAR_STATUS")) {
lexer.nextToken();
return new CobarShowStatus();
}
if (identifierEquals("AUTHORS")) {
lexer.nextToken();
return new MySqlShowAuthorsStatement();
}
if (lexer.token() == Token.BINARY) {
lexer.nextToken();
acceptIdentifier("LOGS");
return new MySqlShowBinaryLogsStatement();
}
if (identifierEquals("MASTER")) {
lexer.nextToken();
if (identifierEquals("LOGS")) {
lexer.nextToken();
return new MySqlShowMasterLogsStatement();
}
acceptIdentifier(STATUS);
return new MySqlShowMasterStatusStatement();
}
if (identifierEquals(CHARACTER)) {
lexer.nextToken();
accept(Token.SET);
MySqlShowCharacterSetStatement stmt = new MySqlShowCharacterSetStatement();
if (lexer.token() == Token.LIKE) {
lexer.nextToken();
stmt.setPattern(this.exprParser.expr());
}
if (lexer.token() == Token.WHERE) {
lexer.nextToken();
stmt.setWhere(this.exprParser.expr());
}
return stmt;
}
if (identifierEquals("COLLATION")) {
lexer.nextToken();
MySqlShowCollationStatement stmt = new MySqlShowCollationStatement();
if (lexer.token() == Token.LIKE) {
lexer.nextToken();
stmt.setPattern(this.exprParser.expr());
}
if (lexer.token() == Token.WHERE) {
lexer.nextToken();
stmt.setWhere(this.exprParser.expr());
}
return stmt;
}
if (identifierEquals(BINLOG)) {
lexer.nextToken();
acceptIdentifier(EVENTS);
MySqlShowBinLogEventsStatement stmt = new MySqlShowBinLogEventsStatement();
if (lexer.token() == Token.IN) {
lexer.nextToken();
stmt.setIn(this.exprParser.expr());
}
if (lexer.token() == Token.FROM) {
lexer.nextToken();
stmt.setFrom(this.exprParser.expr());
}
stmt.setLimit(this.exprParser.parseLimit());
return stmt;
}
if (identifierEquals("CONTRIBUTORS")) {
lexer.nextToken();
return new MySqlShowContributorsStatement();
}
if (lexer.token() == Token.CREATE) {
lexer.nextToken();
if (lexer.token() == Token.DATABASE) {
lexer.nextToken();
MySqlShowCreateDatabaseStatement stmt = new MySqlShowCreateDatabaseStatement();
stmt.setDatabase(this.exprParser.name());
return stmt;
}
if (identifierEquals("EVENT")) {
lexer.nextToken();
MySqlShowCreateEventStatement stmt = new MySqlShowCreateEventStatement();
stmt.setEventName(this.exprParser.name());
return stmt;
}
if (lexer.token() == Token.FUNCTION) {
lexer.nextToken();
MySqlShowCreateFunctionStatement stmt = new MySqlShowCreateFunctionStatement();
stmt.setName(this.exprParser.name());
return stmt;
}
if (lexer.token() == Token.PROCEDURE) {
lexer.nextToken();
MySqlShowCreateProcedureStatement stmt = new MySqlShowCreateProcedureStatement();
stmt.setName(this.exprParser.name());
return stmt;
}
if (lexer.token() == Token.TABLE) {
lexer.nextToken();
MySqlShowCreateTableStatement stmt = new MySqlShowCreateTableStatement();
stmt.setName(this.exprParser.name());
return stmt;
}
if (lexer.token() == Token.VIEW) {
lexer.nextToken();
MySqlShowCreateViewStatement stmt = new MySqlShowCreateViewStatement();
stmt.setName(this.exprParser.name());
return stmt;
}
if (lexer.token() == Token.TRIGGER) {
lexer.nextToken();
MySqlShowCreateTriggerStatement stmt = new MySqlShowCreateTriggerStatement();
stmt.setName(this.exprParser.name());
return stmt;
}
throw new ParserException("TODO " + lexer.stringVal());
}
if (identifierEquals(ENGINE)) {
lexer.nextToken();
MySqlShowEngineStatement stmt = new MySqlShowEngineStatement();
stmt.setName(this.exprParser.name());
stmt.setOption(MySqlShowEngineStatement.Option.valueOf(lexer.stringVal().toUpperCase()));
lexer.nextToken();
return stmt;
}
if (identifierEquals("STORAGE")) {
lexer.nextToken();
acceptIdentifier(ENGINES);
MySqlShowEnginesStatement stmt = new MySqlShowEnginesStatement();
stmt.setStorage(true);
return stmt;
}
if (identifierEquals(ENGINES)) {
lexer.nextToken();
MySqlShowEnginesStatement stmt = new MySqlShowEnginesStatement();
return stmt;
}
if (identifierEquals(EVENTS)) {
lexer.nextToken();
MySqlShowEventsStatement stmt = new MySqlShowEventsStatement();
if (lexer.token() == Token.FROM || lexer.token() == Token.IN) {
lexer.nextToken();
stmt.setSchema(this.exprParser.name());
}
if (lexer.token() == Token.LIKE) {
lexer.nextToken();
stmt.setLike(this.exprParser.expr());
}
if (lexer.token() == Token.WHERE) {
lexer.nextToken();
stmt.setWhere(this.exprParser.expr());
}
return stmt;
}
if (lexer.token() == Token.FUNCTION) {
lexer.nextToken();
if (identifierEquals("CODE")) {
lexer.nextToken();
MySqlShowFunctionCodeStatement stmt = new MySqlShowFunctionCodeStatement();
stmt.setName(this.exprParser.name());
return stmt;
}
acceptIdentifier(STATUS);
MySqlShowFunctionStatusStatement stmt = new MySqlShowFunctionStatusStatement();
if (lexer.token() == Token.LIKE) {
lexer.nextToken();
stmt.setLike(this.exprParser.expr());
}
if (lexer.token() == Token.WHERE) {
lexer.nextToken();
stmt.setWhere(this.exprParser.expr());
}
return stmt;
}
// MySqlShowFunctionStatusStatement
if (identifierEquals(ENGINE)) {
lexer.nextToken();
MySqlShowEngineStatement stmt = new MySqlShowEngineStatement();
stmt.setName(this.exprParser.name());
stmt.setOption(MySqlShowEngineStatement.Option.valueOf(lexer.stringVal().toUpperCase()));
lexer.nextToken();
return stmt;
}
if (identifierEquals("STORAGE")) {
lexer.nextToken();
accept(Token.EQ);
accept(Token.DEFAULT);
MySqlShowEnginesStatement stmt = new MySqlShowEnginesStatement();
stmt.setStorage(true);
return stmt;
}
if (identifierEquals(ENGINES)) {
lexer.nextToken();
MySqlShowEnginesStatement stmt = new MySqlShowEnginesStatement();
return stmt;
}
if (identifierEquals("GRANTS")) {
lexer.nextToken();
MySqlShowGrantsStatement stmt = new MySqlShowGrantsStatement();
if (lexer.token() == Token.FOR) {
lexer.nextToken();
stmt.setUser(this.exprParser.expr());
}
return stmt;
}
if (lexer.token() == Token.INDEX || identifierEquals("INDEXES")) {
lexer.nextToken();
MySqlShowIndexesStatement stmt = new MySqlShowIndexesStatement();
if (lexer.token() == Token.FROM || lexer.token() == Token.IN) {
lexer.nextToken();
SQLName table = exprParser.name();
stmt.setTable(table);
if (lexer.token() == Token.FROM || lexer.token() == Token.IN) {
lexer.nextToken();
SQLName database = exprParser.name();
stmt.setDatabase(database);
}
}
if (lexer.token() == Token.HINT) {
stmt.setHints(this.exprParser.parseHints());
}
return stmt;
}
if (identifierEquals("KEYS")) {
lexer.nextToken();
MySqlShowKeysStatement stmt = new MySqlShowKeysStatement();
if (lexer.token() == Token.FROM || lexer.token() == Token.IN) {
lexer.nextToken();
SQLName table = exprParser.name();
stmt.setTable(table);
if (lexer.token() == Token.FROM || lexer.token() == Token.IN) {
lexer.nextToken();
SQLName database = exprParser.name();
stmt.setDatabase(database);
}
}
return stmt;
}
if (lexer.token() == Token.OPEN || identifierEquals("OPEN")) {
lexer.nextToken();
acceptIdentifier(TABLES);
MySqlShowOpenTablesStatement stmt = new MySqlShowOpenTablesStatement();
if (lexer.token() == Token.FROM || lexer.token() == Token.IN) {
lexer.nextToken();
stmt.setDatabase(this.exprParser.name());
}
if (lexer.token() == Token.LIKE) {
lexer.nextToken();
stmt.setLike(this.exprParser.expr());
}
if (lexer.token() == Token.WHERE) {
lexer.nextToken();
stmt.setWhere(this.exprParser.expr());
}
return stmt;
}
if (identifierEquals("PLUGINS")) {
lexer.nextToken();
MySqlShowPluginsStatement stmt = new MySqlShowPluginsStatement();
return stmt;
}
if (identifierEquals("PRIVILEGES")) {
lexer.nextToken();
MySqlShowPrivilegesStatement stmt = new MySqlShowPrivilegesStatement();
return stmt;
}
if (lexer.token() == Token.PROCEDURE) {
lexer.nextToken();
if (identifierEquals("CODE")) {
lexer.nextToken();
MySqlShowProcedureCodeStatement stmt = new MySqlShowProcedureCodeStatement();
stmt.setName(this.exprParser.name());
return stmt;
}
acceptIdentifier(STATUS);
MySqlShowProcedureStatusStatement stmt = new MySqlShowProcedureStatusStatement();
if (lexer.token() == Token.LIKE) {
lexer.nextToken();
stmt.setLike(this.exprParser.expr());
}
if (lexer.token() == Token.WHERE) {
lexer.nextToken();
stmt.setWhere(this.exprParser.expr());
}
return stmt;
}
if (identifierEquals("PROCESSLIST")) {
lexer.nextToken();
MySqlShowProcessListStatement stmt = new MySqlShowProcessListStatement();
return stmt;
}
if (identifierEquals("PROFILES")) {
lexer.nextToken();
MySqlShowProfilesStatement stmt = new MySqlShowProfilesStatement();
return stmt;
}
if (identifierEquals("PROFILE")) {
lexer.nextToken();
MySqlShowProfileStatement stmt = new MySqlShowProfileStatement();
for (; ; ) {
if (lexer.token() == Token.ALL) {
stmt.getTypes().add(MySqlShowProfileStatement.Type.ALL);
lexer.nextToken();
} else if (identifierEquals("BLOCK")) {
lexer.nextToken();
acceptIdentifier("IO");
stmt.getTypes().add(MySqlShowProfileStatement.Type.BLOCK_IO);
} else if (identifierEquals("CONTEXT")) {
lexer.nextToken();
acceptIdentifier("SWITCHES");
stmt.getTypes().add(MySqlShowProfileStatement.Type.CONTEXT_SWITCHES);
} else if (identifierEquals("CPU")) {
lexer.nextToken();
stmt.getTypes().add(MySqlShowProfileStatement.Type.CPU);
} else if (identifierEquals("IPC")) {
lexer.nextToken();
stmt.getTypes().add(MySqlShowProfileStatement.Type.IPC);
} else if (identifierEquals("MEMORY")) {
lexer.nextToken();
stmt.getTypes().add(MySqlShowProfileStatement.Type.MEMORY);
} else if (identifierEquals("PAGE")) {
lexer.nextToken();
acceptIdentifier("FAULTS");
stmt.getTypes().add(MySqlShowProfileStatement.Type.PAGE_FAULTS);
} else if (identifierEquals("SOURCE")) {
lexer.nextToken();
stmt.getTypes().add(MySqlShowProfileStatement.Type.SOURCE);
} else if (identifierEquals("SWAPS")) {
lexer.nextToken();
stmt.getTypes().add(MySqlShowProfileStatement.Type.SWAPS);
} else {
break;
}
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
break;
}
if (lexer.token() == Token.FOR) {
lexer.nextToken();
acceptIdentifier("QUERY");
stmt.setForQuery(this.exprParser.primary());
}
stmt.setLimit(this.exprParser.parseLimit());
return stmt;
}
if (identifierEquals("RELAYLOG")) {
lexer.nextToken();
acceptIdentifier(EVENTS);
MySqlShowRelayLogEventsStatement stmt = new MySqlShowRelayLogEventsStatement();
if (lexer.token() == Token.IN) {
lexer.nextToken();
stmt.setLogName(this.exprParser.primary());
}
if (lexer.token() == Token.FROM) {
lexer.nextToken();
stmt.setFrom(this.exprParser.primary());
}
stmt.setLimit(this.exprParser.parseLimit());
return stmt;
}
if (identifierEquals("RELAYLOG")) {
lexer.nextToken();
acceptIdentifier(EVENTS);
MySqlShowRelayLogEventsStatement stmt = new MySqlShowRelayLogEventsStatement();
if (lexer.token() == Token.IN) {
lexer.nextToken();
stmt.setLogName(this.exprParser.primary());
}
if (lexer.token() == Token.FROM) {
lexer.nextToken();
stmt.setFrom(this.exprParser.primary());
}
stmt.setLimit(this.exprParser.parseLimit());
return stmt;
}
if (identifierEquals("SLAVE")) {
lexer.nextToken();
if (identifierEquals(STATUS)) {
lexer.nextToken();
return new MySqlShowSlaveStatusStatement();
} else {
acceptIdentifier("HOSTS");
MySqlShowSlaveHostsStatement stmt = new MySqlShowSlaveHostsStatement();
return stmt;
}
}
if (lexer.token() == Token.TABLE) {
lexer.nextToken();
acceptIdentifier(STATUS);
MySqlShowTableStatusStatement stmt = new MySqlShowTableStatusStatement();
if (lexer.token() == Token.FROM || lexer.token() == Token.IN) {
lexer.nextToken();
stmt.setDatabase(this.exprParser.name());
}
if (lexer.token() == Token.LIKE) {
lexer.nextToken();
stmt.setLike(this.exprParser.expr());
}
if (lexer.token() == Token.WHERE) {
lexer.nextToken();
stmt.setWhere(this.exprParser.expr());
}
return stmt;
}
if (identifierEquals("TRIGGERS")) {
lexer.nextToken();
MySqlShowTriggersStatement stmt = new MySqlShowTriggersStatement();
if (lexer.token() == Token.FROM) {
lexer.nextToken();
SQLName database = exprParser.name();
stmt.setDatabase(database);
}
if (lexer.token() == Token.LIKE) {
lexer.nextToken();
SQLExpr like = exprParser.expr();
stmt.setLike(like);
}
if (lexer.token() == Token.WHERE) {
lexer.nextToken();
SQLExpr where = exprParser.expr();
stmt.setWhere(where);
}
return stmt;
}
// MySqlShowSlaveHostsStatement
throw new ParserException("TODO " + lexer.stringVal());
}
private MySqlShowStatusStatement parseShowStatus() {
MySqlShowStatusStatement stmt = new MySqlShowStatusStatement();
if (lexer.token() == Token.LIKE) {
lexer.nextToken();
SQLExpr like = exprParser.expr();
stmt.setLike(like);
}
if (lexer.token() == Token.WHERE) {
lexer.nextToken();
SQLExpr where = exprParser.expr();
stmt.setWhere(where);
}
return stmt;
}
private MySqlShowVariantsStatement parseShowVariants() {
MySqlShowVariantsStatement stmt = new MySqlShowVariantsStatement();
if (lexer.token() == Token.LIKE) {
lexer.nextToken();
SQLExpr like = exprParser.expr();
stmt.setLike(like);
}
if (lexer.token() == Token.WHERE) {
lexer.nextToken();
SQLExpr where = exprParser.expr();
stmt.setWhere(where);
}
return stmt;
}
private MySqlShowWarningsStatement parseShowWarnings() {
MySqlShowWarningsStatement stmt = new MySqlShowWarningsStatement();
stmt.setLimit(this.exprParser.parseLimit());
return stmt;
}
private MySqlShowDatabasesStatement parseShowDatabases() {
MySqlShowDatabasesStatement stmt = new MySqlShowDatabasesStatement();
if (lexer.token() == Token.LIKE) {
lexer.nextToken();
SQLExpr like = exprParser.expr();
stmt.setLike(like);
}
if (lexer.token() == Token.WHERE) {
lexer.nextToken();
SQLExpr where = exprParser.expr();
stmt.setWhere(where);
}
return stmt;
}
private SQLShowTablesStatement parseShowTabless() {
SQLShowTablesStatement stmt = new SQLShowTablesStatement();
if (lexer.token() == Token.FROM) {
lexer.nextToken();
SQLName database = exprParser.name();
stmt.setDatabase(database);
}
if (lexer.token() == Token.LIKE) {
lexer.nextToken();
SQLExpr like = exprParser.expr();
stmt.setLike(like);
}
if (lexer.token() == Token.WHERE) {
lexer.nextToken();
SQLExpr where = exprParser.expr();
stmt.setWhere(where);
}
return stmt;
}
private MySqlShowColumnsStatement parseShowColumns() {
MySqlShowColumnsStatement stmt = new MySqlShowColumnsStatement();
if (lexer.token() == Token.FROM) {
lexer.nextToken();
SQLName table = exprParser.name();
stmt.setTable(table);
if (lexer.token() == Token.FROM || lexer.token() == Token.IN) {
lexer.nextToken();
SQLName database = exprParser.name();
stmt.setDatabase(database);
}
}
if (lexer.token() == Token.LIKE) {
lexer.nextToken();
SQLExpr like = exprParser.expr();
stmt.setLike(like);
}
if (lexer.token() == Token.WHERE) {
lexer.nextToken();
SQLExpr where = exprParser.expr();
stmt.setWhere(where);
}
return stmt;
}
public SQLStartTransactionStatement parseStart() {
acceptIdentifier("START");
acceptIdentifier("TRANSACTION");
SQLStartTransactionStatement stmt = new SQLStartTransactionStatement();
if (lexer.token() == Token.WITH) {
lexer.nextToken();
acceptIdentifier("CONSISTENT");
acceptIdentifier("SNAPSHOT");
stmt.setConsistentSnapshot(true);
}
if (lexer.token() == Token.BEGIN) {
lexer.nextToken();
stmt.setBegin(true);
if (identifierEquals("WORK")) {
lexer.nextToken();
stmt.setWork(true);
}
}
if (lexer.token() == Token.HINT) {
stmt.setHints(this.exprParser.parseHints());
}
return stmt;
}
@Override
public MySqlRollbackStatement parseRollback() {
acceptIdentifier("ROLLBACK");
MySqlRollbackStatement stmt = new MySqlRollbackStatement();
if (identifierEquals("WORK")) {
lexer.nextToken();
}
if (lexer.token() == Token.AND) {
lexer.nextToken();
if (lexer.token() == Token.NOT) {
lexer.nextToken();
acceptIdentifier(CHAIN);
stmt.setChain(Boolean.FALSE);
} else {
acceptIdentifier(CHAIN);
stmt.setChain(Boolean.TRUE);
}
}
if (lexer.token() == Token.TO) {
lexer.nextToken();
if (identifierEquals("SAVEPOINT")) {
lexer.nextToken();
}
stmt.setTo(this.exprParser.name());
}
return stmt;
}
public MySqlCommitStatement parseCommit() {
acceptIdentifier("COMMIT");
MySqlCommitStatement stmt = new MySqlCommitStatement();
if (identifierEquals("WORK")) {
lexer.nextToken();
stmt.setWork(true);
}
if (lexer.token() == Token.AND) {
lexer.nextToken();
if (lexer.token() == Token.NOT) {
lexer.nextToken();
acceptIdentifier(CHAIN);
stmt.setChain(Boolean.FALSE);
} else {
acceptIdentifier(CHAIN);
stmt.setChain(Boolean.TRUE);
}
}
return stmt;
}
public MySqlReplaceStatement parseReplicate() {
MySqlReplaceStatement stmt = new MySqlReplaceStatement();
accept(Token.REPLACE);
if (lexer.token() == Token.COMMENT) {
lexer.nextToken();
}
if (identifierEquals(LOW_PRIORITY)) {
stmt.setLowPriority(true);
lexer.nextToken();
}
if (identifierEquals(DELAYED)) {
stmt.setDelayed(true);
lexer.nextToken();
}
if (lexer.token() == Token.INTO) {
lexer.nextToken();
}
SQLName tableName = exprParser.name();
stmt.setTableName(tableName);
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
if (lexer.token() == Token.SELECT) {
SQLQueryExpr queryExpr = (SQLQueryExpr) this.exprParser.expr();
stmt.setQuery(queryExpr);
} else {
this.exprParser.exprList(stmt.getColumns(), stmt);
}
accept(Token.RPAREN);
}
if (lexer.token() == Token.VALUES || identifierEquals("VALUE")) {
lexer.nextToken();
parseValueClause(stmt.getValuesList(), 0);
} else if (lexer.token() == Token.SELECT) {
SQLQueryExpr queryExpr = (SQLQueryExpr) this.exprParser.expr();
stmt.setQuery(queryExpr);
} else if (lexer.token() == Token.SET) {
lexer.nextToken();
SQLInsertStatement.ValuesClause values = new SQLInsertStatement.ValuesClause();
stmt.getValuesList().add(values);
for (; ; ) {
stmt.addColumn(this.exprParser.name());
if (lexer.token() == Token.COLONEQ) {
lexer.nextToken();
} else {
accept(Token.EQ);
}
values.addValue(this.exprParser.expr());
if (lexer.token() == (Token.COMMA)) {
lexer.nextToken();
continue;
}
break;
}
} else if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
SQLQueryExpr queryExpr = (SQLQueryExpr) this.exprParser.expr();
stmt.setQuery(queryExpr);
accept(Token.RPAREN);
}
return stmt;
}
protected SQLStatement parseLoad() {
acceptIdentifier("LOAD");
if (identifierEquals("DATA")) {
SQLStatement stmt = parseLoadDataInFile();
return stmt;
}
if (identifierEquals("XML")) {
SQLStatement stmt = parseLoadXml();
return stmt;
}
throw new ParserException("TODO");
}
protected MySqlLoadXmlStatement parseLoadXml() {
acceptIdentifier("XML");
MySqlLoadXmlStatement stmt = new MySqlLoadXmlStatement();
if (identifierEquals(LOW_PRIORITY)) {
stmt.setLowPriority(true);
lexer.nextToken();
}
if (identifierEquals("CONCURRENT")) {
stmt.setConcurrent(true);
lexer.nextToken();
}
if (identifierEquals(LOCAL)) {
stmt.setLocal(true);
lexer.nextToken();
}
acceptIdentifier("INFILE");
SQLLiteralExpr fileName = (SQLLiteralExpr) exprParser.expr();
stmt.setFileName(fileName);
if (lexer.token() == Token.REPLACE) {
stmt.setReplicate(true);
lexer.nextToken();
}
if (identifierEquals(IGNORE)) {
stmt.setIgnore(true);
lexer.nextToken();
}
accept(Token.INTO);
accept(Token.TABLE);
SQLName tableName = exprParser.name();
stmt.setTableName(tableName);
if (identifierEquals(CHARACTER)) {
lexer.nextToken();
accept(Token.SET);
if (lexer.token() != Token.LITERAL_CHARS) {
throw new ParserException("syntax error, illegal charset");
}
String charset = lexer.stringVal();
lexer.nextToken();
stmt.setCharset(charset);
}
if (identifierEquals("ROWS")) {
lexer.nextToken();
accept(Token.IDENTIFIED);
accept(Token.BY);
SQLExpr rowsIdentifiedBy = exprParser.expr();
stmt.setRowsIdentifiedBy(rowsIdentifiedBy);
}
if (identifierEquals(IGNORE)) {
throw new ParserException("TODO");
}
if (lexer.token() == Token.SET) {
throw new ParserException("TODO");
}
return stmt;
}
protected MySqlLoadDataInFileStatement parseLoadDataInFile() {
acceptIdentifier("DATA");
MySqlLoadDataInFileStatement stmt = new MySqlLoadDataInFileStatement();
if (identifierEquals(LOW_PRIORITY)) {
stmt.setLowPriority(true);
lexer.nextToken();
}
if (identifierEquals("CONCURRENT")) {
stmt.setConcurrent(true);
lexer.nextToken();
}
if (identifierEquals(LOCAL)) {
stmt.setLocal(true);
lexer.nextToken();
}
acceptIdentifier("INFILE");
SQLLiteralExpr fileName = (SQLLiteralExpr) exprParser.expr();
stmt.setFileName(fileName);
if (lexer.token() == Token.REPLACE) {
stmt.setReplicate(true);
lexer.nextToken();
}
if (identifierEquals(IGNORE)) {
stmt.setIgnore(true);
lexer.nextToken();
}
accept(Token.INTO);
accept(Token.TABLE);
SQLName tableName = exprParser.name();
stmt.setTableName(tableName);
if (identifierEquals(CHARACTER)) {
lexer.nextToken();
accept(Token.SET);
if (lexer.token() != Token.LITERAL_CHARS) {
throw new ParserException("syntax error, illegal charset");
}
String charset = lexer.stringVal();
lexer.nextToken();
stmt.setCharset(charset);
}
if (identifierEquals("FIELDS") || identifierEquals("COLUMNS")) {
lexer.nextToken();
if (identifierEquals("TERMINATED")) {
lexer.nextToken();
accept(Token.BY);
stmt.setColumnsTerminatedBy(new SQLCharExpr(lexer.stringVal()));
lexer.nextToken();
}
if (identifierEquals("OPTIONALLY")) {
stmt.setColumnsEnclosedOptionally(true);
lexer.nextToken();
}
if (identifierEquals("ENCLOSED")) {
lexer.nextToken();
accept(Token.BY);
stmt.setColumnsEnclosedBy(new SQLCharExpr(lexer.stringVal()));
lexer.nextToken();
}
if (identifierEquals("ESCAPED")) {
lexer.nextToken();
accept(Token.BY);
stmt.setColumnsEscaped(new SQLCharExpr(lexer.stringVal()));
lexer.nextToken();
}
}
if (identifierEquals("LINES")) {
lexer.nextToken();
if (identifierEquals("STARTING")) {
lexer.nextToken();
accept(Token.BY);
stmt.setLinesStartingBy(new SQLCharExpr(lexer.stringVal()));
lexer.nextToken();
}
if (identifierEquals("TERMINATED")) {
lexer.nextToken();
accept(Token.BY);
stmt.setLinesTerminatedBy(new SQLCharExpr(lexer.stringVal()));
lexer.nextToken();
}
}
if (identifierEquals(IGNORE)) {
lexer.nextToken();
stmt.setIgnoreLinesNumber(this.exprParser.expr());
acceptIdentifier("LINES");
}
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
this.exprParser.exprList(stmt.getColumns(), stmt);
accept(Token.RPAREN);
}
if (lexer.token() == Token.SET) {
lexer.nextToken();
this.exprParser.exprList(stmt.getSetList(), stmt);
}
return stmt;
}
public MySqlPrepareStatement parsePrepare() {
acceptIdentifier("PREPARE");
SQLName name = exprParser.name();
accept(Token.FROM);
SQLExpr from = exprParser.expr();
return new MySqlPrepareStatement(name, from);
}
public MySqlExecuteStatement parseExecute() {
acceptIdentifier("EXECUTE");
MySqlExecuteStatement stmt = new MySqlExecuteStatement();
SQLName statementName = exprParser.name();
stmt.setStatementName(statementName);
if (identifierEquals("USING")) {
lexer.nextToken();
exprParser.exprList(stmt.getParameters(), stmt);
}
return stmt;
}
public MysqlDeallocatePrepareStatement parseDeallocatePrepare() {
acceptIdentifier("DEALLOCATE");
acceptIdentifier("PREPARE");
MysqlDeallocatePrepareStatement stmt = new MysqlDeallocatePrepareStatement();
SQLName statementName = exprParser.name();
stmt.setStatementName(statementName);
return stmt;
}
public SQLInsertStatement parseInsert() {
MySqlInsertStatement insertStatement = new MySqlInsertStatement();
if (lexer.token() == Token.INSERT) {
lexer.nextToken();
for (; ; ) {
if (identifierEquals(LOW_PRIORITY)) {
insertStatement.setLowPriority(true);
lexer.nextToken();
continue;
}
if (identifierEquals(DELAYED)) {
insertStatement.setDelayed(true);
lexer.nextToken();
continue;
}
if (identifierEquals("HIGH_PRIORITY")) {
insertStatement.setHighPriority(true);
lexer.nextToken();
continue;
}
if (identifierEquals(IGNORE)) {
insertStatement.setIgnore(true);
lexer.nextToken();
continue;
}
if (identifierEquals("ROLLBACK_ON_FAIL")) {
insertStatement.setRollbackOnFail(true);
lexer.nextToken();
continue;
}
break;
}
if (lexer.token() == Token.INTO) {
lexer.nextToken();
}
SQLName tableName = this.exprParser.name();
insertStatement.setTableName(tableName);
if (lexer.token() == Token.IDENTIFIER && !identifierEquals("VALUE")) {
insertStatement.setAlias(lexer.stringVal());
lexer.nextToken();
}
}
int columnSize = 0;
if (lexer.token() == (Token.LPAREN)) {
lexer.nextToken();
if (lexer.token() == (Token.SELECT)) {
SQLSelect select = this.exprParser.createSelectParser().select();
select.setParent(insertStatement);
insertStatement.setQuery(select);
} else {
this.exprParser.exprList(insertStatement.getColumns(), insertStatement);
columnSize = insertStatement.getColumns().size();
}
accept(Token.RPAREN);
}
if (lexer.token() == Token.VALUES || identifierEquals("VALUE")) {
lexer.nextTokenLParen();
parseValueClause(insertStatement.getValuesList(), columnSize);
} else if (lexer.token() == Token.SET) {
lexer.nextToken();
SQLInsertStatement.ValuesClause values = new SQLInsertStatement.ValuesClause();
insertStatement.getValuesList().add(values);
for (; ; ) {
SQLName name = this.exprParser.name();
insertStatement.addColumn(name);
if (lexer.token() == Token.EQ) {
lexer.nextToken();
} else {
accept(Token.COLONEQ);
}
values.addValue(this.exprParser.expr());
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
break;
}
} else if (lexer.token() == (Token.SELECT)) {
SQLSelect select = this.exprParser.createSelectParser().select();
select.setParent(insertStatement);
insertStatement.setQuery(select);
} else if (lexer.token() == (Token.LPAREN)) {
lexer.nextToken();
SQLSelect select = this.exprParser.createSelectParser().select();
select.setParent(insertStatement);
insertStatement.setQuery(select);
accept(Token.RPAREN);
}
if (lexer.token() == Token.ON) {
lexer.nextToken();
acceptIdentifier("DUPLICATE");
accept(Token.KEY);
accept(Token.UPDATE);
exprParser.exprList(insertStatement.getDuplicateKeyUpdate(), insertStatement);
}
return insertStatement;
}
private void parseValueClause(List valueClauseList, int columnSize) {
for (int i = 0; ; ++i) {
if (lexer.token() != Token.LPAREN) {
throw new ParserException("syntax error, expect ')'");
}
lexer.nextTokenValue();
if (lexer.token() != Token.RPAREN) {
List valueExprList;
if (columnSize > 0) {
valueExprList = new ArrayList(columnSize);
} else {
valueExprList = new ArrayList();
}
for (; ; ) {
SQLExpr expr;
if (lexer.token() == Token.LITERAL_INT) {
expr = new SQLIntegerExpr(lexer.integerValue());
lexer.nextTokenComma();
} else if (lexer.token() == Token.LITERAL_CHARS) {
expr = new SQLCharExpr(lexer.stringVal());
lexer.nextTokenComma();
} else if (lexer.token() == Token.LITERAL_NCHARS) {
expr = new SQLNCharExpr(lexer.stringVal());
lexer.nextTokenComma();
} else {
expr = exprParser.expr();
}
if (lexer.token() == Token.COMMA) {
valueExprList.add(expr);
lexer.nextTokenValue();
continue;
} else if (lexer.token() == Token.RPAREN) {
valueExprList.add(expr);
break;
} else {
expr = this.exprParser.primaryRest(expr);
if (lexer.token() != Token.COMMA && lexer.token() != Token.RPAREN) {
expr = this.exprParser.exprRest(expr);
}
valueExprList.add(expr);
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
} else {
break;
}
}
}
SQLInsertStatement.ValuesClause values = new SQLInsertStatement.ValuesClause(valueExprList);
valueClauseList.add(values);
} else {
SQLInsertStatement.ValuesClause values = new SQLInsertStatement.ValuesClause(
new ArrayList(0));
valueClauseList.add(values);
}
if (lexer.token() != Token.RPAREN) {
throw new ParserException("syntax error");
}
if (!parseCompleteValues && valueClauseList.size() >= parseValuesSize) {
lexer.skipToEOF();
break;
}
lexer.nextTokenComma();
if (lexer.token() == Token.COMMA) {
lexer.nextTokenLParen();
continue;
} else {
break;
}
}
}
public SQLSelectParser createSQLSelectParser() {
return new MySqlSelectParser(this.exprParser);
}
public SQLStatement parseSet() {
accept(Token.SET);
if (identifierEquals("PASSWORD")) {
lexer.nextToken();
MySqlSetPasswordStatement stmt = new MySqlSetPasswordStatement();
if (lexer.token() == Token.FOR) {
lexer.nextToken();
stmt.setUser(this.exprParser.name());
}
accept(Token.EQ);
stmt.setPassword(this.exprParser.expr());
return stmt;
}
Boolean global = null;
if (identifierEquals(GLOBAL)) {
global = Boolean.TRUE;
lexer.nextToken();
} else if (identifierEquals(SESSION)) {
global = Boolean.FALSE;
lexer.nextToken();
}
if (identifierEquals("TRANSACTION")) {
MySqlSetTransactionStatement stmt = new MySqlSetTransactionStatement();
stmt.setGlobal(global);
lexer.nextToken();
if (identifierEquals("ISOLATION")) {
lexer.nextToken();
acceptIdentifier("LEVEL");
if (identifierEquals(READ)) {
lexer.nextToken();
if (identifierEquals("UNCOMMITTED")) {
stmt.setIsolationLevel("READ UNCOMMITTED");
lexer.nextToken();
} else if (identifierEquals(WRITE)) {
stmt.setIsolationLevel("READ WRITE");
lexer.nextToken();
} else if (identifierEquals("ONLY")) {
stmt.setIsolationLevel("READ ONLY");
lexer.nextToken();
} else if (identifierEquals("COMMITTED")) {
stmt.setIsolationLevel("READ COMMITTED");
lexer.nextToken();
} else {
throw new ParserException("UNKOWN TRANSACTION LEVEL : " + lexer.stringVal());
}
} else if (identifierEquals("SERIALIZABLE")) {
stmt.setIsolationLevel("SERIALIZABLE");
lexer.nextToken();
} else if (identifierEquals("REPEATABLE")) {
lexer.nextToken();
if (identifierEquals(READ)) {
stmt.setIsolationLevel("REPEATABLE READ");
lexer.nextToken();
} else {
throw new ParserException("UNKOWN TRANSACTION LEVEL : " + lexer.stringVal());
}
} else {
throw new ParserException("UNKOWN TRANSACTION LEVEL : " + lexer.stringVal());
}
} else if (identifierEquals(READ)) {
lexer.nextToken();
if (identifierEquals("ONLY")) {
stmt.setAccessModel("ONLY");
lexer.nextToken();
} else if (identifierEquals("WRITE")) {
stmt.setAccessModel("WRITE");
lexer.nextToken();
} else {
throw new ParserException("UNKOWN ACCESS MODEL : " + lexer.stringVal());
}
}
return stmt;
} else if (identifierEquals("NAMES")) {
lexer.nextToken();
MySqlSetNamesStatement stmt = new MySqlSetNamesStatement();
if (lexer.token() == Token.DEFAULT) {
lexer.nextToken();
stmt.setDefault(true);
} else {
String charSet = lexer.stringVal();
stmt.setCharSet(charSet);
lexer.nextToken();
if (identifierEquals(COLLATE2)) {
lexer.nextToken();
String collate = lexer.stringVal();
stmt.setCollate(collate);
lexer.nextToken();
}
}
return stmt;
} else if (identifierEquals(CHARACTER)) {
lexer.nextToken();
accept(Token.SET);
MySqlSetCharSetStatement stmt = new MySqlSetCharSetStatement();
if (lexer.token() == Token.DEFAULT) {
lexer.nextToken();
stmt.setDefault(true);
} else {
String charSet = lexer.stringVal();
stmt.setCharSet(charSet);
lexer.nextToken();
if (identifierEquals(COLLATE2)) {
lexer.nextToken();
String collate = lexer.stringVal();
stmt.setCollate(collate);
lexer.nextToken();
}
}
return stmt;
} else {
SQLSetStatement stmt = new SQLSetStatement(getDbType());
parseAssignItems(stmt.getItems(), stmt);
if (global != null && global.booleanValue()) {
SQLVariantRefExpr varRef = (SQLVariantRefExpr) stmt.getItems().get(0).getTarget();
varRef.setGlobal(true);
}
if (lexer.token() == Token.HINT) {
stmt.setHints(this.exprParser.parseHints());
}
return stmt;
}
}
public SQLStatement parseAlter() {
accept(Token.ALTER);
if (lexer.token() == Token.USER) {
return parseAlterUser();
}
boolean ignore = false;
if (identifierEquals(IGNORE)) {
ignore = true;
lexer.nextToken();
}
if (lexer.token() == Token.TABLE) {
return parseAlterTable(ignore);
}
if (lexer.token() == Token.DATABASE) {
return parseAlterDatabase();
}
throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal());
}
protected SQLStatement parseAlterTable(boolean ignore) {
lexer.nextToken();
SQLAlterTableStatement stmt = new SQLAlterTableStatement(getDbType());
stmt.setIgnore(ignore);
stmt.setName(this.exprParser.name());
for (; ; ) {
if (lexer.token() == Token.DROP) {
parseAlterDrop(stmt);
} else if (lexer.token() == Token.TRUNCATE) {
lexer.nextToken();
accept(Token.PARTITION);
SQLAlterTableTruncatePartition item = new SQLAlterTableTruncatePartition();
if (lexer.token() == Token.ALL) {
item.getPartitions().add(new SQLIdentifierExpr("ALL"));
lexer.nextToken();
} else {
this.exprParser.names(item.getPartitions(), item);
}
stmt.addItem(item);
} else if (identifierEquals("ADD")) {
lexer.nextToken();
if (lexer.token() == Token.COLUMN) {
lexer.nextToken();
parseAlterTableAddColumn(stmt);
} else if (lexer.token() == Token.INDEX) {
SQLAlterTableAddIndex item = parseAlterTableAddIndex();
item.setParent(stmt);
stmt.addItem(item);
} else if (lexer.token() == Token.UNIQUE) {
SQLAlterTableAddIndex item = parseAlterTableAddIndex();
item.setParent(stmt);
stmt.addItem(item);
} else if (lexer.token() == Token.PRIMARY) {
SQLPrimaryKey primaryKey = this.exprParser.parsePrimaryKey();
SQLAlterTableAddConstraint item = new SQLAlterTableAddConstraint(primaryKey);
stmt.addItem(item);
} else if (lexer.token() == Token.KEY) {
// throw new ParserException("TODO " + lexer.token() +
// " " + lexer.stringVal());
SQLAlterTableAddIndex item = parseAlterTableAddIndex();
item.setParent(stmt);
stmt.addItem(item);
} else if (lexer.token() == Token.CONSTRAINT) {
lexer.nextToken();
SQLName constraintName = this.exprParser.name();
if (lexer.token() == Token.PRIMARY) {
SQLPrimaryKey primaryKey = ((MySqlExprParser) this.exprParser).parsePrimaryKey();
primaryKey.setName(constraintName);
SQLAlterTableAddConstraint item = new SQLAlterTableAddConstraint(primaryKey);
item.setParent(stmt);
stmt.addItem(item);
} else if (lexer.token() == Token.FOREIGN) {
MysqlForeignKey fk = this.getExprParser().parseForeignKey();
fk.setName(constraintName);
fk.setHasConstraint(true);
SQLAlterTableAddConstraint item = new SQLAlterTableAddConstraint(fk);
stmt.addItem(item);
} else if (lexer.token() == Token.UNIQUE) {
SQLUnique unique = this.exprParser.parseUnique();
SQLAlterTableAddConstraint item = new SQLAlterTableAddConstraint(unique);
stmt.addItem(item);
} else {
throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal());
}
} else if (lexer.token() == Token.PARTITION) {
lexer.nextToken();
SQLAlterTableAddPartition item = new SQLAlterTableAddPartition();
if (identifierEquals("PARTITIONS")) {
lexer.nextToken();
item.setPartitionCount(this.exprParser.integerExpr());
}
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
SQLPartition partition = this.getExprParser().parsePartition();
accept(Token.RPAREN);
item.addPartition(partition);
}
stmt.addItem(item);
} else if (identifierEquals(FULLTEXT)) {
throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal());
} else if (identifierEquals(SPATIAL)) {
throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal());
} else {
parseAlterTableAddColumn(stmt);
}
} else if (lexer.token() == Token.ALTER) {
lexer.nextToken();
if (lexer.token() == Token.COLUMN) {
lexer.nextToken();
}
MySqlAlterTableAlterColumn alterColumn = new MySqlAlterTableAlterColumn();
alterColumn.setColumn(this.exprParser.name());
if (lexer.token() == Token.SET) {
lexer.nextToken();
accept(Token.DEFAULT);
alterColumn.setDefaultExpr(this.exprParser.expr());
} else {
accept(Token.DROP);
accept(Token.DEFAULT);
alterColumn.setDropDefault(true);
}
stmt.addItem(alterColumn);
} else if (identifierEquals("CHANGE")) {
lexer.nextToken();
if (lexer.token() == Token.COLUMN) {
lexer.nextToken();
}
MySqlAlterTableChangeColumn item = new MySqlAlterTableChangeColumn();
item.setColumnName(this.exprParser.name());
item.setNewColumnDefinition(this.exprParser.parseColumn());
if (identifierEquals("AFTER")) {
lexer.nextToken();
item.setAfterColumn(this.exprParser.name());
} else if (identifierEquals("FIRST")) {
lexer.nextToken();
if (lexer.token() == Token.IDENTIFIER) {
item.setFirstColumn(this.exprParser.name());
} else {
item.setFirst(true);
}
}
stmt.addItem(item);
} else if (identifierEquals("MODIFY")) {
lexer.nextToken();
if (lexer.token() == Token.COLUMN) {
lexer.nextToken();
}
boolean paren = false;
if (lexer.token() == Token.LPAREN) {
paren = true;
lexer.nextToken();
}
for (; ; ) {
MySqlAlterTableModifyColumn item = new MySqlAlterTableModifyColumn();
item.setNewColumnDefinition(this.exprParser.parseColumn());
if (identifierEquals("AFTER")) {
lexer.nextToken();
item.setAfterColumn(this.exprParser.name());
} else if (identifierEquals("FIRST")) {
lexer.nextToken();
if (lexer.token() == Token.IDENTIFIER) {
item.setFirstColumn(this.exprParser.name());
} else {
item.setFirst(true);
}
}
stmt.addItem(item);
if (paren && lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
break;
}
if (paren) {
accept(Token.RPAREN);
}
} else if (lexer.token() == Token.DISABLE) {
lexer.nextToken();
if (lexer.token() == Token.CONSTRAINT) {
lexer.nextToken();
SQLAlterTableDisableConstraint item = new SQLAlterTableDisableConstraint();
item.setConstraintName(this.exprParser.name());
stmt.addItem(item);
} else {
acceptIdentifier("KEYS");
SQLAlterTableDisableKeys item = new SQLAlterTableDisableKeys();
stmt.addItem(item);
}
} else if (lexer.token() == Token.ENABLE) {
lexer.nextToken();
if (lexer.token() == Token.CONSTRAINT) {
lexer.nextToken();
SQLAlterTableEnableConstraint item = new SQLAlterTableEnableConstraint();
item.setConstraintName(this.exprParser.name());
stmt.addItem(item);
} else {
acceptIdentifier("KEYS");
SQLAlterTableEnableKeys item = new SQLAlterTableEnableKeys();
stmt.addItem(item);
}
} else if (identifierEquals("RENAME")) {
lexer.nextToken();
if (lexer.token() == Token.TO || lexer.token() == Token.AS) {
lexer.nextToken();
}
MySqlRenameTableStatement renameStmt = new MySqlRenameTableStatement();
MySqlRenameTableStatement.Item item = new MySqlRenameTableStatement.Item();
item.setName(stmt.getTableSource().getExpr());
item.setTo(this.exprParser.name());
renameStmt.addItem(item);
return renameStmt;
} else if (lexer.token() == Token.ORDER) {
throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal());
} else if (identifierEquals("CONVERT")) {
lexer.nextToken();
accept(Token.TO);
acceptIdentifier("CHARACTER");
accept(Token.SET);
SQLAlterTableConvertCharSet item = new SQLAlterTableConvertCharSet();
SQLExpr charset = this.exprParser.primary();
item.setCharset(charset);
if (identifierEquals("COLLATE")) {
lexer.nextToken();
SQLExpr collate = this.exprParser.primary();
item.setCollate(collate);
}
stmt.addItem(item);
} else if (lexer.token() == Token.DEFAULT) {
throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal());
} else if (identifierEquals("DISCARD")) {
lexer.nextToken();
if (lexer.token() == Token.PARTITION) {
lexer.nextToken();
SQLAlterTableDiscardPartition item = new SQLAlterTableDiscardPartition();
if (lexer.token() == Token.ALL) {
lexer.nextToken();
item.getPartitions().add(new SQLIdentifierExpr("ALL"));
} else {
this.exprParser.names(item.getPartitions(), item);
}
stmt.addItem(item);
} else {
accept(Token.TABLESPACE);
MySqlAlterTableDiscardTablespace item = new MySqlAlterTableDiscardTablespace();
stmt.addItem(item);
}
} else if (lexer.token() == Token.CHECK) {
lexer.nextToken();
accept(Token.PARTITION);
SQLAlterTableCheckPartition item = new SQLAlterTableCheckPartition();
if (lexer.token() == Token.ALL) {
lexer.nextToken();
item.getPartitions().add(new SQLIdentifierExpr("ALL"));
} else {
this.exprParser.names(item.getPartitions(), item);
}
stmt.addItem(item);
} else if (identifierEquals("IMPORT")) {
lexer.nextToken();
if (lexer.token() == Token.PARTITION) {
lexer.nextToken();
SQLAlterTableImportPartition item = new SQLAlterTableImportPartition();
if (lexer.token() == Token.ALL) {
lexer.nextToken();
item.getPartitions().add(new SQLIdentifierExpr("ALL"));
} else {
this.exprParser.names(item.getPartitions(), item);
}
stmt.addItem(item);
} else {
accept(Token.TABLESPACE);
MySqlAlterTableImportTablespace item = new MySqlAlterTableImportTablespace();
stmt.addItem(item);
}
} else if (lexer.token() == Token.ANALYZE) {
lexer.nextToken();
accept(Token.PARTITION);
SQLAlterTableAnalyzePartition item = new SQLAlterTableAnalyzePartition();
if (lexer.token() == Token.ALL) {
lexer.nextToken();
item.getPartitions().add(new SQLIdentifierExpr("ALL"));
} else {
this.exprParser.names(item.getPartitions(), item);
}
stmt.addItem(item);
} else if (identifierEquals("FORCE")) {
throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal());
} else if (identifierEquals("COALESCE")) {
lexer.nextToken();
accept(Token.PARTITION);
SQLAlterTableCoalescePartition item = new SQLAlterTableCoalescePartition();
SQLIntegerExpr countExpr = this.exprParser.integerExpr();
item.setCount(countExpr);
stmt.addItem(item);
} else if (identifierEquals("REORGANIZE")) {
lexer.nextToken();
accept(Token.PARTITION);
SQLAlterTableReOrganizePartition item = new SQLAlterTableReOrganizePartition();
this.exprParser.names(item.getNames(), item);
accept(Token.INTO);
accept(Token.LPAREN);
for (; ; ) {
SQLPartition partition = this.getExprParser().parsePartition();
item.addPartition(partition);
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
} else {
break;
}
}
accept(Token.RPAREN);
stmt.addItem(item);
} else if (identifierEquals("EXCHANGE")) {
throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal());
} else if (lexer.token() == Token.OPTIMIZE) {
lexer.nextToken();
accept(Token.PARTITION);
SQLAlterTableOptimizePartition item = new SQLAlterTableOptimizePartition();
if (lexer.token() == Token.ALL) {
lexer.nextToken();
item.getPartitions().add(new SQLIdentifierExpr("ALL"));
} else {
this.exprParser.names(item.getPartitions(), item);
}
stmt.addItem(item);
} else if (identifierEquals("REBUILD")) {
lexer.nextToken();
accept(Token.PARTITION);
SQLAlterTableRebuildPartition item = new SQLAlterTableRebuildPartition();
if (lexer.token() == Token.ALL) {
lexer.nextToken();
item.getPartitions().add(new SQLIdentifierExpr("ALL"));
} else {
this.exprParser.names(item.getPartitions(), item);
}
stmt.addItem(item);
} else if (identifierEquals("REPAIR")) {
lexer.nextToken();
accept(Token.PARTITION);
SQLAlterTableRepairPartition item = new SQLAlterTableRepairPartition();
if (lexer.token() == Token.ALL) {
lexer.nextToken();
item.getPartitions().add(new SQLIdentifierExpr("ALL"));
} else {
this.exprParser.names(item.getPartitions(), item);
}
stmt.addItem(item);
} else if (identifierEquals("REMOVE")) {
lexer.nextToken();
acceptIdentifier("PARTITIONING");
stmt.setRemovePatiting(true);
} else if (identifierEquals("UPGRADE")) {
lexer.nextToken();
acceptIdentifier("PARTITIONING");
stmt.setUpgradePatiting(true);
} else if (identifierEquals("ALGORITHM")) {
lexer.nextToken();
accept(Token.EQ);
stmt.addItem(new MySqlAlterTableOption("ALGORITHM", lexer.stringVal()));
lexer.nextToken();
} else if (identifierEquals(ENGINE)) {
lexer.nextToken();
accept(Token.EQ);
stmt.addItem(new MySqlAlterTableOption(ENGINE, lexer.stringVal()));
lexer.nextToken();
} else if (identifierEquals(AUTO_INCREMENT)) {
lexer.nextToken();
accept(Token.EQ);
stmt.addItem(new MySqlAlterTableOption(AUTO_INCREMENT, lexer.integerValue()));
lexer.nextToken();
} else if (identifierEquals(COLLATE2)) {
lexer.nextToken();
accept(Token.EQ);
stmt.addItem(new MySqlAlterTableOption(COLLATE2, lexer.stringVal()));
lexer.nextToken();
} else if (identifierEquals("PACK_KEYS")) {
lexer.nextToken();
accept(Token.EQ);
if (identifierEquals("PACK")) {
lexer.nextToken();
accept(Token.ALL);
stmt.addItem(new MySqlAlterTableOption("PACK_KEYS", "PACK ALL"));
} else {
stmt.addItem(new MySqlAlterTableOption("PACK_KEYS", lexer.stringVal()));
lexer.nextToken();
}
} else if (identifierEquals(CHARACTER)) {
lexer.nextToken();
accept(Token.SET);
accept(Token.EQ);
MySqlAlterTableCharacter item = new MySqlAlterTableCharacter();
item.setCharacterSet(this.exprParser.primary());
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
acceptIdentifier(COLLATE2);
accept(Token.EQ);
item.setCollate(this.exprParser.primary());
}
stmt.addItem(item);
} else if (lexer.token() == Token.COMMENT) {
lexer.nextToken();
if (lexer.token() == Token.EQ) {
accept(Token.EQ);
}
stmt.addItem(new MySqlAlterTableOption("COMMENT", '\'' + lexer.stringVal() + '\''));
lexer.nextToken();
} else if (lexer.token() == Token.UNION) {
lexer.nextToken();
if (lexer.token() == Token.EQ) {
lexer.nextToken();
}
accept(Token.LPAREN);
SQLTableSource tableSrc = this.createSQLSelectParser().parseTableSource();
stmt.getTableOptions().put("UNION", tableSrc);
accept(Token.RPAREN);
} else if (identifierEquals("ROW_FORMAT")) {
lexer.nextToken();
if (lexer.token() == Token.EQ) {
lexer.nextToken();
}
if (lexer.token() == Token.DEFAULT || lexer.token() == Token.IDENTIFIER) {
SQLIdentifierExpr rowFormat = new SQLIdentifierExpr(lexer.stringVal());
lexer.nextToken();
stmt.getTableOptions().put("ROW_FORMAT", rowFormat);
} else {
throw new ParserException("illegal syntax.");
}
} else {
break;
}
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
} else {
break;
}
}
return stmt;
}
protected void parseAlterTableAddColumn(SQLAlterTableStatement stmt) {
boolean parenFlag = false;
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
parenFlag = true;
}
SQLAlterTableAddColumn item = new SQLAlterTableAddColumn();
for (; ; ) {
SQLColumnDefinition columnDef = this.exprParser.parseColumn();
item.addColumn(columnDef);
if (identifierEquals("AFTER")) {
lexer.nextToken();
item.setAfterColumn(this.exprParser.name());
} else if (identifierEquals("FIRST")) {
lexer.nextToken();
if (lexer.token() == Token.IDENTIFIER) {
item.setFirstColumn(this.exprParser.name());
} else {
item.setFirst(true);
}
}
if (parenFlag && lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
break;
}
stmt.addItem(item);
if (parenFlag) {
accept(Token.RPAREN);
}
}
public void parseAlterDrop(SQLAlterTableStatement stmt) {
lexer.nextToken();
if (lexer.token() == Token.INDEX) {
lexer.nextToken();
SQLName indexName = this.exprParser.name();
SQLAlterTableDropIndex item = new SQLAlterTableDropIndex();
item.setIndexName(indexName);
stmt.addItem(item);
} else if (lexer.token() == Token.FOREIGN) {
lexer.nextToken();
accept(Token.KEY);
SQLName indexName = this.exprParser.name();
SQLAlterTableDropForeignKey item = new SQLAlterTableDropForeignKey();
item.setIndexName(indexName);
stmt.addItem(item);
} else if (lexer.token() == Token.KEY) {
lexer.nextToken();
SQLName keyName = this.exprParser.name();
SQLAlterTableDropKey item = new SQLAlterTableDropKey();
item.setKeyName(keyName);
stmt.addItem(item);
} else if (lexer.token() == Token.PRIMARY) {
lexer.nextToken();
accept(Token.KEY);
SQLAlterTableDropPrimaryKey item = new SQLAlterTableDropPrimaryKey();
stmt.addItem(item);
} else if (lexer.token() == Token.CONSTRAINT) {
lexer.nextToken();
SQLAlterTableDropConstraint item = new SQLAlterTableDropConstraint();
item.setConstraintName(this.exprParser.name());
stmt.addItem(item);
} else if (lexer.token() == Token.COLUMN) {
lexer.nextToken();
SQLAlterTableDropColumnItem item = new SQLAlterTableDropColumnItem();
SQLName name = exprParser.name();
name.setParent(item);
item.addColumn(name);
while (lexer.token() == Token.COMMA) {
lexer.mark();
lexer.nextToken();
if (identifierEquals("CHANGE")) {
lexer.reset();
break;
}
if (lexer.token() == Token.IDENTIFIER) {
name = exprParser.name();
name.setParent(item);
} else {
lexer.reset();
break;
}
}
stmt.addItem(item);
} else if (lexer.token() == Token.PARTITION) {
SQLAlterTableDropPartition dropPartition = parseAlterTableDropPartition(false);
stmt.addItem(dropPartition);
} else if (lexer.token() == Token.IDENTIFIER) {
SQLAlterTableDropColumnItem item = new SQLAlterTableDropColumnItem();
this.exprParser.names(item.getColumns());
stmt.addItem(item);
} else {
super.parseAlterDrop(stmt);
}
}
public SQLStatement parseRename() {
MySqlRenameTableStatement stmt = new MySqlRenameTableStatement();
acceptIdentifier("RENAME");
accept(Token.TABLE);
for (; ; ) {
MySqlRenameTableStatement.Item item = new MySqlRenameTableStatement.Item();
item.setName(this.exprParser.name());
accept(Token.TO);
item.setTo(this.exprParser.name());
stmt.addItem(item);
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
break;
}
return stmt;
}
public SQLStatement parseCreateDatabase() {
if (lexer.token() == Token.CREATE) {
lexer.nextToken();
}
accept(Token.DATABASE);
SQLCreateDatabaseStatement stmt = new SQLCreateDatabaseStatement(JdbcConstants.MYSQL);
if (lexer.token() == Token.IF) {
lexer.nextToken();
accept(Token.NOT);
accept(Token.EXISTS);
stmt.setIfNotExists(true);
}
stmt.setName(this.exprParser.name());
if (lexer.token() == Token.DEFAULT) {
lexer.nextToken();
}
if (lexer.token() == Token.HINT) {
stmt.setHints(this.exprParser.parseHints());
}
if (lexer.token() == Token.DEFAULT) {
lexer.nextToken();
}
if (identifierEquals("CHARACTER")) {
lexer.nextToken();
accept(Token.SET);
String charset = lexer.stringVal();
accept(Token.IDENTIFIER);
stmt.setCharacterSet(charset);
} else if (identifierEquals("CHARSET")) {
lexer.nextToken();
if (lexer.token() == Token.EQ) {
lexer.nextToken();
}
String charset = lexer.stringVal();
accept(Token.IDENTIFIER);
stmt.setCharacterSet(charset);
}
if (lexer.token() == Token.DEFAULT) {
lexer.nextToken();
}
if (identifierEquals("COLLATE")) {
lexer.nextToken();
if (lexer.token() == Token.EQ) {
lexer.nextToken();
}
String collate = lexer.stringVal();
accept(Token.IDENTIFIER);
stmt.setCollate(collate);
}
return stmt;
}
protected void parseUpdateSet(SQLUpdateStatement update) {
accept(Token.SET);
for (; ; ) {
SQLUpdateSetItem item = this.exprParser.parseUpdateSetItem();
update.addItem(item);
if (lexer.token() != Token.COMMA) {
break;
}
lexer.nextToken();
}
}
public SQLStatement parseAlterDatabase() {
accept(Token.DATABASE);
SQLAlterDatabaseStatement stmt = new SQLAlterDatabaseStatement();
SQLName name = this.exprParser.name();
stmt.setName(name);
if (identifierEquals("UPGRADE")) {
lexer.nextToken();
acceptIdentifier("DATA");
acceptIdentifier("DIRECTORY");
acceptIdentifier("NAME");
stmt.setUpgradeDataDirectoryName(true);
}
return stmt;
}
public MySqlAlterUserStatement parseAlterUser() {
accept(Token.USER);
MySqlAlterUserStatement stmt = new MySqlAlterUserStatement();
for (; ; ) {
SQLExpr user = this.exprParser.expr();
acceptIdentifier("PASSWORD");
acceptIdentifier("EXPIRE");
stmt.addUser(user);
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
break;
}
return stmt;
}
public MySqlExprParser getExprParser() {
return (MySqlExprParser) exprParser;
}
/**
* parse create procedure statement
*/
public SQLCreateProcedureStatement parseCreateProcedure() {
/**
* CREATE OR REPALCE PROCEDURE SP_NAME(parameter_list) BEGIN block_statement END
*/
SQLCreateProcedureStatement stmt = new SQLCreateProcedureStatement();
if (identifierEquals("DEFINER")) {
lexer.nextToken();
accept(Token.EQ);
SQLName definer = this.exprParser.name();
stmt.setDefiner(definer);
} else {
accept(Token.CREATE);
if (lexer.token() == Token.OR) {
lexer.nextToken();
accept(Token.REPLACE);
stmt.setOrReplace(true);
}
}
accept(Token.PROCEDURE);
stmt.setName(this.exprParser.name());
if (lexer.token() == Token.LPAREN) {// match "("
lexer.nextToken();
parserParameters(stmt.getParameters());
accept(Token.RPAREN);// match ")"
}
SQLBlockStatement block = this.parseBlock();
stmt.setBlock(block);
return stmt;
}
/**
* parse create procedure parameters
*/
private void parserParameters(List parameters) {
if (lexer.token() == Token.RPAREN) {
return;
}
for (; ; ) {
SQLParameter parameter = new SQLParameter();
if (lexer.token() == Token.CURSOR) {
lexer.nextToken();
parameter.setName(this.exprParser.name());
accept(Token.IS);
SQLSelect select = this.createSQLSelectParser().select();
SQLDataTypeImpl dataType = new SQLDataTypeImpl();
dataType.setName("CURSOR");
parameter.setDataType(dataType);
parameter.setDefaultValue(new SQLQueryExpr(select));
} else if (lexer.token() == Token.IN || lexer.token() == Token.OUT
|| lexer.token() == Token.INOUT) {
if (lexer.token() == Token.IN) {
parameter.setParamType(ParameterType.IN);
} else if (lexer.token() == Token.OUT) {
parameter.setParamType(ParameterType.OUT);
} else if (lexer.token() == Token.INOUT) {
parameter.setParamType(ParameterType.INOUT);
}
lexer.nextToken();
parameter.setName(this.exprParser.name());
parameter.setDataType(this.exprParser.parseDataType());
} else {
parameter.setParamType(ParameterType.DEFAULT);// default parameter type is in
parameter.setName(this.exprParser.name());
parameter.setDataType(this.exprParser.parseDataType());
if (lexer.token() == Token.COLONEQ) {
lexer.nextToken();
parameter.setDefaultValue(this.exprParser.expr());
}
}
parameters.add(parameter);
if (lexer.token() == Token.COMMA || lexer.token() == Token.SEMI) {
lexer.nextToken();
}
if (lexer.token() != Token.BEGIN && lexer.token() != Token.RPAREN) {
continue;
}
break;
}
}
/**
* parse procedure statement block
*/
private void parseProcedureStatementList(List statementList) {
parseProcedureStatementList(statementList, -1);
}
/**
* parse procedure statement block
*/
private void parseProcedureStatementList(List statementList, int max) {
for (; ; ) {
if (max != -1) {
if (statementList.size() >= max) {
return;
}
}
if (lexer.token() == Token.EOF) {
return;
}
if (lexer.token() == Token.END) {
return;
}
if (lexer.token() == Token.ELSE) {
return;
}
if (lexer.token() == (Token.SEMI)) {
lexer.nextToken();
continue;
}
if (lexer.token() == Token.WHEN) {
return;
}
if (lexer.token() == Token.UNTIL) {
return;
}
// select into
if (lexer.token() == (Token.SELECT)) {
statementList.add(this.parseSelectInto());
continue;
}
// update
if (lexer.token() == (Token.UPDATE)) {
statementList.add(parseUpdateStatement());
continue;
}
// create
if (lexer.token() == (Token.CREATE)) {
statementList.add(parseCreate());
continue;
}
// insert
if (lexer.token() == Token.INSERT) {
statementList.add(parseInsert());
continue;
}
// delete
if (lexer.token() == (Token.DELETE)) {
statementList.add(parseDeleteStatement());
continue;
}
// call
if (lexer.token() == Token.LBRACE || identifierEquals("CALL")) {
statementList.add(this.parseCall());
continue;
}
// begin
if (lexer.token() == Token.BEGIN) {
statementList.add(this.parseBlock());
continue;
}
if (lexer.token() == Token.VARIANT) {
SQLExpr variant = this.exprParser.primary();
if (variant instanceof SQLBinaryOpExpr) {
SQLBinaryOpExpr binaryOpExpr = (SQLBinaryOpExpr) variant;
if (binaryOpExpr.getOperator() == SQLBinaryOperator.Assignment) {
SQLSetStatement stmt = new SQLSetStatement(binaryOpExpr.getLeft(),
binaryOpExpr.getRight(),
getDbType());
statementList.add(stmt);
continue;
}
}
accept(Token.COLONEQ);
SQLExpr value = this.exprParser.expr();
SQLSetStatement stmt = new SQLSetStatement(variant, value, getDbType());
statementList.add(stmt);
continue;
}
// select
if (lexer.token() == Token.LPAREN) {
char ch = lexer.current();
int bp = lexer.bp();
lexer.nextToken();
if (lexer.token() == Token.SELECT) {
lexer.reset(bp, ch, Token.LPAREN);
statementList.add(this.parseSelect());
continue;
} else {
throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal());
}
}
// assign statement
if (lexer.token() == Token.SET) {
statementList.add(this.parseAssign());
continue;
}
// while statement
if (lexer.token() == Token.WHILE) {
statementList.add(this.parseWhile());
continue;
}
// loop statement
if (lexer.token() == Token.LOOP) {
statementList.add(this.parseLoop());
continue;
}
// if statement
if (lexer.token() == Token.IF) {
statementList.add(this.parseIf());
continue;
}
// case statement
if (lexer.token() == Token.CASE) {
statementList.add(this.parseCase());
continue;
}
// declare statement
if (lexer.token() == Token.DECLARE) {
char markChar = lexer.current();
int markBp = lexer.bp();
lexer.nextToken();
lexer.nextToken();
if (lexer.token() == Token.CURSOR)// cursor declare statement
{
lexer.reset(markBp, markChar, Token.DECLARE);
statementList.add(this.parseCursorDeclare());
} else if (identifierEquals("HANDLER")) {
//DECLARE异常处理程序 [add by zhujun 2016-04-16]
lexer.reset(markBp, markChar, Token.DECLARE);
statementList.add(this.parseDeclareHandler());
} else if (lexer.token() == Token.CONDITION) {
//DECLARE异常 [add by zhujun 2016-04-17]
lexer.reset(markBp, markChar, Token.DECLARE);
statementList.add(this.parseDeclareCondition());
} else {
lexer.reset(markBp, markChar, Token.DECLARE);
statementList.add(this.parseDeclare());
}
continue;
}
// leave statement
if (lexer.token() == Token.LEAVE) {
statementList.add(this.parseLeave());
continue;
}
// iterate statement
if (lexer.token() == Token.ITERATE) {
statementList.add(this.parseIterate());
continue;
}
// repeat statement
if (lexer.token() == Token.REPEAT) {
statementList.add(this.parseRepeat());
continue;
}
// open cursor
if (lexer.token() == Token.OPEN) {
statementList.add(this.parseOpen());
continue;
}
// close cursor
if (lexer.token() == Token.CLOSE) {
statementList.add(this.parseClose());
continue;
}
// fetch cursor into
if (lexer.token() == Token.FETCH) {
statementList.add(this.parseFetch());
continue;
}
if (lexer.token() == Token.IDENTIFIER) {
String label = lexer.stringVal();
char ch = lexer.current();
int bp = lexer.bp();
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
statementList.add(this.parseBlock(label));
} else if (lexer.token() == Token.REPEAT) {
// parse repeat statement with label
statementList.add(this.parseRepeat(label));
}
continue;
} else {
lexer.reset(bp, ch, Token.IDENTIFIER);
}
}
throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal());
}
}
/**
* parse if statement
*
* @return MySqlIfStatement
*/
public SQLIfStatement parseIf() {
accept(Token.IF);
SQLIfStatement stmt = new SQLIfStatement();
stmt.setCondition(this.exprParser.expr());
accept(Token.THEN);
this.parseProcedureStatementList(stmt.getStatements());
while (lexer.token() == Token.ELSE) {
lexer.nextToken();
if (lexer.token() == Token.IF) {
lexer.nextToken();
SQLIfStatement.ElseIf elseIf = new SQLIfStatement.ElseIf();
elseIf.setCondition(this.exprParser.expr());
accept(Token.THEN);
this.parseProcedureStatementList(elseIf.getStatements());
stmt.getElseIfList().add(elseIf);
} else {
SQLIfStatement.Else elseItem = new SQLIfStatement.Else();
this.parseProcedureStatementList(elseItem.getStatements());
stmt.setElseItem(elseItem);
break;
}
}
accept(Token.END);
accept(Token.IF);
accept(Token.SEMI);
return stmt;
}
/**
* parse while statement
*
* @return MySqlWhileStatement
*/
public MySqlWhileStatement parseWhile() {
accept(Token.WHILE);
MySqlWhileStatement stmt = new MySqlWhileStatement();
stmt.setCondition(this.exprParser.expr());
accept(Token.DO);
this.parseProcedureStatementList(stmt.getStatements());
accept(Token.END);
accept(Token.WHILE);
accept(Token.SEMI);
return stmt;
}
/**
* parse while statement with label
*
* @return MySqlWhileStatement
*/
public MySqlWhileStatement parseWhile(String label) {
accept(Token.WHILE);
MySqlWhileStatement stmt = new MySqlWhileStatement();
stmt.setLabelName(label);
stmt.setCondition(this.exprParser.expr());
accept(Token.DO);
this.parseProcedureStatementList(stmt.getStatements());
accept(Token.END);
accept(Token.WHILE);
acceptIdentifier(label);
accept(Token.SEMI);
return stmt;
}
/**
* parse case statement
*
* @return MySqlCaseStatement
*/
public MySqlCaseStatement parseCase() {
MySqlCaseStatement stmt = new MySqlCaseStatement();
accept(Token.CASE);
if (lexer.token() == Token.WHEN)// grammar 1
{
while (lexer.token() == Token.WHEN) {
MySqlWhenStatement when = new MySqlWhenStatement();
// when expr
when.setCondition(exprParser.expr());
accept(Token.THEN);
// when block
parseProcedureStatementList(when.getStatements());
stmt.addWhenStatement(when);
}
if (lexer.token() == Token.ELSE) {
// parse else block
SQLIfStatement.Else elseStmt = new SQLIfStatement.Else();
parseProcedureStatementList(elseStmt.getStatements());
stmt.setElseItem(elseStmt);
}
} else// grammar 2
{
// case expr
stmt.setCondition(exprParser.expr());
while (lexer.token() == Token.WHEN) {
accept(Token.WHEN);
MySqlWhenStatement when = new MySqlWhenStatement();
// when expr
when.setCondition(exprParser.expr());
accept(Token.THEN);
// when block
parseProcedureStatementList(when.getStatements());
stmt.addWhenStatement(when);
}
if (lexer.token() == Token.ELSE) {
accept(Token.ELSE);
// else block
SQLIfStatement.Else elseStmt = new SQLIfStatement.Else();
parseProcedureStatementList(elseStmt.getStatements());
stmt.setElseItem(elseStmt);
}
}
accept(Token.END);
accept(Token.CASE);
accept(Token.SEMI);
return stmt;
}
/**
* parse declare statement
*/
public MySqlDeclareStatement parseDeclare() {
MySqlDeclareStatement stmt = new MySqlDeclareStatement();
accept(Token.DECLARE);
// lexer.nextToken();
for (; ; ) {
SQLDeclareItem item = new SQLDeclareItem();
item.setName(exprParser.name());
stmt.addVar(item);
if (lexer.token() == Token.COMMA) {
accept(Token.COMMA);
continue;
} else if (lexer.token() != Token.EOF) {
// var type
item.setDataType(exprParser.parseDataType());
if (lexer.token() == Token.DEFAULT) {
lexer.nextToken();
SQLExpr defaultValue = this.exprParser.primary();
item.setValue(defaultValue);
}
break;
} else {
throw new ParserException("TODO");
}
}
return stmt;
}
/**
* parse assign statement
*/
public SQLSetStatement parseAssign() {
accept(Token.SET);
SQLSetStatement stmt = new SQLSetStatement(getDbType());
parseAssignItems(stmt.getItems(), stmt);
return stmt;
}
/**
* parse select into
*/
public MySqlSelectIntoStatement parseSelectInto() {
MySqlSelectIntoParser parse = new MySqlSelectIntoParser(this.exprParser);
return parse.parseSelectInto();
}
/**
* parse loop statement
*/
public SQLLoopStatement parseLoop() {
SQLLoopStatement loopStmt = new SQLLoopStatement();
accept(Token.LOOP);
parseProcedureStatementList(loopStmt.getStatements());
accept(Token.END);
accept(Token.LOOP);
accept(Token.SEMI);
return loopStmt;
}
/**
* parse loop statement with label
*/
public SQLLoopStatement parseLoop(String label) {
SQLLoopStatement loopStmt = new SQLLoopStatement();
loopStmt.setLabelName(label);
accept(Token.LOOP);
parseProcedureStatementList(loopStmt.getStatements());
accept(Token.END);
accept(Token.LOOP);
acceptIdentifier(label);
accept(Token.SEMI);
return loopStmt;
}
/**
* parse loop statement with label
*/
public SQLBlockStatement parseBlock(String label) {
SQLBlockStatement block = new SQLBlockStatement();
block.setLabelName(label);
accept(Token.BEGIN);
parseProcedureStatementList(block.getStatementList());
accept(Token.END);
acceptIdentifier(label);
return block;
}
/**
* parse leave statement
*/
public MySqlLeaveStatement parseLeave() {
accept(Token.LEAVE);
MySqlLeaveStatement leaveStmt = new MySqlLeaveStatement();
leaveStmt.setLabelName(exprParser.name().getSimpleName());
accept(Token.SEMI);
return leaveStmt;
}
/**
* parse iterate statement
*/
public MySqlIterateStatement parseIterate() {
accept(Token.ITERATE);
MySqlIterateStatement iterateStmt = new MySqlIterateStatement();
iterateStmt.setLabelName(exprParser.name().getSimpleName());
accept(Token.SEMI);
return iterateStmt;
}
/**
* parse repeat statement
*/
public MySqlRepeatStatement parseRepeat() {
MySqlRepeatStatement repeatStmt = new MySqlRepeatStatement();
accept(Token.REPEAT);
parseProcedureStatementList(repeatStmt.getStatements());
accept(Token.UNTIL);
repeatStmt.setCondition(exprParser.expr());
accept(Token.END);
accept(Token.REPEAT);
accept(Token.SEMI);
return repeatStmt;
}
/**
* parse repeat statement with label
*/
public MySqlRepeatStatement parseRepeat(String label) {
MySqlRepeatStatement repeatStmt = new MySqlRepeatStatement();
repeatStmt.setLabelName(label);
accept(Token.REPEAT);
parseProcedureStatementList(repeatStmt.getStatements());
accept(Token.UNTIL);
repeatStmt.setCondition(exprParser.expr());
accept(Token.END);
accept(Token.REPEAT);
acceptIdentifier(label);
accept(Token.SEMI);
return repeatStmt;
}
/**
* parse cursor declare statement
*/
public MySqlCursorDeclareStatement parseCursorDeclare() {
MySqlCursorDeclareStatement stmt = new MySqlCursorDeclareStatement();
accept(Token.DECLARE);
stmt.setCursorName(exprParser.name().getSimpleName());
accept(Token.CURSOR);
accept(Token.FOR);
SQLSelectStatement selelctStmt = (SQLSelectStatement) parseSelect();
stmt.setSelect(selelctStmt);
accept(Token.SEMI);
return stmt;
}
/**
* zhujun [[email protected] ]
* parse spstatement
*/
public SQLStatement parseSpStatement() {
// update
if (lexer.token() == (Token.UPDATE)) {
return parseUpdateStatement();
}
// create
if (lexer.token() == (Token.CREATE)) {
return parseCreate();
}
// insert
if (lexer.token() == Token.INSERT) {
return parseInsert();
}
// delete
if (lexer.token() == (Token.DELETE)) {
return parseDeleteStatement();
}
// begin
if (lexer.token() == Token.BEGIN) {
return this.parseBlock();
}
// select
if (lexer.token() == Token.LPAREN) {
char ch = lexer.current();
int bp = lexer.bp();
lexer.nextToken();
if (lexer.token() == Token.SELECT) {
lexer.reset(bp, ch, Token.LPAREN);
return this.parseSelect();
} else {
throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal());
}
}
// assign statement
if (lexer.token() == Token.SET) {
return parseAssign();
}
throw new ParserException("error sp_statement");
}
/**
* 定义异常处理程序
*/
public MySqlDeclareHandlerStatement parseDeclareHandler() {
//DECLARE handler_type HANDLER FOR condition_value[,...] sp_statement
//handler_type 取值为 CONTINUE | EXIT | UNDO
//condition_value 取值为 SQLWARNING | NOT FOUND | SQLEXCEPTION | SQLSTATE value(异常码 e.g 1062)
MySqlDeclareHandlerStatement stmt = new MySqlDeclareHandlerStatement();
accept(Token.DECLARE);
//String handlerType = exprParser.name().getSimpleName();
if (lexer.token() == Token.CONTINUE) {
stmt.setHandleType(MySqlHandlerType.CONTINUE);
} else if (lexer.token() == Token.EXIT) {
stmt.setHandleType(MySqlHandlerType.CONTINUE);
} else if (lexer.token() == Token.UNDO) {
stmt.setHandleType(MySqlHandlerType.CONTINUE);
} else {
throw new ParserException("unkown handle type");
}
lexer.nextToken();
acceptIdentifier("HANDLER");
accept(Token.FOR);
for (; ; ) {
String tokenName = lexer.stringVal();
ConditionValue condition = new ConditionValue();
if (tokenName.equalsIgnoreCase("NOT")) {//for 'NOT FOUND'
lexer.nextToken();
acceptIdentifier("HANDLE");
condition.setType(ConditionType.SYSTEM);
condition.setValue("NOT FOUND");
} else if (tokenName.equalsIgnoreCase("SQLSTATE")) { //for SQLSTATE (SQLSTATE '10001')
condition.setType(ConditionType.SQLSTATE);
lexer.nextToken();
//condition.setValue(lexer.stringVal());
//lexer.nextToken();
condition.setValue(exprParser.name().toString());
} else if (identifierEquals("SQLEXCEPTION")) { //for SQLEXCEPTION
condition.setType(ConditionType.SYSTEM);
condition.setValue(lexer.stringVal());
lexer.nextToken();
} else if (identifierEquals("SQLWARNING")) { //for SQLWARNING
condition.setType(ConditionType.SYSTEM);
condition.setValue(lexer.stringVal());
lexer.nextToken();
} else { //for condition_name or mysql_error_code
if (lexer.token() == Token.LITERAL_INT) {
condition.setType(ConditionType.MYSQL_ERROR_CODE);
condition.setValue(lexer.integerValue().toString());
} else {
condition.setType(ConditionType.SELF);
condition.setValue(tokenName);
}
lexer.nextToken();
}
stmt.getConditionValues().add(condition);
if (lexer.token() == Token.COMMA) {
accept(Token.COMMA);
continue;
} else if (lexer.token() != Token.EOF) {
break;
} else {
throw new ParserException("declare handle not eof");
}
}
stmt.setSpStatement(parseSpStatement());
if (!(stmt.getSpStatement() instanceof SQLBlockStatement)) {
accept(Token.SEMI);
}
return stmt;
}
/**
* zhujun [[email protected] ]
* 2016-04-17
* 定义条件
*/
public MySqlDeclareConditionStatement parseDeclareCondition() {
/*
DECLARE condition_name CONDITION FOR condition_value
condition_value:
SQLSTATE [VALUE] sqlstate_value
| mysql_error_code
*/
MySqlDeclareConditionStatement stmt = new MySqlDeclareConditionStatement();
accept(Token.DECLARE);
stmt.setConditionName(exprParser.name().toString());
accept(Token.CONDITION);
accept(Token.FOR);
String tokenName = lexer.stringVal();
ConditionValue condition = new ConditionValue();
if (tokenName.equalsIgnoreCase("SQLSTATE")) { //for SQLSTATE (SQLSTATE '10001')
condition.setType(ConditionType.SQLSTATE);
lexer.nextToken();
condition.setValue(exprParser.name().toString());
} else if (lexer.token() == Token.LITERAL_INT) {
condition.setType(ConditionType.MYSQL_ERROR_CODE);
condition.setValue(lexer.integerValue().toString());
lexer.nextToken();
} else {
throw new ParserException("declare condition grammer error.");
}
stmt.setConditionValue(condition);
accept(Token.SEMI);
return stmt;
}
}