Package com.alibaba.wasp.plan.parser.druid.dialect

Source Code of com.alibaba.wasp.plan.parser.druid.dialect.WaspSqlStatementParser

/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you 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.wasp.plan.parser.druid.dialect;

import com.alibaba.druid.sql.ast.SQLCommentHint;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLOrderBy;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableAddPrimaryKey;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableDropColumnItem;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableDropIndex;
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
import com.alibaba.druid.sql.ast.statement.SQLCreateDatabaseStatement;
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
import com.alibaba.druid.sql.ast.statement.SQLPrimaryKey;
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.SQLTableSource;
import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem;
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
import com.alibaba.druid.sql.parser.Lexer;
import com.alibaba.druid.sql.parser.ParserException;
import com.alibaba.druid.sql.parser.SQLSelectParser;
import com.alibaba.druid.sql.parser.SQLStatementParser;
import com.alibaba.druid.sql.parser.Token;
import com.alibaba.wasp.plan.parser.druid.dialect.WaspSqlLockTableStatement.LockType;

import java.util.List;

/**
*
*
*/
public class WaspSqlStatementParser extends SQLStatementParser {
  private static final String COLLATE2 = "COLLATE";
  private static final String CASCADE = "CASCADE";
  private static final String RESTRICT = "RESTRICT";
  private static final String CHARACTER = "CHARACTER";
  private static final String SESSION = "SESSION";
  private static final String GLOBAL = "GLOBAL";
  private static final String VARIABLES = "VARIABLES";
  private static final String ERRORS = "ERRORS";
  private static final String STATUS = "STATUS";
  private static final String IGNORE = "IGNORE";
  private static final String DESCRIBE = "DESCRIBE";
  private static final String DESC = "DESC";
  private static final String WRITE = "WRITE";
  private static final String READ = "READ";
  private static final String LOCAL = "LOCAL";
  private static final String TABLES = "TABLES";
  private static final String TEMPORARY = "TEMPORARY";
  private static final String USER = "USER";
  private static final String SPATIAL = "SPATIAL";
  private static final String FULLTEXT = "FULLTEXT";
  private static final String REPLACE = "REPLACE";
  private static final String DELAYED = "DELAYED";
  private static final String LOW_PRIORITY = "LOW_PRIORITY";

  /**
   * @param lexer
   */
  public WaspSqlStatementParser(Lexer lexer) {
    super(new WaspSqlExprParser(lexer));
  }

  public WaspSqlStatementParser(String sql) {
    super(new WaspSqlExprParser(sql));
  }

