All Downloads are FREE. Search and download functionalities are using the official Maven repository.
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.parser.SQLStatementParser 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.parser;
import java.util.ArrayList;
import java.util.List;
import studio.raptor.sqlparser.ast.SQLExpr;
import studio.raptor.sqlparser.ast.SQLHint;
import studio.raptor.sqlparser.ast.SQLName;
import studio.raptor.sqlparser.ast.SQLObject;
import studio.raptor.sqlparser.ast.SQLStatement;
import studio.raptor.sqlparser.ast.expr.SQLCharExpr;
import studio.raptor.sqlparser.ast.expr.SQLIdentifierExpr;
import studio.raptor.sqlparser.ast.expr.SQLVariantRefExpr;
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.SQLAlterTableAlterColumn;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableDisableConstraint;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableDisableKeys;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableDisableLifecycle;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableDropColumnItem;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableDropConstraint;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableDropIndex;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableDropPartition;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableEnableConstraint;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableEnableKeys;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableEnableLifecycle;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableItem;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableRename;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableRenameColumn;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableRenamePartition;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableSetComment;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableSetLifecycle;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableStatement;
import studio.raptor.sqlparser.ast.statement.SQLAlterTableTouch;
import studio.raptor.sqlparser.ast.statement.SQLAlterViewRenameStatement;
import studio.raptor.sqlparser.ast.statement.SQLAssignItem;
import studio.raptor.sqlparser.ast.statement.SQLCallStatement;
import studio.raptor.sqlparser.ast.statement.SQLCheck;
import studio.raptor.sqlparser.ast.statement.SQLCloseStatement;
import studio.raptor.sqlparser.ast.statement.SQLColumnDefinition;
import studio.raptor.sqlparser.ast.statement.SQLCommentStatement;
import studio.raptor.sqlparser.ast.statement.SQLConstraint;
import studio.raptor.sqlparser.ast.statement.SQLCreateDatabaseStatement;
import studio.raptor.sqlparser.ast.statement.SQLCreateIndexStatement;
import studio.raptor.sqlparser.ast.statement.SQLCreateTableStatement;
import studio.raptor.sqlparser.ast.statement.SQLCreateTriggerStatement;
import studio.raptor.sqlparser.ast.statement.SQLCreateTriggerStatement.TriggerEvent;
import studio.raptor.sqlparser.ast.statement.SQLCreateTriggerStatement.TriggerType;
import studio.raptor.sqlparser.ast.statement.SQLCreateViewStatement;
import studio.raptor.sqlparser.ast.statement.SQLDeleteStatement;
import studio.raptor.sqlparser.ast.statement.SQLDescribeStatement;
import studio.raptor.sqlparser.ast.statement.SQLDropDatabaseStatement;
import studio.raptor.sqlparser.ast.statement.SQLDropFunctionStatement;
import studio.raptor.sqlparser.ast.statement.SQLDropIndexStatement;
import studio.raptor.sqlparser.ast.statement.SQLDropProcedureStatement;
import studio.raptor.sqlparser.ast.statement.SQLDropSequenceStatement;
import studio.raptor.sqlparser.ast.statement.SQLDropTableSpaceStatement;
import studio.raptor.sqlparser.ast.statement.SQLDropTableStatement;
import studio.raptor.sqlparser.ast.statement.SQLDropTriggerStatement;
import studio.raptor.sqlparser.ast.statement.SQLDropUserStatement;
import studio.raptor.sqlparser.ast.statement.SQLDropViewStatement;
import studio.raptor.sqlparser.ast.statement.SQLErrorLoggingClause;
import studio.raptor.sqlparser.ast.statement.SQLExplainStatement;
import studio.raptor.sqlparser.ast.statement.SQLExprTableSource;
import studio.raptor.sqlparser.ast.statement.SQLFetchStatement;
import studio.raptor.sqlparser.ast.statement.SQLGrantStatement;
import studio.raptor.sqlparser.ast.statement.SQLInsertInto;
import studio.raptor.sqlparser.ast.statement.SQLInsertStatement;
import studio.raptor.sqlparser.ast.statement.SQLMergeStatement;
import studio.raptor.sqlparser.ast.statement.SQLObjectType;
import studio.raptor.sqlparser.ast.statement.SQLOpenStatement;
import studio.raptor.sqlparser.ast.statement.SQLPrimaryKey;
import studio.raptor.sqlparser.ast.statement.SQLReleaseSavePointStatement;
import studio.raptor.sqlparser.ast.statement.SQLRevokeStatement;
import studio.raptor.sqlparser.ast.statement.SQLRollbackStatement;
import studio.raptor.sqlparser.ast.statement.SQLSavePointStatement;
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.SQLSubqueryTableSource;
import studio.raptor.sqlparser.ast.statement.SQLTableSource;
import studio.raptor.sqlparser.ast.statement.SQLTruncateStatement;
import studio.raptor.sqlparser.ast.statement.SQLUpdateSetItem;
import studio.raptor.sqlparser.ast.statement.SQLUpdateStatement;
import studio.raptor.sqlparser.ast.statement.SQLUseStatement;
import studio.raptor.sqlparser.util.JdbcConstants;
public class SQLStatementParser extends SQLParser {
protected SQLExprParser exprParser;
protected boolean parseCompleteValues = true;
protected int parseValuesSize = 3;
public SQLStatementParser(String sql) {
this(sql, null);
}
public SQLStatementParser(String sql, String dbType) {
this(new SQLExprParser(sql, dbType));
}
public SQLStatementParser(SQLExprParser exprParser) {
super(exprParser.getLexer(), exprParser.getDbType());
this.exprParser = exprParser;
}
protected SQLStatementParser(Lexer lexer, String dbType) {
super(lexer, dbType);
}
public boolean isKeepComments() {
return lexer.isKeepComments();
}
public void setKeepComments(boolean keepComments) {
this.lexer.setKeepComments(keepComments);
}
public SQLExprParser getExprParser() {
return exprParser;
}
public List parseStatementList() {
List statementList = new ArrayList();
parseStatementList(statementList);
return statementList;
}
public void parseStatementList(List statementList) {
parseStatementList(statementList, -1);
}
public void parseStatementList(List statementList, int max) {
for (; ; ) {
if (max != -1) {
if (statementList.size() >= max) {
return;
}
}
if (lexer.token() == Token.EOF || lexer.token() == Token.END) {
if (lexer.isKeepComments() && lexer.hasComment() && statementList.size() > 0) {
SQLStatement stmt = statementList.get(statementList.size() - 1);
stmt.addAfterComment(lexer.readAndResetComments());
}
return;
}
if (lexer.token() == Token.SEMI) {
int line0 = lexer.getLine();
lexer.nextToken();
int line1 = lexer.getLine();
if (lexer.isKeepComments() && statementList.size() > 0) {
SQLStatement stmt = statementList.get(statementList.size() - 1);
if (line1 - line0 <= 1) {
stmt.addAfterComment(lexer.readAndResetComments());
}
stmt.getAttributes().put("format.semi", Boolean.TRUE);
}
continue;
}
if (lexer.token() == Token.SELECT) {
statementList.add(parseSelect());
continue;
}
if (lexer.token() == (Token.UPDATE)) {
statementList.add(parseUpdateStatement());
continue;
}
if (lexer.token() == (Token.CREATE)) {
statementList.add(parseCreate());
continue;
}
if (lexer.token() == (Token.INSERT)) {
SQLStatement insertStatement = parseInsert();
statementList.add(insertStatement);
continue;
}
if (lexer.token() == (Token.DELETE)) {
statementList.add(parseDeleteStatement());
continue;
}
if (lexer.token() == (Token.EXPLAIN)) {
statementList.add(parseExplain());
continue;
}
if (lexer.token() == Token.SET) {
statementList.add(parseSet());
continue;
}
if (lexer.token() == Token.ALTER) {
statementList.add(parseAlter());
continue;
}
if (lexer.token() == Token.DROP) {
List beforeComments = null;
if (lexer.isKeepComments() && lexer.hasComment()) {
beforeComments = lexer.readAndResetComments();
}
lexer.nextToken();
if (lexer.token() == Token.TABLE || identifierEquals("TEMPORARY")) {
SQLDropTableStatement stmt = parseDropTable(false);
if (beforeComments != null) {
stmt.addBeforeComment(beforeComments);
}
statementList.add(stmt);
continue;
} else if (lexer.token() == Token.USER) {
SQLStatement stmt = parseDropUser();
if (beforeComments != null) {
stmt.addBeforeComment(beforeComments);
}
statementList.add(stmt);
continue;
} else if (lexer.token() == Token.INDEX) {
SQLStatement stmt = parseDropIndex();
if (beforeComments != null) {
stmt.addBeforeComment(beforeComments);
}
statementList.add(stmt);
continue;
} else if (lexer.token() == Token.VIEW) {
SQLStatement stmt = parseDropView(false);
if (beforeComments != null) {
stmt.addBeforeComment(beforeComments);
}
statementList.add(stmt);
continue;
} else if (lexer.token() == Token.TRIGGER) {
SQLStatement stmt = parseDropTrigger(false);
if (beforeComments != null) {
stmt.addBeforeComment(beforeComments);
}
statementList.add(stmt);
continue;
} else if (lexer.token() == Token.DATABASE) {
SQLStatement stmt = parseDropDatabase(false);
if (beforeComments != null) {
stmt.addBeforeComment(beforeComments);
}
statementList.add(stmt);
continue;
} else if (lexer.token() == Token.FUNCTION) {
SQLStatement stmt = parseDropFunction(false);
if (beforeComments != null) {
stmt.addBeforeComment(beforeComments);
}
statementList.add(stmt);
continue;
} else if (lexer.token() == Token.TABLESPACE) {
SQLStatement stmt = parseDropTablespace(false);
if (beforeComments != null) {
stmt.addBeforeComment(beforeComments);
}
statementList.add(stmt);
continue;
} else if (lexer.token() == Token.PROCEDURE) {
SQLStatement stmt = parseDropProcedure(false);
if (beforeComments != null) {
stmt.addBeforeComment(beforeComments);
}
statementList.add(stmt);
continue;
} else if (lexer.token() == Token.SEQUENCE) {
SQLStatement stmt = parseDropSequece(false);
if (beforeComments != null) {
stmt.addBeforeComment(beforeComments);
}
statementList.add(stmt);
continue;
} else {
throw new ParserException("TODO " + lexer.token());
}
}
if (lexer.token() == Token.TRUNCATE) {
SQLStatement stmt = parseTruncate();
statementList.add(stmt);
continue;
}
if (lexer.token() == Token.USE) {
SQLStatement stmt = parseUse();
statementList.add(stmt);
continue;
}
if (lexer.token() == Token.GRANT) {
SQLStatement stmt = parseGrant();
statementList.add(stmt);
continue;
}
if (lexer.token() == Token.REVOKE) {
SQLStatement stmt = parseRevoke();
statementList.add(stmt);
continue;
}
if (lexer.token() == Token.LBRACE || identifierEquals("CALL")) {
SQLCallStatement stmt = parseCall();
statementList.add(stmt);
continue;
}
if (identifierEquals("RENAME")) {
SQLStatement stmt = parseRename();
statementList.add(stmt);
continue;
}
if (identifierEquals("RELEASE")) {
SQLStatement stmt = parseReleaseSavePoint();
statementList.add(stmt);
continue;
}
if (identifierEquals("SAVEPOINT")) {
SQLStatement stmt = parseSavePoint();
statementList.add(stmt);
continue;
}
if (identifierEquals("ROLLBACK")) {
SQLRollbackStatement stmt = parseRollback();
statementList.add(stmt);
continue;
}
if (identifierEquals("COMMIT")) {
SQLStatement stmt = parseCommit();
statementList.add(stmt);
continue;
}
if (lexer.token() == Token.SHOW) {
SQLStatement stmt = parseShow();
statementList.add(stmt);
continue;
}
if (lexer.token() == Token.LPAREN) {
char markChar = lexer.current();
int markBp = lexer.bp();
lexer.nextToken();
if (lexer.token() == Token.SELECT) {
lexer.reset(markBp, markChar, Token.LPAREN);
SQLStatement stmt = parseSelect();
statementList.add(stmt);
continue;
}
}
if (lexer.token() == Token.MERGE) {
statementList.add(this.parseMerge());
continue;
}
if (parseStatementListDialect(statementList)) {
continue;
}
if (lexer.token() == Token.COMMENT) {
statementList.add(this.parseComment());
continue;
}
if (lexer.token() == Token.UPSERT || identifierEquals("UPSERT")) {
SQLStatement stmt = parseUpsert();
statementList.add(stmt);
continue;
}
// throw new ParserException("syntax error, " + lexer.token() + " "
// + lexer.stringVal() + ", pos "
// + lexer.pos());
printError(lexer.token());
}
}
public SQLStatement parseUpsert() {
SQLInsertStatement insertStatement = new SQLInsertStatement();
if (lexer.token() == Token.UPSERT || identifierEquals("UPSERT")) {
lexer.nextToken();
insertStatement.setUpsert(true);
}
parseInsert0(insertStatement);
return insertStatement;
}
public SQLRollbackStatement parseRollback() {
lexer.nextToken();
if (identifierEquals("WORK")) {
lexer.nextToken();
}
SQLRollbackStatement stmt = new SQLRollbackStatement(getDbType());
if (lexer.token() == Token.TO) {
lexer.nextToken();
if (identifierEquals("SAVEPOINT")) {
lexer.nextToken();
}
stmt.setTo(this.exprParser.name());
}
return stmt;
}
public SQLStatement parseCommit() {
throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal());
}
public SQLStatement parseShow() {
throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal());
}
public SQLUseStatement parseUse() {
accept(Token.USE);
SQLUseStatement stmt = new SQLUseStatement(getDbType());
stmt.setDatabase(this.exprParser.name());
return stmt;
}
public SQLGrantStatement parseGrant() {
accept(Token.GRANT);
SQLGrantStatement stmt = new SQLGrantStatement(getDbType());
parsePrivileages(stmt.getPrivileges(), stmt);
if (lexer.token() == Token.ON) {
lexer.nextToken();
if (lexer.token() == Token.PROCEDURE) {
lexer.nextToken();
stmt.setObjectType(SQLObjectType.PROCEDURE);
} else if (lexer.token() == Token.FUNCTION) {
lexer.nextToken();
stmt.setObjectType(SQLObjectType.FUNCTION);
} else if (lexer.token() == Token.TABLE) {
lexer.nextToken();
stmt.setObjectType(SQLObjectType.TABLE);
} else if (lexer.token() == Token.USER) {
lexer.nextToken();
stmt.setObjectType(SQLObjectType.USER);
} else if (lexer.token() == Token.DATABASE) {
lexer.nextToken();
stmt.setObjectType(SQLObjectType.DATABASE);
}
if (stmt.getObjectType() != null && lexer.token() == Token.COLONCOLON) {
lexer.nextToken(); // sql server
}
SQLExpr expr = this.exprParser.expr();
if (stmt.getObjectType() == SQLObjectType.TABLE || stmt.getObjectType() == null) {
stmt.setOn(new SQLExprTableSource(expr));
} else {
stmt.setOn(expr);
}
}
if (lexer.token() == Token.TO) {
lexer.nextToken();
stmt.setTo(this.exprParser.expr());
}
if (lexer.token() == Token.WITH) {
lexer.nextToken();
for (; ; ) {
if (identifierEquals("MAX_QUERIES_PER_HOUR")) {
lexer.nextToken();
stmt.setMaxQueriesPerHour(this.exprParser.primary());
continue;
}
if (identifierEquals("MAX_UPDATES_PER_HOUR")) {
lexer.nextToken();
stmt.setMaxUpdatesPerHour(this.exprParser.primary());
continue;
}
if (identifierEquals("MAX_CONNECTIONS_PER_HOUR")) {
lexer.nextToken();
stmt.setMaxConnectionsPerHour(this.exprParser.primary());
continue;
}
if (identifierEquals("MAX_USER_CONNECTIONS")) {
lexer.nextToken();
stmt.setMaxUserConnections(this.exprParser.primary());
continue;
}
break;
}
}
if (identifierEquals("ADMIN")) {
lexer.nextToken();
acceptIdentifier("OPTION");
stmt.setAdminOption(true);
}
if (lexer.token() == Token.IDENTIFIED) {
lexer.nextToken();
accept(Token.BY);
stmt.setIdentifiedBy(this.exprParser.expr());
}
return stmt;
}
protected void parsePrivileages(List privileges, SQLObject parent) {
for (; ; ) {
String privilege = null;
if (lexer.token() == Token.ALL) {
lexer.nextToken();
if (identifierEquals("PRIVILEGES")) {
privilege = "ALL PRIVILEGES";
} else {
privilege = "ALL";
}
} else if (lexer.token() == Token.SELECT) {
privilege = "SELECT";
lexer.nextToken();
} else if (lexer.token() == Token.UPDATE) {
privilege = "UPDATE";
lexer.nextToken();
} else if (lexer.token() == Token.DELETE) {
privilege = "DELETE";
lexer.nextToken();
} else if (lexer.token() == Token.INSERT) {
privilege = "INSERT";
lexer.nextToken();
} else if (lexer.token() == Token.INDEX) {
lexer.nextToken();
privilege = "INDEX";
} else if (lexer.token() == Token.TRIGGER) {
lexer.nextToken();
privilege = "TRIGGER";
} else if (lexer.token() == Token.REFERENCES) {
privilege = "REFERENCES";
lexer.nextToken();
} else if (lexer.token() == Token.CREATE) {
lexer.nextToken();
if (lexer.token() == Token.TABLE) {
privilege = "CREATE TABLE";
lexer.nextToken();
} else if (lexer.token() == Token.SESSION) {
privilege = "CREATE SESSION";
lexer.nextToken();
} else if (lexer.token() == Token.TABLESPACE) {
privilege = "CREATE TABLESPACE";
lexer.nextToken();
} else if (lexer.token() == Token.USER) {
privilege = "CREATE USER";
lexer.nextToken();
} else if (lexer.token() == Token.VIEW) {
privilege = "CREATE VIEW";
lexer.nextToken();
} else if (lexer.token() == Token.ANY) {
lexer.nextToken();
if (lexer.token() == Token.TABLE) {
lexer.nextToken();
privilege = "CREATE ANY TABLE";
} else if (identifierEquals("MATERIALIZED")) {
lexer.nextToken();
accept(Token.VIEW);
privilege = "CREATE ANY MATERIALIZED VIEW";
} else {
throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal());
}
} else if (identifierEquals("SYNONYM")) {
privilege = "CREATE SYNONYM";
lexer.nextToken();
} else if (identifierEquals("ROUTINE")) {
privilege = "CREATE ROUTINE";
lexer.nextToken();
} else if (identifierEquals("TEMPORARY")) {
lexer.nextToken();
accept(Token.TABLE);
privilege = "CREATE TEMPORARY TABLE";
} else {
throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal());
}
} else if (lexer.token() == Token.ALTER) {
lexer.nextToken();
if (lexer.token() == Token.TABLE) {
privilege = "ALTER TABLE";
lexer.nextToken();
} else if (lexer.token() == Token.SESSION) {
privilege = "ALTER SESSION";
lexer.nextToken();
} else if (lexer.token() == Token.ANY) {
lexer.nextToken();
if (lexer.token() == Token.TABLE) {
lexer.nextToken();
privilege = "ALTER ANY TABLE";
} else if (identifierEquals("MATERIALIZED")) {
lexer.nextToken();
accept(Token.VIEW);
privilege = "ALTER ANY MATERIALIZED VIEW";
} else {
throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal());
}
} else {
throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal());
}
} else if (lexer.token() == Token.DROP) {
lexer.nextToken();
if (lexer.token() == Token.DROP) {
privilege = "DROP TABLE";
lexer.nextToken();
} else if (lexer.token() == Token.SESSION) {
privilege = "DROP SESSION";
lexer.nextToken();
} else if (lexer.token() == Token.ANY) {
lexer.nextToken();
if (lexer.token() == Token.TABLE) {
lexer.nextToken();
privilege = "DROP ANY TABLE";
} else if (identifierEquals("MATERIALIZED")) {
lexer.nextToken();
accept(Token.VIEW);
privilege = "DROP ANY MATERIALIZED VIEW";
} else {
throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal());
}
} else {
privilege = "DROP";
}
} else if (identifierEquals("USAGE")) {
privilege = "USAGE";
lexer.nextToken();
} else if (identifierEquals("EXECUTE")) {
privilege = "EXECUTE";
lexer.nextToken();
} else if (identifierEquals("PROXY")) {
privilege = "PROXY";
lexer.nextToken();
} else if (identifierEquals("QUERY")) {
lexer.nextToken();
acceptIdentifier("REWRITE");
privilege = "QUERY REWRITE";
} else if (identifierEquals("GLOBAL")) {
lexer.nextToken();
acceptIdentifier("QUERY");
acceptIdentifier("REWRITE");
privilege = "GLOBAL QUERY REWRITE";
} else if (identifierEquals("INHERIT")) {
lexer.nextToken();
acceptIdentifier("PRIVILEGES");
privilege = "INHERIT PRIVILEGES";
} else if (identifierEquals("EVENT")) {
lexer.nextToken();
privilege = "EVENT";
} else if (identifierEquals("FILE")) {
lexer.nextToken();
privilege = "FILE";
} else if (lexer.token() == Token.GRANT) {
lexer.nextToken();
acceptIdentifier("OPTION");
privilege = "GRANT OPTION";
} else if (lexer.token() == Token.LOCK) {
lexer.nextToken();
acceptIdentifier("TABLES");
privilege = "LOCK TABLES";
} else if (identifierEquals("PROCESS")) {
lexer.nextToken();
privilege = "PROCESS";
} else if (identifierEquals("RELOAD")) {
lexer.nextToken();
privilege = "RELOAD";
} else if (identifierEquals("REPLICATION")) {
lexer.nextToken();
if (identifierEquals("SLAVE")) {
lexer.nextToken();
privilege = "REPLICATION SLAVE";
} else {
acceptIdentifier("CLIENT");
privilege = "REPLICATION CLIENT";
}
} else if (lexer.token() == Token.SHOW) {
lexer.nextToken();
if (lexer.token() == Token.VIEW) {
lexer.nextToken();
privilege = "SHOW VIEW";
} else {
acceptIdentifier("DATABASES");
privilege = "SHOW DATABASES";
}
} else if (identifierEquals("SHUTDOWN")) {
lexer.nextToken();
privilege = "SHUTDOWN";
} else if (identifierEquals("SUPER")) {
lexer.nextToken();
privilege = "SUPER";
} else if (identifierEquals("CONTROL")) { // sqlserver
lexer.nextToken();
privilege = "CONTROL";
} else if (identifierEquals("IMPERSONATE")) { // sqlserver
lexer.nextToken();
privilege = "IMPERSONATE";
}
if (privilege != null) {
SQLExpr expr = new SQLIdentifierExpr(privilege);
if (lexer.token() == Token.LPAREN) {
expr = this.exprParser.primaryRest(expr);
}
expr.setParent(parent);
privileges.add(expr);
}
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
break;
}
}
public SQLRevokeStatement parseRevoke() {
accept(Token.REVOKE);
SQLRevokeStatement stmt = new SQLRevokeStatement(getDbType());
parsePrivileages(stmt.getPrivileges(), stmt);
if (lexer.token() == Token.ON) {
lexer.nextToken();
if (lexer.token() == Token.PROCEDURE) {
lexer.nextToken();
stmt.setObjectType(SQLObjectType.PROCEDURE);
} else if (lexer.token() == Token.FUNCTION) {
lexer.nextToken();
stmt.setObjectType(SQLObjectType.FUNCTION);
} else if (lexer.token() == Token.TABLE) {
lexer.nextToken();
stmt.setObjectType(SQLObjectType.TABLE);
} else if (lexer.token() == Token.USER) {
lexer.nextToken();
stmt.setObjectType(SQLObjectType.USER);
}
SQLExpr expr = this.exprParser.expr();
if (stmt.getObjectType() == SQLObjectType.TABLE || stmt.getObjectType() == null) {
stmt.setOn(new SQLExprTableSource(expr));
} else {
stmt.setOn(expr);
}
}
if (lexer.token() == Token.FROM) {
lexer.nextToken();
stmt.setFrom(this.exprParser.expr());
}
return stmt;
}
public SQLStatement parseSavePoint() {
acceptIdentifier("SAVEPOINT");
SQLSavePointStatement stmt = new SQLSavePointStatement(getDbType());
stmt.setName(this.exprParser.name());
return stmt;
}
public SQLStatement parseReleaseSavePoint() {
acceptIdentifier("RELEASE");
acceptIdentifier("SAVEPOINT");
SQLReleaseSavePointStatement stmt = new SQLReleaseSavePointStatement(getDbType());
stmt.setName(this.exprParser.name());
return stmt;
}
public SQLStatement parseAlter() {
accept(Token.ALTER);
if (lexer.token() == Token.TABLE) {
lexer.nextToken();
SQLAlterTableStatement stmt = new SQLAlterTableStatement(getDbType());
stmt.setName(this.exprParser.name());
for (; ; ) {
if (lexer.token() == Token.DROP) {
parseAlterDrop(stmt);
} else if (identifierEquals("ADD")) {
lexer.nextToken();
boolean ifNotExists = false;
if (lexer.token() == Token.IF) {
lexer.nextToken();
accept(Token.NOT);
accept(Token.EXISTS);
ifNotExists = true;
}
if (lexer.token() == Token.PRIMARY) {
SQLPrimaryKey primaryKey = this.exprParser.parsePrimaryKey();
SQLAlterTableAddConstraint item = new SQLAlterTableAddConstraint(primaryKey);
stmt.addItem(item);
} else if (lexer.token() == Token.IDENTIFIER) {
SQLAlterTableAddColumn item = parseAlterTableAddColumn();
stmt.addItem(item);
} else if (lexer.token() == Token.COLUMN) {
lexer.nextToken();
SQLAlterTableAddColumn item = parseAlterTableAddColumn();
stmt.addItem(item);
} else if (lexer.token() == Token.CHECK) {
SQLCheck check = this.exprParser.parseCheck();
SQLAlterTableAddConstraint item = new SQLAlterTableAddConstraint(check);
stmt.addItem(item);
} else if (lexer.token() == Token.CONSTRAINT) {
SQLConstraint constraint = this.exprParser.parseConstaint();
SQLAlterTableAddConstraint item = new SQLAlterTableAddConstraint(constraint);
stmt.addItem(item);
} else if (lexer.token() == Token.FOREIGN) {
SQLConstraint constraint = this.exprParser.parseForeignKey();
SQLAlterTableAddConstraint item = new SQLAlterTableAddConstraint(constraint);
stmt.addItem(item);
} else if (lexer.token() == Token.PARTITION) {
lexer.nextToken();
SQLAlterTableAddPartition addPartition = new SQLAlterTableAddPartition();
addPartition.setIfNotExists(ifNotExists);
accept(Token.LPAREN);
parseAssignItems(addPartition.getPartitions(), addPartition);
accept(Token.RPAREN);
stmt.addItem(addPartition);
} else {
throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal());
}
} 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 if (identifierEquals("LIFECYCLE")) {
lexer.nextToken();
SQLAlterTableDisableLifecycle item = new SQLAlterTableDisableLifecycle();
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 if (identifierEquals("LIFECYCLE")) {
lexer.nextToken();
SQLAlterTableEnableLifecycle item = new SQLAlterTableEnableLifecycle();
stmt.addItem(item);
} else {
acceptIdentifier("KEYS");
SQLAlterTableEnableKeys item = new SQLAlterTableEnableKeys();
stmt.addItem(item);
}
} else if (lexer.token() == Token.ALTER) {
lexer.nextToken();
if (lexer.token() == Token.COLUMN) {
SQLAlterTableAlterColumn alterColumn = parseAlterColumn();
stmt.addItem(alterColumn);
} else if (lexer.token() == Token.LITERAL_ALIAS) {
SQLAlterTableAlterColumn alterColumn = parseAlterColumn();
stmt.addItem(alterColumn);
} else {
throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal());
}
} else if (identifierEquals("CHANGE")) {
lexer.nextToken();
accept(Token.COLUMN);
SQLName columnName = this.exprParser.name();
if (identifierEquals("RENAME")) {
lexer.nextToken();
accept(Token.TO);
SQLName toName = this.exprParser.name();
SQLAlterTableRenameColumn renameColumn = new SQLAlterTableRenameColumn();
renameColumn.setColumn(columnName);
renameColumn.setTo(toName);
stmt.addItem(renameColumn);
} else if (lexer.token() == Token.COMMENT) {
lexer.nextToken();
SQLExpr comment = this.exprParser.primary();
SQLColumnDefinition columnDefinition = new SQLColumnDefinition();
columnDefinition.setName(columnName);
columnDefinition.setComment(comment);
SQLAlterTableAlterColumn changeColumn = new SQLAlterTableAlterColumn();
changeColumn.setColumn(columnDefinition);
stmt.addItem(changeColumn);
} else {
SQLColumnDefinition column = this.exprParser.parseColumn();
SQLAlterTableAlterColumn alterColumn = new SQLAlterTableAlterColumn();
alterColumn.setColumn(column);
alterColumn.setOriginColumn(columnName);
stmt.addItem(alterColumn);
}
} else if (lexer.token() == Token.WITH) {
lexer.nextToken();
acceptIdentifier("NOCHECK");
acceptIdentifier("ADD");
SQLConstraint check = this.exprParser.parseConstaint();
SQLAlterTableAddConstraint addCheck = new SQLAlterTableAddConstraint();
addCheck.setWithNoCheck(true);
addCheck.setConstraint(check);
stmt.addItem(addCheck);
} else if (identifierEquals("RENAME")) {
stmt.addItem(parseAlterTableRename());
} else if (lexer.token() == Token.SET) {
lexer.nextToken();
if (lexer.token() == Token.COMMENT) {
lexer.nextToken();
SQLAlterTableSetComment setComment = new SQLAlterTableSetComment();
setComment.setComment(this.exprParser.primary());
stmt.addItem(setComment);
} else if (identifierEquals("LIFECYCLE")) {
lexer.nextToken();
SQLAlterTableSetLifecycle setLifecycle = new SQLAlterTableSetLifecycle();
setLifecycle.setLifecycle(this.exprParser.primary());
stmt.addItem(setLifecycle);
} else {
throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal());
}
} else if (lexer.token() == Token.PARTITION) {
lexer.nextToken();
SQLAlterTableRenamePartition renamePartition = new SQLAlterTableRenamePartition();
accept(Token.LPAREN);
parseAssignItems(renamePartition.getPartition(), renamePartition);
accept(Token.RPAREN);
if (lexer.token() == Token.ENABLE) {
lexer.nextToken();
if (identifierEquals("LIFECYCLE")) {
lexer.nextToken();
}
SQLAlterTableEnableLifecycle enableLifeCycle = new SQLAlterTableEnableLifecycle();
for (SQLAssignItem condition : renamePartition.getPartition()) {
enableLifeCycle.getPartition().add(condition);
condition.setParent(enableLifeCycle);
}
stmt.addItem(enableLifeCycle);
continue;
}
if (lexer.token() == Token.DISABLE) {
lexer.nextToken();
if (identifierEquals("LIFECYCLE")) {
lexer.nextToken();
}
SQLAlterTableDisableLifecycle disableLifeCycle = new SQLAlterTableDisableLifecycle();
for (SQLAssignItem condition : renamePartition.getPartition()) {
disableLifeCycle.getPartition().add(condition);
condition.setParent(disableLifeCycle);
}
stmt.addItem(disableLifeCycle);
continue;
}
acceptIdentifier("RENAME");
accept(Token.TO);
accept(Token.PARTITION);
accept(Token.LPAREN);
parseAssignItems(renamePartition.getTo(), renamePartition);
accept(Token.RPAREN);
stmt.addItem(renamePartition);
} else if (identifierEquals("TOUCH")) {
lexer.nextToken();
SQLAlterTableTouch item = new SQLAlterTableTouch();
if (lexer.token() == Token.PARTITION) {
lexer.nextToken();
accept(Token.LPAREN);
parseAssignItems(item.getPartition(), item);
accept(Token.RPAREN);
}
stmt.addItem(item);
} else if (JdbcConstants.ODPS.equals(dbType) && identifierEquals("MERGE")) {
lexer.nextToken();
acceptIdentifier("SMALLFILES");
stmt.setMergeSmallFiles(true);
} else {
break;
}
}
return stmt;
} else if (lexer.token() == Token.VIEW) {
lexer.nextToken();
SQLName viewName = this.exprParser.name();
if (identifierEquals("RENAME")) {
lexer.nextToken();
accept(Token.TO);
SQLAlterViewRenameStatement stmt = new SQLAlterViewRenameStatement();
stmt.setName(viewName);
SQLName newName = this.exprParser.name();
stmt.setTo(newName);
return stmt;
}
throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal());
}
throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal());
}
protected SQLAlterTableItem parseAlterTableRename() {
acceptIdentifier("RENAME");
if (lexer.token() == Token.COLUMN) {
lexer.nextToken();
SQLAlterTableRenameColumn renameColumn = new SQLAlterTableRenameColumn();
renameColumn.setColumn(this.exprParser.name());
accept(Token.TO);
renameColumn.setTo(this.exprParser.name());
return renameColumn;
}
if (lexer.token() == Token.TO) {
lexer.nextToken();
SQLAlterTableRename item = new SQLAlterTableRename();
item.setTo(this.exprParser.name());
return item;
}
throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal());
}
protected SQLAlterTableAlterColumn parseAlterColumn() {
lexer.nextToken();
SQLColumnDefinition column = this.exprParser.parseColumn();
SQLAlterTableAlterColumn alterColumn = new SQLAlterTableAlterColumn();
alterColumn.setColumn(column);
return alterColumn;
}
public void parseAlterDrop(SQLAlterTableStatement stmt) {
lexer.nextToken();
boolean ifExists = false;
if (lexer.token() == Token.IF) {
lexer.nextToken();
accept(Token.EXISTS);
ifExists = true;
}
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();
this.exprParser.names(item.getColumns());
if (lexer.token == Token.CASCADE) {
item.setCascade(true);
lexer.nextToken();
}
stmt.addItem(item);
} else if (lexer.token() == Token.LITERAL_ALIAS) {
SQLAlterTableDropColumnItem item = new SQLAlterTableDropColumnItem();
this.exprParser.names(item.getColumns());
if (lexer.token == Token.CASCADE) {
item.setCascade(true);
lexer.nextToken();
}
stmt.addItem(item);
} else if (lexer.token() == Token.PARTITION) {
SQLAlterTableDropPartition dropPartition = parseAlterTableDropPartition(ifExists);
stmt.addItem(dropPartition);
} else if (lexer.token() == Token.INDEX) {
lexer.nextToken();
SQLName indexName = this.exprParser.name();
SQLAlterTableDropIndex item = new SQLAlterTableDropIndex();
item.setIndexName(indexName);
stmt.addItem(item);
} else {
throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal());
}
}
protected SQLAlterTableDropPartition parseAlterTableDropPartition(boolean ifExists) {
lexer.nextToken();
SQLAlterTableDropPartition dropPartition = new SQLAlterTableDropPartition();
dropPartition.setIfExists(ifExists);
if (lexer.token() == Token.LPAREN) {
accept(Token.LPAREN);
parseAssignItems(dropPartition.getPartitions(), dropPartition);
accept(Token.RPAREN);
if (identifierEquals("PURGE")) {
lexer.nextToken();
dropPartition.setPurge(true);
}
} else {
SQLName partition = this.exprParser.name();
dropPartition.addPartition(partition);
}
return dropPartition;
}
public SQLStatement parseRename() {
throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal());
}
protected SQLDropTableStatement parseDropTable(boolean acceptDrop) {
if (acceptDrop) {
accept(Token.DROP);
}
SQLDropTableStatement stmt = new SQLDropTableStatement(getDbType());
if (identifierEquals("TEMPORARY")) {
lexer.nextToken();
stmt.setTemporary(true);
}
accept(Token.TABLE);
if (lexer.token() == Token.IF) {
lexer.nextToken();
accept(Token.EXISTS);
stmt.setIfExists(true);
}
for (; ; ) {
SQLName name = this.exprParser.name();
stmt.addPartition(new SQLExprTableSource(name));
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
break;
}
for (; ; ) {
if (identifierEquals("RESTRICT")) {
lexer.nextToken();
stmt.setRestrict(true);
continue;
}
if (identifierEquals("CASCADE")) {
lexer.nextToken();
stmt.setCascade(true);
if (identifierEquals("CONSTRAINTS")) { // for oracle
lexer.nextToken();
}
continue;
}
if (lexer.token() == Token.PURGE || identifierEquals("PURGE")) {
lexer.nextToken();
stmt.setPurge(true);
continue;
}
break;
}
return stmt;
}
protected SQLDropSequenceStatement parseDropSequece(boolean acceptDrop) {
if (acceptDrop) {
accept(Token.DROP);
}
lexer.nextToken();
SQLName name = this.exprParser.name();
SQLDropSequenceStatement stmt = new SQLDropSequenceStatement(getDbType());
stmt.setName(name);
return stmt;
}
protected SQLDropTriggerStatement parseDropTrigger(boolean acceptDrop) {
if (acceptDrop) {
accept(Token.DROP);
}
lexer.nextToken();
SQLName name = this.exprParser.name();
SQLDropTriggerStatement stmt = new SQLDropTriggerStatement(getDbType());
stmt.setName(name);
return stmt;
}
protected SQLDropViewStatement parseDropView(boolean acceptDrop) {
if (acceptDrop) {
accept(Token.DROP);
}
SQLDropViewStatement stmt = new SQLDropViewStatement(getDbType());
accept(Token.VIEW);
if (lexer.token() == Token.IF) {
lexer.nextToken();
accept(Token.EXISTS);
stmt.setIfExists(true);
}
for (; ; ) {
SQLName name = this.exprParser.name();
stmt.addPartition(new SQLExprTableSource(name));
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
break;
}
if (identifierEquals("RESTRICT")) {
lexer.nextToken();
stmt.setRestrict(true);
} else if (identifierEquals("CASCADE")) {
lexer.nextToken();
if (identifierEquals("CONSTRAINTS")) { // for oracle
lexer.nextToken();
}
stmt.setCascade(true);
}
return stmt;
}
protected SQLDropDatabaseStatement parseDropDatabase(boolean acceptDrop) {
if (acceptDrop) {
accept(Token.DROP);
}
SQLDropDatabaseStatement stmt = new SQLDropDatabaseStatement(getDbType());
accept(Token.DATABASE);
if (lexer.token() == Token.IF) {
lexer.nextToken();
accept(Token.EXISTS);
stmt.setIfExists(true);
}
SQLName name = this.exprParser.name();
stmt.setDatabase(name);
return stmt;
}
protected SQLDropFunctionStatement parseDropFunction(boolean acceptDrop) {
if (acceptDrop) {
accept(Token.DROP);
}
SQLDropFunctionStatement stmt = new SQLDropFunctionStatement(getDbType());
accept(Token.FUNCTION);
if (lexer.token() == Token.IF) {
lexer.nextToken();
accept(Token.EXISTS);
stmt.setIfExists(true);
}
SQLName name = this.exprParser.name();
stmt.setName(name);
return stmt;
}
protected SQLDropTableSpaceStatement parseDropTablespace(boolean acceptDrop) {
SQLDropTableSpaceStatement stmt = new SQLDropTableSpaceStatement(getDbType());
if (lexer.isKeepComments() && lexer.hasComment()) {
stmt.addBeforeComment(lexer.readAndResetComments());
}
if (acceptDrop) {
accept(Token.DROP);
}
accept(Token.TABLESPACE);
if (lexer.token() == Token.IF) {
lexer.nextToken();
accept(Token.EXISTS);
stmt.setIfExists(true);
}
SQLName name = this.exprParser.name();
stmt.setName(name);
return stmt;
}
protected SQLDropProcedureStatement parseDropProcedure(boolean acceptDrop) {
if (acceptDrop) {
accept(Token.DROP);
}
SQLDropProcedureStatement stmt = new SQLDropProcedureStatement(getDbType());
accept(Token.PROCEDURE);
if (lexer.token() == Token.IF) {
lexer.nextToken();
accept(Token.EXISTS);
stmt.setIfExists(true);
}
SQLName name = this.exprParser.name();
stmt.setName(name);
return stmt;
}
public SQLStatement parseTruncate() {
accept(Token.TRUNCATE);
if (lexer.token() == Token.TABLE) {
lexer.nextToken();
}
SQLTruncateStatement stmt = new SQLTruncateStatement(getDbType());
if (lexer.token() == Token.ONLY) {
lexer.nextToken();
stmt.setOnly(true);
}
for (; ; ) {
SQLName name = this.exprParser.name();
stmt.addTableSource(name);
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
break;
}
for (; ; ) {
if (lexer.token() == Token.PURGE) {
lexer.nextToken();
if (identifierEquals("SNAPSHOT")) {
lexer.nextToken();
acceptIdentifier("LOG");
stmt.setPurgeSnapshotLog(true);
} else {
throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal());
}
continue;
}
if (lexer.token() == Token.RESTART) {
lexer.nextToken();
accept(Token.IDENTITY);
stmt.setRestartIdentity(Boolean.TRUE);
continue;
} else if (lexer.token() == Token.SHARE) {
lexer.nextToken();
accept(Token.IDENTITY);
stmt.setRestartIdentity(Boolean.FALSE);
continue;
}
if (lexer.token() == Token.CASCADE) {
lexer.nextToken();
stmt.setCascade(Boolean.TRUE);
continue;
} else if (lexer.token() == Token.RESTRICT) {
lexer.nextToken();
stmt.setCascade(Boolean.FALSE);
continue;
}
if (lexer.token() == Token.DROP) {
lexer.nextToken();
acceptIdentifier("STORAGE");
stmt.setDropStorage(true);
continue;
}
if (identifierEquals("REUSE")) {
lexer.nextToken();
acceptIdentifier("STORAGE");
stmt.setReuseStorage(true);
continue;
}
if (identifierEquals("IGNORE")) {
lexer.nextToken();
accept(Token.DELETE);
acceptIdentifier("TRIGGERS");
stmt.setIgnoreDeleteTriggers(true);
continue;
}
if (identifierEquals("RESTRICT")) {
lexer.nextToken();
accept(Token.WHEN);
accept(Token.DELETE);
acceptIdentifier("TRIGGERS");
stmt.setRestrictWhenDeleteTriggers(true);
continue;
}
if (lexer.token() == Token.CONTINUE) {
lexer.nextToken();
accept(Token.IDENTITY);
continue;
}
if (identifierEquals("IMMEDIATE")) {
lexer.nextToken();
stmt.setImmediate(true);
continue;
}
break;
}
return stmt;
}
public SQLStatement parseInsert() {
SQLInsertStatement insertStatement = new SQLInsertStatement();
if (lexer.token() == Token.INSERT) {
accept(Token.INSERT);
}
parseInsert0(insertStatement);
return insertStatement;
}
protected void parseInsert0(SQLInsertInto insertStatement) {
parseInsert0(insertStatement, true);
}
protected void parseInsert0_hinits(SQLInsertInto insertStatement) {
}
protected void parseInsert0(SQLInsertInto insertStatement, boolean acceptSubQuery) {
if (lexer.token() == Token.INTO) {
lexer.nextToken();
SQLName tableName = this.exprParser.name();
insertStatement.setTableName(tableName);
if (lexer.token() == Token.LITERAL_ALIAS) {
insertStatement.setAlias(as());
}
parseInsert0_hinits(insertStatement);
if (lexer.token() == Token.IDENTIFIER) {
insertStatement.setAlias(lexer.stringVal());
lexer.nextToken();
}
}
if (lexer.token() == (Token.LPAREN)) {
lexer.nextToken();
parseInsertColumns(insertStatement);
accept(Token.RPAREN);
}
if (lexer.token() == Token.VALUES) {
lexer.nextToken();
for (; ; ) {
accept(Token.LPAREN);
SQLInsertStatement.ValuesClause values = new SQLInsertStatement.ValuesClause();
this.exprParser.exprList(values.getValues(), values);
insertStatement.getValuesList().add(values);
accept(Token.RPAREN);
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
} else {
break;
}
}
} else if (acceptSubQuery && (lexer.token() == Token.SELECT || lexer.token() == Token.LPAREN)) {
SQLSelect select = this.createSQLSelectParser().select();
insertStatement.setQuery(select);
}
}
protected void parseInsertColumns(SQLInsertInto insert) {
this.exprParser.exprList(insert.getColumns(), insert);
}
public boolean parseStatementListDialect(List statementList) {
return false;
}
public SQLDropUserStatement parseDropUser() {
accept(Token.USER);
SQLDropUserStatement stmt = new SQLDropUserStatement(getDbType());
for (; ; ) {
SQLExpr expr = this.exprParser.expr();
stmt.addUser(expr);
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
break;
}
return stmt;
}
public SQLStatement parseDropIndex() {
accept(Token.INDEX);
SQLDropIndexStatement stmt = new SQLDropIndexStatement(getDbType());
stmt.setIndexName(this.exprParser.name());
if (lexer.token() == Token.ON) {
lexer.nextToken();
stmt.setTableName(this.exprParser.name());
}
return stmt;
}
public SQLCallStatement parseCall() {
boolean brace = false;
if (lexer.token() == Token.LBRACE) {
lexer.nextToken();
brace = true;
}
SQLCallStatement stmt = new SQLCallStatement(getDbType());
if (lexer.token() == Token.QUES) {
lexer.nextToken();
accept(Token.EQ);
stmt.setOutParameter(new SQLVariantRefExpr("?"));
}
acceptIdentifier("CALL");
stmt.setProcedureName(exprParser.name());
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
exprParser.exprList(stmt.getParameters(), stmt);
accept(Token.RPAREN);
}
if (brace) {
accept(Token.RBRACE);
stmt.setBrace(true);
}
return stmt;
}
public SQLStatement parseSet() {
accept(Token.SET);
SQLSetStatement stmt = new SQLSetStatement(getDbType());
parseAssignItems(stmt.getItems(), stmt);
return stmt;
}
public void parseAssignItems(List super SQLAssignItem> items, SQLObject parent) {
for (; ; ) {
SQLAssignItem item = exprParser.parseAssignItem();
item.setParent(parent);
items.add(item);
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
} else {
break;
}
}
}
public SQLStatement parseCreate() {
char markChar = lexer.current();
int markBp = lexer.bp();
List comments = null;
if (lexer.isKeepComments() && lexer.hasComment()) {
comments = lexer.readAndResetComments();
}
accept(Token.CREATE);
Token token = lexer.token();
if (token == Token.TABLE || identifierEquals("GLOBAL")) {
SQLCreateTableParser createTableParser = getSQLCreateTableParser();
SQLCreateTableStatement stmt = createTableParser.parseCrateTable(false);
if (comments != null) {
stmt.addBeforeComment(comments);
}
return stmt;
} else if (token == Token.INDEX //
|| token == Token.UNIQUE //
|| identifierEquals("NONCLUSTERED") // sql server
) {
return parseCreateIndex(false);
} else if (lexer.token() == Token.SEQUENCE) {
return parseCreateSequence(false);
} else if (token == Token.OR) {
lexer.nextToken();
accept(Token.REPLACE);
if (lexer.token() == Token.PROCEDURE) {
lexer.reset(markBp, markChar, Token.CREATE);
return parseCreateProcedure();
}
if (lexer.token() == Token.VIEW) {
lexer.reset(markBp, markChar, Token.CREATE);
return parseCreateView();
}
// lexer.reset(mark_bp, mark_ch, Token.CREATE);
throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal());
} else if (token == Token.DATABASE) {
lexer.nextToken();
if (identifierEquals("LINK")) {
lexer.reset(markBp, markChar, Token.CREATE);
return parseCreateDbLink();
}
lexer.reset(markBp, markChar, Token.CREATE);
return parseCreateDatabase();
} else if (identifierEquals("PUBLIC") || identifierEquals("SHARE")) {
lexer.reset(markBp, markChar, Token.CREATE);
return parseCreateDbLink();
} else if (token == Token.VIEW) {
return parseCreateView();
} else if (token == Token.TRIGGER) {
return parseCreateTrigger();
}
throw new ParserException("TODO " + lexer.token());
}
public SQLStatement parseCreateDbLink() {
throw new ParserException("TODO " + lexer.token());
}
public SQLStatement parseCreateTrigger() {
accept(Token.TRIGGER);
SQLCreateTriggerStatement stmt = new SQLCreateTriggerStatement(getDbType());
stmt.setName(this.exprParser.name());
if (identifierEquals("BEFORE")) {
stmt.setTriggerType(TriggerType.BEFORE);
lexer.nextToken();
} else if (identifierEquals("AFTER")) {
stmt.setTriggerType(TriggerType.AFTER);
lexer.nextToken();
} else if (identifierEquals("INSTEAD")) {
lexer.nextToken();
accept(Token.OF);
stmt.setTriggerType(TriggerType.INSTEAD_OF);
}
for (; ; ) {
if (lexer.token() == Token.INSERT) {
lexer.nextToken();
stmt.getTriggerEvents().add(TriggerEvent.INSERT);
continue;
}
if (lexer.token() == Token.UPDATE) {
lexer.nextToken();
stmt.getTriggerEvents().add(TriggerEvent.UPDATE);
continue;
}
if (lexer.token() == Token.DELETE) {
lexer.nextToken();
stmt.getTriggerEvents().add(TriggerEvent.DELETE);
continue;
}
break;
}
accept(Token.ON);
stmt.setOn(this.exprParser.name());
if (lexer.token() == Token.FOR) {
lexer.nextToken();
acceptIdentifier("EACH");
accept(Token.ROW);
stmt.setForEachRow(true);
}
List body = this.parseStatementList();
if (body == null || body.isEmpty()) {
throw new ParserException("syntax error");
}
stmt.setBody(body.get(0));
return stmt;
}
public SQLStatement parseBlock() {
throw new ParserException("TODO " + lexer.token());
}
public SQLStatement parseCreateDatabase() {
if (lexer.token() == Token.CREATE) {
lexer.nextToken();
}
accept(Token.DATABASE);
SQLCreateDatabaseStatement stmt = new SQLCreateDatabaseStatement(getDbType());
stmt.setName(this.exprParser.name());
return stmt;
}
public SQLStatement parseCreateProcedure() {
throw new ParserException("TODO " + lexer.token());
}
public SQLStatement parseCreateSequence(boolean acceptCreate) {
throw new ParserException("TODO " + lexer.token());
}
public SQLStatement parseCreateIndex(boolean acceptCreate) {
if (acceptCreate) {
accept(Token.CREATE);
}
SQLCreateIndexStatement stmt = new SQLCreateIndexStatement(getDbType());
if (lexer.token() == Token.UNIQUE) {
lexer.nextToken();
if (identifierEquals("CLUSTERED")) {
lexer.nextToken();
stmt.setType("UNIQUE CLUSTERED");
} else {
stmt.setType("UNIQUE");
}
} else if (identifierEquals("FULLTEXT")) {
stmt.setType("FULLTEXT");
lexer.nextToken();
} else if (identifierEquals("NONCLUSTERED")) {
stmt.setType("NONCLUSTERED");
lexer.nextToken();
}
accept(Token.INDEX);
stmt.setName(this.exprParser.name());
accept(Token.ON);
stmt.setTable(this.exprParser.name());
accept(Token.LPAREN);
for (; ; ) {
SQLSelectOrderByItem item = this.exprParser.parseSelectOrderByItem();
item.setParent(stmt);
stmt.addItem(item);
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
break;
}
accept(Token.RPAREN);
return stmt;
}
public SQLCreateTableParser getSQLCreateTableParser() {
return new SQLCreateTableParser(this.exprParser);
}
public SQLStatement parseSelect() {
SQLSelectParser selectParser = createSQLSelectParser();
SQLSelect select = selectParser.select();
return new SQLSelectStatement(select, getDbType());
}
public SQLSelectParser createSQLSelectParser() {
return new SQLSelectParser(this.exprParser);
}
public SQLUpdateStatement parseUpdateStatement() {
SQLUpdateStatement udpateStatement = createUpdateStatement();
if (lexer.token() == Token.UPDATE) {
lexer.nextToken();
SQLTableSource tableSource = this.exprParser.createSelectParser().parseTableSource();
udpateStatement.setTableSource(tableSource);
}
parseUpdateSet(udpateStatement);
if (lexer.token() == (Token.WHERE)) {
lexer.nextToken();
udpateStatement.setWhere(this.exprParser.expr());
}
return udpateStatement;
}
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();
}
}
protected SQLUpdateStatement createUpdateStatement() {
return new SQLUpdateStatement(getDbType());
}
public SQLDeleteStatement parseDeleteStatement() {
SQLDeleteStatement deleteStatement = new SQLDeleteStatement(getDbType());
if (lexer.token() == Token.DELETE) {
lexer.nextToken();
if (lexer.token() == (Token.FROM)) {
lexer.nextToken();
}
if (lexer.token() == Token.COMMENT) {
lexer.nextToken();
}
SQLName tableName = exprParser.name();
deleteStatement.setTableName(tableName);
if (lexer.token() == Token.FROM) {
lexer.nextToken();
SQLTableSource tableSource = createSQLSelectParser().parseTableSource();
deleteStatement.setFrom(tableSource);
}
}
if (lexer.token() == (Token.WHERE)) {
lexer.nextToken();
SQLExpr where = this.exprParser.expr();
deleteStatement.setWhere(where);
}
return deleteStatement;
}
public SQLCreateTableStatement parseCreateTable() {
// SQLCreateTableParser parser = new SQLCreateTableParser(this.lexer);
// return parser.parseCrateTable();
throw new ParserException("TODO");
}
public SQLCreateViewStatement parseCreateView() {
SQLCreateViewStatement createView = new SQLCreateViewStatement(getDbType());
if (lexer.token() == Token.CREATE) {
lexer.nextToken();
}
if (lexer.token() == Token.OR) {
lexer.nextToken();
accept(Token.REPLACE);
createView.setOrReplace(true);
}
if (identifierEquals("ALGORITHM")) {
lexer.nextToken();
accept(Token.EQ);
String algorithm = lexer.stringVal();
createView.setAlgorithm(algorithm);
lexer.nextToken();
}
if (identifierEquals("DEFINER")) {
lexer.nextToken();
accept(Token.EQ);
SQLName definer = this.exprParser.name();
createView.setDefiner(definer);
lexer.nextToken();
}
if (identifierEquals("SQL")) {
lexer.nextToken();
acceptIdentifier("SECURITY");
String sqlSecurity = lexer.stringVal();
createView.setSqlSecurity(sqlSecurity);
lexer.nextToken();
}
this.accept(Token.VIEW);
if (lexer.token() == Token.IF || identifierEquals("IF")) {
lexer.nextToken();
accept(Token.NOT);
accept(Token.EXISTS);
createView.setIfNotExists(true);
}
createView.setName(exprParser.name());
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
for (; ; ) {
SQLCreateViewStatement.Column column = new SQLCreateViewStatement.Column();
SQLExpr expr = this.exprParser.expr();
column.setExpr(expr);
if (lexer.token() == Token.COMMENT) {
lexer.nextToken();
column.setComment((SQLCharExpr) exprParser.primary());
}
column.setParent(createView);
createView.addColumn(column);
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
} else {
break;
}
}
accept(Token.RPAREN);
}
if (lexer.token() == Token.COMMENT) {
lexer.nextToken();
SQLCharExpr comment = (SQLCharExpr) exprParser.primary();
createView.setComment(comment);
}
this.accept(Token.AS);
createView.setSubQuery(new SQLSelectParser(this.exprParser).select());
return createView;
}
public SQLCommentStatement parseComment() {
accept(Token.COMMENT);
SQLCommentStatement stmt = new SQLCommentStatement();
accept(Token.ON);
if (lexer.token() == Token.TABLE) {
stmt.setType(SQLCommentStatement.Type.TABLE);
lexer.nextToken();
} else if (lexer.token() == Token.COLUMN) {
stmt.setType(SQLCommentStatement.Type.COLUMN);
lexer.nextToken();
}
stmt.setOn(this.exprParser.name());
accept(Token.IS);
stmt.setComment(this.exprParser.expr());
return stmt;
}
protected SQLAlterTableAddColumn parseAlterTableAddColumn() {
boolean odps = JdbcConstants.ODPS.equals(dbType);
if (odps) {
acceptIdentifier("COLUMNS");
accept(Token.LPAREN);
}
SQLAlterTableAddColumn item = new SQLAlterTableAddColumn();
for (; ; ) {
SQLColumnDefinition columnDef = this.exprParser.parseColumn();
item.addColumn(columnDef);
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
if (identifierEquals("ADD")) {
break;
}
continue;
}
break;
}
if (odps) {
accept(Token.RPAREN);
}
return item;
}
public SQLStatement parseStatement() {
return parseStatement(false);
}
/**
* @param tryBest - 为true去解析并忽略之后的错误 强制建议除非明确知道可以忽略才传tryBest=true, 不然会忽略语法错误,且截断sql,导致update和delete无where条件下执行!!!
*/
public SQLStatement parseStatement(final boolean tryBest) {
List list = new ArrayList();
this.parseStatementList(list, 1);
if (tryBest) {
if (lexer.token() != Token.EOF) {
throw new ParserException("sql syntax error, no terminated. " + lexer.token());
}
}
return list.get(0);
}
public SQLExplainStatement parseExplain() {
accept(Token.EXPLAIN);
if (identifierEquals("PLAN")) {
lexer.nextToken();
}
if (lexer.token() == Token.FOR) {
lexer.nextToken();
}
SQLExplainStatement explain = new SQLExplainStatement(getDbType());
if (lexer.token == Token.HINT) {
explain.setHints(this.exprParser.parseHints());
}
if (JdbcConstants.MYSQL.equals(dbType)) {
if (identifierEquals("FORMAT")
|| identifierEquals("EXTENDED")
|| identifierEquals("PARTITIONS")) {
explain.setType(lexer.stringVal);
lexer.nextToken();
}
}
explain.setStatement(parseStatement());
return explain;
}
protected SQLAlterTableAddIndex parseAlterTableAddIndex() {
SQLAlterTableAddIndex item = new SQLAlterTableAddIndex();
if (lexer.token() == Token.UNIQUE) {
item.setUnique(true);
lexer.nextToken();
if (lexer.token() == Token.INDEX) {
lexer.nextToken();
} else if (lexer.token() == Token.KEY) {
item.setKey(true);
lexer.nextToken();
}
} else {
if (lexer.token() == Token.INDEX) {
accept(Token.INDEX);
} else if (lexer.token() == Token.KEY) {
item.setKey(true);
accept(Token.KEY);
}
}
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
} else {
item.setName(this.exprParser.name());
if (JdbcConstants.MYSQL.equals(dbType)) {
if (identifierEquals("USING")) {
lexer.nextToken();
String indexType = lexer.stringVal;
item.setType(indexType);
accept(Token.IDENTIFIER);
}
}
accept(Token.LPAREN);
}
for (; ; ) {
SQLSelectOrderByItem column = this.exprParser.parseSelectOrderByItem();
item.addItem(column);
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
break;
}
accept(Token.RPAREN);
return item;
}
/**
* parse cursor open statement
*/
public SQLOpenStatement parseOpen() {
SQLOpenStatement stmt = new SQLOpenStatement();
accept(Token.OPEN);
stmt.setCursorName(exprParser.name().getSimpleName());
accept(Token.SEMI);
return stmt;
}
public SQLFetchStatement parseFetch() {
accept(Token.FETCH);
SQLFetchStatement stmt = new SQLFetchStatement();
stmt.setCursorName(this.exprParser.name());
accept(Token.INTO);
for (; ; ) {
stmt.getInto().add(this.exprParser.name());
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
break;
}
return stmt;
}
public SQLStatement parseClose() {
SQLCloseStatement stmt = new SQLCloseStatement();
accept(Token.CLOSE);
stmt.setCursorName(exprParser.name().getSimpleName());
accept(Token.SEMI);
return stmt;
}
public boolean isParseCompleteValues() {
return parseCompleteValues;
}
public void setParseCompleteValues(boolean parseCompleteValues) {
this.parseCompleteValues = parseCompleteValues;
}
public int getParseValuesSize() {
return parseValuesSize;
}
public void setParseValuesSize(int parseValuesSize) {
this.parseValuesSize = parseValuesSize;
}
public SQLMergeStatement parseMerge() {
accept(Token.MERGE);
SQLMergeStatement stmt = new SQLMergeStatement();
parseHints(stmt.getHints());
accept(Token.INTO);
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
SQLSelect select = this.createSQLSelectParser().select();
SQLSubqueryTableSource tableSource = new SQLSubqueryTableSource(select);
stmt.setInto(tableSource);
accept(Token.RPAREN);
} else {
stmt.setInto(exprParser.name());
}
stmt.setAlias(as());
accept(Token.USING);
SQLTableSource using = this.createSQLSelectParser().parseTableSource();
stmt.setUsing(using);
accept(Token.ON);
stmt.setOn(exprParser.expr());
boolean insertFlag = false;
if (lexer.token() == Token.WHEN) {
lexer.nextToken();
if (lexer.token() == Token.MATCHED) {
SQLMergeStatement.MergeUpdateClause updateClause = new SQLMergeStatement.MergeUpdateClause();
lexer.nextToken();
accept(Token.THEN);
accept(Token.UPDATE);
accept(Token.SET);
for (; ; ) {
SQLUpdateSetItem item = this.exprParser.parseUpdateSetItem();
updateClause.addItem(item);
item.setParent(updateClause);
if (lexer.token() == (Token.COMMA)) {
lexer.nextToken();
continue;
}
break;
}
if (lexer.token() == Token.WHERE) {
lexer.nextToken();
updateClause.setWhere(exprParser.expr());
}
if (lexer.token() == Token.DELETE) {
lexer.nextToken();
accept(Token.WHERE);
updateClause.setWhere(exprParser.expr());
}
stmt.setUpdateClause(updateClause);
} else if (lexer.token() == Token.NOT) {
lexer.nextToken();
insertFlag = true;
}
}
if (!insertFlag) {
if (lexer.token() == Token.WHEN) {
lexer.nextToken();
}
if (lexer.token() == Token.NOT) {
lexer.nextToken();
insertFlag = true;
}
}
if (insertFlag) {
SQLMergeStatement.MergeInsertClause insertClause = new SQLMergeStatement.MergeInsertClause();
accept(Token.MATCHED);
accept(Token.THEN);
accept(Token.INSERT);
if (lexer.token() == Token.LPAREN) {
accept(Token.LPAREN);
exprParser.exprList(insertClause.getColumns(), insertClause);
accept(Token.RPAREN);
}
accept(Token.VALUES);
accept(Token.LPAREN);
exprParser.exprList(insertClause.getValues(), insertClause);
accept(Token.RPAREN);
if (lexer.token() == Token.WHERE) {
lexer.nextToken();
insertClause.setWhere(exprParser.expr());
}
stmt.setInsertClause(insertClause);
}
SQLErrorLoggingClause errorClause = parseErrorLoggingClause();
stmt.setErrorLoggingClause(errorClause);
return stmt;
}
protected SQLErrorLoggingClause parseErrorLoggingClause() {
if (identifierEquals("LOG")) {
SQLErrorLoggingClause errorClause = new SQLErrorLoggingClause();
lexer.nextToken();
accept(Token.ERRORS);
if (lexer.token() == Token.INTO) {
lexer.nextToken();
errorClause.setInto(exprParser.name());
}
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
errorClause.setSimpleExpression(exprParser.expr());
accept(Token.RPAREN);
}
if (lexer.token() == Token.REJECT) {
lexer.nextToken();
accept(Token.LIMIT);
errorClause.setLimit(exprParser.expr());
}
return errorClause;
}
return null;
}
public void parseHints(List hints) {
this.getExprParser().parseHints(hints);
}
public SQLStatement parseDescribe() {
if (lexer.token() == Token.DESC || identifierEquals("DESCRIBE")) {
lexer.nextToken();
} else {
throw new ParserException("expect DESC, actual " + lexer.token());
}
SQLDescribeStatement stmt = new SQLDescribeStatement();
stmt.setDbType(dbType);
if (identifierEquals("ROLE")) {
lexer.nextToken();
stmt.setObjectType(SQLObjectType.ROLE);
} else if (identifierEquals("PACKAGE")) {
lexer.nextToken();
stmt.setObjectType(SQLObjectType.PACKAGE);
} else if (identifierEquals("INSTANCE")) {
lexer.nextToken();
stmt.setObjectType(SQLObjectType.INSTANCE);
}
stmt.setObject(this.exprParser.name());
Token token = lexer.token();
if (token == Token.PARTITION) {
lexer.nextToken();
this.accept(Token.LPAREN);
for (; ; ) {
stmt.getPartition().add(this.exprParser.expr());
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
if (lexer.token() == Token.RPAREN) {
lexer.nextToken();
break;
}
}
} else if (token == Token.IDENTIFIER) {
SQLName column = this.exprParser.name();
stmt.setColumn(column);
}
return stmt;
}
}