@Override
 public boolean visit(MySqlPartitionByKey x) {
   accept(x.getColumns());
   return false;
 }
  public WaspSqlCreateTableStatement parseCrateTable(boolean acceptCreate) {
    if (acceptCreate) {
      accept(Token.CREATE);
    }
    WaspSqlCreateTableStatement stmt = new WaspSqlCreateTableStatement();

    if (identifierEquals("TEMPORARY")) {
      lexer.nextToken();
      stmt.setType(SQLCreateTableStatement.Type.GLOBAL_TEMPORARY);
    }

    accept(Token.TABLE);

    if (lexer.token() == Token.IF || identifierEquals("IF")) {
      lexer.nextToken();
      accept(Token.NOT);
      accept(Token.EXISTS);

      stmt.setIfNotExiists(true);
    }

    stmt.setName(this.exprParser.name());

    Token start = null;
    if (lexer.token() == (Token.LPAREN)) {
      start = Token.LPAREN;
    } else if (lexer.token() == (Token.LBRACE)) {
      start = Token.LBRACE;
    }
    if (start == (Token.LPAREN) || start == (Token.LBRACE)) {
      lexer.nextToken();

      for (; ; ) {
        if (identifierEquals(REQUIRED)
            || identifierEquals(OPTIONAL)
            || identifierEquals(REPEATED)) {
          if (exprParser instanceof WaspSqlExprParser) {
            SQLColumnDefinition column = ((WaspSqlExprParser) this.exprParser).parseCreateColumn();
            stmt.getTableElementList().add(column);
          } else {
            SQLColumnDefinition column = this.exprParser.parseColumn();
            stmt.getTableElementList().add(column);
          }
        }

        if (!(lexer.token() == (Token.COMMA) || (lexer.token() == (Token.SEMI)))) {
          break;
        } else {
          lexer.nextToken();
        }
      }
      if (start == (Token.LPAREN)) {
        accept(Token.RPAREN);
      } else if (start == (Token.LBRACE)) {
        accept(Token.RBRACE);
      }
    }

    // Primary Key
    accept(Token.PRIMARY);
    accept(Token.KEY);
    accept(Token.LPAREN);
    for (; ; ) {
      stmt.getPrimaryKeys().add(this.exprParser.expr());
      if (!(lexer.token() == (Token.COMMA))) {
        break;
      } else {
        lexer.nextToken();
      }
    }
    accept(Token.RPAREN);
    accept(Token.COMMA);

    // In Table
    if (lexer.stringVal().equalsIgnoreCase("IN")) {
      lexer.nextToken();
      accept(Token.TABLE);
      stmt.setInTableName(this.exprParser.name());
      accept(Token.COMMA);
    }

    for (; ; ) {
      if (identifierEquals("ENTITY")) {
        lexer.nextToken();
        accept(Token.GROUP);
        if (identifierEquals("ROOT")) {
          stmt.setCategory(TableCategory.ROOT);
          lexer.nextToken();
        } else if (lexer.stringVal().equalsIgnoreCase("KEY")) {
          lexer.nextToken();
          accept(Token.LPAREN);
          stmt.setEntityGroupKey(this.exprParser.expr());
          accept(Token.RPAREN);
          if (stmt.getCategory() != TableCategory.ROOT) {
            stmt.setCategory(TableCategory.CHILD);
            accept(Token.REFERENCES);
            stmt.setReferenceTable(this.exprParser.name());
          }
        }
      }

      if (identifierEquals("TYPE")) {
        lexer.nextToken();
        accept(Token.EQ);
        stmt.getTableOptions().put("TYPE", lexer.stringVal());
        lexer.nextToken();
      }

      if (identifierEquals("PARTITION")) {
        lexer.nextToken();
        accept(Token.BY);

        if (lexer.token() == Token.KEY) {
          MySqlPartitionByKey clause = new MySqlPartitionByKey();
          lexer.nextToken();
          accept(Token.LPAREN);
          for (; ; ) {
            clause.getColumns().add(this.exprParser.name());
            if (lexer.token() == Token.COMMA) {
              lexer.nextToken();
              continue;
            }
            break;
          }
          accept(Token.RPAREN);
          stmt.setPartitioning(clause);

          if (identifierEquals("PARTITIONS")) {
            lexer.nextToken();
            clause.setPartitionCount(this.exprParser.expr());
          }
        } else if (identifierEquals("RANGE")) {
          WaspSqlPartitionByKey clause = new WaspSqlPartitionByKey();
          lexer.nextToken();
          accept(Token.LPAREN);
          clause.setStart(this.exprParser.expr());
          accept(Token.COMMA);
          clause.setEnd(this.exprParser.expr());
          accept(Token.COMMA);
          clause.setPartitionCount(this.exprParser.expr());
          accept(Token.RPAREN);
          stmt.setPartitioning(clause);
        } else {
          throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal());
        }
      }

      if (!(lexer.token() == (Token.COMMA))) {
        break;
      } else {
        lexer.nextToken();
      }
    }
    if (lexer.token() == (Token.ON)) {
      throw new ParserException("TODO");
    }

    if (lexer.token() == (Token.SELECT)) {
      SQLSelect query = new MySqlSelectParser(this.exprParser).select();
      stmt.setQuery(query);
    }

    return stmt;
  }