You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tajo.apache.org by ji...@apache.org on 2014/10/26 06:46:18 UTC

[19/33] TAJO-1125: Separate logical plan and optimizer into a maven module.

http://git-wip-us.apache.org/repos/asf/tajo/blob/b143f991/tajo-core/src/main/java/org/apache/tajo/engine/planner/NamedExprsManager.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/NamedExprsManager.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/NamedExprsManager.java
deleted file mode 100644
index 8666a5c..0000000
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/NamedExprsManager.java
+++ /dev/null
@@ -1,380 +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.planner;
-
-import com.google.common.collect.BiMap;
-import com.google.common.collect.HashBiMap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import org.apache.tajo.algebra.ColumnReferenceExpr;
-import org.apache.tajo.algebra.Expr;
-import org.apache.tajo.algebra.NamedExpr;
-import org.apache.tajo.algebra.OpType;
-import org.apache.tajo.annotation.Nullable;
-import org.apache.tajo.engine.eval.EvalNode;
-import org.apache.tajo.engine.eval.EvalType;
-import org.apache.tajo.engine.eval.FieldEval;
-import org.apache.tajo.util.TUtil;
-
-import java.util.*;
-
-/**
- * NamedExprsManager manages an expressions used in a query block. All expressions used in a query block must be
- * added to NamedExprsManager. When an expression is added to NamedExprsManager, NamedExprsManager gives a reference
- * to the expression. If the expression already has an alias name, it gives the alias name as the reference
- * to the expression. If the expression does not have any alias, it gives a generated name as the reference to the
- * expression. Usually, predicates in WHERE clause, expressions in GROUP-BY, ORDER-BY, LIMIT clauses are not given
- * any alias name. Those reference names are used to identify an individual expression.
- *
- * NamedExprsManager only keeps unique expressions. Since expressions in a query block can be duplicated,
- * one or more reference names can point one expressions. Due to this process, it naturally removes duplicated
- * expression.
- *
- * As we mentioned above, one or more reference names can indicate one expression. Primary names are used for
- * representing expressions. A primary name of an expression indicates the reference obtained when
- * the expression is added firstly. All output schemas uses only primary names of expressions.
- *
- * Each expression that NamedExprsManager keeps has an boolean state to indicate whether the expression is evaluated
- * or not. The <code>evaluated</code> state means that upper logical operators can access this expression like a column
- * reference. For it, the reference name is used to access this expression like a column reference,
- * The evaluated state is set with an EvalNode which is an annotated expression.
- * {@link #getTarget(String)} returns EvalNodes by a reference name.
- */
-public class NamedExprsManager {
-  /** a sequence id */
-  private int sequenceId = 0;
-
-  /** Map: Name -> ID. Two or more different names can indicates the same id. */
-  private LinkedHashMap<String, Integer> nameToIdMap = Maps.newLinkedHashMap();
-
-  /** Map; ID <-> EvalNode */
-  private BiMap<Integer, EvalNode> idToEvalMap = HashBiMap.create();
-
-  /** Map: ID -> Names */
-  private LinkedHashMap<Integer, List<String>> idToNamesMap = Maps.newLinkedHashMap();
-
-  /** Map: ID -> Expr */
-  private BiMap<Integer, Expr> idToExprBiMap = HashBiMap.create();
-
-  /** Map; Name -> Boolean (if it is resolved or not) */
-  private LinkedHashMap<Integer, Boolean> evaluationStateMap = Maps.newLinkedHashMap();
-
-  /** Map: Alias Name <-> Original Name */
-  private BiMap<String, String> aliasedColumnMap = HashBiMap.create();
-
-  private final LogicalPlan plan;
-
-  private final LogicalPlan.QueryBlock block;
-
-  public NamedExprsManager(LogicalPlan plan, LogicalPlan.QueryBlock block) {
-    this.plan = plan;
-    this.block = block;
-  }
-
-  private int getNextId() {
-    return sequenceId++;
-  }
-
-  /**
-   * Check whether the expression corresponding to a given name was evaluated.
-   *
-   * @param name The name of a certain expression to be checked
-   * @return true if resolved. Otherwise, false.
-   */
-  public boolean isEvaluated(String name) {
-    if (nameToIdMap.containsKey(name)) {
-      int refId = nameToIdMap.get(name);
-      return evaluationStateMap.containsKey(refId) && evaluationStateMap.get(refId);
-    } else {
-      return false;
-    }
-  }
-
-  public boolean contains(String name) {
-    return nameToIdMap.containsKey(name);
-  }
-
-  public boolean contains(Expr expr) {
-    return idToExprBiMap.inverse().containsKey(expr);
-  }
-
-  private Expr getExpr(String name) {
-    return idToExprBiMap.get(nameToIdMap.get(name));
-  }
-
-  public NamedExpr getNamedExpr(String name) {
-    String normalized = name;
-    return new NamedExpr(getExpr(name), normalized);
-  }
-
-  public boolean isAliased(String name) {
-    return aliasedColumnMap.containsKey(name);
-  }
-
-  public String getAlias(String originalName) {
-    return aliasedColumnMap.get(originalName);
-  }
-
-  public boolean isAliasedName(String aliasName) {
-    return aliasedColumnMap.inverse().containsKey(aliasName);
-  }
-
-  public String getOriginalName(String aliasName) {
-    return aliasedColumnMap.inverse().get(aliasName);
-  }
-
-  /**
-   * Adds an expression and returns a reference name.
-   */
-  public String addExpr(Expr expr) throws PlanningException {
-    if (idToExprBiMap.inverse().containsKey(expr)) {
-      int refId = idToExprBiMap.inverse().get(expr);
-      return idToNamesMap.get(refId).get(0);
-    }
-
-    if (block.isRegisteredConst(expr)) {
-      return block.getConstReference(expr);
-    }
-
-    String generatedName = plan.generateUniqueColumnName(expr);
-    return addExpr(expr, generatedName);
-  }
-
-  /**
-   * Adds an expression with an alias name and returns a reference name.
-   * It specifies the alias as an reference name.
-   */
-  public String addExpr(Expr expr, String alias) throws PlanningException {
-
-    if (OpType.isLiteralType(expr.getType())) {
-      return alias;
-    }
-
-    // if this name already exists, just returns the name.
-    if (nameToIdMap.containsKey(alias)) {
-      return alias;
-    }
-
-    // if the name is first
-    int refId;
-    if (idToExprBiMap.inverse().containsKey(expr)) {
-      refId = idToExprBiMap.inverse().get(expr);
-    } else {
-      refId = getNextId();
-      idToExprBiMap.put(refId, expr);
-    }
-
-    nameToIdMap.put(alias, refId);
-    evaluationStateMap.put(refId, false);
-
-    // add the entry to idToNames map
-    TUtil.putToNestedList(idToNamesMap, refId, alias);
-
-    return alias;
-  }
-
-  /**
-   * Adds an expression and returns a reference name.
-   * If an alias is given, it specifies the alias as an reference name.
-   */
-  public String addNamedExpr(NamedExpr namedExpr) throws PlanningException {
-    if (namedExpr.hasAlias()) {
-      return addExpr(namedExpr.getExpr(), namedExpr.getAlias());
-    } else {
-      return addExpr(namedExpr.getExpr());
-    }
-  }
-
-  /**
-   * Adds a list of expressions and returns a list of reference names.
-   * If some NamedExpr has an alias, NamedExprsManager specifies the alias for the NamedExpr.
-   */
-  public String [] addNamedExprArray(@Nullable Collection<NamedExpr> namedExprs) throws PlanningException {
-    if (namedExprs != null && namedExprs.size() > 0) {
-      String [] names = new String[namedExprs.size()];
-      int i = 0;
-      for (NamedExpr target : namedExprs) {
-        names[i++] = addNamedExpr(target);
-      }
-      return names;
-    } else {
-      return null;
-    }
-  }
-
-  public Collection<NamedExpr> getAllNamedExprs() {
-    List<NamedExpr> namedExprList = Lists.newArrayList();
-    for (Map.Entry<Integer, Expr> entry: idToExprBiMap.entrySet()) {
-      namedExprList.add(new NamedExpr(entry.getValue(), idToNamesMap.get(entry.getKey()).get(0)));
-    }
-    return namedExprList;
-  }
-
-  /**
-   * It marks the expression identified by the reference name as <code>evaluated</code>.
-   * In addition, it adds an EvanNode for the expression identified by the reference.
-   *
-   * @param referenceName The reference name to be marked as 'evaluated'.
-   * @param evalNode EvalNode to be added.
-   */
-  public void markAsEvaluated(String referenceName, EvalNode evalNode) throws PlanningException {
-    String normalized = referenceName;
-
-    int refId = nameToIdMap.get(normalized);
-    evaluationStateMap.put(refId, true);
-    idToEvalMap.put(refId, evalNode);
-
-    String originalName = checkAndGetIfAliasedColumn(normalized);
-    if (originalName != null) {
-      aliasedColumnMap.put(originalName, normalized);
-    }
-  }
-
-  /**
-   * It returns an original column name if it is aliased column reference.
-   * Otherwise, it will return NULL.
-   */
-  public String checkAndGetIfAliasedColumn(String name) {
-    Expr expr = getExpr(name);
-    if (expr != null && expr.getType() == OpType.Column) {
-      ColumnReferenceExpr column = (ColumnReferenceExpr) expr;
-      if (!column.getCanonicalName().equals(name)) {
-        return column.getCanonicalName();
-      }
-    }
-    return null;
-  }
-
-  public Target getTarget(String name) {
-    return getTarget(name, false);
-  }
-
-  /**
-   * It checks if a given name is the primary name.
-   *
-   * @See {@link NamedExprsManager}
-   * @see {@link NamedExprsManager#getPrimaryName}
-   *
-   * @param id The expression id
-   * @param name The name to be checked if it is primary name.
-   * @return The primary name
-   */
-  private boolean isPrimaryName(int id, String name) {
-    return idToNamesMap.get(id).get(0).equals(name);
-  }
-
-  /**
-   * One or more reference names can indicate one expression. Primary names are used for
-   * representing expressions. A primary name of an expression indicates the reference obtained when
-   * the expression is added firstly. All output schemas uses only primary names of expressions.
-   *
-   * @param id The expression id
-   * @return The primary name
-   */
-  private String getPrimaryName(int id) {
-    return idToNamesMap.get(id).get(0);
-  }
-
-  /**
-   * get a Target instance. A target consists of a reference name and an EvalNode corresponding to the reference name.
-   * According to evaluation state, it returns different EvalNodes.
-   * If the expression corresponding to the reference name is evaluated, it just returns {@link FieldEval}
-   * (i.e., a column reference). Otherwise, it returns the original EvalNode of the expression.
-   *
-   * @param referenceName The reference name to get EvalNode
-   * @param unevaluatedForm If TRUE, it always return the annotated EvalNode of the expression.
-   * @return
-   */
-  public Target getTarget(String referenceName, boolean unevaluatedForm) {
-    String normalized = referenceName;
-    int refId = nameToIdMap.get(normalized);
-
-    if (!unevaluatedForm && evaluationStateMap.containsKey(refId) && evaluationStateMap.get(refId)) {
-      EvalNode evalNode = idToEvalMap.get(refId);
-
-      // If the expression is already evaluated, it should use the FieldEval to access a field value.
-      // But, if this reference name is not primary name, it cannot use the reference name.
-      // It changes the given reference name to the primary name.
-      if (evalNode.getType() != EvalType.CONST && isEvaluated(normalized) && !isPrimaryName(refId, referenceName)) {
-        return new Target(new FieldEval(getPrimaryName(refId),evalNode.getValueType()), referenceName);
-      }
-
-      EvalNode referredEval;
-      if (evalNode.getType() == EvalType.CONST) {
-        referredEval = evalNode;
-      } else {
-        referredEval = new FieldEval(idToNamesMap.get(refId).get(0), evalNode.getValueType());
-      }
-      return new Target(referredEval, referenceName);
-
-    } else {
-      if (idToEvalMap.containsKey(refId)) {
-        return new Target(idToEvalMap.get(refId), referenceName);
-      } else {
-        return null;
-      }
-    }
-  }
-
-  public String toString() {
-    return "unevaluated=" + nameToIdMap.size() + ", evaluated=" + idToEvalMap.size()
-        + ", renamed=" + aliasedColumnMap.size();
-  }
-
-  /**
-   * It returns an iterator for unevaluated NamedExprs.
-   */
-  public Iterator<NamedExpr> getIteratorForUnevaluatedExprs() {
-    return new UnevaluatedIterator();
-  }
-
-  public class UnevaluatedIterator implements Iterator<NamedExpr> {
-    private final Iterator<NamedExpr> iterator;
-
-    public UnevaluatedIterator() {
-      List<NamedExpr> unEvaluatedList = TUtil.newList();
-      for (Integer refId: idToNamesMap.keySet()) {
-        String name = idToNamesMap.get(refId).get(0);
-        if (!isEvaluated(name)) {
-          Expr expr = idToExprBiMap.get(refId);
-          unEvaluatedList.add(new NamedExpr(expr, name));
-        }
-      }
-      if (unEvaluatedList.size() == 0) {
-        iterator = null;
-      } else {
-        iterator = unEvaluatedList.iterator();
-      }
-    }
-
-    @Override
-    public boolean hasNext() {
-      return iterator != null && iterator.hasNext();
-    }
-
-    @Override
-    public NamedExpr next() {
-      return iterator.next();
-    }
-
-    @Override
-    public void remove() {
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/b143f991/tajo-core/src/main/java/org/apache/tajo/engine/planner/PhysicalPlanner.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/PhysicalPlanner.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/PhysicalPlanner.java
index ebe47b4..d4c57db 100644
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/PhysicalPlanner.java
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/planner/PhysicalPlanner.java
@@ -22,7 +22,7 @@
 package org.apache.tajo.engine.planner;
 
 import org.apache.tajo.worker.TaskAttemptContext;
-import org.apache.tajo.engine.planner.logical.LogicalNode;
+import org.apache.tajo.plan.logical.LogicalNode;
 import org.apache.tajo.engine.planner.physical.PhysicalExec;
 import org.apache.tajo.exception.InternalException;
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/b143f991/tajo-core/src/main/java/org/apache/tajo/engine/planner/PhysicalPlannerImpl.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/PhysicalPlannerImpl.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/PhysicalPlannerImpl.java
index 485677a..f7f071f 100644
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/PhysicalPlannerImpl.java
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/planner/PhysicalPlannerImpl.java
@@ -36,7 +36,6 @@ import org.apache.tajo.catalog.proto.CatalogProtos.SortSpecProto;
 import org.apache.tajo.conf.TajoConf;
 import org.apache.tajo.engine.planner.enforce.Enforcer;
 import org.apache.tajo.engine.planner.global.DataChannel;
-import org.apache.tajo.engine.planner.logical.*;
 import org.apache.tajo.engine.planner.physical.*;
 import org.apache.tajo.engine.query.QueryContext;
 import org.apache.tajo.exception.InternalException;
@@ -45,6 +44,9 @@ import org.apache.tajo.ipc.TajoWorkerProtocol.DistinctGroupbyEnforcer;
 import org.apache.tajo.ipc.TajoWorkerProtocol.DistinctGroupbyEnforcer.DistinctAggregationAlgorithm;
 import org.apache.tajo.ipc.TajoWorkerProtocol.DistinctGroupbyEnforcer.MultipleAggregationStage;
 import org.apache.tajo.ipc.TajoWorkerProtocol.DistinctGroupbyEnforcer.SortSpecArray;
+import org.apache.tajo.plan.LogicalPlan;
+import org.apache.tajo.plan.util.PlannerUtil;
+import org.apache.tajo.plan.logical.*;
 import org.apache.tajo.storage.StorageConstants;
 import org.apache.tajo.storage.StorageManager;
 import org.apache.tajo.storage.TupleComparator;
@@ -56,7 +58,6 @@ import org.apache.tajo.util.TUtil;
 import org.apache.tajo.worker.TaskAttemptContext;
 
 import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Stack;

http://git-wip-us.apache.org/repos/asf/tajo/blob/b143f991/tajo-core/src/main/java/org/apache/tajo/engine/planner/PlanString.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/PlanString.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/PlanString.java
deleted file mode 100644
index 98f921b..0000000
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/PlanString.java
+++ /dev/null
@@ -1,119 +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.planner;
-
-import org.apache.tajo.engine.planner.logical.LogicalNode;
-
-import java.util.ArrayList;
-import java.util.List;
-
-
-public class PlanString {
-  final StringBuilder title;
-
-  final List<String> explanations = new ArrayList<String>();
-  final List<String> details = new ArrayList<String>();
-
-  StringBuilder currentExplanation;
-  StringBuilder currentDetail;
-
-  public PlanString(LogicalNode node) {
-    this.title = new StringBuilder(node.getType().name() + "(" + node.getPID() + ")");
-  }
-
-  public PlanString(String title) {
-    this.title = new StringBuilder(title);
-  }
-
-  public PlanString appendTitle(String str) {
-    title.append(str);
-    return this;
-  }
-
-  public PlanString addExplan(String explain) {
-    flushCurrentExplanation();
-    currentExplanation = new StringBuilder(explain);
-    return this;
-  }
-
-  public PlanString appendExplain(String explain) {
-    if (currentExplanation == null) {
-      currentExplanation = new StringBuilder();
-    }
-    currentExplanation.append(explain);
-    return this;
-  }
-
-  public PlanString addDetail(String detail) {
-    flushCurrentDetail();
-    currentDetail = new StringBuilder(detail);
-    return this;
-  }
-
-  public PlanString appendDetail(String detail) {
-    if (currentDetail == null) {
-      currentDetail = new StringBuilder();
-    }
-    currentDetail.append(detail);
-    return this;
-
-  }
-
-  public String getTitle() {
-    return title.toString();
-  }
-
-  public List<String> getExplanations() {
-    flushCurrentExplanation();
-    return explanations;
-  }
-
-  public List<String> getDetails() {
-    flushCurrentDetail();
-    return details;
-  }
-
-  private void flushCurrentExplanation() {
-    if (currentExplanation != null) {
-      explanations.add(currentExplanation.toString());
-      currentExplanation = null;
-    }
-  }
-
-  private void flushCurrentDetail() {
-    if (currentDetail != null) {
-      details.add(currentDetail.toString());
-      currentDetail = null;
-    }
-  }
-
-  public String toString() {
-    StringBuilder output = new StringBuilder();
-    output.append(getTitle()).append("\n");
-
-    for (String str : getExplanations()) {
-      output.append("  => ").append(str).append("\n");
-    }
-
-    for (String str : getDetails()) {
-      output.append("  => ").append(str).append("\n");
-    }
-    return output.toString();
-  }
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/b143f991/tajo-core/src/main/java/org/apache/tajo/engine/planner/PlannerUtil.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/PlannerUtil.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/PlannerUtil.java
deleted file mode 100644
index 827be83..0000000
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/PlannerUtil.java
+++ /dev/null
@@ -1,888 +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.planner;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import org.apache.hadoop.fs.FileStatus;
-import org.apache.hadoop.fs.FileSystem;
-import org.apache.hadoop.fs.Path;
-import org.apache.tajo.algebra.*;
-import org.apache.tajo.annotation.Nullable;
-import org.apache.tajo.catalog.Column;
-import org.apache.tajo.catalog.Schema;
-import org.apache.tajo.catalog.SortSpec;
-import org.apache.tajo.catalog.TableDesc;
-import org.apache.tajo.catalog.proto.CatalogProtos;
-import org.apache.tajo.catalog.proto.CatalogProtos.FragmentProto;
-import org.apache.tajo.common.TajoDataTypes.DataType;
-import org.apache.tajo.conf.TajoConf;
-import org.apache.tajo.engine.eval.*;
-import org.apache.tajo.engine.exception.InvalidQueryException;
-import org.apache.tajo.engine.planner.logical.*;
-import org.apache.tajo.engine.utils.SchemaUtil;
-import org.apache.tajo.storage.StorageManager;
-import org.apache.tajo.storage.TupleComparator;
-import org.apache.tajo.storage.fragment.FileFragment;
-import org.apache.tajo.storage.fragment.FragmentConvertor;
-import org.apache.tajo.util.TUtil;
-
-import java.io.IOException;
-import java.util.*;
-import java.util.concurrent.atomic.AtomicInteger;
-
-public class PlannerUtil {
-
-  public static boolean checkIfDDLPlan(LogicalNode node) {
-    LogicalNode baseNode = node;
-    if (node instanceof LogicalRootNode) {
-      baseNode = ((LogicalRootNode) node).getChild();
-    }
-
-    NodeType type = baseNode.getType();
-
-    return
-        type == NodeType.CREATE_DATABASE ||
-            type == NodeType.DROP_DATABASE ||
-            (type == NodeType.CREATE_TABLE && !((CreateTableNode) baseNode).hasSubQuery()) ||
-            baseNode.getType() == NodeType.DROP_TABLE ||
-            baseNode.getType() == NodeType.ALTER_TABLESPACE ||
-            baseNode.getType() == NodeType.ALTER_TABLE ||
-            baseNode.getType() == NodeType.TRUNCATE_TABLE;
-  }
-
-  /**
-   * Checks whether the query is simple or not.
-   * The simple query can be defined as 'select * from tb_name [LIMIT X]'.
-   *
-   * @param plan The logical plan
-   * @return True if the query is a simple query.
-   */
-  public static boolean checkIfSimpleQuery(LogicalPlan plan) {
-    LogicalRootNode rootNode = plan.getRootBlock().getRoot();
-
-    // one block, without where clause, no group-by, no-sort, no-join
-    boolean isOneQueryBlock = plan.getQueryBlocks().size() == 1;
-    boolean simpleOperator = rootNode.getChild().getType() == NodeType.LIMIT
-        || rootNode.getChild().getType() == NodeType.SCAN || rootNode.getChild().getType() == NodeType.PARTITIONS_SCAN;
-    boolean noOrderBy = !plan.getRootBlock().hasNode(NodeType.SORT);
-    boolean noGroupBy = !plan.getRootBlock().hasNode(NodeType.GROUP_BY);
-    boolean noWhere = !plan.getRootBlock().hasNode(NodeType.SELECTION);
-    boolean noJoin = !plan.getRootBlock().hasNode(NodeType.JOIN);
-    boolean singleRelation =
-        (plan.getRootBlock().hasNode(NodeType.SCAN) || plan.getRootBlock().hasNode(NodeType.PARTITIONS_SCAN)) &&
-        PlannerUtil.getRelationLineage(plan.getRootBlock().getRoot()).length == 1;
-
-    boolean noComplexComputation = false;
-    if (singleRelation) {
-      ScanNode scanNode = plan.getRootBlock().getNode(NodeType.SCAN);
-      if (scanNode == null) {
-        scanNode = plan.getRootBlock().getNode(NodeType.PARTITIONS_SCAN);
-      }
-      if (scanNode.hasTargets()) {
-        // If the number of columns in the select clause is s different from table schema,
-        // This query is not a simple query.
-        if (scanNode.getTableDesc().hasPartition()) {
-          // In the case of partitioned table, the actual number of columns is ScanNode.InSchema + partitioned columns
-          int numPartitionColumns = scanNode.getTableDesc().getPartitionMethod().getExpressionSchema().size();
-          if (scanNode.getTargets().length != scanNode.getInSchema().size() + numPartitionColumns) {
-            return false;
-          }
-        } else {
-          if (scanNode.getTargets().length != scanNode.getInSchema().size()) {
-            return false;
-          }
-        }
-        noComplexComputation = true;
-        for (int i = 0; i < scanNode.getTargets().length; i++) {
-          noComplexComputation =
-              noComplexComputation && scanNode.getTargets()[i].getEvalTree().getType() == EvalType.FIELD;
-          if (noComplexComputation) {
-            noComplexComputation = noComplexComputation &&
-                scanNode.getTargets()[i].getNamedColumn().equals(
-                    scanNode.getTableDesc().getLogicalSchema().getColumn(i));
-          }
-          if (!noComplexComputation) {
-            return noComplexComputation;
-          }
-        }
-      }
-    }
-
-    return !checkIfDDLPlan(rootNode) &&
-        (simpleOperator && noComplexComputation && isOneQueryBlock &&
-            noOrderBy && noGroupBy && noWhere && noJoin && singleRelation);
-  }
-
-  /**
-   * Checks whether the query has 'from clause' or not.
-   *
-   * @param plan The logical plan
-   * @return True if a query does not have 'from clause'.
-   */
-  public static boolean checkIfNonFromQuery(LogicalPlan plan) {
-    LogicalNode node = plan.getRootBlock().getRoot();
-
-    // one block, without where clause, no group-by, no-sort, no-join
-    boolean isOneQueryBlock = plan.getQueryBlocks().size() == 1;
-    boolean noRelation = !plan.getRootBlock().hasAlgebraicExpr(OpType.Relation);
-
-    return !checkIfDDLPlan(node) && noRelation && isOneQueryBlock;
-  }
-
-  /**
-   * Get all RelationNodes which are descendant of a given LogicalNode.
-   *
-   * @param from The LogicalNode to start visiting LogicalNodes.
-   * @return an array of all descendant RelationNode of LogicalNode.
-   */
-  public static String[] getRelationLineage(LogicalNode from) {
-    LogicalNode[] scans = findAllNodes(from, NodeType.SCAN, NodeType.PARTITIONS_SCAN);
-    String[] tableNames = new String[scans.length];
-    ScanNode scan;
-    for (int i = 0; i < scans.length; i++) {
-      scan = (ScanNode) scans[i];
-      tableNames[i] = scan.getCanonicalName();
-    }
-    return tableNames;
-  }
-
-  /**
-   * Get all RelationNodes which are descendant of a given LogicalNode.
-   * The finding is restricted within a query block.
-   *
-   * @param from The LogicalNode to start visiting LogicalNodes.
-   * @return an array of all descendant RelationNode of LogicalNode.
-   */
-  public static Collection<String> getRelationLineageWithinQueryBlock(LogicalPlan plan, LogicalNode from)
-      throws PlanningException {
-    RelationFinderVisitor visitor = new RelationFinderVisitor();
-    visitor.visit(null, plan, null, from, new Stack<LogicalNode>());
-    return visitor.getFoundRelations();
-  }
-
-  public static class RelationFinderVisitor extends BasicLogicalPlanVisitor<Object, LogicalNode> {
-    private Set<String> foundRelNameSet = Sets.newHashSet();
-
-    public Set<String> getFoundRelations() {
-      return foundRelNameSet;
-    }
-
-    @Override
-    public LogicalNode visit(Object context, LogicalPlan plan, @Nullable LogicalPlan.QueryBlock block, LogicalNode node,
-                             Stack<LogicalNode> stack) throws PlanningException {
-      if (node.getType() != NodeType.TABLE_SUBQUERY) {
-        super.visit(context, plan, block, node, stack);
-      }
-
-      if (node instanceof RelationNode) {
-        foundRelNameSet.add(((RelationNode) node).getCanonicalName());
-      }
-
-      return node;
-    }
-  }
-
-  /**
-   * Delete the logical node from a plan.
-   *
-   * @param parent      this node must be a parent node of one node to be removed.
-   * @param tobeRemoved this node must be a child node of the parent.
-   */
-  public static LogicalNode deleteNode(LogicalNode parent, LogicalNode tobeRemoved) {
-    Preconditions.checkArgument(tobeRemoved instanceof UnaryNode,
-        "ERROR: the logical node to be removed must be unary node.");
-
-    UnaryNode child = (UnaryNode) tobeRemoved;
-    LogicalNode grandChild = child.getChild();
-    if (parent instanceof UnaryNode) {
-      UnaryNode unaryParent = (UnaryNode) parent;
-
-      Preconditions.checkArgument(unaryParent.getChild() == child,
-          "ERROR: both logical node must be parent and child nodes");
-      unaryParent.setChild(grandChild);
-
-    } else if (parent instanceof BinaryNode) {
-      BinaryNode binaryParent = (BinaryNode) parent;
-      if (binaryParent.getLeftChild().deepEquals(child)) {
-        binaryParent.setLeftChild(grandChild);
-      } else if (binaryParent.getRightChild().deepEquals(child)) {
-        binaryParent.setRightChild(grandChild);
-      } else {
-        throw new IllegalStateException("ERROR: both logical node must be parent and child nodes");
-      }
-    } else {
-      throw new InvalidQueryException("Unexpected logical plan: " + parent);
-    }
-    return child;
-  }
-
-  public static void replaceNode(LogicalPlan plan, LogicalNode startNode, LogicalNode oldNode, LogicalNode newNode) {
-    LogicalNodeReplaceVisitor replacer = new LogicalNodeReplaceVisitor(oldNode, newNode);
-    try {
-      replacer.visit(new ReplacerContext(), plan, null, startNode, new Stack<LogicalNode>());
-    } catch (PlanningException e) {
-      e.printStackTrace();
-    }
-  }
-
-  static class ReplacerContext {
-    boolean updateSchemaFlag = false;
-  }
-
-  public static class LogicalNodeReplaceVisitor extends BasicLogicalPlanVisitor<ReplacerContext, LogicalNode> {
-    private LogicalNode target;
-    private LogicalNode tobeReplaced;
-
-    public LogicalNodeReplaceVisitor(LogicalNode target, LogicalNode tobeReplaced) {
-      this.target = target;
-      this.tobeReplaced = tobeReplaced;
-    }
-
-    /**
-     * If this node can have child, it returns TRUE. Otherwise, it returns FALSE.
-     */
-    private static boolean checkIfVisitable(LogicalNode node) {
-      return node instanceof UnaryNode || node instanceof BinaryNode;
-    }
-
-    @Override
-    public LogicalNode visit(ReplacerContext context, LogicalPlan plan, @Nullable LogicalPlan.QueryBlock block,
-                             LogicalNode node, Stack<LogicalNode> stack) throws PlanningException {
-      LogicalNode left = null;
-      LogicalNode right = null;
-
-      if (node instanceof UnaryNode) {
-        UnaryNode unaryNode = (UnaryNode) node;
-        if (unaryNode.getChild().deepEquals(target)) {
-          unaryNode.setChild(tobeReplaced);
-          left = tobeReplaced;
-          context.updateSchemaFlag = true;
-        } else if (checkIfVisitable(unaryNode.getChild())) {
-          left = visit(context, plan, null, unaryNode.getChild(), stack);
-        }
-      } else if (node instanceof BinaryNode) {
-        BinaryNode binaryNode = (BinaryNode) node;
-        if (binaryNode.getLeftChild().deepEquals(target)) {
-          binaryNode.setLeftChild(tobeReplaced);
-          left = tobeReplaced;
-          context.updateSchemaFlag = true;
-        } else if (checkIfVisitable(binaryNode.getLeftChild())) {
-          left = visit(context, plan, null, binaryNode.getLeftChild(), stack);
-        } else {
-          left = binaryNode.getLeftChild();
-        }
-
-        if (binaryNode.getRightChild().deepEquals(target)) {
-          binaryNode.setRightChild(tobeReplaced);
-          right = tobeReplaced;
-          context.updateSchemaFlag = true;
-        } else if (checkIfVisitable(binaryNode.getRightChild())) {
-          right = visit(context, plan, null, binaryNode.getRightChild(), stack);
-        } else {
-          right = binaryNode.getRightChild();
-        }
-      }
-
-      // update schemas of nodes except for leaf node (i.e., RelationNode)
-      if (context.updateSchemaFlag) {
-        if (node instanceof Projectable) {
-          if (node instanceof BinaryNode) {
-            node.setInSchema(SchemaUtil.merge(left.getOutSchema(), right.getOutSchema()));
-          } else {
-            node.setInSchema(left.getOutSchema());
-          }
-          context.updateSchemaFlag = false;
-        } else {
-          node.setInSchema(left.getOutSchema());
-          node.setOutSchema(left.getOutSchema());
-        }
-      }
-      return node;
-    }
-
-    @Override
-    public LogicalNode visitScan(ReplacerContext context, LogicalPlan plan, LogicalPlan.QueryBlock block, ScanNode node,
-                                 Stack<LogicalNode> stack) throws PlanningException {
-      return node;
-    }
-
-    @Override
-    public LogicalNode visitPartitionedTableScan(ReplacerContext context, LogicalPlan plan, LogicalPlan.
-        QueryBlock block, PartitionedTableScanNode node, Stack<LogicalNode> stack)
-
-        throws PlanningException {
-      return node;
-    }
-  }
-
-  public static void replaceNode(LogicalNode plan, LogicalNode newNode, NodeType type) {
-    LogicalNode parent = findTopParentNode(plan, type);
-    Preconditions.checkArgument(parent instanceof UnaryNode);
-    Preconditions.checkArgument(!(newNode instanceof BinaryNode));
-    UnaryNode parentNode = (UnaryNode) parent;
-    LogicalNode child = parentNode.getChild();
-    if (child instanceof UnaryNode) {
-      ((UnaryNode) newNode).setChild(((UnaryNode) child).getChild());
-    }
-    parentNode.setChild(newNode);
-  }
-
-  /**
-   * Find the top logical node matched to type from the given node
-   *
-   * @param node start node
-   * @param type to find
-   * @return a found logical node
-   */
-  public static <T extends LogicalNode> T findTopNode(LogicalNode node, NodeType type) {
-    Preconditions.checkNotNull(node);
-    Preconditions.checkNotNull(type);
-
-    LogicalNodeFinder finder = new LogicalNodeFinder(type);
-    node.preOrder(finder);
-
-    if (finder.getFoundNodes().size() == 0) {
-      return null;
-    }
-    return (T) finder.getFoundNodes().get(0);
-  }
-
-  /**
-   * Find the most bottom logical node matched to type from the given node
-   *
-   * @param node start node
-   * @param type to find
-   * @return a found logical node
-   */
-  public static <T extends LogicalNode> T findMostBottomNode(LogicalNode node, NodeType type) {
-    Preconditions.checkNotNull(node);
-    Preconditions.checkNotNull(type);
-
-    LogicalNodeFinder finder = new LogicalNodeFinder(type);
-    node.preOrder(finder);
-
-    if (finder.getFoundNodes().size() == 0) {
-      return null;
-    }
-    return (T) finder.getFoundNodes().get(finder.getFoundNodes().size() - 1);
-  }
-
-  /**
-   * Find the all logical node matched to type from the given node
-   *
-   * @param node start node
-   * @param type to find
-   * @return a found logical node
-   */
-  public static LogicalNode[] findAllNodes(LogicalNode node, NodeType... type) {
-    Preconditions.checkNotNull(node);
-    Preconditions.checkNotNull(type);
-
-    LogicalNodeFinder finder = new LogicalNodeFinder(type);
-    node.postOrder(finder);
-
-    if (finder.getFoundNodes().size() == 0) {
-      return new LogicalNode[]{};
-    }
-    List<LogicalNode> founds = finder.getFoundNodes();
-    return founds.toArray(new LogicalNode[founds.size()]);
-  }
-
-  /**
-   * Find a parent node of a given-typed operator.
-   *
-   * @param node start node
-   * @param type to find
-   * @return the parent node of a found logical node
-   */
-  public static <T extends LogicalNode> T findTopParentNode(LogicalNode node, NodeType type) {
-    Preconditions.checkNotNull(node);
-    Preconditions.checkNotNull(type);
-
-    ParentNodeFinder finder = new ParentNodeFinder(type);
-    node.postOrder(finder);
-
-    if (finder.getFoundNodes().size() == 0) {
-      return null;
-    }
-    return (T) finder.getFoundNodes().get(0);
-  }
-
-  private static class LogicalNodeFinder implements LogicalNodeVisitor {
-    private List<LogicalNode> list = new ArrayList<LogicalNode>();
-    private final NodeType[] tofind;
-    private boolean topmost = false;
-    private boolean finished = false;
-
-    public LogicalNodeFinder(NodeType... type) {
-      this.tofind = type;
-    }
-
-    public LogicalNodeFinder(NodeType[] type, boolean topmost) {
-      this(type);
-      this.topmost = topmost;
-    }
-
-    @Override
-    public void visit(LogicalNode node) {
-      if (!finished) {
-        for (NodeType type : tofind) {
-          if (node.getType() == type) {
-            list.add(node);
-          }
-          if (topmost && list.size() > 0) {
-            finished = true;
-          }
-        }
-      }
-    }
-
-    public List<LogicalNode> getFoundNodes() {
-      return list;
-    }
-
-    public LogicalNode[] getFoundNodeArray() {
-      return list.toArray(new LogicalNode[list.size()]);
-    }
-  }
-
-  private static class ParentNodeFinder implements LogicalNodeVisitor {
-    private List<LogicalNode> list = new ArrayList<LogicalNode>();
-    private NodeType tofind;
-
-    public ParentNodeFinder(NodeType type) {
-      this.tofind = type;
-    }
-
-    @Override
-    public void visit(LogicalNode node) {
-      if (node instanceof UnaryNode) {
-        UnaryNode unary = (UnaryNode) node;
-        if (unary.getChild().getType() == tofind) {
-          list.add(node);
-        }
-      } else if (node instanceof BinaryNode) {
-        BinaryNode bin = (BinaryNode) node;
-        if (bin.getLeftChild().getType() == tofind ||
-            bin.getRightChild().getType() == tofind) {
-          list.add(node);
-        }
-      }
-    }
-
-    public List<LogicalNode> getFoundNodes() {
-      return list;
-    }
-  }
-
-  /**
-   * fill targets with FieldEvals from a given schema
-   *
-   * @param schema  to be transformed to targets
-   * @param targets to be filled
-   */
-  public static void schemaToTargets(Schema schema, Target[] targets) {
-    FieldEval eval;
-    for (int i = 0; i < schema.size(); i++) {
-      eval = new FieldEval(schema.getColumn(i));
-      targets[i] = new Target(eval);
-    }
-  }
-
-  public static Target[] schemaToTargets(Schema schema) {
-    Target[] targets = new Target[schema.size()];
-
-    FieldEval eval;
-    for (int i = 0; i < schema.size(); i++) {
-      eval = new FieldEval(schema.getColumn(i));
-      targets[i] = new Target(eval);
-    }
-    return targets;
-  }
-
-  public static Target[] schemaToTargetsWithGeneratedFields(Schema schema) {
-    List<Target> targets = TUtil.newList();
-
-    FieldEval eval;
-    for (int i = 0; i < schema.size(); i++) {
-      eval = new FieldEval(schema.getColumn(i));
-      targets.add(new Target(eval));
-    }
-    return targets.toArray(new Target[targets.size()]);
-  }
-
-  public static SortSpec[] schemaToSortSpecs(Schema schema) {
-    return columnsToSortSpecs(schema.toArray());
-  }
-
-  public static SortSpec[] columnsToSortSpecs(Column[] columns) {
-    SortSpec[] specs = new SortSpec[columns.length];
-
-    for (int i = 0; i < columns.length; i++) {
-      specs[i] = new SortSpec(columns[i], true, false);
-    }
-
-    return specs;
-  }
-
-  public static SortSpec[] columnsToSortSpecs(Collection<Column> columns) {
-    return columnsToSortSpecs(columns.toArray(new Column[columns.size()]));
-  }
-
-  public static Schema sortSpecsToSchema(SortSpec[] sortSpecs) {
-    Schema schema = new Schema();
-    for (SortSpec spec : sortSpecs) {
-      schema.addColumn(spec.getSortKey());
-    }
-
-    return schema;
-  }
-
-  public static SortSpec[][] getSortKeysFromJoinQual(EvalNode joinQual, Schema outer, Schema inner) {
-    // It is used for the merge join executor. The merge join only considers the equi-join.
-    // So, theta-join flag must be false.
-    List<Column[]> joinKeyPairs = getJoinKeyPairs(joinQual, outer, inner, false);
-    SortSpec[] outerSortSpec = new SortSpec[joinKeyPairs.size()];
-    SortSpec[] innerSortSpec = new SortSpec[joinKeyPairs.size()];
-
-    for (int i = 0; i < joinKeyPairs.size(); i++) {
-      outerSortSpec[i] = new SortSpec(joinKeyPairs.get(i)[0]);
-      innerSortSpec[i] = new SortSpec(joinKeyPairs.get(i)[1]);
-    }
-
-    return new SortSpec[][]{outerSortSpec, innerSortSpec};
-  }
-
-  public static TupleComparator[] getComparatorsFromJoinQual(EvalNode joinQual, Schema leftSchema, Schema rightSchema) {
-    SortSpec[][] sortSpecs = getSortKeysFromJoinQual(joinQual, leftSchema, rightSchema);
-    TupleComparator[] comparators = new TupleComparator[2];
-    comparators[0] = new TupleComparator(leftSchema, sortSpecs[0]);
-    comparators[1] = new TupleComparator(rightSchema, sortSpecs[1]);
-    return comparators;
-  }
-
-  /**
-   * @return the first array contains left table's columns, and the second array contains right table's columns.
-   */
-  public static Column[][] joinJoinKeyForEachTable(EvalNode joinQual, Schema leftSchema,
-                                                   Schema rightSchema, boolean includeThetaJoin) {
-    List<Column[]> joinKeys = getJoinKeyPairs(joinQual, leftSchema, rightSchema, includeThetaJoin);
-    Column[] leftColumns = new Column[joinKeys.size()];
-    Column[] rightColumns = new Column[joinKeys.size()];
-    for (int i = 0; i < joinKeys.size(); i++) {
-      leftColumns[i] = joinKeys.get(i)[0];
-      rightColumns[i] = joinKeys.get(i)[1];
-    }
-
-    return new Column[][]{leftColumns, rightColumns};
-  }
-
-  public static List<Column[]> getJoinKeyPairs(EvalNode joinQual, Schema leftSchema, Schema rightSchema,
-                                               boolean includeThetaJoin) {
-    JoinKeyPairFinder finder = new JoinKeyPairFinder(includeThetaJoin, leftSchema, rightSchema);
-    joinQual.preOrder(finder);
-    return finder.getPairs();
-  }
-
-  public static class JoinKeyPairFinder implements EvalNodeVisitor {
-    private boolean includeThetaJoin;
-    private final List<Column[]> pairs = Lists.newArrayList();
-    private Schema[] schemas = new Schema[2];
-
-    public JoinKeyPairFinder(boolean includeThetaJoin, Schema outer, Schema inner) {
-      this.includeThetaJoin = includeThetaJoin;
-      schemas[0] = outer;
-      schemas[1] = inner;
-    }
-
-    @Override
-    public void visit(EvalNode node) {
-      if (EvalTreeUtil.isJoinQual(node, includeThetaJoin)) {
-        BinaryEval binaryEval = (BinaryEval) node;
-        Column[] pair = new Column[2];
-
-        for (int i = 0; i <= 1; i++) { // access left, right sub expression
-          Column column = EvalTreeUtil.findAllColumnRefs(binaryEval.getChild(i)).get(0);
-          for (int j = 0; j < schemas.length; j++) {
-            // check whether the column is for either outer or inner
-            // 0 is outer, and 1 is inner
-            if (schemas[j].contains(column.getQualifiedName())) {
-              pair[j] = column;
-            }
-          }
-        }
-
-        if (pair[0] == null || pair[1] == null) {
-          throw new IllegalStateException("Wrong join key: " + node);
-        }
-        pairs.add(pair);
-      }
-    }
-
-    public List<Column[]> getPairs() {
-      return this.pairs;
-    }
-  }
-
-  public static Schema targetToSchema(Collection<Target> targets) {
-    return targetToSchema(targets.toArray(new Target[targets.size()]));
-  }
-
-  public static Schema targetToSchema(Target[] targets) {
-    Schema schema = new Schema();
-    for (Target t : targets) {
-      DataType type = t.getEvalTree().getValueType();
-      String name;
-      if (t.hasAlias()) {
-        name = t.getAlias();
-      } else {
-        name = t.getEvalTree().getName();
-      }
-      if (!schema.containsByQualifiedName(name)) {
-        schema.addColumn(name, type);
-      }
-    }
-
-    return schema;
-  }
-
-  /**
-   * It removes all table names from FieldEvals in targets
-   *
-   * @param sourceTargets The targets to be stripped
-   * @return The stripped targets
-   */
-  public static Target[] stripTarget(Target[] sourceTargets) {
-    Target[] copy = new Target[sourceTargets.length];
-    for (int i = 0; i < sourceTargets.length; i++) {
-      try {
-        copy[i] = (Target) sourceTargets[i].clone();
-      } catch (CloneNotSupportedException e) {
-        throw new InternalError(e.getMessage());
-      }
-      if (copy[i].getEvalTree().getType() == EvalType.FIELD) {
-        FieldEval fieldEval = copy[i].getEvalTree();
-        if (fieldEval.getColumnRef().hasQualifier()) {
-          fieldEval.replaceColumnRef(fieldEval.getColumnName());
-        }
-      }
-    }
-
-    return copy;
-  }
-
-  public static <T extends LogicalNode> T clone(LogicalPlan plan, LogicalNode node) {
-    try {
-      T copy = (T) node.clone();
-      if (plan == null) {
-        copy.setPID(-1);
-      } else {
-        copy.setPID(plan.newPID());
-        if (node instanceof DistinctGroupbyNode) {
-          DistinctGroupbyNode dNode = (DistinctGroupbyNode)copy;
-          for (GroupbyNode eachNode: dNode.getGroupByNodes()) {
-            eachNode.setPID(plan.newPID());
-          }
-        }
-      }
-      return copy;
-    } catch (CloneNotSupportedException e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-  public static boolean isCommutativeJoin(JoinType joinType) {
-    return joinType == JoinType.INNER;
-  }
-
-  public static boolean existsAggregationFunction(Expr expr) throws PlanningException {
-    AggregationFunctionFinder finder = new AggregationFunctionFinder();
-    AggFunctionFoundResult result = new AggFunctionFoundResult();
-    finder.visit(result, new Stack<Expr>(), expr);
-    return result.generalSetFunction;
-  }
-
-  public static boolean existsDistinctAggregationFunction(Expr expr) throws PlanningException {
-    AggregationFunctionFinder finder = new AggregationFunctionFinder();
-    AggFunctionFoundResult result = new AggFunctionFoundResult();
-    finder.visit(result, new Stack<Expr>(), expr);
-    return result.distinctSetFunction;
-  }
-
-  static class AggFunctionFoundResult {
-    boolean generalSetFunction;
-    boolean distinctSetFunction;
-  }
-
-  static class AggregationFunctionFinder extends SimpleAlgebraVisitor<AggFunctionFoundResult, Object> {
-    @Override
-    public Object visitCountRowsFunction(AggFunctionFoundResult ctx, Stack<Expr> stack, CountRowsFunctionExpr expr)
-        throws PlanningException {
-      ctx.generalSetFunction = true;
-      return super.visitCountRowsFunction(ctx, stack, expr);
-    }
-
-    @Override
-    public Object visitGeneralSetFunction(AggFunctionFoundResult ctx, Stack<Expr> stack, GeneralSetFunctionExpr expr)
-        throws PlanningException {
-      ctx.generalSetFunction = true;
-      ctx.distinctSetFunction = expr.isDistinct();
-      return super.visitGeneralSetFunction(ctx, stack, expr);
-    }
-  }
-
-  public static Collection<String> toQualifiedFieldNames(Collection<String> fieldNames, String qualifier) {
-    List<String> names = TUtil.newList();
-    for (String n : fieldNames) {
-      String[] parts = n.split("\\.");
-      if (parts.length == 1) {
-        names.add(qualifier + "." + parts[0]);
-      } else {
-        names.add(qualifier + "." + parts[1]);
-      }
-    }
-    return names;
-  }
-
-  public static SortSpec[] convertSortSpecs(Collection<CatalogProtos.SortSpecProto> sortSpecProtos) {
-    SortSpec[] sortSpecs = new SortSpec[sortSpecProtos.size()];
-    int i = 0;
-    for (CatalogProtos.SortSpecProto proto : sortSpecProtos) {
-      sortSpecs[i++] = new SortSpec(proto);
-    }
-    return sortSpecs;
-  }
-
-  /**
-   * Generate an explain string of a LogicalNode and its descendant nodes.
-   *
-   * @param node The LogicalNode instance to be started
-   * @return A pretty print explain string
-   */
-  public static String buildExplainString(LogicalNode node) {
-    ExplainLogicalPlanVisitor explain = new ExplainLogicalPlanVisitor();
-
-    StringBuilder explains = new StringBuilder();
-    try {
-      ExplainLogicalPlanVisitor.Context explainContext = explain.getBlockPlanStrings(null, node);
-      while (!explainContext.explains.empty()) {
-        explains.append(
-            ExplainLogicalPlanVisitor.printDepthString(explainContext.getMaxDepth(), explainContext.explains.pop()));
-      }
-    } catch (PlanningException e) {
-      throw new RuntimeException(e);
-    }
-
-    return explains.toString();
-  }
-
-  /**
-   * Listing table data file which is not empty.
-   * If the table is a partitioned table, return file list which has same partition key.
-   * @param tajoConf
-   * @param tableDesc
-   * @param fileIndex
-   * @param numResultFiles
-   * @return
-   * @throws IOException
-   */
-  public static FragmentProto[] getNonZeroLengthDataFiles(TajoConf tajoConf,TableDesc tableDesc,
-                                                          int fileIndex, int numResultFiles) throws IOException {
-    FileSystem fs = tableDesc.getPath().getFileSystem(tajoConf);
-
-    List<FileStatus> nonZeroLengthFiles = new ArrayList<FileStatus>();
-    if (fs.exists(tableDesc.getPath())) {
-      getNonZeroLengthDataFiles(fs, tableDesc.getPath(), nonZeroLengthFiles, fileIndex, numResultFiles,
-          new AtomicInteger(0));
-    }
-
-    List<FileFragment> fragments = new ArrayList<FileFragment>();
-
-    //In the case of partitioned table, return same partition key data files.
-    int numPartitionColumns = 0;
-    if (tableDesc.hasPartition()) {
-      numPartitionColumns = tableDesc.getPartitionMethod().getExpressionSchema().getColumns().size();
-    }
-    String[] previousPartitionPathNames = null;
-    for (FileStatus eachFile: nonZeroLengthFiles) {
-      FileFragment fileFragment = new FileFragment(tableDesc.getName(), eachFile.getPath(), 0, eachFile.getLen(), null);
-
-      if (numPartitionColumns > 0) {
-        // finding partition key;
-        Path filePath = fileFragment.getPath();
-        Path parentPath = filePath;
-        String[] parentPathNames = new String[numPartitionColumns];
-        for (int i = 0; i < numPartitionColumns; i++) {
-          parentPath = parentPath.getParent();
-          parentPathNames[numPartitionColumns - i - 1] = parentPath.getName();
-        }
-
-        // If current partitionKey == previousPartitionKey, add to result.
-        if (previousPartitionPathNames == null) {
-          fragments.add(fileFragment);
-        } else if (previousPartitionPathNames != null && Arrays.equals(previousPartitionPathNames, parentPathNames)) {
-          fragments.add(fileFragment);
-        } else {
-          break;
-        }
-        previousPartitionPathNames = parentPathNames;
-      } else {
-        fragments.add(fileFragment);
-      }
-    }
-    return FragmentConvertor.toFragmentProtoArray(fragments.toArray(new FileFragment[]{}));
-  }
-
-  private static void getNonZeroLengthDataFiles(FileSystem fs, Path path, List<FileStatus> result,
-                                         int startFileIndex, int numResultFiles,
-                                         AtomicInteger currentFileIndex) throws IOException {
-    if (fs.isDirectory(path)) {
-      FileStatus[] files = fs.listStatus(path, StorageManager.hiddenFileFilter);
-      if (files != null && files.length > 0) {
-        for (FileStatus eachFile : files) {
-          if (result.size() >= numResultFiles) {
-            return;
-          }
-          if (eachFile.isDirectory()) {
-            getNonZeroLengthDataFiles(fs, eachFile.getPath(), result, startFileIndex, numResultFiles,
-                currentFileIndex);
-          } else if (eachFile.isFile() && eachFile.getLen() > 0) {
-            if (currentFileIndex.get() >= startFileIndex) {
-              result.add(eachFile);
-            }
-            currentFileIndex.incrementAndGet();
-          }
-        }
-      }
-    } else {
-      FileStatus fileStatus = fs.getFileStatus(path);
-      if (fileStatus != null && fileStatus.getLen() > 0) {
-        if (currentFileIndex.get() >= startFileIndex) {
-          result.add(fileStatus);
-        }
-        currentFileIndex.incrementAndGet();
-        if (result.size() >= numResultFiles) {
-          return;
-        }
-      }
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/b143f991/tajo-core/src/main/java/org/apache/tajo/engine/planner/PlanningException.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/PlanningException.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/PlanningException.java
deleted file mode 100644
index 4fa88ee..0000000
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/PlanningException.java
+++ /dev/null
@@ -1,29 +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.planner;
-
-public class PlanningException extends Exception {
-  public PlanningException(String message) {
-    super(message);
-  }
-
-  public PlanningException(Exception e) {
-    super(e);
-  }
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/b143f991/tajo-core/src/main/java/org/apache/tajo/engine/planner/PreLogicalPlanVerifier.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/PreLogicalPlanVerifier.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/PreLogicalPlanVerifier.java
deleted file mode 100644
index f6d5540..0000000
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/PreLogicalPlanVerifier.java
+++ /dev/null
@@ -1,290 +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.planner;
-
-import org.apache.tajo.TajoConstants;
-import org.apache.tajo.algebra.*;
-import org.apache.tajo.catalog.CatalogService;
-import org.apache.tajo.catalog.CatalogUtil;
-import org.apache.tajo.catalog.TableDesc;
-import org.apache.tajo.catalog.proto.CatalogProtos;
-import org.apache.tajo.engine.query.QueryContext;
-import org.apache.tajo.util.TUtil;
-
-import java.util.Set;
-import java.util.Stack;
-
-public class PreLogicalPlanVerifier extends BaseAlgebraVisitor <PreLogicalPlanVerifier.Context, Expr> {
-  private CatalogService catalog;
-
-  public PreLogicalPlanVerifier(CatalogService catalog) {
-    this.catalog = catalog;
-  }
-
-  public static class Context {
-    QueryContext queryContext;
-    VerificationState state;
-
-    public Context(QueryContext queryContext, VerificationState state) {
-      this.queryContext = queryContext;
-      this.state = state;
-    }
-  }
-
-  public VerificationState verify(QueryContext queryContext, VerificationState state, Expr expr) throws PlanningException {
-    Context context = new Context(queryContext, state);
-    visit(context, new Stack<Expr>(), expr);
-    return context.state;
-  }
-
-  public Expr visitProjection(Context context, Stack<Expr> stack, Projection expr) throws PlanningException {
-    super.visitProjection(context, stack, expr);
-
-    Set<String> names = TUtil.newHashSet();
-    Expr [] distinctValues = null;
-
-    for (NamedExpr namedExpr : expr.getNamedExprs()) {
-
-      if (namedExpr.hasAlias()) {
-        if (names.contains(namedExpr.getAlias())) {
-          context.state.addVerification(String.format("column name \"%s\" specified more than once",
-              namedExpr.getAlias()));
-        } else {
-          names.add(namedExpr.getAlias());
-        }
-      }
-
-      Set<GeneralSetFunctionExpr> exprs = ExprFinder.finds(namedExpr.getExpr(), OpType.GeneralSetFunction);
-
-      // Currently, avg functions with distinct aggregation are not supported.
-      // This code does not allow users to use avg functions with distinct aggregation.
-      if (distinctValues != null) {
-        for (GeneralSetFunctionExpr setFunction : exprs) {
-          if (setFunction.getSignature().equalsIgnoreCase("avg")) {
-            if (setFunction.isDistinct()) {
-              throw new PlanningException("avg(distinct) function is not supported yet.");
-            } else {
-              throw new PlanningException("avg() function with distinct aggregation functions is not supported yet.");
-            }
-          }
-        }
-      }
-    }
-    return expr;
-  }
-
-  @Override
-  public Expr visitLimit(Context context, Stack<Expr> stack, Limit expr) throws PlanningException {
-    stack.push(expr);
-
-    if (ExprFinder.finds(expr.getFetchFirstNum(), OpType.Column).size() > 0) {
-      context.state.addVerification("argument of LIMIT must not contain variables");
-    }
-
-    visit(context, stack, expr.getFetchFirstNum());
-    Expr result = visit(context, stack, expr.getChild());
-    stack.pop();
-    return result;
-  }
-
-  @Override
-  public Expr visitGroupBy(Context context, Stack<Expr> stack, Aggregation expr) throws PlanningException {
-    super.visitGroupBy(context, stack, expr);
-
-    // Enforcer only ordinary grouping set.
-    for (Aggregation.GroupElement groupingElement : expr.getGroupSet()) {
-      if (groupingElement.getType() != Aggregation.GroupType.OrdinaryGroup) {
-        context.state.addVerification(groupingElement.getType() + " is not supported yet");
-      }
-    }
-
-    Projection projection = null;
-    for (Expr parent : stack) {
-      if (parent.getType() == OpType.Projection) {
-        projection = (Projection) parent;
-        break;
-      }
-    }
-
-    if (projection == null) {
-      throw new PlanningException("No Projection");
-    }
-
-    return expr;
-  }
-
-  @Override
-  public Expr visitRelation(Context context, Stack<Expr> stack, Relation expr) throws PlanningException {
-    assertRelationExistence(context, expr.getName());
-    return expr;
-  }
-
-  private boolean assertRelationExistence(Context context, String tableName) {
-    String qualifiedName;
-
-    if (CatalogUtil.isFQTableName(tableName)) {
-      qualifiedName = tableName;
-    } else {
-      qualifiedName = CatalogUtil.buildFQName(context.queryContext.getCurrentDatabase(), tableName);
-    }
-
-    if (!catalog.existsTable(qualifiedName)) {
-      context.state.addVerification(String.format("relation \"%s\" does not exist", qualifiedName));
-      return false;
-    }
-    return true;
-  }
-
-  private boolean assertRelationNoExistence(Context context, String tableName) {
-    String qualifiedName;
-
-    if (CatalogUtil.isFQTableName(tableName)) {
-      qualifiedName = tableName;
-    } else {
-      qualifiedName = CatalogUtil.buildFQName(context.queryContext.getCurrentDatabase(), tableName);
-    }
-    if(qualifiedName == null) {
-      System.out.println("A");
-    }
-    if (catalog.existsTable(qualifiedName)) {
-      context.state.addVerification(String.format("relation \"%s\" already exists", qualifiedName));
-      return false;
-    }
-    return true;
-  }
-
-  private boolean assertUnsupportedStoreType(VerificationState state, String name) {
-    if (name != null && name.equals(CatalogProtos.StoreType.RAW.name())) {
-      state.addVerification(String.format("Unsupported store type :%s", name));
-      return false;
-    }
-    return true;
-  }
-
-  private boolean assertDatabaseExistence(VerificationState state, String name) {
-    if (!catalog.existDatabase(name)) {
-      state.addVerification(String.format("database \"%s\" does not exist", name));
-      return false;
-    }
-    return true;
-  }
-
-  private boolean assertDatabaseNoExistence(VerificationState state, String name) {
-    if (catalog.existDatabase(name)) {
-      state.addVerification(String.format("database \"%s\" already exists", name));
-      return false;
-    }
-    return true;
-  }
-
-  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
-  // Data Definition Language Section
-  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-
-  @Override
-  public Expr visitCreateDatabase(Context context, Stack<Expr> stack, CreateDatabase expr)
-      throws PlanningException {
-    super.visitCreateDatabase(context, stack, expr);
-    if (!expr.isIfNotExists()) {
-      assertDatabaseNoExistence(context.state, expr.getDatabaseName());
-    }
-    return expr;
-  }
-
-  @Override
-  public Expr visitDropDatabase(Context context, Stack<Expr> stack, DropDatabase expr) throws PlanningException {
-    super.visitDropDatabase(context, stack, expr);
-    if (!expr.isIfExists()) {
-      assertDatabaseExistence(context.state, expr.getDatabaseName());
-    }
-    return expr;
-  }
-
-  @Override
-  public Expr visitCreateTable(Context context, Stack<Expr> stack, CreateTable expr) throws PlanningException {
-    super.visitCreateTable(context, stack, expr);
-    if (!expr.isIfNotExists()) {
-      assertRelationNoExistence(context, expr.getTableName());
-    }
-    assertUnsupportedStoreType(context.state, expr.getStorageType());
-    return expr;
-  }
-
-  @Override
-  public Expr visitDropTable(Context context, Stack<Expr> stack, DropTable expr) throws PlanningException {
-    super.visitDropTable(context, stack, expr);
-    if (!expr.isIfExists()) {
-      assertRelationExistence(context, expr.getTableName());
-    }
-    return expr;
-  }
-
-  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
-  // Insert or Update Section
-  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public Expr visitInsert(Context context, Stack<Expr> stack, Insert expr) throws PlanningException {
-    Expr child = super.visitInsert(context, stack, expr);
-
-    if (expr.hasTableName()) {
-      assertRelationExistence(context, expr.getTableName());
-    }
-
-    if (child != null && child.getType() == OpType.Projection) {
-      Projection projection = (Projection) child;
-      int projectColumnNum = projection.getNamedExprs().length;
-
-      if (expr.hasTargetColumns()) {
-        int targetColumnNum = expr.getTargetColumns().length;
-
-        if (targetColumnNum > projectColumnNum)  {
-          context.state.addVerification("INSERT has more target columns than expressions");
-        } else if (targetColumnNum < projectColumnNum) {
-          context.state.addVerification("INSERT has more expressions than target columns");
-        }
-      } else {
-        if (expr.hasTableName()) {
-          String qualifiedName = expr.getTableName();
-          if (TajoConstants.EMPTY_STRING.equals(CatalogUtil.extractQualifier(expr.getTableName()))) {
-            qualifiedName = CatalogUtil.buildFQName(context.queryContext.getCurrentDatabase(),
-                expr.getTableName());
-          }
-
-          TableDesc table = catalog.getTableDesc(qualifiedName);
-          if (table == null) {
-            context.state.addVerification(String.format("relation \"%s\" does not exist", qualifiedName));
-            return null;
-          }
-          if (table.hasPartition()) {
-            int columnSize = table.getSchema().getColumns().size();
-            columnSize += table.getPartitionMethod().getExpressionSchema().getColumns().size();
-            if (projectColumnNum < columnSize) {
-              context.state.addVerification("INSERT has smaller expressions than target columns");
-            } else if (projectColumnNum > columnSize) {
-              context.state.addVerification("INSERT has more expressions than target columns");
-            }
-          }
-        }
-      }
-    }
-
-    return expr;
-  }
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/b143f991/tajo-core/src/main/java/org/apache/tajo/engine/planner/Projector.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/Projector.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/Projector.java
index d8499d0..7c2e81f 100644
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/Projector.java
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/planner/Projector.java
@@ -20,14 +20,16 @@ package org.apache.tajo.engine.planner;
 
 import org.apache.tajo.SessionVars;
 import org.apache.tajo.catalog.Schema;
-import org.apache.tajo.engine.eval.EvalNode;
+import org.apache.tajo.plan.util.PlannerUtil;
+import org.apache.tajo.plan.Target;
+import org.apache.tajo.plan.expr.EvalNode;
 import org.apache.tajo.storage.Tuple;
 import org.apache.tajo.worker.TaskAttemptContext;
 
 public class Projector {
   private final TaskAttemptContext context;
   private final Schema inSchema;
-  private final Target [] targets;
+  private final Target[] targets;
 
   // for projection
   private final int targetNum;

http://git-wip-us.apache.org/repos/asf/tajo/blob/b143f991/tajo-core/src/main/java/org/apache/tajo/engine/planner/SimpleAlgebraVisitor.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/SimpleAlgebraVisitor.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/SimpleAlgebraVisitor.java
deleted file mode 100644
index 8b34189..0000000
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/SimpleAlgebraVisitor.java
+++ /dev/null
@@ -1,210 +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.planner;
-
-import org.apache.tajo.algebra.*;
-
-import java.util.Stack;
-
-/**
- * <code>SimpleAlgebraVisitor</code> provides a simple and fewer visit methods. It makes building concrete class easier.
- */
-public abstract class SimpleAlgebraVisitor<CONTEXT, RESULT> extends BaseAlgebraVisitor<CONTEXT, RESULT> {
-
-  public RESULT visit(CONTEXT ctx, Stack<Expr> stack, Expr expr) throws PlanningException {
-    RESULT result = null;
-    if (expr instanceof UnaryOperator) {
-      preHook(ctx, stack, expr);
-      result = visitUnaryOperator(ctx, stack, (UnaryOperator) expr);
-      postHook(ctx, stack, expr, result);
-    } else if (expr instanceof BinaryOperator) {
-      preHook(ctx, stack, expr);
-      result = visitBinaryOperator(ctx, stack, (BinaryOperator) expr);
-      postHook(ctx, stack, expr, result);
-    } else {
-      result = super.visit(ctx, stack, expr);
-    }
-
-    return result;
-  }
-
-  public RESULT visitUnaryOperator(CONTEXT ctx, Stack<Expr> stack, UnaryOperator expr) throws PlanningException {
-    stack.push(expr);
-    RESULT result = visit(ctx, stack, expr.getChild());
-    stack.pop();
-    return result;
-  }
-
-  public RESULT visitBinaryOperator(CONTEXT ctx, Stack<Expr> stack, BinaryOperator expr) throws PlanningException {
-    stack.push(expr);
-    visit(ctx, stack, expr.getLeft());
-    RESULT result = visit(ctx, stack, expr.getRight());
-    stack.pop();
-    return result;
-  }
-
-  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
-  // Relational Operator Section
-  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-  @Override
-  public RESULT visitProjection(CONTEXT ctx, Stack<Expr> stack, Projection expr) throws PlanningException {
-    return super.visitProjection(ctx, stack, expr);
-  }
-
-  @Override
-  public RESULT visitLimit(CONTEXT ctx, Stack<Expr> stack, Limit expr) throws PlanningException {
-    return super.visitLimit(ctx, stack, expr);
-  }
-
-  @Override
-  public RESULT visitSort(CONTEXT ctx, Stack<Expr> stack, Sort expr) throws PlanningException {
-    return super.visitSort(ctx, stack, expr);
-  }
-
-  @Override
-  public RESULT visitHaving(CONTEXT ctx, Stack<Expr> stack, Having expr) throws PlanningException {
-    return super.visitHaving(ctx, stack, expr);
-  }
-
-  @Override
-  public RESULT visitGroupBy(CONTEXT ctx, Stack<Expr> stack, Aggregation expr) throws PlanningException {
-    return super.visitGroupBy(ctx, stack, expr);
-  }
-
-  public RESULT visitFilter(CONTEXT ctx, Stack<Expr> stack, Selection expr) throws PlanningException {
-    return super.visitFilter(ctx, stack, expr);
-  }
-
-  @Override
-  public RESULT visitJoin(CONTEXT ctx, Stack<Expr> stack, Join expr) throws PlanningException {
-    return super.visitJoin(ctx, stack, expr);
-  }
-
-  @Override
-  public RESULT visitTableSubQuery(CONTEXT ctx, Stack<Expr> stack, TablePrimarySubQuery expr) throws PlanningException {
-    return super.visitTableSubQuery(ctx, stack, expr);
-  }
-
-  @Override
-  public RESULT visitRelationList(CONTEXT ctx, Stack<Expr> stack, RelationList expr) throws PlanningException {
-    return super.visitRelationList(ctx, stack, expr);
-  }
-
-  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
-  // Data Definition Language Section
-  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-  @Override
-  public RESULT visitCreateTable(CONTEXT ctx, Stack<Expr> stack, CreateTable expr) throws PlanningException {
-    return super.visitCreateTable(ctx, stack, expr);
-  }
-
-  @Override
-  public RESULT visitDropTable(CONTEXT ctx, Stack<Expr> stack, DropTable expr) throws PlanningException {
-    return super.visitDropTable(ctx, stack, expr);
-  }
-
-  @Override
-  public RESULT visitAlterTable(CONTEXT ctx, Stack<Expr> stack, AlterTable expr) throws PlanningException {
-    return super.visitAlterTable(ctx, stack, expr);
-  }
-
-  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
-  // Insert or Update Section
-  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
-  @Override
-  public RESULT visitInsert(CONTEXT ctx, Stack<Expr> stack, Insert expr) throws PlanningException {
-    return super.visitInsert(ctx, stack, expr);
-  }
-
-
-  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
-  // Other Predicates Section
-  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-  @Override
-  public RESULT visitBetween(CONTEXT ctx, Stack<Expr> stack, BetweenPredicate expr) throws PlanningException {
-    return super.visitBetween(ctx, stack, expr);
-  }
-
-  @Override
-  public RESULT visitCaseWhen(CONTEXT ctx, Stack<Expr> stack, CaseWhenPredicate expr) throws PlanningException {
-    return super.visitCaseWhen(ctx, stack, expr);
-  }
-
-  @Override
-  public RESULT visitValueListExpr(CONTEXT ctx, Stack<Expr> stack, ValueListExpr expr) throws PlanningException {
-    return super.visitValueListExpr(ctx, stack, expr);
-  }
-
-  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
-  // Functions and General Set Function Section
-  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
-  @Override
-  public RESULT visitFunction(CONTEXT ctx, Stack<Expr> stack, FunctionExpr expr) throws PlanningException {
-    return super.visitFunction(ctx, stack, expr);
-  }
-
-  @Override
-  public RESULT visitCountRowsFunction(CONTEXT ctx, Stack<Expr> stack, CountRowsFunctionExpr expr)
-      throws PlanningException {
-    return super.visitCountRowsFunction(ctx, stack, expr);
-  }
-
-  @Override
-  public RESULT visitGeneralSetFunction(CONTEXT ctx, Stack<Expr> stack, GeneralSetFunctionExpr expr)
-      throws PlanningException {
-    return super.visitGeneralSetFunction(ctx, stack, expr);
-  }
-
-  @Override
-  public RESULT visitWindowFunction(CONTEXT ctx, Stack<Expr> stack, WindowFunctionExpr expr) throws PlanningException {
-    return super.visitWindowFunction(ctx, stack, expr);
-  }
-
-  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
-  // Literal Section
-  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-  @Override
-  public RESULT visitDataType(CONTEXT ctx, Stack<Expr> stack, DataTypeExpr expr) throws PlanningException {
-    return super.visitDataType(ctx, stack, expr);
-  }
-
-  @Override
-  public RESULT visitLiteral(CONTEXT ctx, Stack<Expr> stack, LiteralValue expr) throws PlanningException {
-    return super.visitLiteral(ctx, stack, expr);
-  }
-
-  @Override
-  public RESULT visitNullLiteral(CONTEXT ctx, Stack<Expr> stack, NullLiteral expr) throws PlanningException {
-    return super.visitNullLiteral(ctx, stack, expr);
-  }
-
-  @Override
-  public RESULT visitTimestampLiteral(CONTEXT ctx, Stack<Expr> stack, TimestampLiteral expr) throws PlanningException {
-    return super.visitTimestampLiteral(ctx, stack, expr);
-  }
-
-  @Override
-  public RESULT visitTimeLiteral(CONTEXT ctx, Stack<Expr> stack, TimeLiteral expr) throws PlanningException {
-    return super.visitTimeLiteral(ctx, stack, expr);
-  }
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/b143f991/tajo-core/src/main/java/org/apache/tajo/engine/planner/Target.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/Target.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/Target.java
deleted file mode 100644
index 6a16d3c..0000000
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/Target.java
+++ /dev/null
@@ -1,129 +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.planner;
-
-import com.google.gson.annotations.Expose;
-import org.apache.tajo.catalog.Column;
-import org.apache.tajo.common.TajoDataTypes.DataType;
-import org.apache.tajo.engine.eval.EvalNode;
-import org.apache.tajo.engine.eval.FieldEval;
-import org.apache.tajo.engine.json.CoreGsonHelper;
-import org.apache.tajo.json.GsonObject;
-import org.apache.tajo.util.TUtil;
-
-/**
- * A Target contains how to evaluate an expression and its alias name.
- */
-public class Target implements Cloneable, GsonObject {
-  @Expose private EvalNode expr;
-  @Expose private Column column;
-  @Expose private String alias = null;
-
-  public Target(FieldEval fieldEval) {
-    this.expr = fieldEval;
-    this.column = fieldEval.getColumnRef();
-  }
-
-  public Target(final EvalNode eval, final String alias) {
-    this.expr = eval;
-    // force lower case
-    String normalized = alias;
-
-    // If an expr is a column reference and its alias is equivalent to column name, ignore a given alias.
-    if (eval instanceof FieldEval && eval.getName().equals(normalized)) {
-      column = ((FieldEval) eval).getColumnRef();
-    } else {
-      column = new Column(normalized, eval.getValueType());
-      setAlias(alias);
-    }
-  }
-
-  public String getCanonicalName() {
-    return !hasAlias() ? column.getQualifiedName() : alias;
-  }
-
-  public final void setExpr(EvalNode expr) {
-    this.expr = expr;
-  }
-
-  public final void setAlias(String alias) {
-    this.alias = alias;
-    this.column = new Column(alias, expr.getValueType());
-  }
-
-  public final String getAlias() {
-    return alias;
-  }
-
-  public final boolean hasAlias() {
-    return alias != null;
-  }
-
-  public DataType getDataType() {
-    return column.getDataType();
-  }
-
-  public <T extends EvalNode> T getEvalTree() {
-    return (T) this.expr;
-  }
-
-  public Column getNamedColumn() {
-    return this.column;
-  }
-
-  public String toString() {
-    StringBuilder sb = new StringBuilder(expr.toString());
-    if(hasAlias()) {
-      sb.append(" as ").append(alias);
-    }
-    return sb.toString();
-  }
-
-  public boolean equals(Object obj) {
-    if(obj instanceof Target) {
-      Target other = (Target) obj;
-
-      boolean b1 = expr.equals(other.expr);
-      boolean b2 = column.equals(other.column);
-      boolean b3 = TUtil.checkEquals(alias, other.alias);
-
-      return b1 && b2 && b3;
-    } else {
-      return false;
-    }
-  }
-
-  public int hashCode() {
-    return this.expr.getName().hashCode();
-  }
-
-  @Override
-  public Object clone() throws CloneNotSupportedException {
-    Target target = (Target) super.clone();
-    target.expr = (EvalNode) expr.clone();
-    target.column = column;
-    target.alias = alias != null ? alias : null;
-
-    return target;
-  }
-
-  public String toJson() {
-    return CoreGsonHelper.toJson(this, Target.class);
-  }
-}