package com.alibaba.druid.sql.dialect.clickhouse.parser;

import com.alibaba.druid.sql.ast.statement.SQLWithSubqueryClause;
import com.alibaba.druid.sql.parser.Lexer;
import com.alibaba.druid.sql.parser.SQLCreateTableParser;
import com.alibaba.druid.sql.parser.SQLExprParser;
import com.alibaba.druid.sql.parser.SQLParserFeature;
import com.alibaba.druid.sql.parser.SQLStatementParser;
import com.alibaba.druid.sql.parser.Token;

public class ClickhouseStatementParser extends SQLStatementParser {
   public ClickhouseStatementParser(String sql) {
      super((SQLExprParser)(new ClickhouseExprParser(sql)));
   }

   public ClickhouseStatementParser(String sql, SQLParserFeature... features) {
      super((SQLExprParser)(new ClickhouseExprParser(sql, features)));
   }

   public ClickhouseStatementParser(Lexer lexer) {
      super((SQLExprParser)(new ClickhouseExprParser(lexer)));
   }

   public SQLWithSubqueryClause parseWithQuery() {
      SQLWithSubqueryClause withQueryClause = new SQLWithSubqueryClause();
      if (this.lexer.hasComment() && this.lexer.isKeepComments()) {
         withQueryClause.addBeforeComment(this.lexer.readAndResetComments());
      }

      this.accept(Token.WITH);

      while(true) {
         SQLWithSubqueryClause.Entry entry = new SQLWithSubqueryClause.Entry();
         entry.setParent(withQueryClause);
         if (this.lexer.token() == Token.LPAREN) {
            this.lexer.nextToken();
            switch (this.lexer.token()) {
               case VALUES:
               case WITH:
               case SELECT:
                  entry.setSubQuery(this.createSQLSelectParser().select());
               default:
                  this.accept(Token.RPAREN);
            }
         } else {
            entry.setExpr(this.exprParser.expr());
         }

         this.accept(Token.AS);
         String alias = this.lexer.stringVal();
         this.lexer.nextToken();
         entry.setAlias(alias);
         withQueryClause.addEntry(entry);
         if (this.lexer.token() != Token.COMMA) {
            return withQueryClause;
         }

         this.lexer.nextToken();
      }
   }

   public SQLCreateTableParser getSQLCreateTableParser() {
      return new ClickhouseCreateTableParser(this.exprParser);
   }
}
