http://git-wip-us.apache.org/repos/asf/tajo/blob/d6bc9118/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java
----------------------------------------------------------------------
diff --git 
a/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java 
b/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java
deleted file mode 100644
index b367693..0000000
--- a/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java
+++ /dev/null
@@ -1,1986 +0,0 @@
-/**
- * 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 org.apache.tajo.engine.parser;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
-import org.antlr.v4.runtime.ANTLRInputStream;
-import org.antlr.v4.runtime.CommonTokenStream;
-import org.antlr.v4.runtime.misc.NotNull;
-import org.antlr.v4.runtime.tree.TerminalNode;
-import org.apache.tajo.SessionVars;
-import org.apache.tajo.algebra.*;
-import org.apache.tajo.algebra.Aggregation.GroupType;
-import org.apache.tajo.algebra.CreateIndex.IndexMethodSpec;
-import org.apache.tajo.algebra.DataTypeExpr.MapType;
-import org.apache.tajo.algebra.LiteralValue.LiteralType;
-import org.apache.tajo.algebra.Sort.SortSpec;
-import org.apache.tajo.engine.parser.SQLParser.*;
-import org.apache.tajo.exception.SQLSyntaxError;
-import org.apache.tajo.exception.TajoRuntimeException;
-import org.apache.tajo.storage.StorageConstants;
-import org.apache.tajo.util.StringUtils;
-
-import java.util.*;
-
-import static org.apache.tajo.algebra.Aggregation.GroupElement;
-import static org.apache.tajo.algebra.CreateTable.*;
-import static org.apache.tajo.algebra.WindowSpec.WindowFrameEndBoundType;
-import static org.apache.tajo.algebra.WindowSpec.WindowFrameStartBoundType;
-import static org.apache.tajo.common.TajoDataTypes.Type;
-import static org.apache.tajo.engine.parser.SQLParser.*;
-
-public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
-
-  public Expr parse(String sql) throws SQLSyntaxError {
-    ANTLRInputStream input = new ANTLRInputStream(sql);
-    SQLLexer lexer = new SQLLexer(input);
-    CommonTokenStream tokens = new CommonTokenStream(lexer);
-    SqlContext context;
-    try {
-      SQLParser parser = new SQLParser(tokens);
-      parser.setBuildParseTree(true);
-      parser.removeErrorListeners();
-
-      parser.setErrorHandler(new SQLErrorStrategy());
-      parser.addErrorListener(new SQLErrorListener());
-      context = parser.sql();
-    } catch (SQLParseError e) {
-      throw new SQLSyntaxError(e.getMessage());
-    }
-    return visitSql(context);
-  }
-
-  private static boolean checkIfExist(Object obj) {
-    return obj != null;
-  }
-
-  @Override
-  public Expr visitSql(SqlContext ctx) {
-    Expr statement = visit(ctx.statement());
-    if (checkIfExist(ctx.explain_clause())) {
-      return new Explain(statement, 
checkIfExist(ctx.explain_clause().GLOBAL()));
-    } else {
-      return statement;
-    }
-  }
-
-  public Expr visitSession_statement(@NotNull 
SQLParser.Session_statementContext ctx) {
-
-    if (checkIfExist(ctx.CATALOG())) {
-
-      return new SetSession(SessionVars.CURRENT_DATABASE.name(), 
ctx.dbname.getText());
-
-
-    } else if (checkIfExist(ctx.name)) {
-      String value;
-      if (checkIfExist(ctx.boolean_literal())) {
-        value = ctx.boolean_literal().getText();
-      } else if (checkIfExist(ctx.Character_String_Literal())) {
-        value = stripQuote(ctx.Character_String_Literal().getText());
-      } else if (checkIfExist(ctx.signed_numerical_literal())) {
-        value = ctx.signed_numerical_literal().getText();
-      } else {
-        value = null;
-      }
-      return new SetSession(ctx.name.getText(), value);
-
-
-    } else if (checkIfExist(ctx.TIME()) && checkIfExist(ctx.ZONE())) {
-
-      String value;
-      if (checkIfExist(ctx.Character_String_Literal())) {
-        value = stripQuote(ctx.Character_String_Literal().getText());
-      } else if (checkIfExist(ctx.signed_numerical_literal())) {
-        value = ctx.signed_numerical_literal().getText();
-      } else {
-        value = null;
-      }
-      return new SetSession(SessionVars.TIMEZONE.name(), value);
-
-    } else {
-      throw new TajoRuntimeException(new SQLSyntaxError("Unsupported session 
statement"));
-    }
-  }
-
-  @Override
-  public Expr 
visitNon_join_query_expression(SQLParser.Non_join_query_expressionContext ctx) {
-
-    Expr current = visitNon_join_query_term(ctx.non_join_query_term());
-    if (ctx.getChildCount() == 1) {
-      return current;
-    }
-
-    OpType operatorType;
-    Expr left;
-    for (int i = 1; i < ctx.getChildCount(); i++) {
-      int idx = i;
-      boolean distinct = true;
-
-      if (ctx.getChild(idx) instanceof TerminalNode) {
-        if (((TerminalNode) ctx.getChild(idx)).getSymbol().getType() == UNION) 
{
-          operatorType = OpType.Union;
-        } else {
-          operatorType = OpType.Except;
-        }
-
-        idx++;
-
-        if (ctx.getChild(idx) instanceof TerminalNode) {
-          if (((TerminalNode) ctx.getChild(idx)).getSymbol().getType() == ALL) 
{
-            distinct = false;
-          }
-
-          idx++;
-        }
-
-        SQLParser.Query_termContext queryTermContext =
-            (SQLParser.Query_termContext) ctx.getChild(idx);
-        Expr right = visitQuery_term(queryTermContext);
-
-        left = current;
-        current = new SetOperation(operatorType, left, right, distinct);
-
-        i = idx;
-      }
-    }
-
-    return current;
-  }
-
-  @Override
-  public Expr visitNon_join_query_term(Non_join_query_termContext ctx) {
-
-    Expr current = visitNon_join_query_primary(ctx.non_join_query_primary());
-    Expr left;
-
-    for (int i = 1; i < ctx.getChildCount(); ) {
-      int idx = i;
-      boolean distinct = true;
-
-      if (ctx.getChild(idx) instanceof TerminalNode) {
-        if (((TerminalNode) ctx.getChild(idx)).getSymbol().getType() == 
INTERSECT) {
-          idx++;
-        }
-
-        if (ctx.getChild(idx) instanceof TerminalNode) {
-          if (((TerminalNode) ctx.getChild(idx)).getSymbol().getType() == ALL) 
{
-            distinct = false;
-            idx++;
-          }
-        }
-
-        Query_primaryContext queryPrimaryContext = (Query_primaryContext) 
ctx.getChild(idx);
-        Expr right = visitQuery_primary(queryPrimaryContext);
-
-        left = current;
-        current = new SetOperation(OpType.Intersect, left, right, distinct);
-
-        i += idx;
-      }
-    }
-
-    return current;
-
-  }
-
-  @Override
-  public Expr visitNon_join_query_primary(Non_join_query_primaryContext ctx) {
-    if (ctx.simple_table() != null) {
-      return visitSimple_table(ctx.simple_table());
-    } else if (ctx.non_join_query_expression() != null) {
-      return visitNon_join_query_expression(ctx.non_join_query_expression());
-    }
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public Expr visitQuery_specification(SQLParser.Query_specificationContext 
ctx) {
-    Expr current = null;
-    if (ctx.table_expression() != null) {
-      current = visitFrom_clause(ctx.table_expression().from_clause());
-
-      if (ctx.table_expression().where_clause() != null) {
-        Selection selection = 
visitWhere_clause(ctx.table_expression().where_clause());
-        selection.setChild(current);
-        current = selection;
-      }
-
-      if (ctx.table_expression().groupby_clause() != null) {
-        Aggregation aggregation = 
visitGroupby_clause(ctx.table_expression().groupby_clause());
-        aggregation.setChild(current);
-        current = aggregation;
-
-        if (ctx.table_expression().having_clause() != null) {
-          Expr havingCondition = visitBoolean_value_expression(
-              
ctx.table_expression().having_clause().boolean_value_expression());
-          Having having = new Having(havingCondition);
-          having.setChild(current);
-          current = having;
-        }
-      }
-
-      if (ctx.table_expression().orderby_clause() != null) {
-        Sort sort = 
visitOrderby_clause(ctx.table_expression().orderby_clause());
-        sort.setChild(current);
-        current = sort;
-      }
-
-      if (checkIfExist(ctx.table_expression().window_clause())) {
-        Window window = 
visitWindow_clause(ctx.table_expression().window_clause());
-        window.setChild(current);
-        current = window;
-      }
-
-      if (ctx.table_expression().limit_clause() != null) {
-        Limit limit = visitLimit_clause(ctx.table_expression().limit_clause());
-        limit.setChild(current);
-        current = limit;
-      }
-    }
-
-    Projection projection = visitSelect_list(ctx.select_list());
-
-    if (ctx.set_qualifier() != null && ctx.set_qualifier().DISTINCT() != null) 
{
-      projection.setDistinct();
-    }
-
-    if (current != null) {
-      projection.setChild(current);
-    }
-
-    current = projection;
-
-    return current;
-  }
-
-  /**
-   * <pre>
-   *   select_list
-   *   : select_sublist (COMMA select_sublist)*
-   *   ;
-   * </pre>
-   *
-   * @param ctx
-   * @return
-   */
-  @Override
-  public Projection visitSelect_list(SQLParser.Select_listContext ctx) {
-    Projection projection = new Projection();
-    NamedExpr[] targets = new NamedExpr[ctx.select_sublist().size()];
-    for (int i = 0; i < targets.length; i++) {
-      targets[i] = visitSelect_sublist(ctx.select_sublist(i));
-    }
-    projection.setNamedExprs(targets);
-
-    return projection;
-  }
-
-  /**
-   * <pre>
-   *   select_sublist
-   *   : derived_column
-   *   | asterisked_qualifier
-   *   ;
-   * </pre>
-   *
-   * @param ctx
-   * @return
-   */
-  @Override
-  public NamedExpr visitSelect_sublist(SQLParser.Select_sublistContext ctx) {
-    if (ctx.qualified_asterisk() != null) {
-      return visitQualified_asterisk(ctx.qualified_asterisk());
-    } else {
-      return visitDerived_column(ctx.derived_column());
-    }
-  }
-
-  @Override
-  public RelationList visitFrom_clause(SQLParser.From_clauseContext ctx) {
-    Expr[] relations = new 
Expr[ctx.table_reference_list().table_reference().size()];
-    for (int i = 0; i < relations.length; i++) {
-      relations[i] = 
visitTable_reference(ctx.table_reference_list().table_reference(i));
-    }
-    return new RelationList(relations);
-  }
-
-  @Override
-  public Selection visitWhere_clause(SQLParser.Where_clauseContext ctx) {
-    return new Selection(visitSearch_condition(ctx.search_condition()));
-  }
-
-  @Override
-  public Aggregation visitGroupby_clause(SQLParser.Groupby_clauseContext ctx) {
-    Aggregation clause = new Aggregation();
-
-    // If grouping group is not empty
-    if 
(ctx.grouping_element_list().grouping_element().get(0).empty_grouping_set() == 
null) {
-      int elementSize = ctx.grouping_element_list().grouping_element().size();
-      ArrayList<GroupElement> groups = new ArrayList<GroupElement>(elementSize 
+ 1);
-      ArrayList<Expr> ordinaryExprs = null;
-      int groupSize = 1;
-      groups.add(null);
-
-      for (int i = 0; i < elementSize; i++) {
-        SQLParser.Grouping_elementContext element =
-            ctx.grouping_element_list().grouping_element().get(i);
-        if (element.ordinary_grouping_set() != null) {
-          if (ordinaryExprs == null) {
-            ordinaryExprs = new ArrayList<Expr>();
-          }
-          Collections.addAll(ordinaryExprs, 
getRowValuePredicandsFromOrdinaryGroupingSet(element.ordinary_grouping_set()));
-        } else if (element.rollup_list() != null) {
-          groupSize++;
-          groups.add(new GroupElement(GroupType.Rollup,
-              
getRowValuePredicandsFromOrdinaryGroupingSetList(element.rollup_list().c)));
-        } else if (element.cube_list() != null) {
-          groupSize++;
-          groups.add(new GroupElement(GroupType.Cube,
-              
getRowValuePredicandsFromOrdinaryGroupingSetList(element.cube_list().c)));
-        }
-      }
-
-      if (ordinaryExprs != null) {
-        groups.set(0, new GroupElement(GroupType.OrdinaryGroup, 
ordinaryExprs.toArray(new Expr[ordinaryExprs.size()])));
-        clause.setGroups(groups.subList(0, groupSize).toArray(new 
GroupElement[groupSize]));
-      } else if (groupSize > 1) {
-        clause.setGroups(groups.subList(1, groupSize).toArray(new 
GroupElement[groupSize - 1]));
-      }
-    }
-
-    return clause;
-  }
-
-  @Override public WindowFunctionExpr visitWindow_function(@NotNull 
SQLParser.Window_functionContext context) {
-    WindowFunctionExpr windowFunction = null;
-
-    Window_function_typeContext functionType = context.window_function_type();
-    GeneralSetFunctionExpr functionBody;
-    if (checkIfExist(functionType.rank_function_type())) {
-      Rank_function_typeContext rankFunction = 
functionType.rank_function_type();
-      if (checkIfExist(rankFunction.RANK())) {
-        functionBody = new GeneralSetFunctionExpr("rank", false, new Expr[] 
{});
-      } else if (checkIfExist(rankFunction.DENSE_RANK())) {
-        functionBody = new GeneralSetFunctionExpr("dense_rank", false, new 
Expr[] {});
-      } else if (checkIfExist(rankFunction.PERCENT_RANK())) {
-        functionBody = new GeneralSetFunctionExpr("percent_rank", false, new 
Expr[] {});
-      } else {
-        functionBody = new GeneralSetFunctionExpr("cume_dist", false, new 
Expr[] {});
-      }
-    } else if (checkIfExist(functionType.ROW_NUMBER())) {
-      functionBody = new GeneralSetFunctionExpr("row_number", false, new 
Expr[] {});
-    } else if (checkIfExist(functionType.FIRST_VALUE())) {
-      functionBody = new GeneralSetFunctionExpr("first_value", false, new 
Expr[]{ visitColumn_reference(functionType.column_reference())});
-    } else if (checkIfExist(functionType.LAST_VALUE())) {
-      functionBody = new GeneralSetFunctionExpr("last_value", false, new 
Expr[]{visitColumn_reference(functionType.column_reference())});
-    } else if (checkIfExist(functionType.LAG())) {
-      if (checkIfExist(functionType.numeric_value_expression())) {
-        if (checkIfExist(functionType.common_value_expression())) {
-          functionBody = new GeneralSetFunctionExpr("lag", false, new 
Expr[]{visitColumn_reference(functionType.column_reference()),
-              
visitNumeric_value_expression(functionType.numeric_value_expression()),
-              
visitCommon_value_expression(functionType.common_value_expression())});
-        } else {
-          functionBody = new GeneralSetFunctionExpr("lag", false, new 
Expr[]{visitColumn_reference(functionType.column_reference()),
-              
visitNumeric_value_expression(functionType.numeric_value_expression())});
-        }
-      } else {
-        functionBody = new GeneralSetFunctionExpr("lag", false, new 
Expr[]{visitColumn_reference(functionType.column_reference())});
-      }
-    } else if (checkIfExist(functionType.LEAD())) {
-      if (checkIfExist(functionType.numeric_value_expression())) {
-        if (checkIfExist(functionType.common_value_expression())) {
-          functionBody = new GeneralSetFunctionExpr("lead", false, new 
Expr[]{visitColumn_reference(functionType.column_reference()),
-              
visitNumeric_value_expression(functionType.numeric_value_expression()),
-              
visitCommon_value_expression(functionType.common_value_expression())});
-        } else {
-          functionBody = new GeneralSetFunctionExpr("lead", false, new 
Expr[]{visitColumn_reference(functionType.column_reference()),
-              
visitNumeric_value_expression(functionType.numeric_value_expression())});
-        }
-      } else {
-        functionBody = new GeneralSetFunctionExpr("lead", false, new 
Expr[]{visitColumn_reference(functionType.column_reference())});
-      }
-    } else {
-      functionBody = 
visitAggregate_function(functionType.aggregate_function());
-    }
-    windowFunction = new WindowFunctionExpr(functionBody);
-
-    Window_name_or_specificationContext windowNameOrSpec = 
context.window_name_or_specification();
-    if (checkIfExist(windowNameOrSpec.window_name())) {
-      windowFunction.setWindowName(windowNameOrSpec.window_name().getText());
-    } else {
-      
windowFunction.setWindowSpec(buildWindowSpec(windowNameOrSpec.window_specification()));
-    }
-
-    return windowFunction;
-  }
-
-  @Override
-  public Window visitWindow_clause(@NotNull SQLParser.Window_clauseContext 
ctx) {
-    Window.WindowDefinition [] definitions =
-        new 
Window.WindowDefinition[ctx.window_definition_list().window_definition().size()];
-    for (int i = 0; i < definitions.length; i++) {
-      Window_definitionContext windowDefinitionContext = 
ctx.window_definition_list().window_definition(i);
-      String windowName = 
windowDefinitionContext.window_name().identifier().getText();
-      WindowSpec windowSpec = 
buildWindowSpec(windowDefinitionContext.window_specification());
-      definitions[i] = new Window.WindowDefinition(windowName, windowSpec);
-    }
-    return new Window(definitions);
-  }
-
-  public WindowSpec buildWindowSpec(SQLParser.Window_specificationContext ctx) 
{
-    WindowSpec windowSpec = new WindowSpec();
-    if (checkIfExist(ctx.window_specification_details())) {
-      Window_specification_detailsContext windowSpecDetail = 
ctx.window_specification_details();
-
-      if (checkIfExist(windowSpecDetail.existing_window_name())) {
-        
windowSpec.setWindowName(windowSpecDetail.existing_window_name().getText());
-      }
-
-      if (checkIfExist(windowSpecDetail.window_partition_clause())) {
-        windowSpec.setPartitionKeys(
-            
buildRowValuePredicands(windowSpecDetail.window_partition_clause().row_value_predicand_list()));
-      }
-
-      if (checkIfExist(windowSpecDetail.window_order_clause())) {
-        windowSpec.setSortSpecs(
-            
buildSortSpecs(windowSpecDetail.window_order_clause().orderby_clause().sort_specifier_list()));
-      }
-
-      if (checkIfExist(windowSpecDetail.window_frame_clause())) {
-        Window_frame_clauseContext frameContext = 
windowSpecDetail.window_frame_clause();
-
-        WindowSpec.WindowFrameUnit unit;
-        // frame unit - there are only two cases: RANGE and ROW
-        if (checkIfExist(frameContext.window_frame_units().RANGE())) {
-          unit = WindowSpec.WindowFrameUnit.RANGE;
-        } else {
-          unit = WindowSpec.WindowFrameUnit.ROW;
-        }
-
-        WindowSpec.WindowFrame windowFrame;
-
-        if 
(checkIfExist(frameContext.window_frame_extent().window_frame_between())) { // 
when 'between' is given
-          Window_frame_betweenContext between = 
frameContext.window_frame_extent().window_frame_between();
-          WindowSpec.WindowStartBound startBound = 
buildWindowStartBound(between.window_frame_start_bound());
-          WindowSpec.WindowEndBound endBound = 
buildWindowEndBound(between.window_frame_end_bound());
-
-          windowFrame = new WindowSpec.WindowFrame(unit, startBound, endBound);
-        } else { // if there is only start bound
-          WindowSpec.WindowStartBound startBound =
-              
buildWindowStartBound(frameContext.window_frame_extent().window_frame_start_bound());
-          windowFrame = new WindowSpec.WindowFrame(unit, startBound);
-        }
-
-        windowSpec.setWindowFrame(windowFrame);
-      }
-    }
-    return windowSpec;
-  }
-
-  public WindowSpec.WindowStartBound 
buildWindowStartBound(Window_frame_start_boundContext context) {
-    WindowFrameStartBoundType boundType = null;
-    if (checkIfExist(context.UNBOUNDED())) {
-      boundType = WindowFrameStartBoundType.UNBOUNDED_PRECEDING;
-    } else if (checkIfExist(context.unsigned_value_specification())) {
-      boundType = WindowFrameStartBoundType.PRECEDING;
-    } else {
-      boundType = WindowFrameStartBoundType.CURRENT_ROW;
-    }
-
-    WindowSpec.WindowStartBound bound = new 
WindowSpec.WindowStartBound(boundType);
-    if (boundType == WindowFrameStartBoundType.PRECEDING) {
-      
bound.setNumber(visitUnsigned_value_specification(context.unsigned_value_specification()));
-    }
-
-    return bound;
-  }
-
-  public WindowSpec.WindowEndBound 
buildWindowEndBound(Window_frame_end_boundContext context) {
-    WindowFrameEndBoundType boundType;
-    if (checkIfExist(context.UNBOUNDED())) {
-      boundType = WindowFrameEndBoundType.UNBOUNDED_FOLLOWING;
-    } else if (checkIfExist(context.unsigned_value_specification())) {
-      boundType = WindowFrameEndBoundType.FOLLOWING;
-    } else {
-      boundType = WindowFrameEndBoundType.CURRENT_ROW;
-    }
-
-    WindowSpec.WindowEndBound endBound = new 
WindowSpec.WindowEndBound(boundType);
-    if (boundType == WindowFrameEndBoundType.FOLLOWING) {
-      
endBound.setNumber(visitUnsigned_value_specification(context.unsigned_value_specification()));
-    }
-
-    return endBound;
-  }
-
-  public Sort.SortSpec[] buildSortSpecs(Sort_specifier_listContext context) {
-    int size = context.sort_specifier().size();
-
-    Sort.SortSpec specs[] = new Sort.SortSpec[size];
-    for (int i = 0; i < size; i++) {
-      SQLParser.Sort_specifierContext specContext = context.sort_specifier(i);
-      Expr sortKeyExpr = visitRow_value_predicand(specContext.key);
-      specs[i] = new Sort.SortSpec(sortKeyExpr);
-      if (specContext.order_specification() != null) {
-        if (specContext.order.DESC() != null) {
-          specs[i].setDescending();
-        }
-      }
-
-      if (specContext.null_ordering() != null) {
-        if (specContext.null_ordering().FIRST() != null) {
-          specs[i].setNullFirst();
-        }
-      }
-    }
-
-    return specs;
-  }
-
-  @Override
-  public Sort visitOrderby_clause(SQLParser.Orderby_clauseContext ctx) {
-    return new Sort(buildSortSpecs(ctx.sort_specifier_list()));
-  }
-
-  @Override
-  public Limit visitLimit_clause(SQLParser.Limit_clauseContext ctx) {
-    return new 
Limit(visitNumeric_value_expression(ctx.numeric_value_expression()));
-  }
-
-  @Override
-  public Expr visitJoined_table(SQLParser.Joined_tableContext ctx) {
-    Expr top = visitTable_primary(ctx.table_primary());
-
-    // The following loop builds a left deep join tree.
-    Join join;
-    for (int i = 0; i < ctx.joined_table_primary().size(); i++) {
-      join = visitJoined_table_primary(ctx.joined_table_primary(i));
-      join.setLeft(top);
-      top = join;
-    }
-
-    return top;
-  }
-
-  @Override
-  public Join visitJoined_table_primary(SQLParser.Joined_table_primaryContext 
ctx) {
-    Join join;
-    if (ctx.CROSS() != null) {
-      join = new Join(JoinType.CROSS);
-    } else if (ctx.UNION() != null) {
-      join = new Join(JoinType.UNION);
-    } else { // qualified join or natural
-      if (ctx.join_type() != null && ctx.join_type().outer_join_type() != 
null) {
-        Outer_join_type_part2Context outer_join_typeContext = 
ctx.join_type().outer_join_type()
-            .outer_join_type_part2();
-        if (outer_join_typeContext.FULL() != null) {
-          join = new Join(JoinType.FULL_OUTER);
-        } else if (outer_join_typeContext.LEFT() != null) {
-          join = new Join(JoinType.LEFT_OUTER);
-        } else {
-          join = new Join(JoinType.RIGHT_OUTER);
-        }
-      } else {
-        join = new Join(JoinType.INNER);
-      }
-
-      if (ctx.NATURAL() != null) {
-        join.setNatural();
-      }
-
-      if (ctx.join_specification() != null) { // only for qualified join
-        if (ctx.join_specification().join_condition() != null) {
-          Expr searchCondition = 
visitSearch_condition(ctx.join_specification().
-              join_condition().search_condition());
-          join.setQual(searchCondition);
-        } else if (ctx.join_specification().named_columns_join() != null) {
-          ColumnReferenceExpr[] columns = 
buildColumnReferenceList(ctx.join_specification().
-              named_columns_join().column_reference_list());
-          join.setJoinColumns(columns);
-        }
-      }
-    }
-
-    join.setRight(visitTable_primary(ctx.right));
-    return join;
-  }
-
-  private Expr[] 
getRowValuePredicandsFromOrdinaryGroupingSetList(Ordinary_grouping_set_listContext
 ctx) {
-    ArrayList<Expr> rowValuePredicands = new ArrayList<Expr>();
-    for (int i = 0; i < ctx.ordinary_grouping_set().size(); i++) {
-      Collections.addAll(rowValuePredicands, 
getRowValuePredicandsFromOrdinaryGroupingSet(ctx.ordinary_grouping_set(i)));
-    }
-    return rowValuePredicands.toArray(new Expr[rowValuePredicands.size()]);
-  }
-
-  private Expr[] 
getRowValuePredicandsFromOrdinaryGroupingSet(Ordinary_grouping_setContext ctx) {
-    ArrayList<Expr> rowValuePredicands = new ArrayList<Expr>();
-    if (ctx.row_value_predicand() != null) {
-      
rowValuePredicands.add(visitRow_value_predicand(ctx.row_value_predicand()));
-    }
-    if (ctx.row_value_predicand_list() != null) {
-      Collections.addAll(rowValuePredicands, 
buildRowValuePredicands(ctx.row_value_predicand_list()));
-    }
-    return rowValuePredicands.toArray(new Expr[rowValuePredicands.size()]);
-  }
-
-  private Expr[] buildRowValuePredicands(Row_value_predicand_listContext ctx) {
-    Expr[] rowValuePredicands = new Expr[ctx.row_value_predicand().size()];
-    for (int i = 0; i < rowValuePredicands.length; i++) {
-      rowValuePredicands[i] = 
visitRow_value_predicand(ctx.row_value_predicand(i));
-    }
-    return rowValuePredicands;
-  }
-
-  private ColumnReferenceExpr[] 
buildColumnReferenceList(Column_reference_listContext ctx) {
-    ColumnReferenceExpr[] columnRefs = new 
ColumnReferenceExpr[ctx.column_reference().size()];
-    for (int i = 0; i < columnRefs.length; i++) {
-      columnRefs[i] = visitColumn_reference(ctx.column_reference(i));
-    }
-    return columnRefs;
-  }
-
-  @Override
-  public Expr visitTable_primary(SQLParser.Table_primaryContext ctx) {
-    if (ctx.table_or_query_name() != null) {
-      Relation relation = new Relation(ctx.table_or_query_name().getText());
-      if (ctx.alias != null) {
-        relation.setAlias(ctx.alias.getText());
-      }
-      return relation;
-    } else if (ctx.derived_table() != null) {
-      return new TablePrimarySubQuery(ctx.name.getText(), 
visit(ctx.derived_table().table_subquery()));
-    } else {
-      return null;
-    }
-  }
-
-
-  @Override
-  public Expr visitSubquery(SQLParser.SubqueryContext ctx) {
-    return visitQuery_expression(ctx.query_expression());
-  }
-
-  @Override
-  public BetweenPredicate 
visitBetween_predicate(SQLParser.Between_predicateContext ctx) {
-    Expr predicand = visitRow_value_predicand(ctx.predicand);
-    Expr begin = 
visitRow_value_predicand(ctx.between_predicate_part_2().begin);
-    Expr end = visitRow_value_predicand(ctx.between_predicate_part_2().end);
-    return new 
BetweenPredicate(checkIfExist(ctx.between_predicate_part_2().NOT()),
-        checkIfExist(ctx.between_predicate_part_2().SYMMETRIC()), predicand, 
begin, end);
-  }
-
-  @Override
-  public CaseWhenPredicate visitSimple_case(SQLParser.Simple_caseContext ctx) {
-    Expr leftTerm = 
visitBoolean_value_expression(ctx.boolean_value_expression());
-    CaseWhenPredicate caseWhen = new CaseWhenPredicate();
-
-    for (int i = 0; i < ctx.simple_when_clause().size(); i++) {
-      Simple_when_clauseContext simpleWhenCtx = ctx.simple_when_clause(i);
-      BinaryOperator bin = new BinaryOperator(OpType.Equals, leftTerm,
-          
visitValue_expression(simpleWhenCtx.search_condition().value_expression()));
-      caseWhen.addWhen(bin, buildCaseResult(simpleWhenCtx.result()));
-    }
-    if (ctx.else_clause() != null) {
-      caseWhen.setElseResult(buildCaseResult(ctx.else_clause().result()));
-    }
-    return caseWhen;
-  }
-
-  private Expr buildCaseResult(ResultContext result) {
-    if (result.NULL() != null) {
-      return new NullLiteral();
-    } else {
-      return visitValue_expression(result.value_expression());
-    }
-  }
-
-  @Override
-  public CaseWhenPredicate visitSearched_case(SQLParser.Searched_caseContext 
ctx) {
-    CaseWhenPredicate caseWhen = new CaseWhenPredicate();
-
-    for (int i = 0; i < ctx.searched_when_clause().size(); i++) {
-      Searched_when_clauseContext searchedWhenCtx = 
ctx.searched_when_clause(i);
-      caseWhen.addWhen(
-          visitSearch_condition(searchedWhenCtx.search_condition()),
-          buildCaseResult(searchedWhenCtx.result()));
-    }
-    if (ctx.else_clause() != null) {
-      caseWhen.setElseResult(buildCaseResult(ctx.else_clause().result()));
-    }
-    return caseWhen;
-  }
-
-  @Override
-  public Expr 
visitCommon_value_expression(SQLParser.Common_value_expressionContext ctx) {
-    if (checkIfExist(ctx.NULL())) {
-      return new NullLiteral();
-    } else {
-      return visitChildren(ctx);
-    }
-  }
-
-  @Override
-  public Expr 
visitParenthesized_value_expression(SQLParser.Parenthesized_value_expressionContext
 ctx) {
-    return visitValue_expression(ctx.value_expression());
-  }
-
-  @Override
-  public Expr 
visitBoolean_value_expression(SQLParser.Boolean_value_expressionContext ctx) {
-    Expr current = visitOr_predicate(ctx.or_predicate());
-    return current;
-  }
-
-  @Override
-  public Expr visitOr_predicate(SQLParser.Or_predicateContext ctx) {
-    Expr current = visitAnd_predicate(ctx.and_predicate());
-
-    Expr left;
-    Expr right;
-    for (int i = 0; i < ctx.or_predicate().size(); i++) {
-      left = current;
-      right = visitOr_predicate(ctx.or_predicate(i));
-      current = new BinaryOperator(OpType.Or, left, right);
-    }
-
-    return current;
-  }
-
-  @Override
-  public Expr visitAnd_predicate(SQLParser.And_predicateContext ctx) {
-    Expr current = visitBoolean_factor(ctx.boolean_factor());
-
-    Expr left;
-    Expr right;
-    for (int i = 0; i < ctx.and_predicate().size(); i++) {
-      left = current;
-      right = visitAnd_predicate(ctx.and_predicate(i));
-      current = new BinaryOperator(OpType.And, left, right);
-    }
-
-    return current;
-  }
-
-  @Override
-  public Expr visitBoolean_factor(SQLParser.Boolean_factorContext ctx) {
-    if (ctx.NOT() != null) {
-      return new NotExpr(visitBoolean_test(ctx.boolean_test()));
-    } else {
-      return visitBoolean_test(ctx.boolean_test());
-    }
-  }
-
-  @Override
-  public Expr visitBoolean_test(SQLParser.Boolean_testContext ctx) {
-    if (checkIfExist(ctx.is_clause())) {
-      Is_clauseContext isClauseContext = ctx.is_clause();
-      if (checkIfExist(isClauseContext.NOT())) {
-        if (checkIfExist(ctx.is_clause().truth_value().TRUE())) {
-          return new NotExpr(visitBoolean_primary(ctx.boolean_primary()));
-        } else {
-          return visitBoolean_primary(ctx.boolean_primary());
-        }
-      } else {
-        if (checkIfExist(ctx.is_clause().truth_value().TRUE())) {
-          return visitBoolean_primary(ctx.boolean_primary());
-        } else {
-          return new NotExpr(visitBoolean_primary(ctx.boolean_primary()));
-        }
-      }
-    } else {
-      return visitBoolean_primary(ctx.boolean_primary());
-    }
-  }
-
-  @Override
-  public Expr visitBoolean_primary(SQLParser.Boolean_primaryContext ctx) {
-    if (ctx.predicate() != null) {
-      return visitPredicate(ctx.predicate());
-    } else {
-      return visitBoolean_predicand(ctx.boolean_predicand());
-    }
-  }
-
-  @Override
-  public Expr visitBoolean_predicand(SQLParser.Boolean_predicandContext ctx) {
-    if (checkIfExist(ctx.nonparenthesized_value_expression_primary())) {
-      return 
visitNonparenthesized_value_expression_primary(ctx.nonparenthesized_value_expression_primary());
-    } else {
-      return 
visitBoolean_value_expression(ctx.parenthesized_boolean_value_expression().boolean_value_expression());
-    }
-  }
-
-  @Override
-  public Expr visitNonparenthesized_value_expression_primary(
-      SQLParser.Nonparenthesized_value_expression_primaryContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public Expr visitRow_value_predicand(SQLParser.Row_value_predicandContext 
ctx) {
-    if (checkIfExist(ctx.row_value_special_case())) {
-      return visitRow_value_special_case(ctx.row_value_special_case());
-    } else {
-      return 
visitRow_value_constructor_predicand(ctx.row_value_constructor_predicand());
-    }
-  }
-
-  @Override
-  public Expr 
visitRow_value_constructor_predicand(SQLParser.Row_value_constructor_predicandContext
 ctx) {
-    if (checkIfExist(ctx.boolean_predicand())) {
-      return visitBoolean_predicand(ctx.boolean_predicand());
-    } else {
-      return visitCommon_value_expression(ctx.common_value_expression());
-    }
-  }
-
-  @Override
-  public BinaryOperator 
visitComparison_predicate(SQLParser.Comparison_predicateContext ctx) {
-    TerminalNode operator = (TerminalNode) ctx.comp_op().getChild(0);
-    return new BinaryOperator(tokenToExprType(operator.getSymbol().getType()),
-        visitRow_value_predicand(ctx.left),
-        visitRow_value_predicand(ctx.right));
-  }
-
-  @Override
-  public Expr 
visitNumeric_value_expression(SQLParser.Numeric_value_expressionContext ctx) {
-    Expr current = visitTerm(ctx.term(0));
-
-    Expr left;
-    Expr right;
-    for (int i = 1; i < ctx.getChildCount(); i++) {
-      left = current;
-      TerminalNode operator = (TerminalNode) ctx.getChild(i++);
-      right = visitTerm((TermContext) ctx.getChild(i));
-
-      if (operator.getSymbol().getType() == PLUS) {
-        current = new BinaryOperator(OpType.Plus, left, right);
-      } else {
-        current = new BinaryOperator(OpType.Minus, left, right);
-      }
-    }
-
-    return current;
-  }
-
-  @Override
-  public Expr visitTerm(SQLParser.TermContext ctx) {
-    Expr current = visitFactor(ctx.factor(0));
-
-    Expr left;
-    Expr right;
-    for (int i = 1; i < ctx.getChildCount(); i++) {
-      left = current;
-      TerminalNode operator = (TerminalNode) ctx.getChild(i++);
-      right = visitFactor((FactorContext) ctx.getChild(i));
-
-      if (operator.getSymbol().getType() == MULTIPLY) {
-        current = new BinaryOperator(OpType.Multiply, left, right);
-      } else if (operator.getSymbol().getType() == DIVIDE) {
-        current = new BinaryOperator(OpType.Divide, left, right);
-      } else {
-        current = new BinaryOperator(OpType.Modular, left, right);
-      }
-    }
-
-    return current;
-  }
-
-  @Override
-  public Expr visitFactor(SQLParser.FactorContext ctx) {
-    Expr current = visitNumeric_primary(ctx.numeric_primary());
-    if (checkIfExist(ctx.sign()) && checkIfExist(ctx.sign().MINUS())) {
-      current = new SignedExpr(true, current);
-    }
-    return current;
-  }
-
-  @Override
-  public Expr visitNumeric_primary(SQLParser.Numeric_primaryContext ctx) {
-    Expr current = null;
-    if (checkIfExist(ctx.value_expression_primary())) {
-      current = visitValue_expression_primary(ctx.value_expression_primary());
-      for (int i = 0; i < ctx.CAST_EXPRESSION().size(); i++) {
-        current = new CastExpr(current, 
visitData_type(ctx.cast_target(i).data_type()));
-      }
-    } else if (checkIfExist(ctx.numeric_value_function())) {
-      current = visitNumeric_value_function(ctx.numeric_value_function());
-    }
-
-    return current;
-  }
-
-  public static OpType tokenToExprType(int tokenId) {
-    switch (tokenId) {
-      case SQLParser.UNION:
-        return OpType.Union;
-      case SQLParser.EXCEPT:
-        return OpType.Except;
-      case SQLParser.INTERSECT:
-        return OpType.Intersect;
-
-      case SQLParser.AND:
-        return OpType.And;
-      case SQLParser.OR:
-        return OpType.Or;
-
-      case SQLParser.EQUAL:
-        return OpType.Equals;
-      case SQLParser.NOT_EQUAL:
-        return OpType.NotEquals;
-      case SQLParser.LTH:
-        return OpType.LessThan;
-      case SQLParser.LEQ:
-        return OpType.LessThanOrEquals;
-      case SQLParser.GTH:
-        return OpType.GreaterThan;
-      case SQLParser.GEQ:
-        return OpType.GreaterThanOrEquals;
-
-      case SQLParser.MULTIPLY:
-        return OpType.Multiply;
-      case SQLParser.DIVIDE:
-        return OpType.Divide;
-      case SQLParser.MODULAR:
-        return OpType.Modular;
-      case SQLParser.PLUS:
-        return OpType.Plus;
-      case SQLParser.MINUS:
-        return OpType.Minus;
-
-      default:
-        throw new RuntimeException("Unknown Token Id: " + tokenId);
-    }
-  }
-
-  @Override
-  public InPredicate visitIn_predicate(SQLParser.In_predicateContext ctx) {
-    return new InPredicate(visitChildren(ctx.numeric_value_expression()),
-        visitIn_predicate_value(ctx.in_predicate_value()), ctx.NOT() != null);
-  }
-
-  @Override
-  public Expr visitIn_predicate_value(SQLParser.In_predicate_valueContext ctx) 
{
-    if (checkIfExist(ctx.in_value_list())) {
-      int size = ctx.in_value_list().row_value_predicand().size();
-      Expr [] exprs = new Expr[size];
-      for (int i = 0; i < size; i++) {
-        exprs[i] = 
visitRow_value_predicand(ctx.in_value_list().row_value_predicand(i));
-      }
-      return new ValueListExpr(exprs);
-    } else {
-      return new SimpleTableSubquery(visitChildren(ctx.table_subquery()));
-    }
-  }
-
-  @Override
-  public Expr visitArray(SQLParser.ArrayContext ctx) {
-    int size = ctx.numeric_value_expression().size();
-    Expr[] exprs = new Expr[size];
-    for (int i = 0; i < size; i++) {
-      exprs[i] = visit(ctx.numeric_value_expression(i));
-    }
-    return new ValueListExpr(exprs);
-  }
-
-  @Override
-  public Expr 
visitPattern_matching_predicate(SQLParser.Pattern_matching_predicateContext 
ctx) {
-    Expr predicand = visitChildren(ctx.row_value_predicand());
-    Expr pattern = new 
LiteralValue(stripQuote(ctx.Character_String_Literal().getText()),
-        LiteralType.String);
-
-    if (checkIfExist(ctx.pattern_matcher().negativable_matcher())) {
-      boolean not = ctx.pattern_matcher().NOT() != null;
-      Negativable_matcherContext matcher = 
ctx.pattern_matcher().negativable_matcher();
-      if (checkIfExist(matcher.LIKE())) {
-        return new PatternMatchPredicate(OpType.LikePredicate, not, predicand, 
pattern);
-      } else if (checkIfExist(matcher.ILIKE())) {
-        return new PatternMatchPredicate(OpType.LikePredicate, not, predicand, 
pattern, true);
-      } else if (checkIfExist(matcher.SIMILAR())) {
-        return new PatternMatchPredicate(OpType.SimilarToPredicate, not, 
predicand, pattern);
-      } else if (checkIfExist(matcher.REGEXP()) || 
checkIfExist(matcher.RLIKE())) {
-        return new PatternMatchPredicate(OpType.Regexp, not, predicand, 
pattern);
-      } else {
-        throw new TajoRuntimeException(new SQLSyntaxError("Unsupported 
predicate: " + matcher.getText()));
-      }
-    } else if (checkIfExist(ctx.pattern_matcher().regex_matcher())) {
-      Regex_matcherContext matcher = ctx.pattern_matcher().regex_matcher();
-      if (checkIfExist(matcher.Similar_To())) {
-        return new PatternMatchPredicate(OpType.Regexp, false, predicand, 
pattern, false);
-      } else if (checkIfExist(matcher.Not_Similar_To())) {
-        return new PatternMatchPredicate(OpType.Regexp, true, predicand, 
pattern, false);
-      } else if (checkIfExist(matcher.Similar_To_Case_Insensitive())) {
-        return new PatternMatchPredicate(OpType.Regexp, false, predicand, 
pattern, true);
-      } else if (checkIfExist(matcher.Not_Similar_To_Case_Insensitive())) {
-        return new PatternMatchPredicate(OpType.Regexp, true, predicand, 
pattern, true);
-      } else {
-        throw new TajoRuntimeException(new SQLSyntaxError("Unsupported 
predicate: " + matcher.getText()));
-      }
-    } else {
-      throw new TajoRuntimeException(new SQLSyntaxError("Unsupported 
predicate: " + ctx.pattern_matcher().getText()));
-    }
-  }
-
-  @Override
-  public IsNullPredicate visitNull_predicate(SQLParser.Null_predicateContext 
ctx) {
-    Expr predicand = visitRow_value_predicand(ctx.row_value_predicand());
-    return new IsNullPredicate(ctx.NOT() != null, predicand);
-  }
-
-  @Override
-  public ExistsPredicate 
visitExists_predicate(SQLParser.Exists_predicateContext ctx) {
-    return new ExistsPredicate(new 
SimpleTableSubquery(visitTable_subquery(ctx.table_subquery())), ctx.NOT() != 
null);
-  }
-
-  @Override
-  public ColumnReferenceExpr 
visitColumn_reference(SQLParser.Column_referenceContext ctx) {
-    String columnReferenceName = ctx.getText();
-    // find the last dot (.) position to separate a name into both a qualifier 
and name
-    int lastDotIdx = columnReferenceName.lastIndexOf(".");
-
-    if (lastDotIdx > 0) { // if any qualifier is given
-      String qualifier = columnReferenceName.substring(0, lastDotIdx);
-      String name = columnReferenceName.substring(lastDotIdx + 1, 
columnReferenceName.length());
-      return new ColumnReferenceExpr(qualifier, name);
-    } else {
-      return new ColumnReferenceExpr(ctx.getText());
-    }
-  }
-
-  @Override
-  public LiteralValue visitUnsigned_numeric_literal(@NotNull 
SQLParser.Unsigned_numeric_literalContext ctx) {
-    if (ctx.NUMBER() != null) {
-      long lValue = Long.parseLong(ctx.getText());
-      if (lValue >= Integer.MIN_VALUE && lValue <= Integer.MAX_VALUE) {
-        return new LiteralValue(ctx.getText(), LiteralType.Unsigned_Integer);
-      } else {
-        return new LiteralValue(ctx.getText(), 
LiteralType.Unsigned_Large_Integer);
-      }
-    } else {
-      return new LiteralValue(ctx.getText(), LiteralType.Unsigned_Float);
-    }
-  }
-
-  @Override
-  public GeneralSetFunctionExpr 
visitAggregate_function(SQLParser.Aggregate_functionContext ctx) {
-    if (ctx.COUNT() != null && ctx.MULTIPLY() != null) {
-      return new CountRowsFunctionExpr();
-    } else {
-      return visitGeneral_set_function(ctx.general_set_function());
-    }
-  }
-
-  @Override
-  public GeneralSetFunctionExpr 
visitGeneral_set_function(SQLParser.General_set_functionContext ctx) {
-    String signature = ctx.set_function_type().getText();
-    boolean distinct = checkIfExist(ctx.set_qualifier()) && 
checkIfExist(ctx.set_qualifier().DISTINCT());
-    Expr param = visitValue_expression(ctx.value_expression());
-
-    return new GeneralSetFunctionExpr(signature, distinct, new Expr [] 
{param});
-  }
-
-  @Override
-  public FunctionExpr 
visitRoutine_invocation(SQLParser.Routine_invocationContext ctx) {
-    String signature = ctx.function_name().getText();
-    FunctionExpr function = new FunctionExpr(signature);
-    if (ctx.sql_argument_list() != null) {
-      int numArgs = ctx.sql_argument_list().value_expression().size();
-      Expr[] argument_list = new Expr[numArgs];
-      for (int i = 0; i < numArgs; i++) {
-        argument_list[i] = visitValue_expression(ctx.sql_argument_list().
-            value_expression().get(i));
-      }
-
-      function.setParams(argument_list);
-    }
-    return function;
-  }
-
-  @Override
-  public NamedExpr visitDerived_column(Derived_columnContext ctx) {
-    NamedExpr target = new 
NamedExpr(visitValue_expression(ctx.value_expression()));
-    if (ctx.as_clause() != null) {
-      target.setAlias(ctx.as_clause().identifier().getText());
-    }
-    return target;
-  }
-
-  @Override
-  public NamedExpr visitQualified_asterisk(Qualified_asteriskContext ctx) {
-    QualifiedAsteriskExpr target = new QualifiedAsteriskExpr();
-    if (ctx.tb_name != null) {
-      target.setQualifier(ctx.tb_name.getText());
-    }
-
-    return new NamedExpr(target);
-  }
-
-  @Override
-  public Expr 
visitCharacter_string_type(SQLParser.Character_string_typeContext ctx) {
-    return new LiteralValue(stripQuote(ctx.getText()), LiteralType.String);
-  }
-
-  @Override
-  public Expr 
visitCharacter_value_expression(SQLParser.Character_value_expressionContext 
ctx) {
-    Expr current = visitCharacter_factor(ctx.character_factor(0));
-
-    Expr left;
-    Expr right;
-    for (int i = 1; i < ctx.getChildCount(); i++) {
-      left = current;
-      i++; // skip '||' operator
-      right = visitCharacter_factor((Character_factorContext) ctx.getChild(i));
-
-      if (left.getType() == OpType.Literal && right.getType() == 
OpType.Literal) {
-        current = new LiteralValue(((LiteralValue) left).getValue() + 
((LiteralValue) right).getValue(),
-            LiteralType.String);
-      } else {
-        current = new BinaryOperator(OpType.Concatenate, left, right);
-      }
-    }
-
-    return current;
-  }
-
-
-  @Override
-  public Expr visitNumeric_value_function(Numeric_value_functionContext ctx) {
-    if (checkIfExist(ctx.extract_expression())) {
-      return visitExtract_expression(ctx.extract_expression());
-    }
-    if (checkIfExist(ctx.datetime_value_function())) {
-      return visitDatetime_value_function(ctx.datetime_value_function());
-    }
-    return null;
-  }
-
-  @Override
-  public Expr visitExtract_expression(Extract_expressionContext ctx) {
-    Expr extractTarget = new LiteralValue(ctx.extract_field_string.getText(), 
LiteralType.String);
-    Expr extractSource = 
visitDatetime_value_expression(ctx.extract_source().datetime_value_expression());
-//    if (checkIfExist(ctx.extract_source().column_reference())) {
-//      extractSource = 
visitColumn_reference(ctx.extract_source().column_reference());
-//    } else if (checkIfExist(ctx.extract_source().datetime_literal())) {
-//      extractSource = 
visitDatetime_literal(ctx.extract_source().datetime_literal());
-//    } else {
-//      return null;
-//    }
-
-
-    String functionName = "date_part";
-    Expr[] params = new Expr[]{extractTarget, extractSource};
-
-    return new FunctionExpr(functionName, params);
-  }
-
-  @Override
-  public Expr visitTrim_function(SQLParser.Trim_functionContext ctx) {
-    Expr trimSource = visitChildren(ctx.trim_operands().trim_source);
-    String functionName = "trim";
-    if (checkIfExist(ctx.trim_operands().FROM())) {
-      if (checkIfExist(ctx.trim_operands().trim_specification())) {
-        Trim_specificationContext specification = 
ctx.trim_operands().trim_specification();
-        if (checkIfExist(specification.LEADING())) {
-          functionName = "ltrim";
-        } else if (checkIfExist(specification.TRAILING())) {
-          functionName = "rtrim";
-        } else {
-          functionName = "trim";
-        }
-      }
-    }
-
-    Expr trimCharacters = null;
-    if (checkIfExist(ctx.trim_operands().trim_character)) {
-      trimCharacters = 
visitCharacter_value_expression(ctx.trim_operands().trim_character);
-    }
-
-    Expr[] params;
-    if (trimCharacters != null) {
-      params = new Expr[]{trimSource, trimCharacters};
-    } else {
-      params = new Expr[]{trimSource};
-    }
-
-    return new FunctionExpr(functionName, params);
-  }
-
-  @Override
-  public Expr 
visitCreate_index_statement(SQLParser.Create_index_statementContext ctx) {
-    String indexName = ctx.index_name.getText();
-    String tableName = ctx.table_name().getText();
-    Relation relation = new Relation(tableName);
-    SortSpec[] sortSpecs = buildSortSpecs(ctx.sort_specifier_list());
-    NamedExpr[] targets = new NamedExpr[sortSpecs.length];
-    Projection projection = new Projection();
-    int i = 0;
-    for (SortSpec sortSpec : sortSpecs) {
-      targets[i++] = new NamedExpr(sortSpec.getKey());
-    }
-    projection.setNamedExprs(targets);
-    projection.setChild(relation);
-
-    CreateIndex createIndex = new CreateIndex(indexName, sortSpecs);
-    if (checkIfExist(ctx.UNIQUE())) {
-      createIndex.setUnique(true);
-    }
-    if (checkIfExist(ctx.method_specifier())) {
-      String methodName = ctx.method_specifier().identifier().getText();
-      createIndex.setMethodSpec(new IndexMethodSpec(methodName));
-    }
-    if (checkIfExist(ctx.param_clause())) {
-      Map<String, String> params = getParams(ctx.param_clause());
-      createIndex.setParams(params);
-    }
-    if (checkIfExist(ctx.where_clause())) {
-      Selection selection = visitWhere_clause(ctx.where_clause());
-      selection.setChild(relation);
-      projection.setChild(selection);
-    }
-    if (checkIfExist(ctx.LOCATION())) {
-      createIndex.setIndexPath(stripQuote(ctx.path.getText()));
-    }
-    createIndex.setChild(projection);
-    return createIndex;
-  }
-
-  @Override
-  public Expr visitDrop_index_statement(SQLParser.Drop_index_statementContext 
ctx) {
-    String indexName = ctx.identifier().getText();
-    return new DropIndex(indexName);
-  }
-
-  @Override
-  public Expr visitDatabase_definition(@NotNull 
SQLParser.Database_definitionContext ctx) {
-    return new CreateDatabase(ctx.identifier().getText(), null, 
checkIfExist(ctx.if_not_exists()));
-  }
-
-  @Override
-  public Expr visitDrop_database_statement(@NotNull 
SQLParser.Drop_database_statementContext ctx) {
-    return new DropDatabase(ctx.identifier().getText(), 
checkIfExist(ctx.if_exists()));
-  }
-
-  @Override
-  public Expr 
visitCreate_table_statement(SQLParser.Create_table_statementContext ctx) {
-    String tableName = ctx.table_name(0).getText();
-    CreateTable createTable = new CreateTable(tableName, 
checkIfExist(ctx.if_not_exists()));
-    if(checkIfExist(ctx.LIKE()))  {
-      createTable.setLikeParentTable(ctx.like_table_name.getText());
-      return createTable;
-    }
-
-    if (checkIfExist(ctx.EXTERNAL())) {
-      createTable.setExternal();
-
-      ColumnDefinition[] elements = getDefinitions(ctx.table_elements());
-      String storageType = ctx.storage_type.getText();
-      createTable.setTableElements(elements);
-      createTable.setStorageType(storageType);
-
-      if (checkIfExist(ctx.LOCATION())) {
-        String uri = stripQuote(ctx.uri.getText());
-        createTable.setLocation(uri);
-      }
-    } else {
-      if (checkIfExist(ctx.table_elements())) {
-        ColumnDefinition[] elements = getDefinitions(ctx.table_elements());
-        createTable.setTableElements(elements);
-      }
-
-      if (checkIfExist(ctx.TABLESPACE())) {
-        String spaceName = ctx.spacename.getText();
-        createTable.setTableSpaceName(spaceName);
-      }
-
-      if (checkIfExist(ctx.USING())) {
-        String fileType = ctx.storage_type.getText();
-        createTable.setStorageType(fileType);
-      }
-
-      if (checkIfExist(ctx.query_expression())) {
-        Expr subquery = visitQuery_expression(ctx.query_expression());
-        createTable.setSubQuery(subquery);
-      }
-    }
-
-    if (checkIfExist(ctx.param_clause())) {
-      Map<String, String> params = 
escapeTableMeta(getParams(ctx.param_clause()));
-      createTable.setParams(params);
-    }
-
-    if (checkIfExist(ctx.table_partitioning_clauses())) {
-      PartitionMethodDescExpr partitionMethodDesc =
-          parseTablePartitioningClause(ctx.table_partitioning_clauses());
-      createTable.setPartitionMethod(partitionMethodDesc);
-    }
-    return createTable;
-  }
-
-  @Override
-  public Expr visitTruncate_table_statement(@NotNull 
SQLParser.Truncate_table_statementContext ctx) {
-    List<Table_nameContext> tableNameContexts = ctx.table_name();
-    List<String> tableNames = new ArrayList<String>();
-
-    for (Table_nameContext eachTableNameContext: tableNameContexts) {
-      tableNames.add(eachTableNameContext.getChild(0).getText());
-    }
-
-    return new TruncateTable(tableNames);
-  }
-
-  private ColumnDefinition[] getDefinitions(SQLParser.Table_elementsContext 
ctx) {
-    int size = ctx.field_element().size();
-    ColumnDefinition[] elements = new ColumnDefinition[size];
-    for (int i = 0; i < size; i++) {
-      String name = ctx.field_element(i).name.getText();
-
-      String dataTypeName = 
ctx.field_element(i).field_type().data_type().getText();
-      DataTypeExpr typeDef = 
visitData_type(ctx.field_element(i).field_type().data_type());
-      Preconditions.checkNotNull(typeDef, dataTypeName + " is not handled 
correctly");
-      elements[i] = new ColumnDefinition(name, typeDef);
-    }
-
-    return elements;
-  }
-
-  public PartitionMethodDescExpr 
parseTablePartitioningClause(SQLParser.Table_partitioning_clausesContext ctx) {
-
-    if (checkIfExist(ctx.range_partitions())) { // For Range Partition
-      Range_partitionsContext rangePartitionsContext = ctx.range_partitions();
-      List<Range_value_clauseContext> rangeValueClause = 
rangePartitionsContext.
-          range_value_clause_list().range_value_clause();
-
-      List<RangePartitionSpecifier> specifiers = Lists.newArrayList();
-
-      for (Range_value_clauseContext rangeValue : rangeValueClause) {
-        if (checkIfExist(rangeValue.MAXVALUE())) { // LESS THAN (MAXVALUE)
-          specifiers.add(new 
RangePartitionSpecifier(rangeValue.partition_name().getText()));
-        } else { // LESS THAN (expr)
-          specifiers.add(new 
RangePartitionSpecifier(rangeValue.partition_name().getText(),
-              visitValue_expression(rangeValue.value_expression())));
-        }
-      }
-      return new 
CreateTable.RangePartition(buildColumnReferenceList(ctx.range_partitions().column_reference_list()),
-          specifiers);
-
-    } else if (checkIfExist(ctx.hash_partitions())) { // For Hash Partition
-      Hash_partitionsContext hashPartitions = ctx.hash_partitions();
-
-      if (checkIfExist(hashPartitions.hash_partitions_by_quantity())) { // 
PARTITIONS (num)
-        return new 
HashPartition(buildColumnReferenceList(hashPartitions.column_reference_list()),
-            
visitNumeric_value_expression(hashPartitions.hash_partitions_by_quantity().quantity));
-
-      } else { // ( PARTITION part_name , ...)
-        List<CreateTable.PartitionSpecifier> specifiers = Lists.newArrayList();
-        for (Individual_hash_partitionContext partition :
-            
hashPartitions.individual_hash_partitions().individual_hash_partition()) {
-          specifiers.add(new 
CreateTable.PartitionSpecifier(partition.partition_name().getText()));
-        }
-        return new 
HashPartition(buildColumnReferenceList(hashPartitions.column_reference_list()), 
specifiers);
-      }
-
-    } else if (checkIfExist(ctx.list_partitions())) { // For List Partition
-      List_partitionsContext listPartitions = ctx.list_partitions();
-      List<List_value_partitionContext> partitions = 
listPartitions.list_value_clause_list().list_value_partition();
-      List<ListPartitionSpecifier> specifiers = Lists.newArrayList();
-
-      for (List_value_partitionContext listValuePartition : partitions) {
-        int size = 
listValuePartition.in_value_list().row_value_predicand().size();
-        Expr [] exprs = new Expr[size];
-        for (int i = 0; i < size; i++) {
-          exprs[i] = 
visitRow_value_predicand(listValuePartition.in_value_list().row_value_predicand(i));
-        }
-        specifiers.add(new 
ListPartitionSpecifier(listValuePartition.partition_name().getText(),
-            new ValueListExpr(exprs)));
-      }
-      return new 
ListPartition(buildColumnReferenceList(ctx.list_partitions().column_reference_list()),
 specifiers);
-
-    } else if (checkIfExist(ctx.column_partitions())) { // For Column 
Partition (Hive Style)
-      return new 
CreateTable.ColumnPartition(getDefinitions(ctx.column_partitions().table_elements()));
-    } else {
-      throw new TajoRuntimeException(new SQLSyntaxError("Invalid Partition 
Type: " + ctx.toStringTree()));
-    }
-  }
-
-  @Override
-  public DataTypeExpr visitData_type(SQLParser.Data_typeContext ctx) {
-    SQLParser.Predefined_typeContext predefined_type = ctx.predefined_type();
-
-    DataTypeExpr typeDefinition = null;
-
-    // CHAR -> FIXED   CHAR
-    //      |- VARYING CHAR
-    // TEXT
-    if (checkIfExist(predefined_type.character_string_type())) {
-
-      SQLParser.Character_string_typeContext character_string_type = 
predefined_type.character_string_type();
-
-
-      if ((checkIfExist(character_string_type.CHARACTER()) || 
checkIfExist(character_string_type.CHAR())) &&
-          !checkIfExist(character_string_type.VARYING())) {
-
-        typeDefinition = new DataTypeExpr(Type.CHAR.name());
-
-        if (character_string_type.type_length() != null) {
-          typeDefinition.setLengthOrPrecision(
-              
Integer.parseInt(character_string_type.type_length().NUMBER().getText()));
-        }
-
-      } else if (checkIfExist(character_string_type.VARCHAR()) || 
checkIfExist(character_string_type.VARYING())) {
-
-        typeDefinition = new DataTypeExpr(Type.VARCHAR.name());
-
-        if (character_string_type.type_length() != null) {
-          typeDefinition.setLengthOrPrecision(
-              
Integer.parseInt(character_string_type.type_length().NUMBER().getText()));
-        }
-
-      } else if (checkIfExist(character_string_type.TEXT())) {
-        typeDefinition = new DataTypeExpr(Type.TEXT.name());
-      }
-
-    // NCHAR
-    } else if (checkIfExist(predefined_type.national_character_string_type())) 
{
-
-      National_character_string_typeContext nchar_type = 
predefined_type.national_character_string_type();
-
-      if ((checkIfExist(nchar_type.CHAR()) || 
checkIfExist(nchar_type.CHARACTER()) ||
-          checkIfExist(nchar_type.NCHAR()) && 
!checkIfExist(nchar_type.VARYING()))) {
-
-        typeDefinition = new DataTypeExpr(Type.NCHAR.name());
-
-      } else if (checkIfExist(nchar_type.NVARCHAR()) || 
checkIfExist(nchar_type.VARYING())) {
-
-        typeDefinition = new DataTypeExpr(Type.NVARCHAR.name());
-      }
-
-      // if a length is given
-      if (checkIfExist(nchar_type.type_length())) {
-        
typeDefinition.setLengthOrPrecision(Integer.parseInt(nchar_type.type_length().NUMBER().getText()));
-      }
-
-    // BLOB types
-    } else if 
(checkIfExist(predefined_type.binary_large_object_string_type())) {
-
-      Binary_large_object_string_typeContext blob_type = 
predefined_type.binary_large_object_string_type();
-
-      typeDefinition = new DataTypeExpr(Type.BLOB.name());
-
-      if (checkIfExist(blob_type.type_length())) {
-        
typeDefinition.setLengthOrPrecision(Integer.parseInt(blob_type.type_length().NUMBER().getText()));
-      }
-
-    // NUMERIC types
-    } else if (checkIfExist(predefined_type.numeric_type())) {
-      // exact number
-      if (checkIfExist(predefined_type.numeric_type().exact_numeric_type())) {
-
-        Exact_numeric_typeContext exactType = 
predefined_type.numeric_type().exact_numeric_type();
-
-        if (checkIfExist(exactType.TINYINT()) || 
checkIfExist(exactType.INT1())) {
-          typeDefinition = new DataTypeExpr(Type.INT1.name());
-
-        } else if (checkIfExist(exactType.INT2()) || 
checkIfExist(exactType.SMALLINT())) {
-          typeDefinition = new DataTypeExpr(Type.INT2.name());
-
-        } else if (checkIfExist(exactType.INT4()) ||
-            checkIfExist(exactType.INTEGER()) ||
-            checkIfExist(exactType.INT())) {
-          typeDefinition = new DataTypeExpr(Type.INT4.name());
-
-        } else if (checkIfExist(exactType.INT8()) || 
checkIfExist(exactType.BIGINT()) ) {
-          typeDefinition = new DataTypeExpr(Type.INT8.name());
-
-        } else if (checkIfExist(exactType.NUMERIC()) ||
-            checkIfExist(exactType.DECIMAL()) ||
-            checkIfExist(exactType.DEC())) {
-          typeDefinition = new DataTypeExpr(Type.NUMERIC.name());
-
-          if (checkIfExist(exactType.precision_param())) {
-            
typeDefinition.setLengthOrPrecision(Integer.parseInt(exactType.precision_param().precision.getText()));
-
-            if (checkIfExist(exactType.precision_param().scale)) {
-              
typeDefinition.setScale(Integer.parseInt(exactType.precision_param().scale.getText()));
-            }
-          }
-        }
-
-
-      } else { // approximate number
-        Approximate_numeric_typeContext approximateType = 
predefined_type.numeric_type().approximate_numeric_type();
-        if (checkIfExist(approximateType.FLOAT()) ||
-            checkIfExist(approximateType.FLOAT4()) ||
-            checkIfExist(approximateType.REAL())) {
-          typeDefinition = new DataTypeExpr(Type.FLOAT4.name());
-
-        } else if (checkIfExist(approximateType.FLOAT8()) || 
checkIfExist(approximateType.DOUBLE())) {
-          typeDefinition = new DataTypeExpr(Type.FLOAT8.name());
-        }
-      }
-
-    } else if (checkIfExist(predefined_type.boolean_type())) {
-      typeDefinition = new DataTypeExpr(Type.BOOLEAN.name());
-
-    } else if (checkIfExist(predefined_type.datetime_type())) {
-
-      Datetime_typeContext dateTimeType = predefined_type.datetime_type();
-      if (checkIfExist(dateTimeType.DATE())) {
-        typeDefinition = new DataTypeExpr(Type.DATE.name());
-
-      } else if (checkIfExist(dateTimeType.TIME(0))) {
-        if (checkIfExist(dateTimeType.ZONE())) {
-          typeDefinition = new DataTypeExpr(Type.TIMEZ.name());
-        } else {
-          typeDefinition = new DataTypeExpr(Type.TIME.name());
-        }
-
-      } else if (checkIfExist(dateTimeType.TIMETZ())) {
-        typeDefinition = new DataTypeExpr(Type.TIMEZ.name());
-
-      } else if (checkIfExist(dateTimeType.TIMESTAMP())) {
-         if (checkIfExist(dateTimeType.ZONE())) {
-           typeDefinition = new DataTypeExpr(Type.TIMESTAMPZ.name());
-         }  else {
-           typeDefinition = new DataTypeExpr(Type.TIMESTAMP.name());
-         }
-
-      } else if (checkIfExist(dateTimeType.TIMESTAMPTZ())) {
-        typeDefinition = new DataTypeExpr(Type.TIMESTAMPZ.name());
-      }
-
-      // bit data types
-    } else if (predefined_type.bit_type() != null) {
-      Bit_typeContext bitType = predefined_type.bit_type();
-
-      if (checkIfExist(bitType.VARBIT()) || checkIfExist(bitType.VARYING())) {
-        typeDefinition = new DataTypeExpr(Type.VARBIT.name());
-
-      } else {
-        typeDefinition = new DataTypeExpr(Type.BIT.name());
-      }
-
-      if (checkIfExist(bitType.type_length())) {
-        typeDefinition.setLengthOrPrecision(
-            Integer.parseInt(bitType.type_length().NUMBER().getText()));
-      }
-
-
-      // binary data types
-    } else if (checkIfExist(predefined_type.binary_type())) {
-      SQLParser.Binary_typeContext binaryType = predefined_type.binary_type();
-
-      if (checkIfExist(binaryType.VARBINARY()) || 
checkIfExist(binaryType.VARYING())) {
-        typeDefinition = new DataTypeExpr(Type.VARBINARY.name());
-      } else {
-        typeDefinition = new DataTypeExpr(Type.BINARY.name());
-      }
-
-
-      if (checkIfExist(binaryType.type_length())) {
-        
typeDefinition.setLengthOrPrecision(Integer.parseInt(binaryType.type_length().NUMBER().getText()));
-      }
-
-      // inet
-    } else if (checkIfExist(predefined_type.network_type())) {
-      typeDefinition = new DataTypeExpr(Type.INET4.name());
-
-
-    } else if (checkIfExist(predefined_type.record_type())) {
-      ColumnDefinition [] nestedRecordDefine = 
getDefinitions(predefined_type.record_type().table_elements());
-      typeDefinition = new DataTypeExpr(new 
DataTypeExpr.RecordType(nestedRecordDefine));
-
-    } else if (checkIfExist(predefined_type.map_type())) {
-      Map_typeContext mapTypeContext = predefined_type.map_type();
-      typeDefinition = new DataTypeExpr(
-          new MapType(visitData_type(mapTypeContext.key_type), 
visitData_type(mapTypeContext.value_type)));
-    }
-
-    return typeDefinition;
-  }
-
-  @Override
-  public Expr visitInsert_statement(SQLParser.Insert_statementContext ctx) {
-    Insert insertExpr = new Insert();
-
-    if (ctx.OVERWRITE() != null) {
-      insertExpr.setOverwrite();
-    }
-
-    if (ctx.table_name() != null) {
-      insertExpr.setTableName(ctx.table_name().getText());
-
-      if (ctx.column_reference_list() != null) {
-        ColumnReferenceExpr [] targetColumns =
-            new 
ColumnReferenceExpr[ctx.column_reference_list().column_reference().size()];
-
-        for (int i = 0; i < targetColumns.length; i++) {
-          targetColumns[i] = 
visitColumn_reference(ctx.column_reference_list().column_reference(i));
-        }
-
-        insertExpr.setTargetColumns(targetColumns);
-      }
-    }
-
-    if (ctx.LOCATION() != null) {
-      insertExpr.setLocation(stripQuote(ctx.path.getText()));
-
-      if (ctx.USING() != null) {
-        insertExpr.setStorageType(ctx.storage_type.getText());
-
-        if (ctx.param_clause() != null) {
-          insertExpr.setParams(escapeTableMeta(getParams(ctx.param_clause())));
-        }
-      }
-    }
-
-    insertExpr.setSubQuery(visitQuery_expression(ctx.query_expression()));
-
-    Preconditions.checkState(insertExpr.hasTableName() || 
insertExpr.hasLocation(),
-        "Either a table name or a location should be given.");
-    Preconditions.checkState(insertExpr.hasTableName() ^ 
insertExpr.hasLocation(),
-        "A table name and a location cannot coexist.");
-    return insertExpr;
-  }
-
-  @Override
-  public Expr visitDrop_table_statement(SQLParser.Drop_table_statementContext 
ctx) {
-    return new DropTable(ctx.table_name().getText(), 
checkIfExist(ctx.if_exists()), checkIfExist(ctx.PURGE()));
-  }
-
-
-  private Map<String, String> getParams(SQLParser.Param_clauseContext ctx) {
-    Map<String, String> params = new HashMap<String, String>();
-    for (int i = 0; i < ctx.param().size(); i++) {
-      params.put(stripQuote(ctx.param(i).key.getText()), 
stripQuote(ctx.param(i).value.getText()));
-    }
-
-    return params;
-  }
-
-  public Map<String, String> escapeTableMeta(Map<String, String> map) {
-    Map<String, String> params = new HashMap<String, String>();
-    for (Map.Entry<String, String> entry : map.entrySet()) {
-      if (entry.getKey().equals(StorageConstants.TEXT_DELIMITER)) {
-        params.put(StorageConstants.TEXT_DELIMITER, 
StringUtils.unicodeEscapedDelimiter(entry.getValue()));
-      } else {
-        params.put(entry.getKey(), entry.getValue());
-      }
-    }
-    return params;
-  }
-
-  private static String stripQuote(String str) {
-    return str.substring(1, str.length() - 1);
-  }
-
-  @Override
-  public Expr visitCast_specification(SQLParser.Cast_specificationContext ctx) 
{
-    Expr operand = visitChildren(ctx.cast_operand());
-    DataTypeExpr castTarget = visitData_type(ctx.cast_target().data_type());
-    return new CastExpr(operand, castTarget);
-  }
-
-  @Override
-  public Expr visitUnsigned_value_specification(@NotNull 
SQLParser.Unsigned_value_specificationContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public Expr visitUnsigned_literal(@NotNull SQLParser.Unsigned_literalContext 
ctx) {
-    if (checkIfExist(ctx.unsigned_numeric_literal())) {
-      return visitUnsigned_numeric_literal(ctx.unsigned_numeric_literal());
-    } else {
-      return visitGeneral_literal(ctx.general_literal());
-    }
-  }
-
-  @Override
-  public Expr visitGeneral_literal(SQLParser.General_literalContext ctx) {
-    if (checkIfExist(ctx.Character_String_Literal())) {
-      return new 
LiteralValue(stripQuote(ctx.Character_String_Literal().getText()), 
LiteralType.String);
-    } else if (checkIfExist(ctx.datetime_literal())) {
-      return visitDatetime_literal(ctx.datetime_literal());
-    } else {
-      return new BooleanLiteral(checkIfExist(ctx.boolean_literal().TRUE()));
-    }
-  }
-
-  @Override
-  public Expr visitDatetime_literal(@NotNull SQLParser.Datetime_literalContext 
ctx) {
-    if (checkIfExist(ctx.time_literal())) {
-      return visitTime_literal(ctx.time_literal());
-    } else if (checkIfExist(ctx.date_literal())) {
-      return visitDate_literal(ctx.date_literal());
-    } else if (checkIfExist(ctx.interval_literal())) {
-      return visitInterval_literal(ctx.interval_literal());
-    } else {
-      return visitTimestamp_literal(ctx.timestamp_literal());
-    }
-  }
-
-  @Override
-  public Expr visitTime_literal(SQLParser.Time_literalContext ctx) {
-    String timePart = stripQuote(ctx.time_string.getText());
-    return new TimeLiteral(parseTime(timePart));
-  }
-
-  @Override
-  public Expr visitDate_literal(SQLParser.Date_literalContext ctx) {
-    String datePart = stripQuote(ctx.date_string.getText());
-    return new DateLiteral(parseDate(datePart));
-  }
-
-  @Override
-  public Expr visitTimestamp_literal(SQLParser.Timestamp_literalContext ctx) {
-    String timestampStr = stripQuote(ctx.timestamp_string.getText());
-    String[] parts = timestampStr.split(" ");
-    String datePart = parts[0];
-    String timePart = parts[1];
-    return new TimestampLiteral(parseDate(datePart), parseTime(timePart));
-  }
-
-  @Override
-  public Expr visitInterval_literal(@NotNull SQLParser.Interval_literalContext 
ctx) {
-    String intervalStr = stripQuote(ctx.interval_string.getText());
-    return new IntervalLiteral(intervalStr);
-  }
-
-  @Override
-  public Expr visitDatetime_value_expression(@NotNull 
SQLParser.Datetime_value_expressionContext ctx) {
-    return visitDatetime_term(ctx.datetime_term());
-  }
-
-  @Override
-  public Expr visitDatetime_term(@NotNull SQLParser.Datetime_termContext ctx) {
-    return visitDatetime_factor(ctx.datetime_factor());
-  }
-
-  @Override
-  public Expr visitDatetime_factor(@NotNull SQLParser.Datetime_factorContext 
ctx) {
-    return visitDatetime_primary(ctx.datetime_primary());
-  }
-
-  @Override
-  public Expr visitDatetime_primary(@NotNull SQLParser.Datetime_primaryContext 
ctx) {
-    if (checkIfExist(ctx.value_expression_primary())) {
-      return visitValue_expression_primary(ctx.value_expression_primary());
-    } else {
-      return visitDatetime_value_function(ctx.datetime_value_function());
-    }
-  }
-
-  @Override
-  public Expr visitDatetime_value_function(@NotNull 
SQLParser.Datetime_value_functionContext ctx) {
-    if (checkIfExist(ctx.current_date_value_function())) {
-      return 
visitCurrent_date_value_function(ctx.current_date_value_function());
-    } else if (checkIfExist(ctx.current_time_value_function())) {
-      return 
visitCurrent_time_value_function(ctx.current_time_value_function());
-    } else {
-      return 
visitCurrent_timestamp_value_function(ctx.current_timestamp_value_function());
-    }
-  }
-
-  @Override
-  public Expr visitCurrent_date_value_function(@NotNull 
SQLParser.Current_date_value_functionContext ctx) {
-    String functionName = "current_date";
-    Expr[] params = new Expr[]{};
-    return new FunctionExpr(functionName, params);
-  }
-
-  @Override
-  public Expr visitCurrent_time_value_function(@NotNull 
SQLParser.Current_time_value_functionContext ctx) {
-    String functionName = "current_time";
-    Expr[] params = new Expr[]{};
-    return new FunctionExpr(functionName, params);
-  }
-
-  @Override
-  public Expr visitCurrent_timestamp_value_function(@NotNull 
SQLParser.Current_timestamp_value_functionContext ctx) {
-    String functionName = "now";
-    Expr[] params = new Expr[]{};
-    return new FunctionExpr(functionName, params);
-  }
-
-  private DateValue parseDate(String datePart) {
-    // e.g., 1980-04-01
-    String[] parts = datePart.split("-");
-    return new DateValue(parts[0], parts[1], parts[2]);
-  }
-
-  private TimeValue parseTime(String timePart) {
-    // e.g., 12:01:50.399
-    String[] parts = timePart.split(":");
-
-    TimeValue time;
-    boolean hasFractionOfSeconds = (parts.length > 2 && parts[2].indexOf('.') 
> 0);
-    if (hasFractionOfSeconds) {
-      String[] secondsParts = parts[2].split("\\.");
-      time = new TimeValue(parts[0], parts[1], secondsParts[0]);
-      if (secondsParts.length == 2) {
-        time.setSecondsFraction(secondsParts[1]);
-      }
-    } else {
-      time = new TimeValue(parts[0],
-          (parts.length > 1 ? parts[1] : "0"),
-          (parts.length > 2 ? parts[2] : "0"));
-    }
-    return time;
-  }
-
-  @Override
-  public Expr visitAlter_tablespace_statement(@NotNull 
SQLParser.Alter_tablespace_statementContext ctx) {
-    AlterTablespace alter = new AlterTablespace(ctx.space_name.getText());
-    alter.setLocation(stripQuote(ctx.uri.getText()));
-    return alter;
-  }
-
-  @Override
-  public Expr 
visitAlter_table_statement(SQLParser.Alter_table_statementContext ctx) {
-
-    final List<Table_nameContext> tables = ctx.table_name();
-
-    final AlterTable alterTable = new AlterTable(tables.get(0).getText());
-
-    if (tables.size() == 2) {
-      alterTable.setNewTableName(tables.get(1).getText());
-    }
-
-    if (checkIfExist(ctx.column_name()) && ctx.column_name().size() == 2) {
-      final List<Column_nameContext> columns = ctx.column_name();
-      alterTable.setColumnName(columns.get(0).getText());
-      alterTable.setNewColumnName(columns.get(1).getText());
-    }
-
-    Field_elementContext field_elementContext = ctx.field_element();
-    if (checkIfExist(field_elementContext)) {
-      final String name = field_elementContext.name.getText();
-      final DataTypeExpr typeDef = 
visitData_type(field_elementContext.field_type().data_type());
-      final ColumnDefinition columnDefinition = new ColumnDefinition(name, 
typeDef);
-      alterTable.setAddNewColumn(columnDefinition);
-    }
-
-    if (checkIfExist(ctx.partition_column_value_list())) {
-      List<Partition_column_valueContext> columnValueList = 
ctx.partition_column_value_list().partition_column_value();
-      int size = columnValueList.size();
-      ColumnReferenceExpr[] columns = new ColumnReferenceExpr[size];
-      Expr[] values = new Expr[size];
-      for (int i = 0; i < size; i++) {
-        Partition_column_valueContext columnValue = columnValueList.get(i);
-        columns[i] = new 
ColumnReferenceExpr(columnValue.identifier().getText());
-        values[i] = 
visitRow_value_predicand(columnValue.row_value_predicand());
-      }
-      alterTable.setColumns(columns);
-      alterTable.setValues(values);
-      if (ctx.LOCATION() != null) {
-        String path = stripQuote(ctx.path.getText());
-        alterTable.setLocation(path);
-      }
-      alterTable.setPurge(checkIfExist(ctx.PURGE()));
-      alterTable.setIfNotExists(checkIfExist(ctx.if_not_exists()));
-      alterTable.setIfExists(checkIfExist(ctx.if_exists()));
-    }
-
-    if (checkIfExist(ctx.property_list())) {
-      alterTable.setParams(getProperties(ctx.property_list()));
-    }
-
-    alterTable.setAlterTableOpType(determineAlterTableType(ctx));
-
-    return alterTable;
-  }
-
-  private Map<String, String> getProperties(SQLParser.Property_listContext 
ctx) {
-    Map<String, String> params = new HashMap<String, String>();
-    for (int i = 0; i < ctx.property().size(); i++) {
-      params.put(stripQuote(ctx.property(i).key.getText()), 
stripQuote(ctx.property(i).value.getText()));
-    }
-
-    return params;
-  }
-
-  private AlterTableOpType 
determineAlterTableType(SQLParser.Alter_table_statementContext ctx) {
-
-    final int RENAME_MASK = 00000001;
-    final int COLUMN_MASK = 00000010;
-    final int TO_MASK = 00000100;
-    final int ADD_MASK = 00001000;
-    final int DROP_MASK = 00001001;
-    final int PARTITION_MASK = 00000020;
-    final int SET_MASK = 00000002;
-    final int PROPERTY_MASK = 00010000;
-
-    int val = 00000000;
-
-    for (int idx = 1; idx < ctx.getChildCount(); idx++) {
-
-      if (ctx.getChild(idx) instanceof TerminalNode) {
-        switch (((TerminalNode) ctx.getChild(idx)).getSymbol().getType()) {
-          case RENAME:
-            val = val | RENAME_MASK;
-            break;
-          case COLUMN:
-            val = val | COLUMN_MASK;
-            break;
-          case TO:
-            val = val | TO_MASK;
-            break;
-          case ADD:
-            val = val | ADD_MASK;
-            break;
-          case DROP:
-            val = val | DROP_MASK;
-            break;
-          case PARTITION:
-            val = val | PARTITION_MASK;
-            break;
-          case SET:
-            val = val | SET_MASK;
-            break;
-          case PROPERTY:
-            val = val | PROPERTY_MASK;
-            break;
-          default:
-            break;
-        }
-      }
-    }
-    return evaluateAlterTableOperationTye(val);
-  }
-
-  private AlterTableOpType evaluateAlterTableOperationTye(final int value) {
-
-    switch (value) {
-      case 65:
-        return AlterTableOpType.RENAME_TABLE;
-      case 73:
-        return AlterTableOpType.RENAME_COLUMN;
-      case 520:
-        return AlterTableOpType.ADD_COLUMN;
-      case 528:
-        return AlterTableOpType.ADD_PARTITION;
-      case 529:
-        return AlterTableOpType.DROP_PARTITION;
-      case 4098:
-        return AlterTableOpType.SET_PROPERTY;
-      default:
-        return null;
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/d6bc9118/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLErrorListener.java
----------------------------------------------------------------------
diff --git 
a/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLErrorListener.java 
b/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLErrorListener.java
deleted file mode 100644
index 1df5f7b..0000000
--- 
a/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLErrorListener.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- * 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 org.apache.tajo.engine.parser;
-
-import org.antlr.v4.runtime.*;
-import org.apache.commons.lang.StringUtils;
-
-public class SQLErrorListener extends BaseErrorListener {
-  public void syntaxError(Recognizer<?, ?> recognizer,
-                          Object offendingSymbol,
-                          int line, int charPositionInLine,
-                          String msg,
-                          RecognitionException e) {
-    CommonTokenStream tokens = (CommonTokenStream) recognizer.getInputStream();
-    String input = tokens.getTokenSource().getInputStream().toString();
-    Token token = (Token) offendingSymbol;
-    String[] lines = StringUtils.splitPreserveAllTokens(input, '\n');
-    String errorLine = lines[line - 1];
-
-    throw new SQLParseError(token, line, charPositionInLine, msg, errorLine);
-  }
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/d6bc9118/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLErrorStrategy.java
----------------------------------------------------------------------
diff --git 
a/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLErrorStrategy.java 
b/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLErrorStrategy.java
deleted file mode 100644
index 7e1d43c..0000000
--- 
a/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLErrorStrategy.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- * 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 org.apache.tajo.engine.parser;
-
-import org.antlr.v4.runtime.*;
-import org.antlr.v4.runtime.misc.NotNull;
-
-public class SQLErrorStrategy extends DefaultErrorStrategy {
-
-  @Override
-  public void reportError(Parser recognizer, RecognitionException e) {
-    // if we've already reported an error and have not matched a token
-    // yet successfully, don't report any errors.
-    if (inErrorRecoveryMode(recognizer)) {
-      return; // don't report spurious errors
-    }
-    beginErrorCondition(recognizer);
-    if (e instanceof NoViableAltException) {
-      reportNoViableAltException(recognizer, (NoViableAltException) e);
-    } else if (e instanceof InputMismatchException) {
-      reportInputMismatchException(recognizer, (InputMismatchException) e);
-    } else if (e instanceof FailedPredicateException) {
-      reportFailedPredicate(recognizer, (FailedPredicateException) e);
-    } else {
-      recognizer.notifyErrorListeners(e.getOffendingToken(), e.getMessage(), 
e);
-    }
-  }
-
-  protected void reportNoViableAltException(@NotNull Parser recognizer, 
@NotNull NoViableAltException e) {
-    TokenStream tokens = recognizer.getInputStream();
-    String msg;
-    Token token = e.getStartToken();
-    if (tokens != null) {
-      if (tokens.LT(-1) != null && token.getType() == Token.EOF) {
-        token = tokens.LT(-1);
-      }
-      msg = "syntax error at or near " + getTokenErrorDisplay(token);
-    } else {
-      msg = "no viable alternative at input " + escapeWSAndQuote("<unknown 
input>");
-    }
-    recognizer.notifyErrorListeners(token, msg, e);
-  }
-
-  protected void reportInputMismatchException(@NotNull Parser recognizer,
-                                              @NotNull InputMismatchException 
e) {
-    String msg = "mismatched input " + 
getTokenErrorDisplay(e.getOffendingToken()) +
-        " expecting " + 
e.getExpectedTokens().toString(recognizer.getTokenNames());
-    recognizer.notifyErrorListeners(e.getOffendingToken(), msg, e);
-  }
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/d6bc9118/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLParseError.java
----------------------------------------------------------------------
diff --git 
a/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLParseError.java 
b/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLParseError.java
deleted file mode 100644
index 2106b53..0000000
--- a/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLParseError.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/**
- * 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 org.apache.tajo.engine.parser;
-
-
-import org.antlr.v4.runtime.Token;
-import org.apache.commons.lang.StringUtils;
-
-public class SQLParseError extends RuntimeException {
-  private String header;
-  private String errorLine;
-  private int charPositionInLine;
-  private int line;
-  private Token offendingToken;
-  private String detailedMessage;
-
-  public SQLParseError(Token offendingToken,
-                       int line, int charPositionInLine,
-                       String msg,
-                       String errorLine) {
-    super(msg);
-    this.offendingToken = offendingToken;
-    this.charPositionInLine = charPositionInLine;
-    this.line = line;
-    this.errorLine = errorLine;
-    this.header = msg;
-  }
-
-  @Override
-  public String getMessage() {
-    if (detailedMessage == null) {
-      if (offendingToken != null) {
-        detailedMessage = getDetailedMessageWithLocation();
-      } else {
-        StringBuilder sb = new StringBuilder();
-        sb.append("ERROR: ").append(header).append("\n");
-        sb.append("LINE: ").append(errorLine);
-        detailedMessage = sb.toString();
-      }
-    }
-
-    return detailedMessage;
-  }
-
-  public String getMessageHeader(){
-    return this.header;
-  }
-
-  private String getDetailedMessageWithLocation() {
-    StringBuilder sb = new StringBuilder();
-    int displayLimit = 80;
-    String queryPrefix = "LINE " + line + ":" + charPositionInLine + " ";
-    String prefixPadding = StringUtils.repeat(" ", queryPrefix.length());
-    String locationString;
-
-    int tokenLength = offendingToken.getStopIndex() - 
offendingToken.getStartIndex() + 1;
-    if(tokenLength > 0){
-      locationString = StringUtils.repeat(" ", charPositionInLine) + 
StringUtils.repeat("^", tokenLength);
-    } else {
-      locationString = StringUtils.repeat(" ", charPositionInLine) + "^";
-    }
-
-    sb.append("ERROR: ").append(header).append("\n");
-    sb.append(queryPrefix);
-
-    if (errorLine.length() > displayLimit) {
-      int padding = (displayLimit / 2);
-
-      String ellipsis = " ... ";
-      int startPos = locationString.length() - padding - 1;
-      if (startPos <= 0) {
-        startPos = 0;
-        sb.append(errorLine.substring(startPos, 
displayLimit)).append(ellipsis).append("\n");
-        sb.append(prefixPadding).append(locationString);
-      } else if (errorLine.length() - (locationString.length() + padding) <= 
0) {
-        startPos = errorLine.length() - displayLimit - 1;
-        sb.append(ellipsis).append(errorLine.substring(startPos)).append("\n");
-        sb.append(prefixPadding).append(StringUtils.repeat(" ", 
ellipsis.length()))
-            .append(locationString.substring(startPos));
-      } else {
-        sb.append(ellipsis).append(errorLine.substring(startPos, startPos + 
displayLimit)).append(ellipsis).append("\n");
-        sb.append(prefixPadding).append(StringUtils.repeat(" ", 
ellipsis.length()))
-            .append(locationString.substring(startPos));
-      }
-    } else {
-      sb.append(errorLine).append("\n");
-      sb.append(prefixPadding).append(locationString);
-    }
-    return sb.toString();
-  }
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/d6bc9118/tajo-core/src/main/java/org/apache/tajo/master/GlobalEngine.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/master/GlobalEngine.java 
b/tajo-core/src/main/java/org/apache/tajo/master/GlobalEngine.java
index d651154..0d14d9a 100644
--- a/tajo-core/src/main/java/org/apache/tajo/master/GlobalEngine.java
+++ b/tajo-core/src/main/java/org/apache/tajo/master/GlobalEngine.java
@@ -35,7 +35,7 @@ import org.apache.tajo.catalog.CatalogService;
 import org.apache.tajo.catalog.Schema;
 import org.apache.tajo.catalog.TableDesc;
 import org.apache.tajo.conf.TajoConf;
-import org.apache.tajo.engine.parser.SQLAnalyzer;
+import org.apache.tajo.parser.sql.SQLAnalyzer;
 import org.apache.tajo.engine.query.QueryContext;
 import org.apache.tajo.exception.*;
 import org.apache.tajo.master.TajoMaster.MasterContext;

Reply via email to