  public SQLStatement parseCreate() {
    accept(Token.CREATE);
    List<SQLCommentHint> hints = this.exprParser.parseHints();
    if (lexer.token() == Token.TABLE || identifierEquals(TEMPORARY)) {
      WaspSqlCreateTableParser parser = new WaspSqlCreateTableParser(
          this.exprParser);
      WaspSqlCreateTableStatement stmt = parser.parseCrateTable(false);
      stmt.setHints(hints);
      return stmt;
    }
    if (lexer.token() == Token.DATABASE) {
      return parseCreateDatabase();
    }
    if (lexer.token() == Token.UNIQUE || lexer.token() == Token.INDEX
       // || identifierEquals(FULLTEXT) || identifierEquals(SPATIAL)
       ) {
      return parseCreateIndex();
    }

    if (identifierEquals(USER)) {
      return parseCreateUser();
    }
    throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal());
  }

  public SQLStatement parseCreateIndex()  {
    WaspSqlCreateIndexStatement stmt = new WaspSqlCreateIndexStatement();
    if (lexer.token() == Token.UNIQUE) {
      stmt.setType("UNIQUE");
      lexer.nextToken();
    } else if (identifierEquals(FULLTEXT)) {
      stmt.setType(FULLTEXT);
      lexer.nextToken();
    } else if (identifierEquals(SPATIAL)) {
      stmt.setType(SPATIAL);
      lexer.nextToken();
    }
    accept(Token.INDEX);
    stmt.setName(this.exprParser.name());
    parseCreateIndexUsing(stmt);
    accept(Token.ON);
    stmt.setTable(this.exprParser.name());
    accept(Token.LPAREN);
    for (;;) {
      SQLSelectOrderByItem item = this.exprParser.parseSelectOrderByItem();
      stmt.getItems().add(item);
      if (lexer.token() == Token.COMMA) {
        lexer.nextToken();
        continue;
      }
      break;
    }
    accept(Token.RPAREN);
    parseCreateIndexUsing(stmt);
    return stmt;
  }

  private void parseCreateIndexUsing(WaspSqlCreateIndexStatement stmt) {
    if (identifierEquals("USING")) {
      lexer.nextToken();
      if (identifierEquals("BTREE")) {
        stmt.setUsing("BTREE");
        lexer.nextToken();
      } else if (identifierEquals("HASH")) {
        stmt.setUsing("HASH");
        lexer.nextToken();
      } else {
        throw new ParserException("TODO " + lexer.token() + " "
            + lexer.stringVal());
      }
    } else if (identifierEquals("STORING")) {
      lexer.nextToken();
      accept(Token.LPAREN);
      for (;;) {
        stmt.getStoringCols().add(this.exprParser.expr());
        if (!(lexer.token() == (Token.COMMA))) {
          break;
        } else {
          lexer.nextToken();
        }
      }
      accept(Token.RPAREN);
    }
  }

  public SQLCreateTableStatement parseCreateTable() {
    WaspSqlCreateTableParser parser = new WaspSqlCreateTableParser(
        this.exprParser);
    return parser.parseCrateTable(false);
  }

  public SQLSelectStatement parseSelect() {
    return new SQLSelectStatement(
        new WaspSqlSelectParser(this.exprParser).select());
  }

  public SQLUpdateStatement parseUpdateStatement() {
    WaspSqlUpdateStatement stmt = createUpdateStatement();
    if (lexer.token() == Token.UPDATE) {
      lexer.nextToken();
      if (identifierEquals(LOW_PRIORITY)) {
        lexer.nextToken();
        stmt.setLowPriority(true);
      }
      if (identifierEquals(IGNORE)) {
        lexer.nextToken();
        stmt.setIgnore(true);
      }
      SQLTableSource tableSource = this.exprParser.createSelectParser()
          .parseTableSource();
      stmt.setTableSource(tableSource);
    }
    accept(Token.SET);
    for (;;) {
      SQLUpdateSetItem item = new SQLUpdateSetItem();
      item.setColumn(this.exprParser.name());
      if (lexer.token() == Token.EQ) {
        lexer.nextToken();
      } else {
        accept(Token.COLONEQ);
      }
      item.setValue(this.exprParser.expr());
      stmt.getItems().add(item);
      if (lexer.token() == (Token.COMMA)) {
        lexer.nextToken();
        continue;
      }
      break;
    }
    if (lexer.token() == (Token.WHERE)) {
      lexer.nextToken();
      stmt.setWhere(this.exprParser.expr());
    }
    stmt.setOrderBy(this.exprParser.parseOrderBy());
    stmt.setLimit(parseLimit());
    return stmt;
  }

  protected WaspSqlUpdateStatement createUpdateStatement() {
    return new WaspSqlUpdateStatement();
  }

  public WaspSqlDeleteStatement parseDeleteStatement() {
    WaspSqlDeleteStatement deleteStatement = new WaspSqlDeleteStatement();
    if (lexer.token() == Token.DELETE) {
      lexer.nextToken();
      if (identifierEquals(LOW_PRIORITY)) {
        deleteStatement.setLowPriority(true);
        lexer.nextToken();
      }
      if (identifierEquals("QUICK")) {
        deleteStatement.setQuick(true);
        lexer.nextToken();
      }
      if (identifierEquals(IGNORE)) {
        deleteStatement.setIgnore(true);
        lexer.nextToken();
      }
      if (lexer.token() == Token.IDENTIFIER) {
        deleteStatement.setTableSource(createSQLSelectParser()
            .parseTableSource());
        if (lexer.token() == Token.FROM) {
          lexer.nextToken();
          SQLTableSource tableSource = createSQLSelectParser()
              .parseTableSource();
          deleteStatement.setFrom(tableSource);
        }
      } else {
        if (lexer.token() == Token.FROM) {
          lexer.nextToken();
          deleteStatement.setTableSource(createSQLSelectParser()
              .parseTableSource());
        }
      }
      if (identifierEquals("USING")) {
        lexer.nextToken();
        SQLTableSource tableSource = createSQLSelectParser().parseTableSource();
        deleteStatement.setUsing(tableSource);
      }
    }

    if (lexer.token() == (Token.WHERE)) {
      lexer.nextToken();
      SQLExpr where = this.exprParser.expr();
      deleteStatement.setWhere(where);
    }
    if (lexer.token() == (Token.ORDER)) {
      SQLOrderBy orderBy = exprParser.parseOrderBy();
      deleteStatement.setOrderBy(orderBy);
    }
    deleteStatement.setLimit(parseLimit());
    return deleteStatement;
  }

  public SQLStatement parseCreateUser() {
    if (lexer.token() == Token.CREATE) {
      lexer.nextToken();
    }
    acceptIdentifier(USER);
    WaspSqlCreateUserStatement stmt = new WaspSqlCreateUserStatement();
    for (;;) {
      WaspSqlCreateUserStatement.UserSpecification userSpec = new WaspSqlCreateUserStatement.UserSpecification();
      SQLExpr expr = exprParser.primary();
      userSpec.setUser(expr);
      if (lexer.token() == Token.IDENTIFIED) {
        lexer.nextToken();
        if (lexer.token() == Token.BY) {
          lexer.nextToken();
          if (identifierEquals("PASSWORD")) {
            lexer.nextToken();
          }
          SQLCharExpr password = (SQLCharExpr) this.exprParser.expr();
          userSpec.setPassword(password);
        } else if (lexer.token() == Token.WITH) {
          lexer.nextToken();
          SQLCharExpr text = (SQLCharExpr) this.exprParser.expr();
          userSpec.setAuthPlugin(text);
        }
      }
      stmt.getUsers().add(userSpec);
      if (lexer.token() == Token.COMMA) {
        lexer.nextToken();
        continue;
      }
      break;
    }
    return stmt;
  }

  public SQLStatement parseKill() {
    accept(Token.KILL);
    WaspSqlKillStatement stmt = new WaspSqlKillStatement();
    if (identifierEquals("CONNECTION")) {
      stmt.setType(WaspSqlKillStatement.Type.CONNECTION);
      lexer.nextToken();
    } else if (identifierEquals("QUERY")) {
      stmt.setType(WaspSqlKillStatement.Type.QUERY);
      lexer.nextToken();
    } else {
      throw new ParserException("not support kill type " + lexer.token());
    }
    SQLExpr threadId = this.exprParser.expr();
    stmt.setThreadId(threadId);
    return stmt;
  }

  public boolean parseStatementListDialect(List<SQLStatement> statementList) {
    if (lexer.token() == Token.KILL) {
      SQLStatement stmt = parseKill();
      statementList.add(stmt);
      return true;
    }

    if (identifierEquals("PREPARE")) {
      WaspSqlPrepareStatement stmt = parsePrepare();
      statementList.add(stmt);
      return true;
    }

    if (identifierEquals("EXECUTE")) {
      WaspSqlExecuteStatement stmt = parseExecute();
      statementList.add(stmt);
      return true;
    }

    if (identifierEquals("LOAD")) {
      SQLStatement stmt = parseLoad();
      statementList.add(stmt);
      return true;
    }

    if (identifierEquals("START")) {
      WaspSqlStartTransactionStatement stmt = parseStart();
      statementList.add(stmt);
      return true;
    }

    if (identifierEquals("SHOW")) {
      SQLStatement stmt = parseShow();
      statementList.add(stmt);
      return true;
    }

    if (identifierEquals("HELP")) {
      lexer.nextToken();
      WaspSqlHelpStatement stmt = new WaspSqlHelpStatement();
      stmt.setContent(this.exprParser.primary());
      statementList.add(stmt);
      return true;
    }

    if (identifierEquals(DESC) || identifierEquals(DESCRIBE)) {
      SQLStatement stmt = parseDescribe();
      statementList.add(stmt);
      return true;
    }

    if (lexer.token() == Token.LOCK) {
      lexer.nextToken();
      acceptIdentifier(TABLES);

      WaspSqlLockTableStatement stmt = new WaspSqlLockTableStatement();
      stmt.setTableSource(this.exprParser.name());

      if (identifierEquals(READ)) {
        lexer.nextToken();
        if (identifierEquals(LOCAL)) {
          lexer.nextToken();
          stmt.setLockType(LockType.READ_LOCAL);
        } else {
          stmt.setLockType(LockType.READ);
        }
      } else if (identifierEquals(WRITE)) {
        stmt.setLockType(LockType.WRITE);
      } else if (identifierEquals(LOW_PRIORITY)) {
        lexer.nextToken();
        acceptIdentifier(WRITE);
        stmt.setLockType(LockType.LOW_PRIORITY_WRITE);
      }

      statementList.add(stmt);
      return true;
    }

    if (identifierEquals("UNLOCK")) {
      lexer.nextToken();
      acceptIdentifier(TABLES);
      statementList.add(new WaspSqlUnlockTablesStatement());
      return true;
    }

    return false;
  }

  public WaspSqlDescribeStatement parseDescribe() {
    if (lexer.token() == Token.DESC || identifierEquals(DESCRIBE)) {
      lexer.nextToken();
    } else {
      throw new ParserException("expect DESC, actual " + lexer.token());
    }

    WaspSqlDescribeStatement stmt = new WaspSqlDescribeStatement();
    stmt.setObject(this.exprParser.name());

    return stmt;
  }

  public SQLStatement parseShow() {
    acceptIdentifier("SHOW");
    if (lexer.token() == Token.FULL) {
      lexer.nextToken();
      if (identifierEquals("PROCESSLIST")) {
        lexer.nextToken();
        WaspSqlShowProcessListStatement stmt = new WaspSqlShowProcessListStatement();
        stmt.setFull(true);
        return stmt;
      }
      acceptIdentifier("COLUMNS");
      WaspSqlShowColumnsStatement stmt = parseShowColumns();
      stmt.setFull(true);
      return stmt;
    }
    if (identifierEquals("COLUMNS")) {
      lexer.nextToken();
      WaspSqlShowColumnsStatement stmt = parseShowColumns();
      return stmt;
    }
    if (identifierEquals(TABLES)) {
      lexer.nextToken();
      WaspSqlShowTablesStatement stmt = parseShowTabless();
      return stmt;
    }
    if (identifierEquals("DATABASES")) {
      lexer.nextToken();
      WaspSqlShowDatabasesStatement stmt = parseShowDatabases();
      return stmt;
    }
    if (identifierEquals("WARNINGS")) {
      lexer.nextToken();
      WaspSqlShowWarningsStatement stmt = parseShowWarnings();
      return stmt;
    }
    if (identifierEquals("COUNT")) {
      lexer.nextToken();
      accept(Token.LPAREN);
      accept(Token.STAR);
      accept(Token.RPAREN);
      if (identifierEquals(ERRORS)) {
        lexer.nextToken();
        WaspSqlShowErrorsStatement stmt = new WaspSqlShowErrorsStatement();
        stmt.setCount(true);
        return stmt;
      } else {
        acceptIdentifier("WARNINGS");
        WaspSqlShowWarningsStatement stmt = new WaspSqlShowWarningsStatement();
        stmt.setCount(true);
        return stmt;
      }
    }
    if (identifierEquals(ERRORS)) {
      lexer.nextToken();
      WaspSqlShowErrorsStatement stmt = new WaspSqlShowErrorsStatement();
      stmt.setLimit(parseLimit());
      return stmt;
    }
    if (identifierEquals(STATUS)) {
      lexer.nextToken();
      WaspSqlShowStatusStatement stmt = parseShowStatus();
      return stmt;
    }
    if (identifierEquals(VARIABLES)) {
      lexer.nextToken();
      WaspSqlShowVariantsStatement stmt = parseShowVariants();
      return stmt;
    }
    if (identifierEquals(GLOBAL)) {
      lexer.nextToken();
      if (identifierEquals(STATUS)) {
        lexer.nextToken();
        WaspSqlShowStatusStatement stmt = parseShowStatus();
        stmt.setGlobal(true);
        return stmt;
      }
      if (identifierEquals(VARIABLES)) {
        lexer.nextToken();
        WaspSqlShowVariantsStatement stmt = parseShowVariants();
        stmt.setGlobal(true);
        return stmt;
      }
    }
    if (identifierEquals(SESSION)) {
      lexer.nextToken();
      if (identifierEquals(STATUS)) {
        lexer.nextToken();
        WaspSqlShowStatusStatement stmt = parseShowStatus();
        stmt.setSession(true);
        return stmt;
      }
      if (identifierEquals(VARIABLES)) {
        lexer.nextToken();
        WaspSqlShowVariantsStatement stmt = parseShowVariants();
        stmt.setSession(true);
        return stmt;
      }
    }
    if (identifierEquals(CHARACTER)) {
      lexer.nextToken();
      accept(Token.SET);
      WaspSqlShowCharacterSetStatement stmt = new WaspSqlShowCharacterSetStatement();
      if (lexer.token() == Token.LIKE) {
        lexer.nextToken();
        stmt.setPattern(this.exprParser.expr());
      }
      if (lexer.token() == Token.WHERE) {
        lexer.nextToken();
        stmt.setWhere(this.exprParser.expr());
      }
      return stmt;
    }
    if (lexer.token() == Token.CREATE) {
      lexer.nextToken();
      if (lexer.token() == Token.DATABASE) {
        lexer.nextToken();
        WaspSqlShowCreateDatabaseStatement stmt = new WaspSqlShowCreateDatabaseStatement();
        stmt.setDatabase(this.exprParser.name());
        return stmt;
      }
      if (lexer.token() == Token.TABLE) {
        lexer.nextToken();
        WaspSqlShowCreateTableStatement stmt = new WaspSqlShowCreateTableStatement();
        stmt.setName(this.exprParser.name());
        return stmt;
      }
      throw new ParserException("TODO " + lexer.stringVal());
    }
    if (identifierEquals("GRANTS")) {
      lexer.nextToken();
      WaspSqlShowGrantsStatement stmt = new WaspSqlShowGrantsStatement();
      if (lexer.token() == Token.FOR) {
        lexer.nextToken();
        stmt.setUser(this.exprParser.expr());
      }
      return stmt;
    }
    if (lexer.token() == Token.INDEX || identifierEquals("INDEXES")) {
      lexer.nextToken();
      WaspSqlShowIndexesStatement stmt = new WaspSqlShowIndexesStatement();
      if (lexer.token() == Token.FROM || lexer.token() == Token.IN) {
        lexer.nextToken();
        SQLName table = exprParser.name();
        stmt.setTable(table);
        if (lexer.token() == Token.FROM || lexer.token() == Token.IN) {
          lexer.nextToken();
          SQLName database = exprParser.name();
          stmt.setDatabase(database);
        }
      }
      return stmt;
    }
    if (identifierEquals("OPEN")) {
      lexer.nextToken();
      acceptIdentifier(TABLES);
      WaspSqlShowOpenTablesStatement stmt = new WaspSqlShowOpenTablesStatement();
      if (lexer.token() == Token.FROM || lexer.token() == Token.IN) {
        lexer.nextToken();
        stmt.setDatabase(this.exprParser.name());
      }
      if (lexer.token() == Token.LIKE) {
        lexer.nextToken();
        stmt.setLike(this.exprParser.expr());
      }
      if (lexer.token() == Token.WHERE) {
        lexer.nextToken();
        stmt.setWhere(this.exprParser.expr());
      }
      return stmt;
    }
    if (identifierEquals("PROFILES")) {
      lexer.nextToken();
      WaspSqlShowProfilesStatement stmt = new WaspSqlShowProfilesStatement();
      return stmt;
    }

    if (identifierEquals("PROFILE")) {
      lexer.nextToken();
      WaspSqlShowProfileStatement stmt = new WaspSqlShowProfileStatement();
      for (;;) {
        if (lexer.token() == Token.ALL) {
          stmt.getTypes().add(WaspSqlShowProfileStatement.Type.ALL);
          lexer.nextToken();
        } else if (identifierEquals("BLOCK")) {
          lexer.nextToken();
          acceptIdentifier("IO");
          stmt.getTypes().add(WaspSqlShowProfileStatement.Type.BLOCK_IO);
        } else if (identifierEquals("CONTEXT")) {
          lexer.nextToken();
          acceptIdentifier("SWITCHES");
          stmt.getTypes()
              .add(WaspSqlShowProfileStatement.Type.CONTEXT_SWITCHES);
        } else if (identifierEquals("CPU")) {
          lexer.nextToken();
          stmt.getTypes().add(WaspSqlShowProfileStatement.Type.CPU);
        } else if (identifierEquals("IPC")) {
          lexer.nextToken();
          stmt.getTypes().add(WaspSqlShowProfileStatement.Type.IPC);
        } else if (identifierEquals("MEMORY")) {
          lexer.nextToken();
          stmt.getTypes().add(WaspSqlShowProfileStatement.Type.MEMORY);
        } else if (identifierEquals("PAGE")) {
          lexer.nextToken();
          acceptIdentifier("FAULTS");
          stmt.getTypes().add(WaspSqlShowProfileStatement.Type.PAGE_FAULTS);
        } else if (identifierEquals("SOURCE")) {
          lexer.nextToken();
          stmt.getTypes().add(WaspSqlShowProfileStatement.Type.SOURCE);
        } else if (identifierEquals("SWAPS")) {
          lexer.nextToken();
          stmt.getTypes().add(WaspSqlShowProfileStatement.Type.SWAPS);
        } else {
          break;
        }

        if (lexer.token() == Token.COMMA) {
          lexer.nextToken();
          continue;
        }
        break;
      }

      if (lexer.token() == Token.FOR) {
        lexer.nextToken();
        acceptIdentifier("QUERY");
        stmt.setForQuery(this.exprParser.primary());
      }

      stmt.setLimit(this.parseLimit());

      return stmt;
    }
    if (lexer.token() == Token.TABLE) {
      lexer.nextToken();
      acceptIdentifier(STATUS);
      WaspSqlShowTableStatusStatement stmt = new WaspSqlShowTableStatusStatement();
      if (lexer.token() == Token.FROM || lexer.token() == Token.IN) {
        lexer.nextToken();
        stmt.setDatabase(this.exprParser.name());
      }
      if (lexer.token() == Token.LIKE) {
        lexer.nextToken();
        stmt.setLike(this.exprParser.expr());
      }
      if (lexer.token() == Token.WHERE) {
        lexer.nextToken();
        stmt.setWhere(this.exprParser.expr());
      }
      return stmt;
    }
    throw new ParserException("TODO " + lexer.stringVal());
  }

  private WaspSqlShowStatusStatement parseShowStatus() {
    WaspSqlShowStatusStatement stmt = new WaspSqlShowStatusStatement();
    if (lexer.token() == Token.LIKE) {
      lexer.nextToken();
      SQLExpr like = exprParser.expr();
      stmt.setLike(like);
    }
    if (lexer.token() == Token.WHERE) {
      lexer.nextToken();
      SQLExpr where = exprParser.expr();
      stmt.setWhere(where);
    }
    return stmt;
  }

  private WaspSqlShowVariantsStatement parseShowVariants() {
    WaspSqlShowVariantsStatement stmt = new WaspSqlShowVariantsStatement();
    if (lexer.token() == Token.LIKE) {
      lexer.nextToken();
      SQLExpr like = exprParser.expr();
      stmt.setLike(like);
    }
    if (lexer.token() == Token.WHERE) {
      lexer.nextToken();
      SQLExpr where = exprParser.expr();
      stmt.setWhere(where);
    }
    return stmt;
  }

  private WaspSqlShowWarningsStatement parseShowWarnings() {
    WaspSqlShowWarningsStatement stmt = new WaspSqlShowWarningsStatement();
    stmt.setLimit(parseLimit());
    return stmt;
  }

  private WaspSqlShowDatabasesStatement parseShowDatabases() {
    WaspSqlShowDatabasesStatement stmt = new WaspSqlShowDatabasesStatement();
    if (lexer.token() == Token.LIKE) {
      lexer.nextToken();
      SQLExpr like = exprParser.expr();
      stmt.setLike(like);
    }
    if (lexer.token() == Token.WHERE) {
      lexer.nextToken();
      SQLExpr where = exprParser.expr();
      stmt.setWhere(where);
    }
    return stmt;
  }

  private WaspSqlShowTablesStatement parseShowTabless() {
    WaspSqlShowTablesStatement stmt = new WaspSqlShowTablesStatement();
    if (lexer.token() == Token.FROM) {
      lexer.nextToken();
      SQLName database = exprParser.name();
      stmt.setDatabase(database);
    }
    if (lexer.token() == Token.LIKE) {
      lexer.nextToken();
      SQLExpr like = exprParser.expr();
      stmt.setLike(like);
    }
    if (lexer.token() == Token.WHERE) {
      lexer.nextToken();
      SQLExpr where = exprParser.expr();
      stmt.setWhere(where);
    }
    return stmt;
  }

  private WaspSqlShowColumnsStatement parseShowColumns() {
    WaspSqlShowColumnsStatement stmt = new WaspSqlShowColumnsStatement();
    if (lexer.token() == Token.FROM) {
      lexer.nextToken();
      SQLName table = exprParser.name();
      stmt.setTable(table);
      if (lexer.token() == Token.FROM) {
        lexer.nextToken();
        SQLName database = exprParser.name();
        stmt.setDatabase(database);
      }
    }
    if (lexer.token() == Token.LIKE) {
      lexer.nextToken();
      SQLExpr like = exprParser.expr();
      stmt.setLike(like);
    }
    if (lexer.token() == Token.WHERE) {
      lexer.nextToken();
      SQLExpr where = exprParser.expr();
      stmt.setWhere(where);
    }
    return stmt;
  }

  public WaspSqlStartTransactionStatement parseStart() {
    acceptIdentifier("START");
    acceptIdentifier("TRANSACTION");
    WaspSqlStartTransactionStatement stmt = new WaspSqlStartTransactionStatement();
    if (identifierEquals("WITH")) {
      lexer.nextToken();
      acceptIdentifier("CONSISTENT");
      acceptIdentifier("SNAPSHOT");
      stmt.setConsistentSnapshot(true);
    }
    if (identifierEquals("BEGIN")) {
      lexer.nextToken();
      stmt.setBegin(true);
      if (identifierEquals("WORK")) {
        lexer.nextToken();
        stmt.setWork(true);
      }
    }
    return stmt;
  }

  protected SQLStatement parseLoad() {
    acceptIdentifier("LOAD");
    if (identifierEquals("DATA")) {
      SQLStatement stmt = parseLoadDataInFile();
      return stmt;
    }
    if (identifierEquals("XML")) {
      SQLStatement stmt = parseLoadXml();
      return stmt;
    }
    throw new ParserException("TODO");
  }

  protected WaspSqlLoadXmlStatement parseLoadXml() {
    acceptIdentifier("XML");
    WaspSqlLoadXmlStatement stmt = new WaspSqlLoadXmlStatement();
    if (identifierEquals(LOW_PRIORITY)) {
      stmt.setLowPriority(true);
      lexer.nextToken();
    }
    if (identifierEquals("CONCURRENT")) {
      stmt.setConcurrent(true);
      lexer.nextToken();
    }
    if (identifierEquals(LOCAL)) {
      stmt.setLocal(true);
      lexer.nextToken();
    }
    acceptIdentifier("INFILE");
    SQLLiteralExpr fileName = (SQLLiteralExpr) exprParser.expr();
    stmt.setFileName(fileName);
    if (identifierEquals(REPLACE)) {
      stmt.setReplicate(true);
      lexer.nextToken();
    }
    if (identifierEquals(IGNORE)) {
      stmt.setIgnore(true);
      lexer.nextToken();
    }
    accept(Token.INTO);
    accept(Token.TABLE);
    SQLName tableName = exprParser.name();
    stmt.setTableName(tableName);
    if (identifierEquals(CHARACTER)) {
      lexer.nextToken();
      accept(Token.SET);
      if (lexer.token() != Token.LITERAL_CHARS) {
        throw new ParserException("syntax error, illegal charset");
      }
      String charset = lexer.stringVal();
      lexer.nextToken();
      stmt.setCharset(charset);
    }
    if (identifierEquals("ROWS")) {
      lexer.nextToken();
      accept(Token.IDENTIFIED);
      accept(Token.BY);
      SQLExpr rowsIdentifiedBy = exprParser.expr();
      stmt.setRowsIdentifiedBy(rowsIdentifiedBy);
    }
    if (identifierEquals(IGNORE)) {
      throw new ParserException("TODO");
    }
    if (lexer.token() == Token.SET) {
      throw new ParserException("TODO");
    }
    return stmt;
  }

  protected WaspSqlLoadDataInFileStatement parseLoadDataInFile() {
    acceptIdentifier("DATA");
    WaspSqlLoadDataInFileStatement stmt = new WaspSqlLoadDataInFileStatement();
    if (identifierEquals(LOW_PRIORITY)) {
      stmt.setLowPriority(true);
      lexer.nextToken();
    }
    if (identifierEquals("CONCURRENT")) {
      stmt.setConcurrent(true);
      lexer.nextToken();
    }
    if (identifierEquals(LOCAL)) {
      stmt.setLocal(true);
      lexer.nextToken();
    }
    acceptIdentifier("INFILE");
    SQLLiteralExpr fileName = (SQLLiteralExpr) exprParser.expr();
    stmt.setFileName(fileName);
    if (identifierEquals(REPLACE)) {
      stmt.setReplicate(true);
      lexer.nextToken();
    }
    if (identifierEquals(IGNORE)) {
      stmt.setIgnore(true);
      lexer.nextToken();
    }
    accept(Token.INTO);
    accept(Token.TABLE);
    SQLName tableName = exprParser.name();
    stmt.setTableName(tableName);
    if (identifierEquals(CHARACTER)) {
      lexer.nextToken();
      accept(Token.SET);
      if (lexer.token() != Token.LITERAL_CHARS) {
        throw new ParserException("syntax error, illegal charset");
      }
      String charset = lexer.stringVal();
      lexer.nextToken();
      stmt.setCharset(charset);
    }
    if (identifierEquals("FIELDS") || identifierEquals("COLUMNS")) {
      throw new ParserException("TODO");
    }
    if (identifierEquals("LINES")) {
      throw new ParserException("TODO");
    }
    if (identifierEquals(IGNORE)) {
      throw new ParserException("TODO");
    }
    if (lexer.token() == Token.SET) {
      throw new ParserException("TODO");
    }
    return stmt;
  }

  public WaspSqlPrepareStatement parsePrepare() {
    acceptIdentifier("PREPARE");
    SQLName name = exprParser.name();
    accept(Token.FROM);
    SQLExpr from = exprParser.expr();
    return new WaspSqlPrepareStatement(name, from);
  }

  public WaspSqlExecuteStatement parseExecute() {
    acceptIdentifier("EXECUTE");
    WaspSqlExecuteStatement stmt = new WaspSqlExecuteStatement();
    SQLName statementName = exprParser.name();
    stmt.setStatementName(statementName);
    if (identifierEquals("USING")) {
      lexer.nextToken();
      exprParser.exprList(stmt.getParameters());
    }
    return stmt;
  }

  public SQLInsertStatement parseInsert() {
    WaspSqlInsertStatement insertStatement = new WaspSqlInsertStatement();
    if (lexer.token() == Token.INSERT) {
      lexer.nextToken();
      if (identifierEquals(LOW_PRIORITY)) {
        insertStatement.setLowPriority(true);
        lexer.nextToken();
      }
      if (identifierEquals(DELAYED)) {
        insertStatement.setDelayed(true);
        lexer.nextToken();
      }
      if (identifierEquals("HIGH_PRIORITY")) {
        insertStatement.setHighPriority(true);
        lexer.nextToken();
      }
      if (identifierEquals(IGNORE)) {
        insertStatement.setIgnore(true);
        lexer.nextToken();
      }
      if (lexer.token() == Token.INTO) {
        lexer.nextToken();
      }
      SQLName tableName = this.exprParser.name();
      insertStatement.setTableName(tableName);
      if (lexer.token() == Token.IDENTIFIER && !identifierEquals("VALUE")) {
        insertStatement.setAlias(lexer.stringVal());
        lexer.nextToken();
      }
    }
    if (lexer.token() == (Token.LPAREN)) {
      lexer.nextToken();
      if (lexer.token() == (Token.SELECT)) {
        SQLSelect select = this.exprParser.createSelectParser().select();
        select.setParent(insertStatement);
        insertStatement.setQuery(select);
      } else {
        this.exprParser.exprList(insertStatement.getColumns());
      }
      accept(Token.RPAREN);
    }
    if (lexer.token() == Token.VALUES || identifierEquals("VALUE")) {
      lexer.nextToken();
      for (;;) {
        accept(Token.LPAREN);
        SQLInsertStatement.ValuesClause values = new SQLInsertStatement.ValuesClause();
        this.exprParser.exprList(values.getValues());
        insertStatement.getValuesList().add(values);
        accept(Token.RPAREN);
        if (lexer.token() == Token.COMMA) {
          lexer.nextToken();
          continue;
        } else {
          break;
        }
      }
    } else if (lexer.token() == Token.SET) {
      lexer.nextToken();
      SQLInsertStatement.ValuesClause values = new SQLInsertStatement.ValuesClause();
      insertStatement.getValuesList().add(values);
      for (;;) {
        SQLName name = this.exprParser.name();
        insertStatement.getColumns().add(name);
        if (lexer.token() == Token.EQ) {
          lexer.nextToken();
        } else {
          accept(Token.COLONEQ);
        }
        values.getValues().add(this.exprParser.expr());
        if (lexer.token() == Token.COMMA) {
          lexer.nextToken();
          continue;
        }
        break;
      }
    } else if (lexer.token() == (Token.SELECT)) {
      SQLSelect select = this.exprParser.createSelectParser().select();
      select.setParent(insertStatement);
      insertStatement.setQuery(select);
    } else if (lexer.token() == (Token.LPAREN)) {
      lexer.nextToken();
      SQLSelect select = this.exprParser.createSelectParser().select();
      select.setParent(insertStatement);
      insertStatement.setQuery(select);
      accept(Token.RPAREN);
    }
    if (lexer.token() == Token.ON) {
      lexer.nextToken();
      acceptIdentifier("DUPLICATE");
      accept(Token.KEY);
      accept(Token.UPDATE);
      exprParser.exprList(insertStatement.getDuplicateKeyUpdate());
    }

    return insertStatement;
  }

  public SQLStatement parseDropUser() {
    acceptIdentifier(USER);
    WaspSqlDropUser stmt = new WaspSqlDropUser();
    for (;;) {
      SQLExpr expr = this.exprParser.expr();
      stmt.getUsers().add(expr);
      if (lexer.token() == Token.COMMA) {
        lexer.nextToken();
        continue;
      }
      break;
    }
    return stmt;
  }

  protected SQLDropTableStatement parseDropTable(boolean acceptDrop) {
    if (acceptDrop) {
      accept(Token.DROP);
    }
    WaspSqlDropTableStatement stmt = new WaspSqlDropTableStatement();
    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.addTableSource(name);
      if (lexer.token() == Token.COMMA) {
        lexer.nextToken();
        continue;
      }
      break;
    }
    if (identifierEquals(RESTRICT)) {
      stmt.setOption(RESTRICT);
      lexer.nextToken();
    } else if (identifierEquals(CASCADE)) {
      stmt.setOption(CASCADE);
      lexer.nextToken();
    }
    return stmt;
  }

  public SQLSelectParser createSQLSelectParser() {
    return new WaspSqlSelectParser(this.exprParser);
  }

  public Limit parseLimit() {
    return ((WaspSqlExprParser) this.exprParser).parseLimit();
  }

  public SQLStatement parseAlter() {
    accept(Token.ALTER);
    boolean ignore = false;
    if (identifierEquals(IGNORE)) {
      ignore = true;
      lexer.nextToken();
    }
    if (lexer.token() == Token.TABLE) {
      lexer.nextToken();
      WaspSqlAlterTableStatement stmt = new WaspSqlAlterTableStatement();
      stmt.setIgnore(ignore);
      stmt.setName(this.exprParser.name());
      for (;;) {
        if (identifierEquals("ADD")) {
          lexer.nextToken();
          if (identifierEquals("COLUMN")) {
            lexer.nextToken();
            WaspSqlAlterTableAddColumn item = new WaspSqlAlterTableAddColumn();
            SQLColumnDefinition columnDef = this.exprParser.parseColumn();
            item.getColumns().add(columnDef);
            if (identifierEquals("AFTER")) {
              lexer.nextToken();
              item.setAfterColumn(this.exprParser.name());
            } else if (identifierEquals("FIRST")) {
              lexer.nextToken();
              item.setFirst(true);
            }
            stmt.getItems().add(item);
          } else if (lexer.token() == Token.INDEX) {
            lexer.nextToken();
            WaspSqlAlterTableAddIndex item = new WaspSqlAlterTableAddIndex();

            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);
            stmt.getItems().add(item);
          } else if (lexer.token() == Token.UNIQUE) {
            lexer.nextToken();
            if (lexer.token() == Token.INDEX) {
              lexer.nextToken();
            }
            WaspSqlAlterTableAddUnique item = new WaspSqlAlterTableAddUnique();
            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);
            stmt.getItems().add(item);
          } else if (lexer.token() == Token.PRIMARY) {
            SQLPrimaryKey primaryKey = ((WaspSqlExprParser) this.exprParser)
                .parsePrimaryKey();
            SQLAlterTableAddPrimaryKey item = new SQLAlterTableAddPrimaryKey();
            item.setPrimaryKey(primaryKey);
            stmt.getItems().add(item);
          } else if (lexer.token() == Token.KEY) {
            throw new ParserException("TODO " + lexer.token() + " "
                + lexer.stringVal());
          } else if (lexer.token() == Token.CONSTRAINT) {
            throw new ParserException("TODO " + lexer.token() + " "
                + lexer.stringVal());
          } else if (identifierEquals(FULLTEXT)) {
            throw new ParserException("TODO " + lexer.token() + " "
                + lexer.stringVal());
          } else if (identifierEquals(SPATIAL)) {
            throw new ParserException("TODO " + lexer.token() + " "
                + lexer.stringVal());
          } else {
            WaspSqlAlterTableAddColumn item = new WaspSqlAlterTableAddColumn();
            SQLColumnDefinition columnDef = this.exprParser.parseColumn();
            item.getColumns().add(columnDef);
            if (identifierEquals("AFTER")) {
              lexer.nextToken();
              item.setAfterColumn(this.exprParser.name());
            }
            stmt.getItems().add(item);
          }
        } else if (identifierEquals("ALTER")) {
          throw new ParserException("TODO " + lexer.token() + " "
              + lexer.stringVal());
        } else if (identifierEquals("CHANGE")) {
          lexer.nextToken();
          if (identifierEquals("COLUMN")) {
            lexer.nextToken();
          }
          WaspSqlAlterTableChangeColumn item = new WaspSqlAlterTableChangeColumn();
          item.setColumnName(this.exprParser.name());
          item.setNewColumnDefinition(this.exprParser.parseColumn());
          if (identifierEquals("AFTER")) {
            lexer.nextToken();
            item.setAfterColumn(this.exprParser.name());
          } else if (identifierEquals("FIRST")) {
            lexer.nextToken();
            if (lexer.token() == Token.IDENTIFIER) {
              item.setFirstColumn(this.exprParser.name());
            } else {
              item.setFirst(true);
            }
          }
          stmt.getItems().add(item);
        } else if (identifierEquals("MODIFY")) {
          throw new ParserException("TODO " + lexer.token() + " "
              + lexer.stringVal());
        } else if (lexer.token() == Token.DROP) {
          lexer.nextToken();
          if (lexer.token() == Token.INDEX) {
            lexer.nextToken();
            SQLName indexName = this.exprParser.name();
            SQLAlterTableDropIndex item = new SQLAlterTableDropIndex();
            item.setIndexName(indexName);
            stmt.getItems().add(item);
          } else {
            if (identifierEquals("COLUMN")) {
              lexer.nextToken();
            }
            SQLAlterTableDropColumnItem item = new SQLAlterTableDropColumnItem();
            item.setColumnName(this.exprParser.name());
            stmt.getItems().add(item);
          }
        } else if (identifierEquals("DISABLE")) {
          throw new ParserException("TODO " + lexer.token() + " "
              + lexer.stringVal());
        } else if (identifierEquals("ENABLE")) {
          throw new ParserException("TODO " + lexer.token() + " "
              + lexer.stringVal());
        } else if (identifierEquals("RENAME")) {
          lexer.nextToken();
          WaspSqlRenameTableStatement renameStmt = new WaspSqlRenameTableStatement();
          WaspSqlRenameTableStatement.Item item = new WaspSqlRenameTableStatement.Item();
          item.setName(stmt.getTableSource().getExpr());
          item.setTo(this.exprParser.name());
          renameStmt.getItems().add(item);

          return renameStmt;
        } else if (lexer.token() == Token.ORDER) {
          throw new ParserException("TODO " + lexer.token() + " "
              + lexer.stringVal());
        } else if (identifierEquals("CONVERT")) {
          throw new ParserException("TODO " + lexer.token() + " "
              + lexer.stringVal());
        } else if (lexer.token() == Token.DEFAULT) {
          throw new ParserException("TODO " + lexer.token() + " "
              + lexer.stringVal());
        } else if (identifierEquals("DISCARD")) {
          throw new ParserException("TODO " + lexer.token() + " "
              + lexer.stringVal());
        } else if (identifierEquals("IMPORT")) {
          throw new ParserException("TODO " + lexer.token() + " "
              + lexer.stringVal());
        } else if (identifierEquals("FORCE")) {
          throw new ParserException("TODO " + lexer.token() + " "
              + lexer.stringVal());
        } else if (identifierEquals("TRUNCATE")) {
          throw new ParserException("TODO " + lexer.token() + " "
              + lexer.stringVal());
        } else if (identifierEquals("COALESCE")) {
          throw new ParserException("TODO " + lexer.token() + " "
              + lexer.stringVal());

        } else if (identifierEquals("REORGANIZE")) {
          throw new ParserException("TODO " + lexer.token() + " "
              + lexer.stringVal());
        } else if (identifierEquals("EXCHANGE")) {
          throw new ParserException("TODO " + lexer.token() + " "
              + lexer.stringVal());
        } else if (identifierEquals("ANALYZE")) {
          throw new ParserException("TODO " + lexer.token() + " "
              + lexer.stringVal());
        } else if (identifierEquals("CHECK")) {
          throw new ParserException("TODO " + lexer.token() + " "
              + lexer.stringVal());
        } else if (identifierEquals("OPTIMIZE")) {
          throw new ParserException("TODO " + lexer.token() + " "
              + lexer.stringVal());
        } else if (identifierEquals("REBUILD")) {
          throw new ParserException("TODO " + lexer.token() + " "
              + lexer.stringVal());
        } else if (identifierEquals("REPAIR")) {
          throw new ParserException("TODO " + lexer.token() + " "
              + lexer.stringVal());
        } else if (identifierEquals("REMOVE")) {
          throw new ParserException("TODO " + lexer.token() + " "
              + lexer.stringVal());
        } else if (identifierEquals(CHARACTER)) {
          lexer.nextToken();
          accept(Token.SET);
          accept(Token.EQ);
          WaspSqlAlterTableCharacter item = new WaspSqlAlterTableCharacter();
          item.setCharacterSet(this.exprParser.primary());
          if (lexer.token() == Token.COMMA) {
            lexer.nextToken();
            acceptIdentifier(COLLATE2);
            accept(Token.EQ);
            item.setCollate(this.exprParser.primary());
          }
          stmt.getItems().add(item);
        } else {
          break;
        }

        if (lexer.token() == Token.COMMA) {
          lexer.nextToken();
          continue;
        } else {
          break;
        }
      }

      return stmt;
    }
    throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal());
  }

  public SQLStatement parseRename() {
    WaspSqlRenameTableStatement stmt = new WaspSqlRenameTableStatement();
    acceptIdentifier("RENAME");
    accept(Token.TABLE);
    for (;;) {
      WaspSqlRenameTableStatement.Item item = new WaspSqlRenameTableStatement.Item();
      item.setName(this.exprParser.name());
      acceptIdentifier("TO");
      item.setTo(this.exprParser.name());
      stmt.getItems().add(item);
      if (lexer.token() == Token.COMMA) {
        lexer.nextToken();
        continue;
      }
      break;
    }
    return stmt;
  }

  public SQLStatement parseCreateDatabase() {
    if (lexer.token() == Token.CREATE) {
      lexer.nextToken();
    }
    accept(Token.DATABASE);
    SQLCreateDatabaseStatement stmt = new SQLCreateDatabaseStatement();
    stmt.setName(this.exprParser.name());
    if (lexer.token() == Token.DEFAULT) {
      lexer.nextToken();
    }
    return stmt;
  }
}
TOP

Related Classes of com.alibaba.wasp.plan.parser.druid.dialect.WaspSqlStatementParser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.