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:15 UTC

[16/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/logical/TruncateTableNode.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/TruncateTableNode.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/TruncateTableNode.java
deleted file mode 100644
index 3ffbd7b..0000000
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/TruncateTableNode.java
+++ /dev/null
@@ -1,62 +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.logical;
-
-import com.google.gson.annotations.Expose;
-import org.apache.tajo.engine.planner.PlanString;
-import org.apache.tajo.util.TUtil;
-
-import java.util.List;
-
-public class TruncateTableNode extends LogicalNode {
-  @Expose
-  private List<String> tableNames;
-
-  public TruncateTableNode(int pid) {
-    super(pid, NodeType.TRUNCATE_TABLE);
-  }
-
-  public List<String> getTableNames() {
-    return tableNames;
-  }
-
-  public void setTableNames(List<String> tableNames) {
-    this.tableNames = tableNames;
-  }
-
-  @Override
-  public String toString() {
-    return "TruncateTable (table=" + TUtil.collectionToString(tableNames, ", ") + ")";
-  }
-
-  @Override
-  public void preOrder(LogicalNodeVisitor visitor) {
-    visitor.visit(this);
-  }
-
-  @Override
-  public void postOrder(LogicalNodeVisitor visitor) {
-    visitor.visit(this);
-  }
-
-  @Override
-  public PlanString getPlanString() {
-    return new PlanString(this);
-  }
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/b143f991/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/UnaryNode.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/UnaryNode.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/UnaryNode.java
deleted file mode 100644
index 0b06e9e..0000000
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/UnaryNode.java
+++ /dev/null
@@ -1,69 +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.logical;
-
-import com.google.gson.annotations.Expose;
-import org.apache.tajo.util.TUtil;
-
-
-public abstract class UnaryNode extends LogicalNode implements Cloneable {
-	@Expose LogicalNode child;
-	
-	/**
-	 * @param type
-	 */
-	public UnaryNode(int pid, NodeType type) {
-		super(pid, type);
-	}
-	
-	public void setChild(LogicalNode subNode) {
-		this.child = subNode;
-	}
-	
-	public <T extends LogicalNode> T getChild() {
-		return (T) this.child;
-	}
-
-  @Override
-  public boolean deepEquals(Object o) {
-    if (o instanceof UnaryNode) {
-      UnaryNode u = (UnaryNode) o;
-      return equals(o) && TUtil.checkEquals(child, u.child);
-    }
-    return false;
-  }
-	
-	@Override
-  public Object clone() throws CloneNotSupportedException {
-	  UnaryNode unary = (UnaryNode) super.clone();
-	  unary.child = (LogicalNode) (child == null ? null : child.clone());
-	  
-	  return unary;
-	}
-	
-	public void preOrder(LogicalNodeVisitor visitor) {
-	  visitor.visit(this);
-	  child.preOrder(visitor);
-  }
-	
-	public void postOrder(LogicalNodeVisitor visitor) {
-	  child.postOrder(visitor);
-	  visitor.visit(this);
-	}
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/b143f991/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/UnionNode.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/UnionNode.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/UnionNode.java
deleted file mode 100644
index 49183d0..0000000
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/UnionNode.java
+++ /dev/null
@@ -1,37 +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.logical;
-
-import org.apache.tajo.engine.planner.PlanString;
-
-public class UnionNode extends BinaryNode {
-
-  public UnionNode(int pid) {
-    super(pid, NodeType.UNION);
-  }
-
-  @Override
-  public PlanString getPlanString() {
-    PlanString planStr = new PlanString(this);
-    return planStr;
-  }
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/b143f991/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/WindowAggNode.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/WindowAggNode.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/WindowAggNode.java
deleted file mode 100644
index 20b195f..0000000
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/WindowAggNode.java
+++ /dev/null
@@ -1,238 +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.logical;
-
-import com.google.common.base.Objects;
-import com.google.gson.annotations.Expose;
-import org.apache.tajo.catalog.Column;
-import org.apache.tajo.catalog.SortSpec;
-import org.apache.tajo.engine.eval.WindowFunctionEval;
-import org.apache.tajo.engine.planner.PlanString;
-import org.apache.tajo.engine.planner.PlannerUtil;
-import org.apache.tajo.engine.planner.Target;
-import org.apache.tajo.util.TUtil;
-
-public class WindowAggNode extends UnaryNode implements Projectable, Cloneable {
-	/** partition key sets */
-  @Expose private Column [] partitionKeys;
-  /** order key sets */
-  @Expose private SortSpec [] sortSpecs;
-
-  /** Aggregation Functions */
-  @Expose private WindowFunctionEval[] windowFuncs;
-  /**
-   * It's a list of targets. The partition key columns should be followed by window functions.
-   * aggrFunctions keep actual aggregation functions, but it only contains field references.
-   * */
-  @Expose private Target [] targets;
-  @Expose private boolean hasDistinct = false;
-
-  public WindowAggNode(int pid) {
-    super(pid, NodeType.WINDOW_AGG);
-  }
-
-  public final boolean hasPartitionKeys() {
-    return partitionKeys != null && partitionKeys.length > 0;
-  }
-
-  public void setPartitionKeys(Column[] groupingColumns) {
-    this.partitionKeys = groupingColumns;
-  }
-
-	public final Column [] getPartitionKeys() {
-	  return this.partitionKeys;
-	}
-
-  public final boolean hasSortSpecs() {
-    return this.sortSpecs != null;
-  }
-
-  public void setSortSpecs(SortSpec [] sortSpecs) {
-    this.sortSpecs = sortSpecs;
-  }
-
-  public final SortSpec [] getSortSpecs() {
-    return this.sortSpecs;
-  }
-
-  public final boolean isDistinct() {
-    return hasDistinct;
-  }
-
-  public void setDistinct(boolean distinct) {
-    hasDistinct = distinct;
-  }
-
-  public boolean hasAggFunctions() {
-    return this.windowFuncs != null;
-  }
-
-  public WindowFunctionEval [] getWindowFunctions() {
-    return this.windowFuncs;
-  }
-
-  public void setWindowFunctions(WindowFunctionEval[] evals) {
-    this.windowFuncs = evals;
-  }
-
-  @Override
-  public boolean hasTargets() {
-    return this.targets != null;
-  }
-
-  @Override
-  public void setTargets(Target[] targets) {
-    this.targets = targets;
-    setOutSchema(PlannerUtil.targetToSchema(targets));
-  }
-
-  @Override
-  public Target[] getTargets() {
-    return this.targets;
-  }
-  
-  public void setChild(LogicalNode subNode) {
-    super.setChild(subNode);
-  }
-  
-  public String toString() {
-    StringBuilder sb = new StringBuilder("WinAgg (");
-    if (hasPartitionKeys()) {
-      sb.append("partition keys=").append(TUtil.arrayToString(partitionKeys));
-      sb.append(", ");
-    }
-    if (hasAggFunctions()) {
-      sb.append("funcs=").append(TUtil.arrayToString(windowFuncs));
-    }
-    if (hasSortSpecs()) {
-      sb.append("sort=").append(TUtil.arrayToString(sortSpecs));
-    }
-    sb.append(")");
-    return sb.toString();
-  }
-  
-  @Override
-  public boolean equals(Object obj) {
-    if (obj instanceof WindowAggNode) {
-      WindowAggNode other = (WindowAggNode) obj;
-      boolean eq = super.equals(other);
-      eq = eq && TUtil.checkEquals(partitionKeys, other.partitionKeys);
-      eq = eq && TUtil.checkEquals(sortSpecs, other.sortSpecs);
-      eq = eq && TUtil.checkEquals(windowFuncs, other.windowFuncs);
-      eq = eq && TUtil.checkEquals(targets, other.targets);
-      eq = eq && TUtil.checkEquals(hasDistinct, other.hasDistinct);
-      return eq;
-    } else {
-      return false;  
-    }
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hashCode(partitionKeys, sortSpecs, windowFuncs, targets, hasDistinct);
-  }
-  
-  @Override
-  public Object clone() throws CloneNotSupportedException {
-    WindowAggNode grp = (WindowAggNode) super.clone();
-    if (partitionKeys != null) {
-      grp.partitionKeys = new Column[partitionKeys.length];
-      for (int i = 0; i < partitionKeys.length; i++) {
-        grp.partitionKeys[i] = partitionKeys[i];
-      }
-    }
-
-    if (windowFuncs != null) {
-      grp.windowFuncs = new WindowFunctionEval[windowFuncs.length];
-      for (int i = 0; i < windowFuncs.length; i++) {
-        grp.windowFuncs[i] = (WindowFunctionEval) windowFuncs[i].clone();
-      }
-    }
-
-    if (targets != null) {
-      grp.targets = new Target[targets.length];
-      for (int i = 0; i < targets.length; i++) {
-        grp.targets[i] = (Target) targets[i].clone();
-      }
-    }
-
-    return grp;
-  }
-
-  @Override
-  public PlanString getPlanString() {
-    PlanString planStr = new PlanString(this);
-
-    StringBuilder sb = new StringBuilder();
-    sb.append("(");
-    if (hasPartitionKeys()) {
-      sb.append("PARTITION BY ");
-      for (int j = 0; j < partitionKeys.length; j++) {
-        sb.append(partitionKeys[j].getSimpleName());
-        if(j < partitionKeys.length - 1) {
-          sb.append(",");
-        }
-      }
-    }
-
-    if (hasSortSpecs()) {
-      sb.append("ORDER BY ");
-      for (int i = 0; i < sortSpecs.length; i++) {
-        sb.append(sortSpecs[i].getSortKey().getSimpleName()).append(" ")
-            .append(sortSpecs[i].isAscending() ? "asc" : "desc");
-        if( i < sortSpecs.length - 1) {
-          sb.append(",");
-        }
-      }
-    }
-
-    sb.append(")");
-
-    planStr.appendTitle(sb.toString());
-
-    // there can be no aggregation functions
-    if (hasAggFunctions()) {
-      sb = new StringBuilder();
-      sb.append("(");
-
-      for (int j = 0; j < windowFuncs.length; j++) {
-        sb.append(windowFuncs[j]);
-        if(j < windowFuncs.length - 1) {
-          sb.append(",");
-        }
-      }
-      sb.append(")");
-      planStr.appendExplain("exprs: ").appendExplain(sb.toString());
-    }
-
-    sb = new StringBuilder("target list: ");
-    for (int i = 0; i < targets.length; i++) {
-      sb.append(targets[i]);
-      if( i < targets.length - 1) {
-        sb.append(", ");
-      }
-    }
-    planStr.addExplan(sb.toString());
-
-    planStr.addDetail("out schema:").appendDetail(getOutSchema().toString());
-    planStr.addDetail("in schema:").appendDetail(getInSchema().toString());
-
-    return planStr;
-  }
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/b143f991/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/WindowSpec.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/WindowSpec.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/WindowSpec.java
deleted file mode 100644
index afec0ac..0000000
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/WindowSpec.java
+++ /dev/null
@@ -1,208 +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.logical;
-
-
-import com.google.common.base.Objects;
-import com.google.gson.annotations.Expose;
-import org.apache.tajo.catalog.Column;
-import org.apache.tajo.engine.eval.EvalNode;
-import org.apache.tajo.util.TUtil;
-
-import static org.apache.tajo.algebra.WindowSpec.WindowFrameEndBoundType;
-import static org.apache.tajo.algebra.WindowSpec.WindowFrameStartBoundType;
-
-public class WindowSpec {
-  @Expose private String windowName;
-
-  @Expose private Column[] partitionKeys;
-
-  @Expose private WindowFrame windowFrame;
-
-  public String getWindowName() {
-    return windowName;
-  }
-
-  public boolean hasPartitionKeys() {
-    return partitionKeys != null;
-  }
-
-  public Column [] getPartitionKeys() {
-    return partitionKeys;
-  }
-
-  public boolean hasWindowFrame() {
-    return windowFrame != null;
-  }
-
-  public WindowFrame getWindowFrame() {
-    return windowFrame;
-  }
-
-  @Override
-  public boolean equals(Object obj) {
-    if (obj instanceof WindowSpec) {
-      WindowSpec another = (WindowSpec) obj;
-      return
-          TUtil.checkEquals(windowName, another.windowName) &&
-          TUtil.checkEquals(partitionKeys, another.partitionKeys) &&
-          TUtil.checkEquals(windowFrame, another.windowFrame);
-    } else {
-      return false;
-    }
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hashCode(windowName, partitionKeys, windowFrame);
-  }
-
-  public static class WindowFrame {
-    @Expose private WindowStartBound startBound;
-    @Expose private WindowEndBound endBound;
-    @Expose org.apache.tajo.algebra.WindowSpec.WindowFrameUnit unit; // TODO - to be supported
-
-    public WindowFrame() {
-      this.startBound = new WindowStartBound(WindowFrameStartBoundType.UNBOUNDED_PRECEDING);
-      this.endBound = new WindowEndBound(WindowFrameEndBoundType.UNBOUNDED_FOLLOWING);
-    }
-
-    public WindowFrame(WindowStartBound startBound) {
-      this.startBound = startBound;
-    }
-
-    public WindowFrame(WindowStartBound startBound, WindowEndBound endBound) {
-      this(startBound);
-      this.endBound = endBound;
-    }
-
-    public WindowStartBound getStartBound() {
-      return startBound;
-    }
-
-    public boolean hasEndBound() {
-      return endBound != null;
-    }
-
-    public WindowEndBound getEndBound() {
-      return endBound;
-    }
-
-    public boolean hasFrameUnit() {
-      return this.unit != null;
-    }
-
-    public void setFrameUnit(org.apache.tajo.algebra.WindowSpec.WindowFrameUnit unit) {
-      this.unit = unit;
-    }
-
-    public org.apache.tajo.algebra.WindowSpec.WindowFrameUnit getFrameUnit() {
-      return this.unit;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-      if (obj instanceof WindowFrame) {
-        WindowFrame another = (WindowFrame) obj;
-        return
-            TUtil.checkEquals(startBound, another.startBound) &&
-            TUtil.checkEquals(endBound, another.endBound) &&
-            TUtil.checkEquals(unit, another.unit);
-      } else {
-        return false;
-      }
-    }
-
-    public int hashCode() {
-      return Objects.hashCode(startBound, endBound, unit);
-    }
-  }
-
-  public static class WindowStartBound {
-    @Expose private WindowFrameStartBoundType boundType;
-    @Expose private EvalNode number;
-
-    public WindowStartBound(WindowFrameStartBoundType type) {
-      this.boundType = type;
-    }
-
-    public WindowFrameStartBoundType getBoundType() {
-      return boundType;
-    }
-
-    public void setNumber(EvalNode number) {
-      this.number = number;
-    }
-
-    public EvalNode getNumber() {
-      return number;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-      if (obj instanceof WindowStartBound) {
-        WindowStartBound other = (WindowStartBound) obj;
-        return boundType == other.boundType && number.equals(other.number);
-      } else {
-        return false;
-      }
-    }
-
-    @Override
-    public int hashCode() {
-      return Objects.hashCode(boundType, number);
-    }
-  }
-
-  public static class WindowEndBound {
-    @Expose private WindowFrameEndBoundType boundType;
-    @Expose private EvalNode number;
-
-    public WindowEndBound(WindowFrameEndBoundType type) {
-      this.boundType = type;
-    }
-
-    public WindowFrameEndBoundType getBoundType() {
-      return boundType;
-    }
-
-    public EvalNode setNumber(EvalNode number) {
-      return number;
-    }
-
-    public EvalNode getNumber() {
-      return number;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-      if (obj instanceof WindowStartBound) {
-        WindowEndBound other = (WindowEndBound) obj;
-        return boundType == other.boundType && number.equals(other.number);
-      } else {
-        return false;
-      }
-    }
-
-    @Override
-    public int hashCode() {
-      return Objects.hashCode(boundType, number);
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/b143f991/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/join/Edge.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/join/Edge.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/join/Edge.java
deleted file mode 100644
index c8bca03..0000000
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/join/Edge.java
+++ /dev/null
@@ -1,50 +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.logical.join;
-
-import org.apache.tajo.engine.eval.EvalNode;
-
-public class Edge {
-  private String src;
-  private String target;
-  private EvalNode joinQual;
-
-  public Edge(String src, String target, EvalNode joinQual) {
-    this.src = src;
-    this.target = target;
-    this.joinQual = joinQual;
-  }
-
-  public String getSrc() {
-    return this.src;
-  }
-
-  public String getTarget() {
-    return this.target;
-  }
-
-  public EvalNode getJoinQual() {
-    return this.joinQual;
-  }
-
-  @Override
-  public String toString() {
-    return "(" + src + "=> " + target + ", " + joinQual + ")";
-  }
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/b143f991/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/join/FoundJoinOrder.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/join/FoundJoinOrder.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/join/FoundJoinOrder.java
deleted file mode 100644
index 5ae34f7..0000000
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/join/FoundJoinOrder.java
+++ /dev/null
@@ -1,47 +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.logical.join;
-
-import org.apache.hadoop.classification.InterfaceStability;
-import org.apache.tajo.engine.planner.logical.JoinNode;
-
-/**
- * It contains the result of join enumeration.
- */
-@InterfaceStability.Evolving
-public class FoundJoinOrder {
-  private JoinNode joinNode;
-  private double cost;
-
-  public FoundJoinOrder(JoinNode joinNode, double cost) {
-    this.joinNode = joinNode;
-    this.cost = cost;
-  }
-
-  /**
-   * @return a ordered join operators
-   */
-  public JoinNode getOrderedJoin() {
-    return this.joinNode;
-  }
-
-  public double getCost() {
-    return cost;
-  }
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/b143f991/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/join/GreedyHeuristicJoinOrderAlgorithm.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/join/GreedyHeuristicJoinOrderAlgorithm.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/join/GreedyHeuristicJoinOrderAlgorithm.java
deleted file mode 100644
index e445de7..0000000
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/join/GreedyHeuristicJoinOrderAlgorithm.java
+++ /dev/null
@@ -1,301 +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.logical.join;
-
-import org.apache.tajo.algebra.JoinType;
-import org.apache.tajo.catalog.Schema;
-import org.apache.tajo.engine.eval.AlgebraicUtil;
-import org.apache.tajo.engine.planner.LogicalPlan;
-import org.apache.tajo.engine.planner.PlannerUtil;
-import org.apache.tajo.engine.planner.PlanningException;
-import org.apache.tajo.engine.planner.logical.*;
-import org.apache.tajo.engine.utils.SchemaUtil;
-import org.apache.tajo.util.TUtil;
-
-import java.util.*;
-
-/**
- * This is a greedy heuristic algorithm to find a bushy join tree. This algorithm finds
- * the best join order with join conditions and pushed-down join conditions to
- * all join operators.
- */
-public class GreedyHeuristicJoinOrderAlgorithm implements JoinOrderAlgorithm {
-  public static double DEFAULT_SELECTION_FACTOR = 0.1;
-
-  @Override
-  public FoundJoinOrder findBestOrder(LogicalPlan plan, LogicalPlan.QueryBlock block, JoinGraph joinGraph,
-                                      Set<String> relationsWithoutQual) throws PlanningException {
-
-    // Setup a remain relation set to be joined
-    // Why we should use LinkedHashSet? - it should keep the deterministic for the order of joins.
-    // Otherwise, join orders can be different even if join costs are the same to each other.
-    Set<LogicalNode> remainRelations = new LinkedHashSet<LogicalNode>();
-    for (RelationNode relation : block.getRelations()) {
-      remainRelations.add(relation);
-    }
-
-    LogicalNode latestJoin;
-    JoinEdge bestPair;
-
-    while (remainRelations.size() > 1) {
-      // Find the best join pair among all joinable operators in candidate set.
-      bestPair = getBestPair(plan, joinGraph, remainRelations);
-
-      remainRelations.remove(bestPair.getLeftRelation()); // remainRels = remainRels \ Ti
-      remainRelations.remove(bestPair.getRightRelation()); // remainRels = remainRels \ Tj
-
-      latestJoin = createJoinNode(plan, bestPair);
-      remainRelations.add(latestJoin);
-
-      // all logical nodes should be registered to corresponding blocks
-      block.registerNode(latestJoin);
-    }
-
-    JoinNode joinTree = (JoinNode) remainRelations.iterator().next();
-    // all generated nodes should be registered to corresponding blocks
-    block.registerNode(joinTree);
-    return new FoundJoinOrder(joinTree, getCost(joinTree));
-  }
-
-  private static JoinNode createJoinNode(LogicalPlan plan, JoinEdge joinEdge) {
-    LogicalNode left = joinEdge.getLeftRelation();
-    LogicalNode right = joinEdge.getRightRelation();
-
-    JoinNode joinNode = plan.createNode(JoinNode.class);
-
-    if (PlannerUtil.isCommutativeJoin(joinEdge.getJoinType())) {
-      // if only one operator is relation
-      if ((left instanceof RelationNode) && !(right instanceof RelationNode)) {
-        // for left deep
-        joinNode.init(joinEdge.getJoinType(), right, left);
-      } else {
-        // if both operators are relation or if both are relations
-        // we don't need to concern the left-right position.
-        joinNode.init(joinEdge.getJoinType(), left, right);
-      }
-    } else {
-      joinNode.init(joinEdge.getJoinType(), left, right);
-    }
-
-    Schema mergedSchema = SchemaUtil.merge(joinNode.getLeftChild().getOutSchema(),
-        joinNode.getRightChild().getOutSchema());
-    joinNode.setInSchema(mergedSchema);
-    joinNode.setOutSchema(mergedSchema);
-    if (joinEdge.hasJoinQual()) {
-      joinNode.setJoinQual(AlgebraicUtil.createSingletonExprFromCNF(joinEdge.getJoinQual()));
-    }
-    return joinNode;
-  }
-
-  /**
-   * Find the best join pair among all joinable operators in candidate set.
-   *
-   * @param plan a logical plan
-   * @param graph a join graph which consists of vertices and edges, where vertex is relation and
-   *              each edge is join condition.
-   * @param candidateSet candidate operators to be joined.
-   * @return The best join pair among them
-   * @throws PlanningException
-   */
-  private JoinEdge getBestPair(LogicalPlan plan, JoinGraph graph, Set<LogicalNode> candidateSet)
-      throws PlanningException {
-    double minCost = Double.MAX_VALUE;
-    JoinEdge bestJoin = null;
-
-    double minNonCrossJoinCost = Double.MAX_VALUE;
-    JoinEdge bestNonCrossJoin = null;
-
-    for (LogicalNode outer : candidateSet) {
-      for (LogicalNode inner : candidateSet) {
-        if (outer.equals(inner)) {
-          continue;
-        }
-
-        JoinEdge foundJoin = findJoin(plan, graph, outer, inner);
-        if (foundJoin == null) {
-          continue;
-        }
-        double cost = getCost(foundJoin);
-
-        if (cost < minCost) {
-          minCost = cost;
-          bestJoin = foundJoin;
-        }
-
-        // Keep the min cost join
-        // But, if there exists a qualified join, the qualified join must be chosen
-        // rather than cross join regardless of cost.
-        if (foundJoin.hasJoinQual()) {
-          if (cost < minNonCrossJoinCost) {
-            minNonCrossJoinCost = cost;
-            bestNonCrossJoin = foundJoin;
-          }
-        }
-      }
-    }
-
-    if (bestNonCrossJoin != null) {
-      return bestNonCrossJoin;
-    } else {
-      return bestJoin;
-    }
-  }
-
-  /**
-   * Find a join between two logical operator trees
-   *
-   * @return If there is no join condition between two relation, it returns NULL value.
-   */
-  private static JoinEdge findJoin(LogicalPlan plan, JoinGraph graph, LogicalNode outer, LogicalNode inner)
-      throws PlanningException {
-    JoinEdge foundJoinEdge = null;
-
-    // If outer is outer join, make edge key using all relation names in outer.
-    SortedSet<String> relationNames =
-        new TreeSet<String>(PlannerUtil.getRelationLineageWithinQueryBlock(plan, outer));
-    String outerEdgeKey = TUtil.collectionToString(relationNames, ", ");
-    for (String innerName : PlannerUtil.getRelationLineageWithinQueryBlock(plan, inner)) {
-      if (graph.hasEdge(outerEdgeKey, innerName)) {
-        JoinEdge existJoinEdge = graph.getEdge(outerEdgeKey, innerName);
-        if (foundJoinEdge == null) {
-          foundJoinEdge = new JoinEdge(existJoinEdge.getJoinType(), outer, inner,
-              existJoinEdge.getJoinQual());
-        } else {
-          foundJoinEdge.addJoinQual(AlgebraicUtil.createSingletonExprFromCNF(
-              existJoinEdge.getJoinQual()));
-        }
-      }
-    }
-    if (foundJoinEdge != null) {
-      return foundJoinEdge;
-    }
-
-    relationNames =
-        new TreeSet<String>(PlannerUtil.getRelationLineageWithinQueryBlock(plan, inner));
-    outerEdgeKey = TUtil.collectionToString(relationNames, ", ");
-    for (String outerName : PlannerUtil.getRelationLineageWithinQueryBlock(plan, outer)) {
-      if (graph.hasEdge(outerEdgeKey, outerName)) {
-        JoinEdge existJoinEdge = graph.getEdge(outerEdgeKey, outerName);
-        if (foundJoinEdge == null) {
-          foundJoinEdge = new JoinEdge(existJoinEdge.getJoinType(), inner, outer,
-              existJoinEdge.getJoinQual());
-        } else {
-          foundJoinEdge.addJoinQual(AlgebraicUtil.createSingletonExprFromCNF(
-              existJoinEdge.getJoinQual()));
-        }
-      }
-    }
-    if (foundJoinEdge != null) {
-      return foundJoinEdge;
-    }
-
-    for (String outerName : PlannerUtil.getRelationLineageWithinQueryBlock(plan, outer)) {
-      for (String innerName : PlannerUtil.getRelationLineageWithinQueryBlock(plan, inner)) {
-
-        // Find all joins between two relations and merge them into one join if possible
-        if (graph.hasEdge(outerName, innerName)) {
-          JoinEdge existJoinEdge = graph.getEdge(outerName, innerName);
-          if (foundJoinEdge == null) {
-            foundJoinEdge = new JoinEdge(existJoinEdge.getJoinType(), outer, inner,
-                existJoinEdge.getJoinQual());
-          } else {
-            foundJoinEdge.addJoinQual(AlgebraicUtil.createSingletonExprFromCNF(
-                existJoinEdge.getJoinQual()));
-          }
-        }
-      }
-    }
-
-    if (foundJoinEdge == null) {
-      foundJoinEdge = new JoinEdge(JoinType.CROSS, outer, inner);
-    }
-
-    return foundJoinEdge;
-  }
-
-  /**
-   * Getting a cost of one join
-   * @param joinEdge
-   * @return
-   */
-  public static double getCost(JoinEdge joinEdge) {
-    double filterFactor = 1;
-    if (joinEdge.hasJoinQual()) {
-      // TODO - should consider join type
-      // TODO - should statistic information obtained from query history
-      filterFactor = filterFactor * Math.pow(DEFAULT_SELECTION_FACTOR, joinEdge.getJoinQual().length);
-      return getCost(joinEdge.getLeftRelation()) * getCost(joinEdge.getRightRelation()) * filterFactor;
-    } else {
-      // make cost bigger if cross join
-      return Math.pow(getCost(joinEdge.getLeftRelation()) * getCost(joinEdge.getRightRelation()), 2);
-    }
-  }
-
-  // TODO - costs of other operator operators (e.g., group-by and sort) should be computed in proper manners.
-  public static double getCost(LogicalNode node) {
-    switch (node.getType()) {
-
-    case PROJECTION:
-      ProjectionNode projectionNode = (ProjectionNode) node;
-      return getCost(projectionNode.getChild());
-
-    case JOIN:
-      JoinNode joinNode = (JoinNode) node;
-      double filterFactor = 1;
-      if (joinNode.hasJoinQual()) {
-        filterFactor = Math.pow(DEFAULT_SELECTION_FACTOR,
-            AlgebraicUtil.toConjunctiveNormalFormArray(joinNode.getJoinQual()).length);
-        return getCost(joinNode.getLeftChild()) * getCost(joinNode.getRightChild()) * filterFactor;
-      } else {
-        return Math.pow(getCost(joinNode.getLeftChild()) * getCost(joinNode.getRightChild()), 2);
-      }
-
-    case SELECTION:
-      SelectionNode selectionNode = (SelectionNode) node;
-      return getCost(selectionNode.getChild()) *
-          Math.pow(DEFAULT_SELECTION_FACTOR, AlgebraicUtil.toConjunctiveNormalFormArray(selectionNode.getQual()).length);
-
-    case TABLE_SUBQUERY:
-      TableSubQueryNode subQueryNode = (TableSubQueryNode) node;
-      return getCost(subQueryNode.getSubQuery());
-
-    case SCAN:
-      ScanNode scanNode = (ScanNode) node;
-      if (scanNode.getTableDesc().getStats() != null) {
-        double cost = ((ScanNode)node).getTableDesc().getStats().getNumBytes();
-        return cost;
-      } else {
-        return Long.MAX_VALUE;
-      }
-
-    case UNION:
-      UnionNode unionNode = (UnionNode) node;
-      return getCost(unionNode.getLeftChild()) + getCost(unionNode.getRightChild());
-
-    case EXCEPT:
-    case INTERSECT:
-      throw new UnsupportedOperationException("getCost() does not support EXCEPT or INTERSECT yet");
-
-    default:
-      // all binary operators (join, union, except, and intersect) are handled in the above cases.
-      // So, we need to handle only unary nodes in default.
-      return getCost(((UnaryNode) node).getChild());
-    }
-  }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/b143f991/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/join/JoinEdge.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/join/JoinEdge.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/join/JoinEdge.java
deleted file mode 100644
index eabdf13..0000000
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/join/JoinEdge.java
+++ /dev/null
@@ -1,75 +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.logical.join;
-
-import com.google.common.collect.Sets;
-import org.apache.tajo.algebra.JoinType;
-import org.apache.tajo.engine.eval.EvalNode;
-import org.apache.tajo.engine.planner.logical.LogicalNode;
-import org.apache.tajo.util.TUtil;
-
-import java.util.Collections;
-import java.util.Set;
-
-public class JoinEdge {
-  private final JoinType joinType;
-  private final LogicalNode leftRelation;
-  private final LogicalNode rightRelation;
-  private final Set<EvalNode> joinQual = Sets.newHashSet();
-
-  public JoinEdge(JoinType joinType, LogicalNode leftRelation, LogicalNode rightRelation) {
-    this.joinType = joinType;
-    this.leftRelation = leftRelation;
-    this.rightRelation = rightRelation;
-  }
-
-  public JoinEdge(JoinType joinType, LogicalNode leftRelation, LogicalNode rightRelation,
-                  EvalNode ... condition) {
-    this(joinType, leftRelation, rightRelation);
-    Collections.addAll(joinQual, condition);
-  }
-
-  public JoinType getJoinType() {
-    return joinType;
-  }
-
-  public LogicalNode getLeftRelation() {
-    return leftRelation;
-  }
-
-  public LogicalNode getRightRelation() {
-    return rightRelation;
-  }
-
-  public boolean hasJoinQual() {
-    return joinQual.size() > 0;
-  }
-
-  public void addJoinQual(EvalNode joinQual) {
-    this.joinQual.add(joinQual);
-  }
-
-  public EvalNode [] getJoinQual() {
-    return joinQual.toArray(new EvalNode[joinQual.size()]);
-  }
-
-  public String toString() {
-    return leftRelation + " " + joinType + " " + rightRelation + " ON " + TUtil.collectionToString(joinQual, ", ");
-  }
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/b143f991/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/join/JoinGraph.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/join/JoinGraph.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/join/JoinGraph.java
deleted file mode 100644
index 5a861f9..0000000
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/join/JoinGraph.java
+++ /dev/null
@@ -1,154 +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.logical.join;
-
-import com.google.common.collect.Sets;
-import org.apache.tajo.algebra.JoinType;
-import org.apache.tajo.catalog.CatalogUtil;
-import org.apache.tajo.catalog.Column;
-import org.apache.tajo.engine.eval.AlgebraicUtil;
-import org.apache.tajo.engine.eval.BinaryEval;
-import org.apache.tajo.engine.eval.EvalNode;
-import org.apache.tajo.engine.eval.EvalTreeUtil;
-import org.apache.tajo.engine.planner.LogicalPlan;
-import org.apache.tajo.engine.planner.NamedExprsManager;
-import org.apache.tajo.engine.planner.PlannerUtil;
-import org.apache.tajo.engine.planner.PlanningException;
-import org.apache.tajo.engine.planner.graph.SimpleUndirectedGraph;
-import org.apache.tajo.engine.planner.logical.JoinNode;
-import org.apache.tajo.engine.planner.logical.RelationNode;
-import org.apache.tajo.util.TUtil;
-
-import java.util.*;
-
-public class JoinGraph extends SimpleUndirectedGraph<String, JoinEdge> {
-
-  private String [] guessRelationsFromJoinQual(LogicalPlan.QueryBlock block, BinaryEval joinCondition)
-      throws PlanningException {
-
-    // Note that we can guarantee that each join qual used here is a singleton.
-    // This is because we use dissect a join qual into conjunctive normal forms.
-    // In other words, each join qual has a form 'col1 = col2'.
-    Column leftExpr = EvalTreeUtil.findAllColumnRefs(joinCondition.getLeftExpr()).get(0);
-    Column rightExpr = EvalTreeUtil.findAllColumnRefs(joinCondition.getRightExpr()).get(0);
-
-    // 0 - left table, 1 - right table
-    String [] relationNames = new String[2];
-
-    NamedExprsManager namedExprsMgr = block.getNamedExprsManager();
-    if (leftExpr.hasQualifier()) {
-      relationNames[0] = leftExpr.getQualifier();
-    } else {
-      if (namedExprsMgr.isAliasedName(leftExpr.getSimpleName())) {
-        String columnName = namedExprsMgr.getOriginalName(leftExpr.getSimpleName());
-        String qualifier = CatalogUtil.extractQualifier(columnName);
-        relationNames[0] = qualifier;
-      } else {
-        // search for a relation which evaluates a right term included in a join condition
-        for (RelationNode rel : block.getRelations()) {
-          if (rel.getOutSchema().contains(leftExpr)) {
-            String qualifier = rel.getCanonicalName();
-            relationNames[0] = qualifier;
-          }
-        }
-
-        if (relationNames[0] == null) { // if not found
-          throw new PlanningException("Cannot expect a referenced relation: " + leftExpr);
-        }
-      }
-    }
-
-    if (rightExpr.hasQualifier()) {
-      relationNames[1] = rightExpr.getQualifier();
-    } else {
-      if (namedExprsMgr.isAliasedName(rightExpr.getSimpleName())) {
-        String columnName = namedExprsMgr.getOriginalName(rightExpr.getSimpleName());
-        String qualifier = CatalogUtil.extractQualifier(columnName);
-        relationNames[1] = qualifier;
-      } else {
-        // search for a relation which evaluates a right term included in a join condition
-        for (RelationNode rel : block.getRelations()) {
-          if (rel.getOutSchema().contains(rightExpr)) {
-            String qualifier = rel.getCanonicalName();
-            relationNames[1] = qualifier;
-          }
-        }
-
-        if (relationNames[1] == null) { // if not found
-          throw new PlanningException("Cannot expect a referenced relation: " + rightExpr);
-        }
-      }
-    }
-
-    return relationNames;
-  }
-
-  public Collection<EvalNode> addJoin(LogicalPlan plan, LogicalPlan.QueryBlock block,
-                                      JoinNode joinNode) throws PlanningException {
-    if (joinNode.getJoinType() == JoinType.LEFT_OUTER || joinNode.getJoinType() == JoinType.RIGHT_OUTER) {
-      JoinEdge edge = new JoinEdge(joinNode.getJoinType(),
-            joinNode.getLeftChild(), joinNode.getRightChild(), joinNode.getJoinQual());
-
-      SortedSet<String> leftNodeRelationName =
-          new TreeSet<String>(PlannerUtil.getRelationLineageWithinQueryBlock(plan, joinNode.getLeftChild()));
-      SortedSet<String> rightNodeRelationName =
-          new TreeSet<String>(PlannerUtil.getRelationLineageWithinQueryBlock(plan, joinNode.getRightChild()));
-
-      addEdge(
-          TUtil.collectionToString(leftNodeRelationName, ", "),
-          TUtil.collectionToString(rightNodeRelationName, ", "),
-          edge);
-
-      Set<EvalNode> allInOneCnf = new HashSet<EvalNode>();
-      allInOneCnf.add(joinNode.getJoinQual());
-
-      return allInOneCnf;
-    } else {
-      Set<EvalNode> cnf = Sets.newHashSet(AlgebraicUtil.toConjunctiveNormalFormArray(joinNode.getJoinQual()));
-
-      for (EvalNode singleQual : cnf) {
-        if (EvalTreeUtil.isJoinQual(block, singleQual, true)) {
-          String[] relations = guessRelationsFromJoinQual(block, (BinaryEval) singleQual);
-          String leftExprRelName = relations[0];
-          String rightExprRelName = relations[1];
-
-          Collection<String> leftLineage = PlannerUtil.getRelationLineageWithinQueryBlock(plan, joinNode.getLeftChild());
-
-          boolean isLeftExprForLeftTable = leftLineage.contains(leftExprRelName);
-
-          JoinEdge edge = getEdge(leftExprRelName, rightExprRelName);
-          if (edge != null) {
-            edge.addJoinQual(singleQual);
-          } else {
-            if (isLeftExprForLeftTable) {
-              edge = new JoinEdge(joinNode.getJoinType(),
-                  block.getRelation(leftExprRelName), block.getRelation(rightExprRelName), singleQual);
-              addEdge(leftExprRelName, rightExprRelName, edge);
-            } else {
-              edge = new JoinEdge(joinNode.getJoinType(),
-                  block.getRelation(rightExprRelName), block.getRelation(leftExprRelName), singleQual);
-              addEdge(rightExprRelName, leftExprRelName, edge);
-            }
-          }
-        }
-      }
-      return cnf;
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/b143f991/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/join/JoinOrderAlgorithm.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/join/JoinOrderAlgorithm.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/join/JoinOrderAlgorithm.java
deleted file mode 100644
index eafa671..0000000
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/join/JoinOrderAlgorithm.java
+++ /dev/null
@@ -1,46 +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.logical.join;
-
-import org.apache.hadoop.classification.InterfaceStability;
-import org.apache.tajo.engine.planner.LogicalPlan;
-import org.apache.tajo.engine.planner.PlanningException;
-
-import java.util.Set;
-
-/**
- * An interface for join order algorithms
- */
-@InterfaceStability.Evolving
-public interface JoinOrderAlgorithm {
-
-  /**
-   *
-   * @param plan
-   * @param block
-   * @param joinGraph A join graph represents join conditions and their connections among relations.
-   *                  Given a graph, each vertex represents a relation, and each edge contains a join condition.
-   *                  A join graph does not contain relations that do not have any corresponding join condition.
-   * @param relationsWithoutQual The names of relations that do not have any corresponding join condition.
-   * @return
-   * @throws PlanningException
-   */
-  FoundJoinOrder findBestOrder(LogicalPlan plan, LogicalPlan.QueryBlock block, JoinGraph joinGraph,
-                               Set<String> relationsWithoutQual) throws PlanningException;
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/b143f991/tajo-core/src/main/java/org/apache/tajo/engine/planner/nameresolver/NameResolver.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/nameresolver/NameResolver.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/nameresolver/NameResolver.java
deleted file mode 100644
index aee5d43..0000000
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/nameresolver/NameResolver.java
+++ /dev/null
@@ -1,291 +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.nameresolver;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import org.apache.tajo.algebra.ColumnReferenceExpr;
-import org.apache.tajo.catalog.CatalogUtil;
-import org.apache.tajo.catalog.Column;
-import org.apache.tajo.catalog.Schema;
-import org.apache.tajo.engine.exception.AmbiguousFieldException;
-import org.apache.tajo.engine.exception.NoSuchColumnException;
-import org.apache.tajo.engine.exception.VerifyException;
-import org.apache.tajo.engine.planner.LogicalPlan;
-import org.apache.tajo.engine.planner.PlanningException;
-import org.apache.tajo.engine.planner.logical.RelationNode;
-import org.apache.tajo.util.Pair;
-import org.apache.tajo.util.TUtil;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * NameResolver utility
- */
-public abstract class NameResolver {
-
-  public static Map<NameResolvingMode, NameResolver> resolverMap = Maps.newHashMap();
-
-  static {
-    resolverMap.put(NameResolvingMode.RELS_ONLY, new ResolverByRels());
-    resolverMap.put(NameResolvingMode.RELS_AND_SUBEXPRS, new ResolverByRelsAndSubExprs());
-    resolverMap.put(NameResolvingMode.SUBEXPRS_AND_RELS, new ResolverBySubExprsAndRels());
-    resolverMap.put(NameResolvingMode.LEGACY, new ResolverByLegacy());
-  }
-
-  abstract Column resolve(LogicalPlan plan, LogicalPlan.QueryBlock block, ColumnReferenceExpr columnRef)
-  throws PlanningException;
-
-  /**
-   * Try to find the database name
-   *
-   * @param block the current block
-   * @param tableName The table name
-   * @return The found database name
-   * @throws PlanningException
-   */
-  public static String resolveDatabase(LogicalPlan.QueryBlock block, String tableName) throws PlanningException {
-    List<String> found = new ArrayList<String>();
-    for (RelationNode relation : block.getRelations()) {
-      // check alias name or table name
-      if (CatalogUtil.extractSimpleName(relation.getCanonicalName()).equals(tableName) ||
-          CatalogUtil.extractSimpleName(relation.getTableName()).equals(tableName)) {
-        // obtain the database name
-        found.add(CatalogUtil.extractQualifier(relation.getTableName()));
-      }
-    }
-
-    if (found.size() == 0) {
-      return null;
-    } else if (found.size() > 1) {
-      throw new PlanningException("Ambiguous table name \"" + tableName + "\"");
-    }
-
-    return found.get(0);
-  }
-
-  public static Column resolve(LogicalPlan plan, LogicalPlan.QueryBlock block, ColumnReferenceExpr column,
-                        NameResolvingMode mode) throws PlanningException {
-    if (!resolverMap.containsKey(mode)) {
-      throw new PlanningException("Unsupported name resolving level: " + mode.name());
-    }
-    return resolverMap.get(mode).resolve(plan, block, column);
-  }
-
-  /**
-   * Try to find a column from all relations within a given query block.
-   * If a given column reference is qualified, it tries to resolve the name
-   * from only the relation corresponding to the qualifier.
-   *
-   * @param plan The logical plan
-   * @param block The current query block
-   * @param columnRef The column reference to be found
-   * @return The found column
-   * @throws PlanningException
-   */
-  static Column resolveFromRelsWithinBlock(LogicalPlan plan, LogicalPlan.QueryBlock block,
-                                                  ColumnReferenceExpr columnRef) throws PlanningException {
-    String qualifier;
-    String canonicalName;
-
-    if (columnRef.hasQualifier()) {
-      Pair<String, String> normalized = normalizeQualifierAndCanonicalName(block, columnRef);
-      qualifier = normalized.getFirst();
-      canonicalName = normalized.getSecond();
-
-      RelationNode relationOp = block.getRelation(qualifier);
-
-      // If we cannot find any relation against a qualified column name
-      if (relationOp == null) {
-        throw null;
-      }
-
-      // Please consider a query case:
-      // select lineitem.l_orderkey from lineitem a order by lineitem.l_orderkey;
-      //
-      // The relation lineitem is already renamed to "a", but lineitem.l_orderkey still can be used.
-      // The below code makes it available. Otherwise, it cannot find any match in the relation schema.
-      if (block.isAlreadyRenamedTableName(CatalogUtil.extractQualifier(canonicalName))) {
-        canonicalName =
-            CatalogUtil.buildFQName(relationOp.getCanonicalName(), CatalogUtil.extractSimpleName(canonicalName));
-      }
-
-      Schema schema = relationOp.getTableSchema();
-      Column column = schema.getColumn(canonicalName);
-
-      return column;
-    } else {
-      return resolveFromAllRelsInBlock(block, columnRef);
-    }
-  }
-
-  /**
-   * Try to find the column from the current node and child node. It can find subexprs generated from the optimizer.
-   *
-   * @param block The current query block
-   * @param columnRef The column reference to be found
-   * @return The found column
-   */
-  static Column resolveFromCurrentAndChildNode(LogicalPlan.QueryBlock block, ColumnReferenceExpr columnRef)
-      throws NoSuchColumnException {
-
-    if (block.getCurrentNode() != null && block.getCurrentNode().getInSchema() != null) {
-      Column found = block.getCurrentNode().getInSchema().getColumn(columnRef.getCanonicalName());
-      if (found != null) {
-        return found;
-      } else if (block.getLatestNode() != null) {
-        found = block.getLatestNode().getOutSchema().getColumn(columnRef.getName());
-        if (found != null) {
-          return found;
-        }
-      }
-    }
-    return null;
-  }
-
-  /**
-   * It tries to find a full qualified column name from all relations in the current block.
-   *
-   * @param block The current query block
-   * @param columnRef The column reference to be found
-   * @return The found column
-   */
-  static Column resolveFromAllRelsInBlock(LogicalPlan.QueryBlock block,
-                                          ColumnReferenceExpr columnRef) throws VerifyException {
-    List<Column> candidates = TUtil.newList();
-
-    for (RelationNode rel : block.getRelations()) {
-      Column found = rel.getTableSchema().getColumn(columnRef.getName());
-      if (found != null) {
-        candidates.add(found);
-      }
-    }
-
-    if (!candidates.isEmpty()) {
-      return ensureUniqueColumn(candidates);
-    } else {
-      return null;
-    }
-  }
-
-  /**
-   * Trying to find a column from all relations in other blocks
-   *
-   * @param plan The logical plan
-   * @param columnRef The column reference to be found
-   * @return The found column
-   */
-  static Column resolveFromAllRelsInAllBlocks(LogicalPlan plan, ColumnReferenceExpr columnRef) throws VerifyException {
-
-    List<Column> candidates = Lists.newArrayList();
-
-    // from all relations of all query blocks
-    for (LogicalPlan.QueryBlock eachBlock : plan.getQueryBlocks()) {
-
-      for (RelationNode rel : eachBlock.getRelations()) {
-        Column found = rel.getTableSchema().getColumn(columnRef.getName());
-        if (found != null) {
-          candidates.add(found);
-        }
-      }
-    }
-
-    if (!candidates.isEmpty()) {
-      return NameResolver.ensureUniqueColumn(candidates);
-    } else {
-      return null;
-    }
-  }
-
-  /**
-   * Try to find a column from the final schema of the current block.
-   *
-   * @param block The current query block
-   * @param columnRef The column reference to be found
-   * @return The found column
-   */
-  static Column resolveAliasedName(LogicalPlan.QueryBlock block, ColumnReferenceExpr columnRef) throws VerifyException {
-    List<Column> candidates = Lists.newArrayList();
-
-    if (block.getSchema() != null) {
-      Column found = block.getSchema().getColumn(columnRef.getName());
-      if (found != null) {
-        candidates.add(found);
-      }
-    }
-
-    if (!candidates.isEmpty()) {
-      return NameResolver.ensureUniqueColumn(candidates);
-    } else {
-      return null;
-    }
-  }
-
-  /**
-   * It returns a pair of names, which the first value is ${database}.${table} and the second value
-   * is a simple column name.
-   *
-   * @param block The current block
-   * @param columnRef The column name
-   * @return A pair of normalized qualifier and column name
-   * @throws PlanningException
-   */
-  static Pair<String, String> normalizeQualifierAndCanonicalName(LogicalPlan.QueryBlock block,
-                                                                 ColumnReferenceExpr columnRef)
-      throws PlanningException {
-    String qualifier;
-    String canonicalName;
-
-    if (CatalogUtil.isFQTableName(columnRef.getQualifier())) {
-      qualifier = columnRef.getQualifier();
-      canonicalName = columnRef.getCanonicalName();
-    } else {
-      String resolvedDatabaseName = resolveDatabase(block, columnRef.getQualifier());
-      if (resolvedDatabaseName == null) {
-        throw new NoSuchColumnException(columnRef.getQualifier());
-      }
-      qualifier = CatalogUtil.buildFQName(resolvedDatabaseName, columnRef.getQualifier());
-      canonicalName = CatalogUtil.buildFQName(qualifier, columnRef.getName());
-    }
-
-    return new Pair<String, String>(qualifier, canonicalName);
-  }
-
-  static Column ensureUniqueColumn(List<Column> candidates) throws VerifyException {
-    if (candidates.size() == 1) {
-      return candidates.get(0);
-    } else if (candidates.size() > 2) {
-      StringBuilder sb = new StringBuilder();
-      boolean first = true;
-      for (Column column : candidates) {
-        if (first) {
-          first = false;
-        } else {
-          sb.append(", ");
-        }
-        sb.append(column);
-      }
-      throw new AmbiguousFieldException("Ambiguous Column Name: " + sb.toString());
-    } else {
-      return null;
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/b143f991/tajo-core/src/main/java/org/apache/tajo/engine/planner/nameresolver/NameResolvingMode.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/nameresolver/NameResolvingMode.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/nameresolver/NameResolvingMode.java
deleted file mode 100644
index dcbb5f1..0000000
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/nameresolver/NameResolvingMode.java
+++ /dev/null
@@ -1,80 +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.nameresolver;
-
-/**
- *
- * <h2>Motivation</h2>
- *
- * Please take a look at the following example query:
- *
- *  <pre>
- *   select (l_orderkey + l_orderkey) l_orderkey from lineitem where l_orderkey > 2 order by l_orderkey;
- * </pre>
- *
- * Although <code>l_orderkey</code> seems to be ambiguous, the above usages are available in commercial DBMSs.
- * In order to eliminate the ambiguity, Tajo follows the behaviors of PostgreSQL.
- *
- * <h2>Resolving Modes</h2>
- *
- * From the behaviors of PostgreSQL, we found that there are three kinds of name resolving modes.
- * Each definition is as follows:
- *
- * <ul>
- *   <li><b>RELS_ONLY</b> finds a column from the relations in the current block.
- *  <li><b>RELS_AND_SUBEXPRS</b> finds a column from the all relations in the current block and
- *  from aliased temporal fields; a temporal field means an explicitly aliased expression. If there are duplicated
- *  columns in the relation and temporal fields, this level firstly chooses the field in a relation.</li>
- *  <li><b>SUBEXPRS_AND_RELS</b> is very similar to <code>RELS_AND_SUBEXPRS</code>. The main difference is that it
- *  firstly chooses an aliased temporal field instead of the fields in a relation.</li>
- * </ul>
- *
- * <h2>The relationship between resolving modes and operators</h3>
- *
- * <ul>
- *   <li>fields in select list and LIMIT are resolved in the REL_ONLY mode.</li>
- *   <li>fields in WHERE clause are resolved in the RELS_AND_SUBEXPRS mode.</li>
- *   <li>fields in GROUP BY, HAVING, and ORDER BY are resolved in the SUBEXPRS_AND_RELS mode.</li>
- * </ul>
- *
- * <h2>Example</h2>
- *
- * Please revisit the aforementioned example:
- *
- * <pre>
- *   select (l_orderkey + l_orderkey) l_orderkey from lineitem where l_orderkey > 2 order by l_orderkey;
- * </pre>
- *
- * With the above rules and the relationship between modes and operators, we can easily identify which reference
- * points to which field.
- * <ol>
- *   <li><code>l_orderkey</code> included in <code>(l_orderkey + l_orderkey)</code> points to the field
- *   in the relation <code>lineitem</code>.</li>
- *   <li><code>l_orderkey</code> included in WHERE clause also points to the field in the relation
- *   <code>lineitem</code>.</li>
- *   <li><code>l_orderkey</code> included in ORDER BY clause points to the temporal field
- *   <code>(l_orderkey + l_orderkey)</code>.</li>
- * </ol>
- */
-public enum NameResolvingMode {
-  RELS_ONLY,          // finding from only relations
-  RELS_AND_SUBEXPRS,  // finding from relations and subexprs in a place
-  SUBEXPRS_AND_RELS,  // finding from subexprs and relations in a place
-  LEGACY              // Finding in a legacy manner (globally)
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/b143f991/tajo-core/src/main/java/org/apache/tajo/engine/planner/nameresolver/ResolverByLegacy.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/nameresolver/ResolverByLegacy.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/nameresolver/ResolverByLegacy.java
deleted file mode 100644
index 396bc1b..0000000
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/nameresolver/ResolverByLegacy.java
+++ /dev/null
@@ -1,126 +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.nameresolver;
-
-import org.apache.tajo.algebra.ColumnReferenceExpr;
-import org.apache.tajo.catalog.CatalogUtil;
-import org.apache.tajo.catalog.Column;
-import org.apache.tajo.catalog.Schema;
-import org.apache.tajo.engine.exception.NoSuchColumnException;
-import org.apache.tajo.engine.planner.LogicalPlan;
-import org.apache.tajo.engine.planner.PlanningException;
-import org.apache.tajo.engine.planner.logical.LogicalNode;
-import org.apache.tajo.engine.planner.logical.NodeType;
-import org.apache.tajo.engine.planner.logical.RelationNode;
-import org.apache.tajo.util.Pair;
-import org.apache.tajo.util.TUtil;
-
-import java.util.List;
-
-public class ResolverByLegacy extends NameResolver {
-  @Override
-  public Column resolve(LogicalPlan plan, LogicalPlan.QueryBlock block, ColumnReferenceExpr columnRef)
-      throws PlanningException {
-
-    if (columnRef.hasQualifier()) {
-      return resolveColumnWithQualifier(plan, block, columnRef);
-    } else {
-      return resolveColumnWithoutQualifier(plan, block, columnRef);
-    }
-  }
-
-  private static Column resolveColumnWithQualifier(LogicalPlan plan, LogicalPlan.QueryBlock block,
-                                                   ColumnReferenceExpr columnRef) throws PlanningException {
-    final String qualifier;
-    String canonicalName;
-    final String qualifiedName;
-
-    Pair<String, String> normalized = normalizeQualifierAndCanonicalName(block, columnRef);
-    qualifier = normalized.getFirst();
-    canonicalName = normalized.getSecond();
-    qualifiedName = CatalogUtil.buildFQName(qualifier, columnRef.getName());
-
-    Column found = resolveFromRelsWithinBlock(plan, block, columnRef);
-    if (found == null) {
-      throw new NoSuchColumnException(columnRef.getCanonicalName());
-    }
-
-    // If code reach here, a column is found.
-    // But, it may be aliased from bottom logical node.
-    // If the column is aliased, the found name may not be used in upper node.
-
-    // Here, we try to check if column reference is already aliased.
-    // If so, it replaces the name with aliased name.
-    LogicalNode currentNode = block.getCurrentNode();
-
-    // The condition (currentNode.getInSchema().contains(column)) means
-    // the column can be used at the current node. So, we don't need to find aliase name.
-    Schema currentNodeSchema = null;
-    if (currentNode != null) {
-      if (currentNode instanceof RelationNode) {
-        currentNodeSchema = ((RelationNode) currentNode).getTableSchema();
-      } else {
-        currentNodeSchema = currentNode.getInSchema();
-      }
-    }
-
-    if (currentNode != null && !currentNodeSchema.contains(found)
-        && currentNode.getType() != NodeType.TABLE_SUBQUERY) {
-      List<Column> candidates = TUtil.newList();
-      if (block.getNamedExprsManager().isAliased(qualifiedName)) {
-        String alias = block.getNamedExprsManager().getAlias(canonicalName);
-        found = resolve(plan, block, new ColumnReferenceExpr(alias), NameResolvingMode.LEGACY);
-        if (found != null) {
-          candidates.add(found);
-        }
-      }
-      if (!candidates.isEmpty()) {
-        return ensureUniqueColumn(candidates);
-      }
-    }
-
-    return found;
-  }
-
-  static Column resolveColumnWithoutQualifier(LogicalPlan plan, LogicalPlan.QueryBlock block,
-                                                     ColumnReferenceExpr columnRef)throws PlanningException {
-
-    Column found = resolveFromAllRelsInBlock(block, columnRef);
-    if (found != null) {
-      return found;
-    }
-
-    found = resolveAliasedName(block, columnRef);
-    if (found != null) {
-      return found;
-    }
-
-    found = resolveFromCurrentAndChildNode(block, columnRef);
-    if (found != null) {
-      return found;
-    }
-
-    found = resolveFromAllRelsInAllBlocks(plan, columnRef);
-    if (found != null) {
-      return found;
-    }
-
-    throw new NoSuchColumnException("ERROR: no such a column name "+ columnRef.getCanonicalName());
-  }
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/b143f991/tajo-core/src/main/java/org/apache/tajo/engine/planner/nameresolver/ResolverByRels.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/nameresolver/ResolverByRels.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/nameresolver/ResolverByRels.java
deleted file mode 100644
index 9713e52..0000000
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/nameresolver/ResolverByRels.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.planner.nameresolver;
-
-import org.apache.tajo.algebra.ColumnReferenceExpr;
-import org.apache.tajo.catalog.Column;
-import org.apache.tajo.engine.exception.NoSuchColumnException;
-import org.apache.tajo.engine.planner.LogicalPlan;
-import org.apache.tajo.engine.planner.PlanningException;
-
-public class ResolverByRels extends NameResolver {
-  @Override
-  public Column resolve(LogicalPlan plan, LogicalPlan.QueryBlock block, ColumnReferenceExpr columnRef)
-      throws PlanningException {
-
-    Column column = resolveFromRelsWithinBlock(plan, block, columnRef);
-    if (column == null) {
-      throw new NoSuchColumnException(columnRef.getCanonicalName());
-    }
-    return column;
-  }
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/b143f991/tajo-core/src/main/java/org/apache/tajo/engine/planner/nameresolver/ResolverByRelsAndSubExprs.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/nameresolver/ResolverByRelsAndSubExprs.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/nameresolver/ResolverByRelsAndSubExprs.java
deleted file mode 100644
index 7ca3c53..0000000
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/nameresolver/ResolverByRelsAndSubExprs.java
+++ /dev/null
@@ -1,42 +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.nameresolver;
-
-import org.apache.tajo.algebra.ColumnReferenceExpr;
-import org.apache.tajo.catalog.Column;
-import org.apache.tajo.engine.exception.NoSuchColumnException;
-import org.apache.tajo.engine.planner.LogicalPlan;
-import org.apache.tajo.engine.planner.PlanningException;
-
-public class ResolverByRelsAndSubExprs extends NameResolver {
-  @Override
-  public Column resolve(LogicalPlan plan, LogicalPlan.QueryBlock block, ColumnReferenceExpr columnRef)
-      throws PlanningException {
-
-    Column column = resolveFromRelsWithinBlock(plan, block, columnRef);
-    if (column == null) {
-      column =  resolveFromCurrentAndChildNode(block, columnRef);
-    }
-
-    if (column == null) {
-      throw new NoSuchColumnException(columnRef.getCanonicalName());
-    }
-    return column;
-  }
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/b143f991/tajo-core/src/main/java/org/apache/tajo/engine/planner/nameresolver/ResolverBySubExprsAndRels.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/nameresolver/ResolverBySubExprsAndRels.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/nameresolver/ResolverBySubExprsAndRels.java
deleted file mode 100644
index 7337ece..0000000
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/nameresolver/ResolverBySubExprsAndRels.java
+++ /dev/null
@@ -1,42 +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.nameresolver;
-
-import org.apache.tajo.algebra.ColumnReferenceExpr;
-import org.apache.tajo.catalog.Column;
-import org.apache.tajo.engine.exception.NoSuchColumnException;
-import org.apache.tajo.engine.planner.LogicalPlan;
-import org.apache.tajo.engine.planner.PlanningException;
-
-public class ResolverBySubExprsAndRels extends NameResolver {
-  @Override
-  public Column resolve(LogicalPlan plan, LogicalPlan.QueryBlock block, ColumnReferenceExpr columnRef)
-      throws PlanningException {
-
-    Column column = resolveFromCurrentAndChildNode(block, columnRef);
-    if (column == null) {
-      column = resolveFromRelsWithinBlock(plan, block, columnRef);
-    }
-
-    if (column == null) {
-      throw new NoSuchColumnException(columnRef.getCanonicalName());
-    }
-    return column;
-  }
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/b143f991/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/AggregationExec.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/AggregationExec.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/AggregationExec.java
index 2a671e6..8c484a0 100644
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/AggregationExec.java
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/AggregationExec.java
@@ -20,8 +20,8 @@ package org.apache.tajo.engine.planner.physical;
 
 import org.apache.tajo.catalog.Column;
 import org.apache.tajo.catalog.Schema;
-import org.apache.tajo.engine.eval.AggregationFunctionCallEval;
-import org.apache.tajo.engine.planner.logical.GroupbyNode;
+import org.apache.tajo.plan.expr.AggregationFunctionCallEval;
+import org.apache.tajo.plan.logical.GroupbyNode;
 import org.apache.tajo.worker.TaskAttemptContext;
 
 import java.io.IOException;

http://git-wip-us.apache.org/repos/asf/tajo/blob/b143f991/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/BNLJoinExec.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/BNLJoinExec.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/BNLJoinExec.java
index 91cefa1..117b04c 100644
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/BNLJoinExec.java
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/BNLJoinExec.java
@@ -18,10 +18,10 @@
 
 package org.apache.tajo.engine.planner.physical;
 
-import org.apache.tajo.engine.eval.EvalNode;
-import org.apache.tajo.engine.planner.PlannerUtil;
 import org.apache.tajo.engine.planner.Projector;
-import org.apache.tajo.engine.planner.logical.JoinNode;
+import org.apache.tajo.plan.util.PlannerUtil;
+import org.apache.tajo.plan.expr.EvalNode;
+import org.apache.tajo.plan.logical.JoinNode;
 import org.apache.tajo.storage.FrameTuple;
 import org.apache.tajo.storage.Tuple;
 import org.apache.tajo.storage.VTuple;

http://git-wip-us.apache.org/repos/asf/tajo/blob/b143f991/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/BSTIndexScanExec.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/BSTIndexScanExec.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/BSTIndexScanExec.java
index 51f70a0..f699607 100644
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/BSTIndexScanExec.java
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/BSTIndexScanExec.java
@@ -22,9 +22,9 @@ import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.io.IOUtils;
 import org.apache.tajo.catalog.Schema;
 import org.apache.tajo.datum.Datum;
-import org.apache.tajo.engine.eval.EvalNode;
 import org.apache.tajo.engine.planner.Projector;
-import org.apache.tajo.engine.planner.logical.ScanNode;
+import org.apache.tajo.plan.expr.EvalNode;
+import org.apache.tajo.plan.logical.ScanNode;
 import org.apache.tajo.storage.*;
 import org.apache.tajo.storage.fragment.FileFragment;
 import org.apache.tajo.storage.index.bst.BSTIndex;

http://git-wip-us.apache.org/repos/asf/tajo/blob/b143f991/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/ColPartitionStoreExec.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/ColPartitionStoreExec.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/ColPartitionStoreExec.java
index a072904..ec239de 100644
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/ColPartitionStoreExec.java
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/ColPartitionStoreExec.java
@@ -30,10 +30,10 @@ import org.apache.tajo.catalog.Column;
 import org.apache.tajo.catalog.Schema;
 import org.apache.tajo.catalog.TableMeta;
 import org.apache.tajo.catalog.statistics.TableStats;
-import org.apache.tajo.engine.planner.logical.CreateTableNode;
-import org.apache.tajo.engine.planner.logical.InsertNode;
-import org.apache.tajo.engine.planner.logical.NodeType;
-import org.apache.tajo.engine.planner.logical.StoreTableNode;
+import org.apache.tajo.plan.logical.CreateTableNode;
+import org.apache.tajo.plan.logical.InsertNode;
+import org.apache.tajo.plan.logical.NodeType;
+import org.apache.tajo.plan.logical.StoreTableNode;
 import org.apache.tajo.storage.Appender;
 import org.apache.tajo.storage.StorageManager;
 import org.apache.tajo.storage.StorageUtil;

http://git-wip-us.apache.org/repos/asf/tajo/blob/b143f991/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/DistinctGroupbyFirstAggregationExec.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/DistinctGroupbyFirstAggregationExec.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/DistinctGroupbyFirstAggregationExec.java
index 7201ed4..bd24fa3 100644
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/DistinctGroupbyFirstAggregationExec.java
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/DistinctGroupbyFirstAggregationExec.java
@@ -24,10 +24,10 @@ import org.apache.tajo.catalog.Column;
 import org.apache.tajo.catalog.statistics.TableStats;
 import org.apache.tajo.datum.Int2Datum;
 import org.apache.tajo.datum.NullDatum;
-import org.apache.tajo.engine.eval.AggregationFunctionCallEval;
-import org.apache.tajo.engine.function.FunctionContext;
-import org.apache.tajo.engine.planner.logical.DistinctGroupbyNode;
-import org.apache.tajo.engine.planner.logical.GroupbyNode;
+import org.apache.tajo.plan.expr.AggregationFunctionCallEval;
+import org.apache.tajo.plan.function.FunctionContext;
+import org.apache.tajo.plan.logical.DistinctGroupbyNode;
+import org.apache.tajo.plan.logical.GroupbyNode;
 import org.apache.tajo.storage.Tuple;
 import org.apache.tajo.storage.VTuple;
 import org.apache.tajo.worker.TaskAttemptContext;

http://git-wip-us.apache.org/repos/asf/tajo/blob/b143f991/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/DistinctGroupbyHashAggregationExec.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/DistinctGroupbyHashAggregationExec.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/DistinctGroupbyHashAggregationExec.java
index 3fac509..eac5c70 100644
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/DistinctGroupbyHashAggregationExec.java
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/DistinctGroupbyHashAggregationExec.java
@@ -23,10 +23,10 @@ import org.apache.tajo.catalog.Schema;
 import org.apache.tajo.catalog.statistics.TableStats;
 import org.apache.tajo.datum.DatumFactory;
 import org.apache.tajo.datum.NullDatum;
-import org.apache.tajo.engine.eval.AggregationFunctionCallEval;
-import org.apache.tajo.engine.function.FunctionContext;
-import org.apache.tajo.engine.planner.logical.DistinctGroupbyNode;
-import org.apache.tajo.engine.planner.logical.GroupbyNode;
+import org.apache.tajo.plan.expr.AggregationFunctionCallEval;
+import org.apache.tajo.plan.function.FunctionContext;
+import org.apache.tajo.plan.logical.DistinctGroupbyNode;
+import org.apache.tajo.plan.logical.GroupbyNode;
 import org.apache.tajo.storage.Tuple;
 import org.apache.tajo.storage.VTuple;
 import org.apache.tajo.worker.TaskAttemptContext;

http://git-wip-us.apache.org/repos/asf/tajo/blob/b143f991/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/DistinctGroupbySecondAggregationExec.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/DistinctGroupbySecondAggregationExec.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/DistinctGroupbySecondAggregationExec.java
index bc8885f..383ccd3 100644
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/DistinctGroupbySecondAggregationExec.java
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/DistinctGroupbySecondAggregationExec.java
@@ -18,22 +18,22 @@
 
 package org.apache.tajo.engine.planner.physical;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.tajo.catalog.Column;
-import org.apache.tajo.engine.eval.AggregationFunctionCallEval;
-import org.apache.tajo.engine.function.FunctionContext;
-import org.apache.tajo.engine.planner.logical.DistinctGroupbyNode;
-import org.apache.tajo.engine.planner.logical.GroupbyNode;
-import org.apache.tajo.storage.Tuple;
-import org.apache.tajo.storage.VTuple;
-import org.apache.tajo.worker.TaskAttemptContext;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+  import org.apache.commons.logging.Log;
+  import org.apache.commons.logging.LogFactory;
+  import org.apache.tajo.catalog.Column;
+  import org.apache.tajo.plan.expr.AggregationFunctionCallEval;
+  import org.apache.tajo.plan.function.FunctionContext;
+  import org.apache.tajo.plan.logical.DistinctGroupbyNode;
+  import org.apache.tajo.plan.logical.GroupbyNode;
+  import org.apache.tajo.storage.Tuple;
+  import org.apache.tajo.storage.VTuple;
+  import org.apache.tajo.worker.TaskAttemptContext;
+
+  import java.io.IOException;
+  import java.util.ArrayList;
+  import java.util.HashSet;
+  import java.util.List;
+  import java.util.Set;
 
 /**
  * This class adjusts shuffle columns between DistinctGroupbyFirstAggregationExec and

http://git-wip-us.apache.org/repos/asf/tajo/blob/b143f991/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/DistinctGroupbySortAggregationExec.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/DistinctGroupbySortAggregationExec.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/DistinctGroupbySortAggregationExec.java
index b786672..06b241c 100644
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/DistinctGroupbySortAggregationExec.java
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/DistinctGroupbySortAggregationExec.java
@@ -22,8 +22,8 @@ import org.apache.tajo.catalog.statistics.TableStats;
 import org.apache.tajo.common.TajoDataTypes;
 import org.apache.tajo.datum.DatumFactory;
 import org.apache.tajo.datum.NullDatum;
-import org.apache.tajo.engine.planner.logical.DistinctGroupbyNode;
-import org.apache.tajo.engine.planner.logical.GroupbyNode;
+import org.apache.tajo.plan.logical.DistinctGroupbyNode;
+import org.apache.tajo.plan.logical.GroupbyNode;
 import org.apache.tajo.storage.Tuple;
 import org.apache.tajo.storage.VTuple;
 import org.apache.tajo.worker.TaskAttemptContext;