mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
1415 lines
47 KiB
Java
1415 lines
47 KiB
Java
/*
|
|
* Copyright 1999-2011 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 com.alibaba.druid.sql.parser;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
import com.alibaba.druid.sql.ast.SQLExpr;
|
|
import com.alibaba.druid.sql.ast.SQLName;
|
|
import com.alibaba.druid.sql.ast.SQLStatement;
|
|
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
|
import com.alibaba.druid.sql.ast.expr.SQLListExpr;
|
|
import com.alibaba.druid.sql.ast.expr.SQLQueryExpr;
|
|
import com.alibaba.druid.sql.ast.statement.SQLAlterTableAddColumn;
|
|
import com.alibaba.druid.sql.ast.statement.SQLAlterTableAddConstraint;
|
|
import com.alibaba.druid.sql.ast.statement.SQLAlterTableAddIndex;
|
|
import com.alibaba.druid.sql.ast.statement.SQLAlterTableAlterColumn;
|
|
import com.alibaba.druid.sql.ast.statement.SQLAlterTableDisableConstraint;
|
|
import com.alibaba.druid.sql.ast.statement.SQLAlterTableDisableKeys;
|
|
import com.alibaba.druid.sql.ast.statement.SQLAlterTableDropColumnItem;
|
|
import com.alibaba.druid.sql.ast.statement.SQLAlterTableDropConstraint;
|
|
import com.alibaba.druid.sql.ast.statement.SQLAlterTableEnableConstraint;
|
|
import com.alibaba.druid.sql.ast.statement.SQLAlterTableEnableKeys;
|
|
import com.alibaba.druid.sql.ast.statement.SQLAlterTableStatement;
|
|
import com.alibaba.druid.sql.ast.statement.SQLAssignItem;
|
|
import com.alibaba.druid.sql.ast.statement.SQLCallStatement;
|
|
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
|
|
import com.alibaba.druid.sql.ast.statement.SQLCommentStatement;
|
|
import com.alibaba.druid.sql.ast.statement.SQLConstaint;
|
|
import com.alibaba.druid.sql.ast.statement.SQLCreateDatabaseStatement;
|
|
import com.alibaba.druid.sql.ast.statement.SQLCreateIndexStatement;
|
|
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
|
|
import com.alibaba.druid.sql.ast.statement.SQLCreateTriggerStatement;
|
|
import com.alibaba.druid.sql.ast.statement.SQLCreateTriggerStatement.TriggerEvent;
|
|
import com.alibaba.druid.sql.ast.statement.SQLCreateTriggerStatement.TriggerType;
|
|
import com.alibaba.druid.sql.ast.statement.SQLCreateViewStatement;
|
|
import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement;
|
|
import com.alibaba.druid.sql.ast.statement.SQLDropDatabaseStatement;
|
|
import com.alibaba.druid.sql.ast.statement.SQLDropIndexStatement;
|
|
import com.alibaba.druid.sql.ast.statement.SQLDropSequenceStatement;
|
|
import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement;
|
|
import com.alibaba.druid.sql.ast.statement.SQLDropTriggerStatement;
|
|
import com.alibaba.druid.sql.ast.statement.SQLDropUserStatement;
|
|
import com.alibaba.druid.sql.ast.statement.SQLDropViewStatement;
|
|
import com.alibaba.druid.sql.ast.statement.SQLExplainStatement;
|
|
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
|
|
import com.alibaba.druid.sql.ast.statement.SQLGrantStatement;
|
|
import com.alibaba.druid.sql.ast.statement.SQLGrantStatement.ObjectType;
|
|
import com.alibaba.druid.sql.ast.statement.SQLInsertInto;
|
|
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
|
|
import com.alibaba.druid.sql.ast.statement.SQLPrimaryKey;
|
|
import com.alibaba.druid.sql.ast.statement.SQLReleaseSavePointStatement;
|
|
import com.alibaba.druid.sql.ast.statement.SQLRollbackStatement;
|
|
import com.alibaba.druid.sql.ast.statement.SQLSavePointStatement;
|
|
import com.alibaba.druid.sql.ast.statement.SQLSelect;
|
|
import com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem;
|
|
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
|
|
import com.alibaba.druid.sql.ast.statement.SQLSetStatement;
|
|
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
|
|
import com.alibaba.druid.sql.ast.statement.SQLTruncateStatement;
|
|
import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem;
|
|
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
|
|
import com.alibaba.druid.sql.ast.statement.SQLUseStatement;
|
|
|
|
public class SQLStatementParser extends SQLParser {
|
|
|
|
protected SQLExprParser exprParser;
|
|
|
|
public SQLStatementParser(String sql){
|
|
this(new SQLExprParser(sql));
|
|
}
|
|
|
|
public SQLStatementParser(SQLExprParser exprParser){
|
|
super(exprParser.getLexer());
|
|
this.exprParser = exprParser;
|
|
}
|
|
|
|
public SQLExprParser getExprParser() {
|
|
return exprParser;
|
|
}
|
|
|
|
public List<SQLStatement> parseStatementList() {
|
|
List<SQLStatement> statementList = new ArrayList<SQLStatement>();
|
|
parseStatementList(statementList);
|
|
return statementList;
|
|
}
|
|
|
|
public void parseStatementList(List<SQLStatement> statementList) {
|
|
parseStatementList(statementList, -1);
|
|
}
|
|
|
|
public void parseStatementList(List<SQLStatement> statementList, int max) {
|
|
for (;;) {
|
|
if (max != -1) {
|
|
if (statementList.size() >= max) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (lexer.token() == Token.EOF) {
|
|
return;
|
|
}
|
|
|
|
if (lexer.token() == (Token.SEMI)) {
|
|
lexer.nextToken();
|
|
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) {
|
|
lexer.nextToken();
|
|
|
|
if (lexer.token() == Token.TABLE || identifierEquals("TEMPORARY")) {
|
|
|
|
SQLDropTableStatement stmt = parseDropTable(false);
|
|
|
|
statementList.add(stmt);
|
|
continue;
|
|
} else if (lexer.token() == Token.USER) {
|
|
SQLStatement stmt = parseDropUser();
|
|
statementList.add(stmt);
|
|
continue;
|
|
} else if (lexer.token() == Token.INDEX) {
|
|
SQLStatement stmt = parseDropIndex();
|
|
statementList.add(stmt);
|
|
continue;
|
|
} else if (lexer.token() == Token.VIEW) {
|
|
SQLStatement stmt = parseDropView(false);
|
|
statementList.add(stmt);
|
|
continue;
|
|
} else if (lexer.token() == Token.TRIGGER) {
|
|
SQLStatement stmt = parseDropTrigger(false);
|
|
statementList.add(stmt);
|
|
continue;
|
|
} else if (lexer.token() == Token.DATABASE) {
|
|
SQLStatement stmt = parseDropDatabase(false);
|
|
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.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 (parseStatementListDialect(statementList)) {
|
|
continue;
|
|
}
|
|
|
|
if (lexer.token() == Token.HINT) {
|
|
lexer.nextToken();
|
|
continue;
|
|
}
|
|
|
|
if (lexer.token() == Token.COMMENT) {
|
|
statementList.add(this.parseComment());
|
|
continue;
|
|
}
|
|
|
|
throw new ParserException("syntax error, " + lexer.token() + " " + lexer.stringVal() + ", pos "
|
|
+ lexer.pos());
|
|
}
|
|
}
|
|
|
|
public SQLRollbackStatement parseRollback() {
|
|
lexer.nextToken();
|
|
|
|
if (identifierEquals("WORK")) {
|
|
lexer.nextToken();
|
|
}
|
|
|
|
SQLRollbackStatement stmt = new SQLRollbackStatement();
|
|
|
|
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();
|
|
stmt.setDatabase(this.exprParser.name());
|
|
return stmt;
|
|
}
|
|
|
|
public SQLGrantStatement parseGrant() {
|
|
accept(Token.GRANT);
|
|
SQLGrantStatement stmt = new SQLGrantStatement();
|
|
|
|
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.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.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 {
|
|
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 {
|
|
throw new ParserException("TODO : " + lexer.token() + " " + lexer.stringVal());
|
|
}
|
|
} 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";
|
|
}
|
|
|
|
if (privilege != null) {
|
|
SQLExpr expr = new SQLIdentifierExpr(privilege);
|
|
|
|
if (lexer.token() == Token.LPAREN) {
|
|
expr = this.exprParser.primaryRest(expr);
|
|
}
|
|
|
|
expr.setParent(stmt);
|
|
stmt.getPrivileges().add(expr);
|
|
}
|
|
|
|
if (lexer.token() == Token.COMMA) {
|
|
lexer.nextToken();
|
|
continue;
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (lexer.token() == Token.ON) {
|
|
lexer.nextToken();
|
|
|
|
if (lexer.token() == Token.PROCEDURE) {
|
|
lexer.nextToken();
|
|
stmt.setObjectType(ObjectType.PROCEDURE);
|
|
} else if (lexer.token() == Token.FUNCTION) {
|
|
lexer.nextToken();
|
|
stmt.setObjectType(ObjectType.FUNCTION);
|
|
} else if (lexer.token() == Token.TABLE) {
|
|
lexer.nextToken();
|
|
stmt.setObjectType(ObjectType.TABLE);
|
|
} else if (lexer.token() == Token.USER) {
|
|
lexer.nextToken();
|
|
stmt.setObjectType(ObjectType.USER);
|
|
}
|
|
|
|
stmt.setOn(this.exprParser.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);
|
|
}
|
|
|
|
return stmt;
|
|
}
|
|
|
|
public SQLStatement parseSavePoint() {
|
|
acceptIdentifier("SAVEPOINT");
|
|
SQLSavePointStatement stmt = new SQLSavePointStatement();
|
|
stmt.setName(this.exprParser.name());
|
|
return stmt;
|
|
}
|
|
|
|
public SQLStatement parseReleaseSavePoint() {
|
|
acceptIdentifier("RELEASE");
|
|
acceptIdentifier("SAVEPOINT");
|
|
SQLReleaseSavePointStatement stmt = new SQLReleaseSavePointStatement();
|
|
stmt.setName(this.exprParser.name());
|
|
return stmt;
|
|
}
|
|
|
|
public SQLStatement parseAlter() {
|
|
accept(Token.ALTER);
|
|
|
|
if (lexer.token() == Token.TABLE) {
|
|
lexer.nextToken();
|
|
|
|
SQLAlterTableStatement stmt = new SQLAlterTableStatement();
|
|
stmt.setName(this.exprParser.name());
|
|
|
|
for (;;) {
|
|
if (lexer.token() == Token.DROP) {
|
|
parseAlterDrop(stmt);
|
|
} else if (identifierEquals("ADD")) {
|
|
lexer.nextToken();
|
|
|
|
if (lexer.token() == Token.PRIMARY) {
|
|
SQLPrimaryKey primaryKey = this.exprParser.parsePrimaryKey();
|
|
SQLAlterTableAddConstraint item = new SQLAlterTableAddConstraint(primaryKey);
|
|
stmt.getItems().add(item);
|
|
} else if (lexer.token() == Token.IDENTIFIER) {
|
|
SQLAlterTableAddColumn item = parseAlterTableAddColumn();
|
|
stmt.getItems().add(item);
|
|
} 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.getItems().add(item);
|
|
} else {
|
|
acceptIdentifier("KEYS");
|
|
SQLAlterTableDisableKeys item = new SQLAlterTableDisableKeys();
|
|
stmt.getItems().add(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.getItems().add(item);
|
|
} else {
|
|
acceptIdentifier("KEYS");
|
|
SQLAlterTableEnableKeys item = new SQLAlterTableEnableKeys();
|
|
stmt.getItems().add(item);
|
|
}
|
|
} else if (lexer.token() == Token.ALTER) {
|
|
lexer.nextToken();
|
|
if (lexer.token() == Token.COLUMN) {
|
|
lexer.nextToken();
|
|
SQLColumnDefinition column = this.exprParser.parseColumn();
|
|
SQLAlterTableAlterColumn alterColumn = new SQLAlterTableAlterColumn();
|
|
alterColumn.setColumn(column);
|
|
stmt.getItems().add(alterColumn);
|
|
} else {
|
|
throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal());
|
|
}
|
|
} else if (lexer.token() == Token.WITH) {
|
|
lexer.nextToken();
|
|
acceptIdentifier("NOCHECK");
|
|
acceptIdentifier("ADD");
|
|
SQLConstaint check = this.exprParser.parseConstaint();
|
|
|
|
SQLAlterTableAddConstraint addCheck = new SQLAlterTableAddConstraint();
|
|
addCheck.setWithNoCheck(true);
|
|
addCheck.setConstraint(check);
|
|
stmt.getItems().add(addCheck);
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
|
|
return stmt;
|
|
}
|
|
throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal());
|
|
}
|
|
|
|
public void parseAlterDrop(SQLAlterTableStatement stmt) {
|
|
lexer.nextToken();
|
|
|
|
if (lexer.token() == Token.CONSTRAINT) {
|
|
lexer.nextToken();
|
|
SQLAlterTableDropConstraint item = new SQLAlterTableDropConstraint();
|
|
item.setConstraintName(this.exprParser.name());
|
|
stmt.getItems().add(item);
|
|
} else if (lexer.token() == Token.COLUMN) {
|
|
lexer.nextToken();
|
|
SQLAlterTableDropColumnItem item = new SQLAlterTableDropColumnItem();
|
|
this.exprParser.names(item.getColumns());
|
|
stmt.getItems().add(item);
|
|
} else {
|
|
throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal());
|
|
}
|
|
}
|
|
|
|
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();
|
|
|
|
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.getTableSources().add(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) {
|
|
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();
|
|
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();
|
|
stmt.setName(name);
|
|
return stmt;
|
|
}
|
|
|
|
protected SQLDropViewStatement parseDropView(boolean acceptDrop) {
|
|
if (acceptDrop) {
|
|
accept(Token.DROP);
|
|
}
|
|
|
|
SQLDropViewStatement stmt = new SQLDropViewStatement();
|
|
|
|
accept(Token.VIEW);
|
|
|
|
if (lexer.token() == Token.IF) {
|
|
lexer.nextToken();
|
|
accept(Token.EXISTS);
|
|
stmt.setIfExists(true);
|
|
}
|
|
|
|
for (;;) {
|
|
SQLName name = this.exprParser.name();
|
|
stmt.getTableSources().add(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();
|
|
|
|
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;
|
|
}
|
|
|
|
public SQLStatement parseTruncate() {
|
|
accept(Token.TRUNCATE);
|
|
if (lexer.token() == Token.TABLE) {
|
|
lexer.nextToken();
|
|
}
|
|
SQLTruncateStatement stmt = new SQLTruncateStatement();
|
|
|
|
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;
|
|
}
|
|
|
|
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();
|
|
this.exprParser.exprList(insertStatement.getColumns());
|
|
accept(Token.RPAREN);
|
|
}
|
|
|
|
if (lexer.token() == Token.VALUES) {
|
|
lexer.nextToken();
|
|
accept(Token.LPAREN);
|
|
SQLInsertStatement.ValuesClause values = new SQLInsertStatement.ValuesClause();
|
|
this.exprParser.exprList(values.getValues());
|
|
insertStatement.setValues(values);
|
|
accept(Token.RPAREN);
|
|
} else if (acceptSubQuery && (lexer.token() == Token.SELECT || lexer.token() == Token.LPAREN)) {
|
|
SQLQueryExpr queryExpr = (SQLQueryExpr) this.exprParser.expr();
|
|
insertStatement.setQuery(queryExpr.getSubQuery());
|
|
}
|
|
}
|
|
|
|
public boolean parseStatementListDialect(List<SQLStatement> statementList) {
|
|
return false;
|
|
}
|
|
|
|
public SQLDropUserStatement parseDropUser() {
|
|
accept(Token.USER);
|
|
|
|
SQLDropUserStatement stmt = new SQLDropUserStatement();
|
|
for (;;) {
|
|
SQLExpr expr = this.exprParser.expr();
|
|
stmt.getUsers().add(expr);
|
|
if (lexer.token() == Token.COMMA) {
|
|
lexer.nextToken();
|
|
continue;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return stmt;
|
|
}
|
|
|
|
public SQLStatement parseDropIndex() {
|
|
accept(Token.INDEX);
|
|
SQLDropIndexStatement stmt = new SQLDropIndexStatement();
|
|
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;
|
|
}
|
|
|
|
acceptIdentifier("CALL");
|
|
|
|
SQLCallStatement stmt = new SQLCallStatement();
|
|
stmt.setProcedureName(exprParser.name());
|
|
|
|
if (lexer.token() == Token.LPAREN) {
|
|
lexer.nextToken();
|
|
exprParser.exprList(stmt.getParameters());
|
|
accept(Token.RPAREN);
|
|
}
|
|
|
|
if (brace) {
|
|
accept(Token.RBRACE);
|
|
}
|
|
|
|
return stmt;
|
|
}
|
|
|
|
public SQLStatement parseSet() {
|
|
accept(Token.SET);
|
|
SQLSetStatement stmt = new SQLSetStatement();
|
|
|
|
parseAssignItems(stmt.getItems());
|
|
|
|
return stmt;
|
|
}
|
|
|
|
public void parseAssignItems(List<SQLAssignItem> items) {
|
|
for (;;) {
|
|
SQLAssignItem item = exprParser.parseAssignItem();
|
|
items.add(item);
|
|
|
|
if (lexer.token() == Token.COMMA) {
|
|
lexer.nextToken();
|
|
continue;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
public SQLStatement parseCreate() {
|
|
char markChar = lexer.current();
|
|
int markBp = lexer.bp();
|
|
|
|
accept(Token.CREATE);
|
|
|
|
Token token = lexer.token();
|
|
|
|
if (token == Token.TABLE || identifierEquals("GLOBAL")) {
|
|
SQLCreateTableParser createTableParser = getSQLCreateTableParser();
|
|
return createTableParser.parseCrateTable(false);
|
|
} 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();
|
|
}
|
|
|
|
// 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();
|
|
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);
|
|
}
|
|
|
|
SQLStatement body = this.parseBlock();
|
|
stmt.setBody(body);
|
|
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();
|
|
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();
|
|
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.getItems().add(item);
|
|
if (lexer.token() == Token.COMMA) {
|
|
lexer.nextToken();
|
|
continue;
|
|
}
|
|
break;
|
|
}
|
|
accept(Token.RPAREN);
|
|
|
|
return stmt;
|
|
}
|
|
|
|
public SQLCreateTableParser getSQLCreateTableParser() {
|
|
return new SQLCreateTableParser(this.exprParser);
|
|
}
|
|
|
|
public SQLSelectStatement parseSelect() {
|
|
SQLSelectParser selectParser = createSQLSelectParser();
|
|
SQLSelect select = selectParser.select();
|
|
return new SQLSelectStatement(select);
|
|
}
|
|
|
|
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 = new SQLUpdateSetItem();
|
|
|
|
if (lexer.token() == (Token.LPAREN)) {
|
|
lexer.nextToken();
|
|
SQLListExpr list = new SQLListExpr();
|
|
this.exprParser.exprList(list.getItems());
|
|
accept(Token.RPAREN);
|
|
item.setColumn(list);
|
|
} else {
|
|
item.setColumn(this.exprParser.primary());
|
|
}
|
|
accept(Token.EQ);
|
|
item.setValue(this.exprParser.expr());
|
|
update.getItems().add(item);
|
|
|
|
if (lexer.token() != Token.COMMA) {
|
|
break;
|
|
}
|
|
|
|
lexer.nextToken();
|
|
}
|
|
}
|
|
|
|
protected SQLUpdateStatement createUpdateStatement() {
|
|
return new SQLUpdateStatement();
|
|
}
|
|
|
|
public SQLDeleteStatement parseDeleteStatement() {
|
|
SQLDeleteStatement deleteStatement = new SQLDeleteStatement();
|
|
|
|
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.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();
|
|
|
|
if (lexer.token() == Token.CREATE) {
|
|
lexer.nextToken();
|
|
}
|
|
|
|
if (lexer.token() == Token.OR) {
|
|
lexer.nextToken();
|
|
accept(Token.REPLACE);
|
|
createView.setOrReplace(true);
|
|
}
|
|
|
|
this.accept(Token.VIEW);
|
|
|
|
createView.setName(exprParser.name());
|
|
|
|
if (lexer.token() == Token.LPAREN) {
|
|
lexer.nextToken();
|
|
this.exprParser.exprList(createView.getColumns());
|
|
accept(Token.RPAREN);
|
|
}
|
|
|
|
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() {
|
|
SQLAlterTableAddColumn item = new SQLAlterTableAddColumn();
|
|
|
|
for (;;) {
|
|
SQLColumnDefinition columnDef = this.exprParser.parseColumn();
|
|
item.getColumns().add(columnDef);
|
|
if (lexer.token() == Token.COMMA) {
|
|
lexer.nextToken();
|
|
continue;
|
|
}
|
|
break;
|
|
}
|
|
return item;
|
|
}
|
|
|
|
public SQLStatement parseStatement() {
|
|
List<SQLStatement> list = new ArrayList<SQLStatement>();
|
|
|
|
this.parseStatementList(list, 1);
|
|
|
|
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();
|
|
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 {
|
|
accept(Token.INDEX);
|
|
}
|
|
|
|
if (lexer.token() == Token.LPAREN) {
|
|
lexer.nextToken();
|
|
} else {
|
|
item.setName(this.exprParser.name());
|
|
accept(Token.LPAREN);
|
|
}
|
|
|
|
for (;;) {
|
|
SQLSelectOrderByItem column = this.exprParser.parseSelectOrderByItem();
|
|
item.getItems().add(column);
|
|
if (lexer.token() == Token.COMMA) {
|
|
lexer.nextToken();
|
|
continue;
|
|
}
|
|
break;
|
|
}
|
|
accept(Token.RPAREN);
|
|
return item;
|
|
}
|
|
}
|