/**
* Alipay.com Inc.
* Copyright (c) 2004-2012 All Rights Reserved.
*/
package com.alipay.zdal.parser.sql.parser;
import java.util.ArrayList;
import java.util.List;
import com.alipay.zdal.parser.sql.ast.SQLExpr;
import com.alipay.zdal.parser.sql.ast.SQLName;
import com.alipay.zdal.parser.sql.ast.SQLStatement;
import com.alipay.zdal.parser.sql.ast.expr.SQLQueryExpr;
import com.alipay.zdal.parser.sql.ast.statement.SQLAssignItem;
import com.alipay.zdal.parser.sql.ast.statement.SQLCallStatement;
import com.alipay.zdal.parser.sql.ast.statement.SQLCommentStatement;
import com.alipay.zdal.parser.sql.ast.statement.SQLCreateDatabaseStatement;
import com.alipay.zdal.parser.sql.ast.statement.SQLCreateTableStatement;
import com.alipay.zdal.parser.sql.ast.statement.SQLCreateViewStatement;
import com.alipay.zdal.parser.sql.ast.statement.SQLDeleteStatement;
import com.alipay.zdal.parser.sql.ast.statement.SQLDropIndexStatement;
import com.alipay.zdal.parser.sql.ast.statement.SQLDropTableStatement;
import com.alipay.zdal.parser.sql.ast.statement.SQLDropViewStatement;
import com.alipay.zdal.parser.sql.ast.statement.SQLExprTableSource;
import com.alipay.zdal.parser.sql.ast.statement.SQLInsertInto;
import com.alipay.zdal.parser.sql.ast.statement.SQLInsertStatement;
import com.alipay.zdal.parser.sql.ast.statement.SQLReleaseSavePointStatement;
import com.alipay.zdal.parser.sql.ast.statement.SQLRollbackStatement;
import com.alipay.zdal.parser.sql.ast.statement.SQLSavePointStatement;
import com.alipay.zdal.parser.sql.ast.statement.SQLSelectStatement;
import com.alipay.zdal.parser.sql.ast.statement.SQLSetStatement;
import com.alipay.zdal.parser.sql.ast.statement.SQLTableSource;
import com.alipay.zdal.parser.sql.ast.statement.SQLTruncateStatement;
import com.alipay.zdal.parser.sql.ast.statement.SQLUpdateSetItem;
import com.alipay.zdal.parser.sql.ast.statement.SQLUpdateStatement;
import com.alipay.zdal.parser.sql.ast.statement.SQLUseStatement;
/**
*
* @author ����
* @version $Id: SQLStatementParser.java, v 0.1 2012-11-17 ����3:54:46 Exp $
*/
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() throws ParserException {
List<SQLStatement> statementList = new ArrayList<SQLStatement>();
parseStatementList(statementList);
return statementList;
}
public void parseStatementList(List<SQLStatement> statementList) throws ParserException {
for (;;) {
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.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 (identifierEquals("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 {
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 (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 (identifierEquals("SHOW")) {
SQLStatement stmt = parseShow();
statementList.add(stmt);
continue;
}
if (lexer.token() == Token.LPAREN) {
char mark_ch = lexer.current();
int mark_bp = lexer.bp();
lexer.nextToken();
if (lexer.token() == Token.SELECT) {
lexer.reset(mark_bp, mark_ch, Token.LPAREN);
SQLStatement stmt = parseSelect();
statementList.add(stmt);
continue;
}
}
if (parseStatementListDialect(statementList)) {
continue;
}
if (lexer.token() == Token.HINT) {
lexer.nextToken();
continue;
}
throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal());
}
}
public SQLRollbackStatement parseRollback() {
lexer.nextToken();
if (identifierEquals("WORK")) {
lexer.nextToken();
}
SQLRollbackStatement stmt = new SQLRollbackStatement();
if (identifierEquals("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 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);
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);
}
accept(Token.TABLE);
SQLDropTableStatement stmt = new SQLDropTableStatement();
for (;;) {
SQLName name = this.exprParser.name();
stmt.getTableSources().add(new SQLExprTableSource(name));
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
break;
}
return stmt;
}
protected SQLDropViewStatement parseDropView(boolean acceptDrop) {
if (acceptDrop) {
accept(Token.DROP);
}
accept(Token.VIEW);
SQLDropViewStatement stmt = new SQLDropViewStatement();
for (;;) {
SQLName name = this.exprParser.name();
stmt.getTableSources().add(new SQLExprTableSource(name));
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
break;
}
return stmt;
}
public SQLStatement parseTruncate() {
accept(Token.TRUNCATE);
if (lexer.token() == Token.TABLE) {
lexer.nextToken();
}
SQLTruncateStatement stmt = new SQLTruncateStatement();
for (;;) {
SQLName name = this.exprParser.name();
stmt.addTableSource(name);
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
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 parseInsert0Hinits(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());
}
parseInsert0Hinits(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 SQLStatement parseDropUser() throws ParserException {
throw new ParserException("TODO " + lexer.token());
}
public SQLStatement parseDropIndex() throws ParserException {
accept(Token.INDEX);
SQLDropIndexStatement stmt = new SQLDropIndexStatement();
stmt.setIndexName(this.exprParser.name());
accept(Token.ON);
stmt.setTableName(this.exprParser.name());
return stmt;
}
public SQLCallStatement parseCall() throws ParserException {
acceptIdentifier("CALL");
SQLCallStatement stmt = new SQLCallStatement();
stmt.setProcedureName(exprParser.name());
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
exprParser.exprList(stmt.getParameters());
accept(Token.RPAREN);
}
return stmt;
}
public SQLStatement parseSet() throws ParserException {
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() throws ParserException {
char mark_ch = lexer.current();
int mark_bp = 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) {
return parseCreateIndex(false);
} else if (identifierEquals("SEQUENCE")) {
return parseCreateSequence(false);
} else if (token == Token.OR) {
lexer.nextToken();
acceptIdentifier("REPLACE");
if (lexer.token() == Token.PROCEDURE) {
lexer.reset(mark_bp, mark_ch, 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) {
return parseCreateDatabase();
}
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) {
throw new ParserException("TODO " + lexer.token());
}
public SQLCreateTableParser getSQLCreateTableParser() {
return new SQLCreateTableParser(this.exprParser);
}
public SQLSelectStatement parseSelect() throws ParserException {
return new SQLSelectStatement(createSQLSelectParser().select());
}
public SQLSelectParser createSQLSelectParser() {
return new SQLSelectParser(this.exprParser);
}
public SQLUpdateStatement parseUpdateStatement() throws ParserException {
SQLUpdateStatement udpateStatement = createUpdateStatement();
if (lexer.token() == Token.UPDATE) {
lexer.nextToken();
SQLTableSource tableSource = this.exprParser.createSelectParser().parseTableSource();
udpateStatement.setTableSource(tableSource);
}
accept(Token.SET);
for (;;) {
SQLUpdateSetItem item = new SQLUpdateSetItem();
item.setColumn(this.exprParser.name());
accept(Token.EQ);
item.setValue(this.exprParser.expr());
udpateStatement.getItems().add(item);
if (lexer.token() == (Token.COMMA)) {
lexer.nextToken();
continue;
}
break;
}
if (lexer.token() == (Token.WHERE)) {
lexer.nextToken();
udpateStatement.setWhere(this.exprParser.expr());
}
return udpateStatement;
}
protected SQLUpdateStatement createUpdateStatement() {
return new SQLUpdateStatement();
}
public SQLDeleteStatement parseDeleteStatement() throws ParserException {
SQLDeleteStatement deleteStatement = new SQLDeleteStatement();
if (lexer.token() == Token.DELETE) {
lexer.nextToken();
if (lexer.token() == (Token.FROM)) {
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() throws ParserException {
// SQLCreateTableParser parser = new SQLCreateTableParser(this.lexer);
// return parser.parseCrateTable();
throw new ParserException("TODO");
}
public SQLCreateViewStatement parseCreateView() throws ParserException {
SQLCreateViewStatement createView = new SQLCreateViewStatement();
this.accept(Token.CREATE);
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;
}
}