tajo-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hyun...@apache.org
Subject [2/2] git commit: TAJO-614: Explaning a logical node should use ExplainLogicalPlanVisitor.
Date Fri, 21 Feb 2014 06:26:12 GMT
TAJO-614: Explaning a logical node should use ExplainLogicalPlanVisitor.


Project: http://git-wip-us.apache.org/repos/asf/incubator-tajo/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tajo/commit/5fb959b7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tajo/tree/5fb959b7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tajo/diff/5fb959b7

Branch: refs/heads/branch-0.8.0
Commit: 5fb959b7c3fac2feb696442589f4acfce7d77261
Parents: e2f4798
Author: Hyunsik Choi <hyunsik@apache.org>
Authored: Fri Feb 21 15:25:33 2014 +0900
Committer: Hyunsik Choi <hyunsik@apache.org>
Committed: Fri Feb 21 15:25:33 2014 +0900

----------------------------------------------------------------------
 CHANGES.txt                                     |   3 +
 .../planner/ExplainLogicalPlanVisitor.java      |  13 +-
 .../tajo/engine/planner/ExprsVerifier.java      |   2 +-
 .../apache/tajo/engine/planner/InsertNode.java  | 199 -------------------
 .../apache/tajo/engine/planner/LogicalPlan.java |  35 +++-
 .../engine/planner/LogicalPlanPreprocessor.java |  29 +--
 .../tajo/engine/planner/LogicalPlanner.java     |  20 +-
 .../engine/planner/PhysicalPlannerImpl.java     |  18 +-
 .../apache/tajo/engine/planner/PlannerUtil.java |  23 +++
 .../engine/planner/global/GlobalPlanner.java    |   4 +-
 .../tajo/engine/planner/global/MasterPlan.java  |  10 +-
 .../engine/planner/logical/CreateTableNode.java |  15 +-
 .../engine/planner/logical/DropTableNode.java   |   2 +-
 .../engine/planner/logical/EvalExprNode.java    |  16 +-
 .../tajo/engine/planner/logical/ExceptNode.java |  13 +-
 .../engine/planner/logical/GroupbyNode.java     |  31 +--
 .../tajo/engine/planner/logical/HavingNode.java |   8 +-
 .../engine/planner/logical/IndexScanNode.java   |   3 +-
 .../tajo/engine/planner/logical/InsertNode.java | 182 +++++++++++++++++
 .../engine/planner/logical/IntersectNode.java   |  13 +-
 .../tajo/engine/planner/logical/JoinNode.java   |  36 +---
 .../tajo/engine/planner/logical/LimitNode.java  |   8 +-
 .../engine/planner/logical/LogicalNode.java     |   7 +-
 .../tajo/engine/planner/logical/NodeType.java   |   2 -
 .../logical/PartitionedTableScanNode.java       |  64 ++----
 .../planner/logical/PersistentStoreNode.java    |   2 +-
 .../engine/planner/logical/ProjectionNode.java  |  22 +-
 .../engine/planner/logical/RelationNode.java    |   2 +-
 .../tajo/engine/planner/logical/ScanNode.java   |  48 ++---
 .../engine/planner/logical/SelectionNode.java   |   8 +-
 .../planner/logical/ShuffleFileWriteNode.java   |  24 +--
 .../engine/planner/logical/StoreIndexNode.java  |  27 ---
 .../engine/planner/logical/StoreTableNode.java  |  19 +-
 .../planner/logical/TableSubQueryNode.java      |  16 +-
 .../tajo/engine/planner/logical/UnionNode.java  |   4 -
 .../join/GreedyHeuristicJoinOrderAlgorithm.java |   9 +-
 .../planner/physical/ColPartitionStoreExec.java |   2 +-
 .../engine/planner/physical/StoreTableExec.java |   2 +-
 .../rewrite/PartitionedTableRewriter.java       |   4 +-
 .../apache/tajo/master/querymaster/Query.java   |   2 +-
 .../tajo/engine/planner/TestLogicalNode.java    |  12 +-
 .../planner/physical/TestPhysicalPlanner.java   |   2 +-
 42 files changed, 407 insertions(+), 554 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 0be4426..aca69b0 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -130,6 +130,9 @@ Release 0.8.0 - unreleased
 
   IMPROVEMENTS
 
+    TAJO-614: Explaning a logical node should use ExplainLogicalPlanVisitor.
+    (hyunsik)
+
     TAJO-610: Refactor Column class. (hyunsik)
 
     TAJO-601: Improve distinct aggregation query processing. (hyunsik)

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/ExplainLogicalPlanVisitor.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/ExplainLogicalPlanVisitor.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/ExplainLogicalPlanVisitor.java
index 4cd40f7..e2f65ad 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/ExplainLogicalPlanVisitor.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/ExplainLogicalPlanVisitor.java
@@ -18,6 +18,7 @@
 
 package org.apache.tajo.engine.planner;
 
+import org.apache.tajo.annotation.Nullable;
 import org.apache.tajo.engine.planner.logical.*;
 
 import java.util.Stack;
@@ -64,10 +65,10 @@ public class ExplainLogicalPlanVisitor extends BasicLogicalPlanVisitor<ExplainLo
     }
   }
 
-  public Context getBlockPlanStrings(LogicalPlan plan, String block) throws PlanningException {
+  public Context getBlockPlanStrings(@Nullable LogicalPlan plan, LogicalNode node) throws PlanningException {
     Stack<LogicalNode> stack = new Stack<LogicalNode>();
     Context explainContext = new Context();
-    visit(explainContext, plan, plan.getBlock(block), plan.getBlock(block).getRoot(), stack);
+    visit(explainContext, plan, null, node, stack);
     return explainContext;
   }
 
@@ -181,6 +182,14 @@ public class ExplainLogicalPlanVisitor extends BasicLogicalPlanVisitor<ExplainLo
   }
 
   @Override
+  public LogicalNode visitPartitionedTableScan(Context context, LogicalPlan plan, LogicalPlan.QueryBlock block,
+                                          PartitionedTableScanNode node, Stack<LogicalNode> stack)
+      throws PlanningException {
+    context.add(context.depth, node.getPlanString());
+    return node;
+  }
+
+  @Override
   public LogicalNode visitStoreTable(Context context, LogicalPlan plan, LogicalPlan.QueryBlock block,
                                      StoreTableNode node, Stack<LogicalNode> stack) throws PlanningException {
     return visitUnaryNode(context, plan, block, node, stack);

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/ExprsVerifier.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/ExprsVerifier.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/ExprsVerifier.java
index 87ced21..2231df0 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/ExprsVerifier.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/ExprsVerifier.java
@@ -48,7 +48,7 @@ public class ExprsVerifier extends BasicEvalNodeVisitor<VerificationState, EvalN
     Set<Column> referredColumns = EvalTreeUtil.findUniqueColumns(expression);
     for (Column referredColumn : referredColumns) {
       if (!currentNode.getInSchema().contains(referredColumn)) {
-        throw new PlanningException("Invalid State: " + referredColumn + " cannot be referred at Node ("
+        throw new PlanningException("Invalid State: " + referredColumn + " cannot be accessible at Node ("
             + currentNode.getPID() + ")");
       }
     }

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/InsertNode.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/InsertNode.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/InsertNode.java
deleted file mode 100644
index bdc7837..0000000
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/InsertNode.java
+++ /dev/null
@@ -1,199 +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.hadoop.fs.Path;
-import org.apache.tajo.catalog.Schema;
-import org.apache.tajo.catalog.TableDesc;
-import org.apache.tajo.engine.planner.logical.LogicalNode;
-import org.apache.tajo.engine.planner.logical.LogicalNodeVisitor;
-import org.apache.tajo.engine.planner.logical.NodeType;
-import org.apache.tajo.engine.planner.logical.StoreTableNode;
-import org.apache.tajo.util.TUtil;
-
-public class InsertNode extends StoreTableNode implements Cloneable {
-  @Expose private boolean overwrite;
-  @Expose private Schema tableSchema;
-
-  /** a target schema of a target table */
-  @Expose private Schema targetSchema;
-  /** a output schema of select clause */
-  @Expose private Schema projectedSchema;
-  @Expose private Path path;
-
-  public InsertNode(int pid) {
-    super(pid, NodeType.INSERT);
-  }
-
-  public void setTargetTable(TableDesc desc) {
-    setTableName(desc.getName());
-    if (desc.hasPartition()) {
-      tableSchema = desc.getLogicalSchema();
-    } else {
-      tableSchema = desc.getSchema();
-    }
-    setPath(desc.getPath());
-    setOptions(desc.getMeta().getOptions());
-    setStorageType(desc.getMeta().getStoreType());
-
-    if (desc.hasPartition()) {
-      this.setPartitionMethod(desc.getPartitionMethod());
-    }
-  }
-
-  public void setTargetLocation(Path path) {
-    this.path = path;
-  }
-
-  public void setSubQuery(LogicalNode subQuery) {
-    this.setChild(subQuery);
-    this.setInSchema(subQuery.getOutSchema());
-    this.setOutSchema(subQuery.getOutSchema());
-  }
-
-  public boolean isOverwrite() {
-    return overwrite;
-  }
-
-  public void setOverwrite(boolean overwrite) {
-    this.overwrite = overwrite;
-  }
-
-  public Schema getTableSchema() {
-    return tableSchema;
-  }
-
-  public void setTableSchema(Schema tableSchema) {
-    this.tableSchema = tableSchema;
-  }
-
-  public boolean hasTargetSchema() {
-    return this.targetSchema != null;
-  }
-
-  public Schema getTargetSchema() {
-    return this.targetSchema;
-  }
-
-  public void setTargetSchema(Schema schema) {
-    this.targetSchema = schema;
-  }
-
-  public Schema getProjectedSchema() {
-    return this.projectedSchema;
-  }
-
-  public void setProjectedSchema(Schema projected) {
-    this.projectedSchema = projected;
-  }
-
-  public boolean hasPath() {
-    return this.path != null;
-  }
-
-  public void setPath(Path path) {
-    this.path = path;
-  }
-  
-  public Path getPath() {
-    return this.path;
-  }
-
-  public boolean hasStorageType() {
-    return this.storageType != null;
-  }
-  
-  @Override
-  public boolean equals(Object obj) {
-    if (obj instanceof InsertNode) {
-      InsertNode other = (InsertNode) obj;
-      return super.equals(other)
-          && this.overwrite == other.overwrite
-          && TUtil.checkEquals(this.tableSchema, other.tableSchema)
-          && TUtil.checkEquals(this.targetSchema, other.targetSchema)
-          && TUtil.checkEquals(path, other.path);
-    } else {
-      return false;
-    }
-  }
-  
-  @Override
-  public Object clone() throws CloneNotSupportedException {
-    InsertNode insertNode = (InsertNode) super.clone();
-    insertNode.overwrite = overwrite;
-    insertNode.tableSchema = new Schema(tableSchema);
-    insertNode.targetSchema = targetSchema != null ? new Schema(targetSchema) : null;
-    insertNode.path = path != null ? new Path(path.toString()) : null;
-    return insertNode;
-  }
-  
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("INSERT ");
-    if (overwrite) {
-      sb.append("OVERWRITE ");
-    }
-    sb.append("INTO ");
-
-    if (hasTargetTable()) {
-      sb.append("  ").append(tableName);
-    }
-
-    if (hasTargetSchema()) {
-      sb.append("\n  ").append(targetSchema);
-    }
-
-    if (hasPath()) {
-      sb.append("\n  LOCATION ");
-      sb.append(path);
-    }
-
-    sb.append("\n").append(getChild());
-    
-    return sb.toString();
-  }
-
-  @Override
-  public void preOrder(LogicalNodeVisitor visitor) {
-    getChild().preOrder(visitor);
-    visitor.visit(this);
-  }
-
-  @Override
-  public void postOrder(LogicalNodeVisitor visitor) {
-    visitor.visit(this);
-    getChild().postOrder(visitor);
-  }
-
-  @Override
-  public PlanString getPlanString() {
-    PlanString planString = new PlanString(this);
-    planString.appendTitle(" INTO ");
-    if (hasTargetTable()) {
-      planString.appendTitle(getTableName());
-      if (hasTargetSchema()) {
-        planString.addExplan(getTargetSchema().toString());
-      }
-    } else {
-      planString.addExplan("LOCATION " + path);
-    }
-    return planString;
-  }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlan.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlan.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlan.java
index 5491fef..8280d3e 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlan.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlan.java
@@ -36,6 +36,7 @@ import org.apache.tajo.engine.planner.logical.NodeType;
 import org.apache.tajo.engine.planner.logical.RelationNode;
 import org.apache.tajo.util.TUtil;
 
+import java.lang.reflect.Constructor;
 import java.util.*;
 
 /**
@@ -49,6 +50,7 @@ public class LogicalPlan {
   /** it indicates the root block */
   public static final String ROOT_BLOCK = VIRTUAL_TABLE_PREFIX + "ROOT";
   public static final String NONAME_BLOCK_PREFIX = VIRTUAL_TABLE_PREFIX + "QB_";
+  private static final int NO_SEQUENCE_PID = -1;
   private int nextPid = 0;
   private Integer noNameBlockId = 0;
   private Integer noNameColumnId = 0;
@@ -69,6 +71,37 @@ public class LogicalPlan {
   }
 
   /**
+   * Create a LogicalNode instance for a type. Each a LogicalNode instance is given an unique plan node id (PID).
+   *
+   * @param theClass The class to be created
+   * @return a LogicalNode instance identified by an unique plan node id (PID).
+   */
+  public <T extends LogicalNode> T createNode(Class<T> theClass) {
+    try {
+      Constructor<T> ctor = theClass.getConstructor(int.class);
+      return ctor.newInstance(newPID());
+    } catch (Exception e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  /**
+   * Create a LogicalNode instance for a type. Each a LogicalNode instance is not given an unique plan node id (PID).
+   * This method must be only used after all query planning and optimization phases.
+   *
+   * @param theClass The class to be created
+   * @return a LogicalNode instance
+   */
+  public static <T extends LogicalNode> T createNodeWithoutPID(Class<T> theClass) {
+    try {
+      Constructor<T> ctor = theClass.getConstructor(int.class);
+      return ctor.newInstance(NO_SEQUENCE_PID);
+    } catch (Exception e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  /**
    * Create a new {@link QueryBlock} and Get
    *
    * @param blockName the query block name
@@ -399,7 +432,7 @@ public class LogicalPlan {
 
     StringBuilder explains = new StringBuilder();
     try {
-      ExplainLogicalPlanVisitor.Context explainContext = explain.getBlockPlanStrings(this, ROOT_BLOCK);
+      ExplainLogicalPlanVisitor.Context explainContext = explain.getBlockPlanStrings(this, getRootBlock().getRoot());
       while(!explainContext.explains.empty()) {
         explains.append(
             ExplainLogicalPlanVisitor.printDepthString(explainContext.getMaxDepth(), explainContext.explains.pop()));

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanPreprocessor.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanPreprocessor.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanPreprocessor.java
index 818e01c..b08109d 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanPreprocessor.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanPreprocessor.java
@@ -165,7 +165,7 @@ class LogicalPlanPreprocessor extends BaseAlgebraVisitor<LogicalPlanPreprocessor
   public LogicalNode visitProjection(PreprocessContext ctx, Stack<Expr> stack, Projection expr) throws PlanningException {
     // If Non-from statement, it immediately returns.
     if (!expr.hasChild()) {
-      return new EvalExprNode(ctx.plan.newPID());
+      return ctx.plan.createNode(EvalExprNode.class);
     }
 
     stack.push(expr); // <--- push
@@ -206,7 +206,7 @@ class LogicalPlanPreprocessor extends BaseAlgebraVisitor<LogicalPlanPreprocessor
     }
     stack.pop(); // <--- Pop
 
-    ProjectionNode projectionNode = new ProjectionNode(ctx.plan.newPID());
+    ProjectionNode projectionNode = ctx.plan.createNode(ProjectionNode.class);
     projectionNode.setInSchema(child.getOutSchema());
     projectionNode.setOutSchema(PlannerUtil.targetToSchema(targets));
     return projectionNode;
@@ -218,7 +218,7 @@ class LogicalPlanPreprocessor extends BaseAlgebraVisitor<LogicalPlanPreprocessor
     LogicalNode child = visit(ctx, stack, expr.getChild());
     stack.pop();
 
-    LimitNode limitNode = new LimitNode(ctx.plan.newPID());
+    LimitNode limitNode = ctx.plan.createNode(LimitNode.class);
     limitNode.setInSchema(child.getOutSchema());
     limitNode.setOutSchema(child.getOutSchema());
     return limitNode;
@@ -230,7 +230,7 @@ class LogicalPlanPreprocessor extends BaseAlgebraVisitor<LogicalPlanPreprocessor
     LogicalNode child = visit(ctx, stack, expr.getChild());
     stack.pop();
 
-    SortNode sortNode = new SortNode(ctx.plan.newPID());
+    SortNode sortNode = ctx.plan.createNode(SortNode.class);
     sortNode.setInSchema(child.getOutSchema());
     sortNode.setOutSchema(child.getOutSchema());
     return sortNode;
@@ -242,7 +242,7 @@ class LogicalPlanPreprocessor extends BaseAlgebraVisitor<LogicalPlanPreprocessor
     LogicalNode child = visit(ctx, stack, expr.getChild());
     stack.pop();
 
-    HavingNode havingNode = new HavingNode(ctx.plan.newPID());
+    HavingNode havingNode = ctx.plan.createNode(HavingNode.class);
     havingNode.setInSchema(child.getOutSchema());
     havingNode.setOutSchema(child.getOutSchema());
     return havingNode;
@@ -269,7 +269,7 @@ class LogicalPlanPreprocessor extends BaseAlgebraVisitor<LogicalPlanPreprocessor
     }
     stack.pop();
 
-    GroupbyNode groupByNode = new GroupbyNode(ctx.plan.newPID());
+    GroupbyNode groupByNode = ctx.plan.createNode(GroupbyNode.class);
     groupByNode.setInSchema(child.getOutSchema());
     groupByNode.setOutSchema(PlannerUtil.targetToSchema(targets));
     return groupByNode;
@@ -301,7 +301,7 @@ class LogicalPlanPreprocessor extends BaseAlgebraVisitor<LogicalPlanPreprocessor
     LogicalNode child = visit(ctx, stack, expr.getChild());
     stack.pop();
 
-    SelectionNode selectionNode = new SelectionNode(ctx.plan.newPID());
+    SelectionNode selectionNode = ctx.plan.createNode(SelectionNode.class);
     selectionNode.setInSchema(child.getOutSchema());
     selectionNode.setOutSchema(child.getOutSchema());
     return selectionNode;
@@ -313,7 +313,7 @@ class LogicalPlanPreprocessor extends BaseAlgebraVisitor<LogicalPlanPreprocessor
     LogicalNode left = visit(ctx, stack, expr.getLeft());
     LogicalNode right = visit(ctx, stack, expr.getRight());
     stack.pop();
-    JoinNode joinNode = new JoinNode(ctx.plan.newPID());
+    JoinNode joinNode = ctx.plan.createNode(JoinNode.class);
     joinNode.setJoinType(expr.getJoinType());
     Schema merged = SchemaUtil.merge(left.getOutSchema(), right.getOutSchema());
     joinNode.setInSchema(merged);
@@ -330,11 +330,11 @@ class LogicalPlanPreprocessor extends BaseAlgebraVisitor<LogicalPlanPreprocessor
     Relation relation = expr;
     TableDesc desc = catalog.getTableDesc(relation.getName());
 
-    ScanNode scanNode;
+    ScanNode scanNode = ctx.plan.createNode(ScanNode.class);
     if (relation.hasAlias()) {
-      scanNode = new ScanNode(ctx.plan.newPID(), desc, relation.getAlias());
+      scanNode.init(desc, relation.getAlias());
     } else {
-      scanNode = new ScanNode(ctx.plan.newPID(), desc);
+      scanNode.init(desc);
     }
     ctx.currentBlock.addRelation(scanNode);
 
@@ -352,7 +352,8 @@ class LogicalPlanPreprocessor extends BaseAlgebraVisitor<LogicalPlanPreprocessor
     LogicalNode child = super.visitTableSubQuery(newContext, stack, expr);
 
     // a table subquery should be dealt as a relation.
-    TableSubQueryNode node = new TableSubQueryNode(ctx.plan.newPID(), expr.getName(), child);
+    TableSubQueryNode node = ctx.plan.createNode(TableSubQueryNode.class);
+    node.init(expr.getName(), child);
     ctx.currentBlock.addRelation(node);
     return node;
   }
@@ -365,7 +366,7 @@ class LogicalPlanPreprocessor extends BaseAlgebraVisitor<LogicalPlanPreprocessor
   public LogicalNode visitCreateTable(PreprocessContext ctx, Stack<Expr> stack, CreateTable expr)
       throws PlanningException {
 
-    CreateTableNode createTableNode = new CreateTableNode(ctx.plan.newPID());
+    CreateTableNode createTableNode = ctx.plan.createNode(CreateTableNode.class);
 
     if (expr.hasSubQuery()) {
       stack.push(expr);
@@ -379,7 +380,7 @@ class LogicalPlanPreprocessor extends BaseAlgebraVisitor<LogicalPlanPreprocessor
   @Override
   public LogicalNode visitDropTable(PreprocessContext ctx, Stack<Expr> stack, DropTable expr)
       throws PlanningException {
-    DropTableNode dropTable = new DropTableNode(ctx.plan.newPID());
+    DropTableNode dropTable = ctx.plan.createNode(DropTableNode.class);
     return dropTable;
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanner.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanner.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanner.java
index 2a4e151..756ede4 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanner.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanner.java
@@ -117,7 +117,7 @@ public class LogicalPlanner extends BaseAlgebraVisitor<LogicalPlanner.PlanContex
     LogicalNode topMostNode = this.visit(context, new Stack<Expr>(), expr);
 
     // Add Root Node
-    LogicalRootNode root = new LogicalRootNode(plan.newPID());
+    LogicalRootNode root = plan.createNode(LogicalRootNode.class);
     root.setInSchema(topMostNode.getOutSchema());
     root.setChild(topMostNode);
     root.setOutSchema(topMostNode.getOutSchema());
@@ -251,7 +251,7 @@ public class LogicalPlanner extends BaseAlgebraVisitor<LogicalPlanner.PlanContex
     QueryBlock block = context.queryBlock;
 
     Schema outSchema = projectionNode.getOutSchema();
-    GroupbyNode dupRemoval = new GroupbyNode(plan.newPID());
+    GroupbyNode dupRemoval = context.plan.createNode(GroupbyNode.class);
     dupRemoval.setChild(child);
     dupRemoval.setInSchema(projectionNode.getInSchema());
     dupRemoval.setTargets(PlannerUtil.schemaToTargets(outSchema));
@@ -413,7 +413,7 @@ public class LogicalPlanner extends BaseAlgebraVisitor<LogicalPlanner.PlanContex
 
     LogicalPlan plan = context.plan;
     QueryBlock block = context.queryBlock;
-    GroupbyNode groupbyNode = new GroupbyNode(plan.newPID());
+    GroupbyNode groupbyNode = context.plan.createNode(GroupbyNode.class);
     groupbyNode.setChild(child);
     groupbyNode.setInSchema(child.getOutSchema());
 
@@ -877,7 +877,8 @@ public class LogicalPlanner extends BaseAlgebraVisitor<LogicalPlanner.PlanContex
     QueryBlock block = context.queryBlock;
 
     Schema merged = SchemaUtil.merge(left.getOutSchema(), right.getOutSchema());
-    JoinNode join = new JoinNode(plan.newPID(), JoinType.CROSS, left, right);
+    JoinNode join = plan.createNode(JoinNode.class);
+    join.init(JoinType.CROSS, left, right);
     join.setInSchema(merged);
 
     EvalNode evalNode;
@@ -1087,9 +1088,9 @@ public class LogicalPlanner extends BaseAlgebraVisitor<LogicalPlanner.PlanContex
     if (setOperation.getType() == OpType.Union) {
       setOp = block.getNodeFromExpr(setOperation);
     } else if (setOperation.getType() == OpType.Except) {
-      setOp = new ExceptNode(plan.newPID(), leftChild, rightChild);
+      setOp = block.getNodeFromExpr(setOperation);
     } else if (setOperation.getType() == OpType.Intersect) {
-      setOp = new IntersectNode(plan.newPID(), leftChild, rightChild);
+      setOp = block.getNodeFromExpr(setOperation);
     } else {
       throw new VerifyException("Invalid Type: " + setOperation.getType());
     }
@@ -1183,8 +1184,9 @@ public class LogicalPlanner extends BaseAlgebraVisitor<LogicalPlanner.PlanContex
 
       // See PreLogicalPlanVerifier.visitInsert.
       // It guarantees that the equivalence between the numbers of target and projected columns.
-
-      context.queryBlock.addRelation(new ScanNode(context.plan.newPID(), desc));
+      ScanNode scanNode = context.plan.createNode(ScanNode.class);
+      scanNode.init(desc);
+      context.queryBlock.addRelation(scanNode);
       String [] targets = expr.getTargetColumns();
       Schema targetColumns = new Schema();
       for (int i = 0; i < targets.length; i++) {
@@ -1424,7 +1426,7 @@ public class LogicalPlanner extends BaseAlgebraVisitor<LogicalPlanner.PlanContex
   @Override
   public LogicalNode visitDropTable(PlanContext context, Stack<Expr> stack, DropTable dropTable) {
     DropTableNode dropTableNode = context.queryBlock.getNodeFromExpr(dropTable);
-    dropTableNode.set(dropTable.getTableName(), dropTable.isPurge());
+    dropTableNode.init(dropTable.getTableName(), dropTable.isPurge());
     return dropTableNode;
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/PhysicalPlannerImpl.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/PhysicalPlannerImpl.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/PhysicalPlannerImpl.java
index 7ba2889..9c28a80 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/PhysicalPlannerImpl.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/PhysicalPlannerImpl.java
@@ -101,7 +101,7 @@ public class PhysicalPlannerImpl implements PhysicalPlanner {
   private PhysicalExec buildOutputOperator(TaskAttemptContext context, LogicalNode plan,
                                            PhysicalExec execPlan) throws IOException {
     DataChannel channel = context.getDataChannel();
-    ShuffleFileWriteNode shuffleFileWriteNode = new ShuffleFileWriteNode(UNGENERATED_PID);
+    ShuffleFileWriteNode shuffleFileWriteNode = LogicalPlan.createNodeWithoutPID(ShuffleFileWriteNode.class);
     shuffleFileWriteNode.setStorageType(context.getDataChannel().getStoreType());
     shuffleFileWriteNode.setInSchema(plan.getOutSchema());
     shuffleFileWriteNode.setOutSchema(plan.getOutSchema());
@@ -409,13 +409,13 @@ public class PhysicalPlannerImpl implements PhysicalPlanner {
     SortSpec[][] sortSpecs = PlannerUtil.getSortKeysFromJoinQual(
         plan.getJoinQual(), leftExec.getSchema(), rightExec.getSchema());
 
-    SortNode leftSortNode = new SortNode(UNGENERATED_PID);
+    SortNode leftSortNode = LogicalPlan.createNodeWithoutPID(SortNode.class);
     leftSortNode.setSortSpecs(sortSpecs[0]);
     leftSortNode.setInSchema(leftExec.getSchema());
     leftSortNode.setOutSchema(leftExec.getSchema());
     ExternalSortExec outerSort = new ExternalSortExec(context, sm, leftSortNode, leftExec);
 
-    SortNode rightSortNode = new SortNode(UNGENERATED_PID);
+    SortNode rightSortNode = LogicalPlan.createNodeWithoutPID(SortNode.class);
     rightSortNode.setSortSpecs(sortSpecs[1]);
     rightSortNode.setInSchema(rightExec.getSchema());
     rightSortNode.setOutSchema(rightExec.getSchema());
@@ -487,13 +487,13 @@ public class PhysicalPlannerImpl implements PhysicalPlanner {
     SortSpec[][] sortSpecs2 = PlannerUtil.getSortKeysFromJoinQual(
         plan.getJoinQual(), leftExec.getSchema(), rightExec.getSchema());
 
-    SortNode leftSortNode2 = new SortNode(UNGENERATED_PID);
+    SortNode leftSortNode2 = LogicalPlan.createNodeWithoutPID(SortNode.class);
     leftSortNode2.setSortSpecs(sortSpecs2[0]);
     leftSortNode2.setInSchema(leftExec.getSchema());
     leftSortNode2.setOutSchema(leftExec.getSchema());
     ExternalSortExec outerSort2 = new ExternalSortExec(context, sm, leftSortNode2, leftExec);
 
-    SortNode rightSortNode2 = new SortNode(UNGENERATED_PID);
+    SortNode rightSortNode2 = LogicalPlan.createNodeWithoutPID(SortNode.class);
     rightSortNode2.setSortSpecs(sortSpecs2[1]);
     rightSortNode2.setInSchema(rightExec.getSchema());
     rightSortNode2.setOutSchema(rightExec.getSchema());
@@ -578,13 +578,13 @@ public class PhysicalPlannerImpl implements PhysicalPlanner {
     SortSpec[][] sortSpecs3 = PlannerUtil.getSortKeysFromJoinQual(plan.getJoinQual(),
         leftExec.getSchema(), rightExec.getSchema());
 
-    SortNode leftSortNode = new SortNode(UNGENERATED_PID);
+    SortNode leftSortNode = LogicalPlan.createNodeWithoutPID(SortNode.class);
     leftSortNode.setSortSpecs(sortSpecs3[0]);
     leftSortNode.setInSchema(leftExec.getSchema());
     leftSortNode.setOutSchema(leftExec.getSchema());
     ExternalSortExec outerSort3 = new ExternalSortExec(context, sm, leftSortNode, leftExec);
 
-    SortNode rightSortNode = new SortNode(UNGENERATED_PID);
+    SortNode rightSortNode = LogicalPlan.createNodeWithoutPID(SortNode.class);
     rightSortNode.setSortSpecs(sortSpecs3[1]);
     rightSortNode.setInSchema(rightExec.getSchema());
     rightSortNode.setOutSchema(rightExec.getSchema());
@@ -806,7 +806,7 @@ public class PhysicalPlannerImpl implements PhysicalPlanner {
       }
     }
 
-    SortNode sortNode = new SortNode(-1);
+    SortNode sortNode = LogicalPlan.createNodeWithoutPID(SortNode.class);
     sortNode.setSortSpecs(sortSpecs);
     sortNode.setInSchema(child.getSchema());
     sortNode.setOutSchema(child.getSchema());
@@ -929,7 +929,7 @@ public class PhysicalPlannerImpl implements PhysicalPlanner {
       sortSpecs = ObjectArrays.concat(sortSpecs, TUtil.toArray(enforcedSortSpecList, SortSpec.class), SortSpec.class);
     }
 
-    SortNode sortNode = new SortNode(-1);
+    SortNode sortNode = LogicalPlan.createNodeWithoutPID(SortNode.class);
     sortNode.setSortSpecs(sortSpecs);
     sortNode.setInSchema(subOp.getSchema());
     sortNode.setOutSchema(subOp.getSchema());

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/PlannerUtil.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/PlannerUtil.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/PlannerUtil.java
index 4f1421b..a928fb5 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/PlannerUtil.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/PlannerUtil.java
@@ -686,4 +686,27 @@ public class PlannerUtil {
     }
     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();
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/global/GlobalPlanner.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/global/GlobalPlanner.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/global/GlobalPlanner.java
index 258a2e7..461c5d5 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/global/GlobalPlanner.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/global/GlobalPlanner.java
@@ -144,7 +144,9 @@ public class GlobalPlanner {
         "Channel schema (" + channel.getSrcId().getId() + " -> " + channel.getTargetId().getId() + ") is not initialized");
     TableMeta meta = new TableMeta(channel.getStoreType(), new Options());
     TableDesc desc = new TableDesc(channel.getSrcId().toString(), channel.getSchema(), meta, new Path("/"));
-    return new ScanNode(plan.newPID(), desc);
+    ScanNode scanNode = plan.createNode(ScanNode.class);
+    scanNode.init(desc);
+    return scanNode;
   }
 
   private DataChannel createDataChannelFromJoin(ExecutionBlock leftBlock, ExecutionBlock rightBlock,

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/global/MasterPlan.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/global/MasterPlan.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/global/MasterPlan.java
index e72ba05..37b0db1 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/global/MasterPlan.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/global/MasterPlan.java
@@ -24,11 +24,11 @@ package org.apache.tajo.engine.planner.global;
 import org.apache.tajo.ExecutionBlockId;
 import org.apache.tajo.QueryId;
 import org.apache.tajo.engine.planner.LogicalPlan;
+import org.apache.tajo.engine.planner.PlannerUtil;
 import org.apache.tajo.engine.planner.enforce.Enforcer;
 import org.apache.tajo.engine.planner.graph.SimpleDirectedGraph;
 import org.apache.tajo.engine.query.QueryContext;
 import org.apache.tajo.ipc.TajoWorkerProtocol;
-import org.apache.tajo.util.TUtil;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -235,11 +235,6 @@ public class MasterPlan {
         continue;
       }
 
-      if (block.getBroadcastTables().size() > 0) {
-        sb.append("[Broadcasted Tables]: ").append(TUtil.collectionToString(block.getBroadcastTables()));
-        sb.append("\n");
-      }
-
       if (!isLeaf(block)) {
         sb.append("\n[Incoming]\n");
         for (DataChannel channel : getIncomingChannels(block.getId())) {
@@ -265,10 +260,9 @@ public class MasterPlan {
         }
       }
 
-      sb.append("\n").append(block.getPlan());
+      sb.append("\n").append(PlannerUtil.buildExplainString(block.getPlan()));
     }
 
     return sb.toString();
   }
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/CreateTableNode.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/CreateTableNode.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/CreateTableNode.java
index 6dcca2d..b8e7143 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/CreateTableNode.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/CreateTableNode.java
@@ -105,20 +105,9 @@ public class CreateTableNode extends StoreTableNode implements Cloneable {
     store.options = (Options) (options != null ? options.clone() : null);
     return store;
   }
-  
+
   public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("\"CreateTable\": {\"table\": \""+tableName+"\",");
-    sb.append("\"schema: \"{" + this.schema).append("}");
-    sb.append(",\"storeType\": \"" + this.storageType);
-    sb.append(",\"path\" : \"" + this.path).append("\",");
-    sb.append(",\"external\" : \"" + this.external).append("\",");
-    
-    sb.append("\n  \"out schema\": ").append(getOutSchema()).append(",")
-    .append("\n  \"in schema\": ").append(getInSchema())
-    .append("}");
-    
-    return sb.toString();
+    return "CreateTable (table=" + tableName + ", external=" + external + ", storeType=" + storageType + ")";
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/DropTableNode.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/DropTableNode.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/DropTableNode.java
index 06d8185..0c6675f 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/DropTableNode.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/DropTableNode.java
@@ -28,7 +28,7 @@ public class DropTableNode extends LogicalNode {
     super(pid, NodeType.DROP_TABLE);
   }
 
-  public void set(String tableName, boolean purge) {
+  public void init(String tableName, boolean purge) {
     this.tableName = tableName;
     this.purge = purge;
   }

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/EvalExprNode.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/EvalExprNode.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/EvalExprNode.java
index ed63bbc..6ea3f40 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/EvalExprNode.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/EvalExprNode.java
@@ -54,21 +54,7 @@ public class EvalExprNode extends LogicalNode implements Projectable {
   
   @Override
   public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("\"EvalExpr\": {");
-    sb.append("\"targets\": [");
-
-    for (int i = 0; i < exprs.length; i++) {
-      sb.append("\"").append(exprs[i]).append("\"");
-      if( i < exprs.length - 1) {
-        sb.append(",");
-      }
-    }
-    sb.append("],");
-    sb.append("\n  \"out schema\": ").append(getOutSchema()).append(",");
-    sb.append("\n  \"in schema\": ").append(getInSchema());
-    sb.append("}");
-    return sb.toString();
+    return "EvalExprNode (" + TUtil.arrayToString(exprs) + ")";
   }
 
   public boolean equals(Object object) {

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/ExceptNode.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/ExceptNode.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/ExceptNode.java
index 0ed39df..1540e1c 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/ExceptNode.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/ExceptNode.java
@@ -25,10 +25,13 @@ import org.apache.tajo.engine.planner.PlanString;
 
 public class ExceptNode extends BinaryNode {
 
-  public ExceptNode(int pid, LogicalNode outer, LogicalNode inner) {
+  public ExceptNode(int pid) {
     super(pid, NodeType.EXCEPT);
-    setLeftChild(outer);
-    setRightChild(inner);
+  }
+
+  public void init(LogicalNode left, LogicalNode right) {
+    setLeftChild(left);
+    setRightChild(right);
   }
 
   @Override
@@ -39,8 +42,4 @@ public class ExceptNode extends BinaryNode {
     planStr.appendTitle(")");
     return planStr;
   }
-
-  public String toString() {
-    return getLeftChild().toString() + "\n EXCEPT \n" + getRightChild().toString();
-  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/GroupbyNode.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/GroupbyNode.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/GroupbyNode.java
index 38ca29b..76b51c2 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/GroupbyNode.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/GroupbyNode.java
@@ -95,31 +95,16 @@ public class GroupbyNode extends UnaryNode implements Projectable, Cloneable {
   }
   
   public String toString() {
-    StringBuilder sb = new StringBuilder("\"GroupBy\": {\"grouping fields\":[");
-    for (int i=0; i < groupingColumns.length; i++) {
-      sb.append("\"").append(groupingColumns[i]).append("\"");
-      if(i < groupingColumns.length - 1)
-        sb.append(",");
-    }
-
-    if(hasTargets()) {
-      sb.append(", \"target\": [");
-      for (int i = 0; i < targets.length; i++) {
-        sb.append("\"").append(targets[i]).append("\"");
-        if( i < targets.length - 1) {
-          sb.append(",");
-        }
-      }
-      sb.append("],");
+    StringBuilder sb = new StringBuilder("GroupBy (");
+    if (groupingColumns != null || groupingColumns.length > 0) {
+      sb.append("grouping set=").append(TUtil.arrayToString(groupingColumns));
+      sb.append(", ");
     }
-    if (aggrFunctions != null) {
-      sb.append("\n  \"expr\": ").append(TUtil.arrayToString(aggrFunctions)).append(",");
+    if (hasAggFunctions()) {
+      sb.append("funcs=").append(TUtil.arrayToString(aggrFunctions));
     }
-    sb.append("\n  \"out schema\": ").append(getOutSchema()).append(",");
-    sb.append("\n  \"in schema\": ").append(getInSchema());
-    sb.append("}");
-    
-    return sb.toString() + "\n" + getChild().toString();
+    sb.append(")");
+    return sb.toString();
   }
   
   @Override

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/HavingNode.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/HavingNode.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/HavingNode.java
index 816c34e..6c45868 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/HavingNode.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/HavingNode.java
@@ -62,12 +62,6 @@ public class HavingNode extends UnaryNode implements Cloneable {
   }
 
   public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("\"Having\": {\"qual\": \"").append(qual.toString()).append("\",");
-    sb.append("\n  \"out schema\": ").append(getOutSchema()).append(",");
-    sb.append("\n  \"in schema\": ").append(getInSchema()).append("}");
-
-    return sb.toString()+"\n"
-        + getChild().toString();
+    return "Having (filter=" + qual + ")";
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/IndexScanNode.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/IndexScanNode.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/IndexScanNode.java
index e82cc3e..bff0b31 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/IndexScanNode.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/IndexScanNode.java
@@ -32,7 +32,8 @@ public class IndexScanNode extends ScanNode {
   
   public IndexScanNode(int pid, ScanNode scanNode ,
       Schema keySchema , Datum[] datum, SortSpec[] sortKeys ) {
-    super(pid, scanNode.getTableDesc());
+    super(pid);
+    init(scanNode.getTableDesc());
     setQual(scanNode.getQual());
     setInSchema(scanNode.getInSchema());
     setTargets(scanNode.getTargets());

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/InsertNode.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/InsertNode.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/InsertNode.java
new file mode 100644
index 0000000..f5e87ef
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/InsertNode.java
@@ -0,0 +1,182 @@
+/**
+ * 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.hadoop.fs.Path;
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.catalog.TableDesc;
+import org.apache.tajo.engine.planner.PlanString;
+import org.apache.tajo.util.TUtil;
+
+public class InsertNode extends StoreTableNode implements Cloneable {
+  @Expose private boolean overwrite;
+  @Expose private Schema tableSchema;
+
+  /** a target schema of a target table */
+  @Expose private Schema targetSchema;
+  /** a output schema of select clause */
+  @Expose private Schema projectedSchema;
+  @Expose private Path path;
+
+  public InsertNode(int pid) {
+    super(pid, NodeType.INSERT);
+  }
+
+  public void setTargetTable(TableDesc desc) {
+    setTableName(desc.getName());
+    if (desc.hasPartition()) {
+      tableSchema = desc.getLogicalSchema();
+    } else {
+      tableSchema = desc.getSchema();
+    }
+    setPath(desc.getPath());
+    setOptions(desc.getMeta().getOptions());
+    setStorageType(desc.getMeta().getStoreType());
+
+    if (desc.hasPartition()) {
+      this.setPartitionMethod(desc.getPartitionMethod());
+    }
+  }
+
+  public void setTargetLocation(Path path) {
+    this.path = path;
+  }
+
+  public void setSubQuery(LogicalNode subQuery) {
+    this.setChild(subQuery);
+    this.setInSchema(subQuery.getOutSchema());
+    this.setOutSchema(subQuery.getOutSchema());
+  }
+
+  public boolean isOverwrite() {
+    return overwrite;
+  }
+
+  public void setOverwrite(boolean overwrite) {
+    this.overwrite = overwrite;
+  }
+
+  public Schema getTableSchema() {
+    return tableSchema;
+  }
+
+  public void setTableSchema(Schema tableSchema) {
+    this.tableSchema = tableSchema;
+  }
+
+  public boolean hasTargetSchema() {
+    return this.targetSchema != null;
+  }
+
+  public Schema getTargetSchema() {
+    return this.targetSchema;
+  }
+
+  public void setTargetSchema(Schema schema) {
+    this.targetSchema = schema;
+  }
+
+  public Schema getProjectedSchema() {
+    return this.projectedSchema;
+  }
+
+  public void setProjectedSchema(Schema projected) {
+    this.projectedSchema = projected;
+  }
+
+  public boolean hasPath() {
+    return this.path != null;
+  }
+
+  public void setPath(Path path) {
+    this.path = path;
+  }
+  
+  public Path getPath() {
+    return this.path;
+  }
+
+  public boolean hasStorageType() {
+    return this.storageType != null;
+  }
+  
+  @Override
+  public boolean equals(Object obj) {
+    if (obj instanceof InsertNode) {
+      InsertNode other = (InsertNode) obj;
+      return super.equals(other)
+          && this.overwrite == other.overwrite
+          && TUtil.checkEquals(this.tableSchema, other.tableSchema)
+          && TUtil.checkEquals(this.targetSchema, other.targetSchema)
+          && TUtil.checkEquals(path, other.path);
+    } else {
+      return false;
+    }
+  }
+  
+  @Override
+  public Object clone() throws CloneNotSupportedException {
+    InsertNode insertNode = (InsertNode) super.clone();
+    insertNode.overwrite = overwrite;
+    insertNode.tableSchema = new Schema(tableSchema);
+    insertNode.targetSchema = targetSchema != null ? new Schema(targetSchema) : null;
+    insertNode.path = path != null ? new Path(path.toString()) : null;
+    return insertNode;
+  }
+  
+  public String toString() {
+    StringBuilder sb = new StringBuilder("Insert (overwrite=").append(overwrite);
+    if (hasTargetTable()) {
+      sb.append(",table=").append(tableName);
+    }
+    if (hasPath()) {
+      sb.append(", location=").append(path);
+    }
+    sb.append(")");
+    return sb.toString();
+  }
+
+  @Override
+  public void preOrder(LogicalNodeVisitor visitor) {
+    getChild().preOrder(visitor);
+    visitor.visit(this);
+  }
+
+  @Override
+  public void postOrder(LogicalNodeVisitor visitor) {
+    visitor.visit(this);
+    getChild().postOrder(visitor);
+  }
+
+  @Override
+  public PlanString getPlanString() {
+    PlanString planString = new PlanString(this);
+    planString.appendTitle(" INTO ");
+    if (hasTargetTable()) {
+      planString.appendTitle(getTableName());
+      if (hasTargetSchema()) {
+        planString.addExplan(getTargetSchema().toString());
+      }
+    } else {
+      planString.addExplan("LOCATION " + path);
+    }
+    return planString;
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/IntersectNode.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/IntersectNode.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/IntersectNode.java
index 74aa9eb..4bcfd24 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/IntersectNode.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/IntersectNode.java
@@ -24,10 +24,13 @@ package org.apache.tajo.engine.planner.logical;
 import org.apache.tajo.engine.planner.PlanString;
 
 public class IntersectNode extends BinaryNode {
-  public IntersectNode(int pid, LogicalNode outer, LogicalNode inner) {
+  public IntersectNode(int pid) {
     super(pid, NodeType.INTERSECT);
-    setLeftChild(outer);
-    setRightChild(inner);
+  }
+
+  public void init(LogicalNode left, LogicalNode right) {
+    setLeftChild(left);
+    setRightChild(right);
   }
 
   @Override
@@ -38,8 +41,4 @@ public class IntersectNode extends BinaryNode {
     planStr.appendTitle(")");
     return planStr;
   }
-
-  public String toString() {
-    return getLeftChild().toString() + "\n INTERSECT \n" + getRightChild().toString();
-  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/JoinNode.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/JoinNode.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/JoinNode.java
index 8902932..0d607d3 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/JoinNode.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/JoinNode.java
@@ -38,18 +38,7 @@ public class JoinNode extends BinaryNode implements Projectable, Cloneable {
     super(pid, NodeType.JOIN);
   }
 
-  public JoinNode(int pid, JoinType joinType) {
-    this(pid);
-    this.joinType = joinType;
-  }
-
-  public JoinNode(int pid, JoinType joinType, LogicalNode left) {
-    this(pid, joinType);
-    setLeftChild(left);
-  }
-
-  public JoinNode(int pid, JoinType joinType, LogicalNode left, LogicalNode right) {
-    super(pid, NodeType.JOIN);
+  public void init(JoinType joinType, LogicalNode left, LogicalNode right) {
     this.joinType = joinType;
     setLeftChild(left);
     setRightChild(right);
@@ -144,26 +133,11 @@ public class JoinNode extends BinaryNode implements Projectable, Cloneable {
   }
 
   public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("\"Join\": \"joinType\": \" ").append(joinType).append("\"");
-    if (joinQual != null) {
-      sb.append(", \"qual\": ").append(joinQual);
-    }
-    if (targets != null) {
-      sb.append(", \"target list\": ");
-      boolean first = true;
-      for (Target target : targets) {
-        if (!first) {
-          sb.append(", ");
-        }
-        sb.append(target);
-        first = false;
-      }
+    StringBuilder sb = new StringBuilder("Join (type").append(joinType);
+    if (hasJoinQual()) {
+      sb.append(",filter=").append(joinQual);
     }
-
-    sb.append("\n\"out schema: ").append(getOutSchema());
-    sb.append("\n\"in schema: ").append(getInSchema());
-    sb.append("\n" + getLeftChild().toString()).append(" and ").append(getRightChild());
+    sb.append(")");
     return sb.toString();
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/LimitNode.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/LimitNode.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/LimitNode.java
index a3d1f4b..7f5b258 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/LimitNode.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/LimitNode.java
@@ -60,12 +60,6 @@ public final class LimitNode extends UnaryNode implements Cloneable {
   }
 
   public String toString() {
-    StringBuilder sb = new StringBuilder("Limit (").append(fetchFirstNum).append(")");
-
-    sb.append("\n  \"out schema: ").append(getOutSchema())
-        .append("\n  \"in schema: " + getInSchema());
-    sb.append("\n").append(getChild().toString());
-
-    return sb.toString();
+    return "Limit (fetch first=" + fetchFirstNum + ")";
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/LogicalNode.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/LogicalNode.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/LogicalNode.java
index 4e9721f..f62caa4 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/LogicalNode.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/LogicalNode.java
@@ -25,6 +25,7 @@ import com.google.gson.annotations.Expose;
 import org.apache.tajo.catalog.Schema;
 import org.apache.tajo.engine.json.CoreGsonHelper;
 import org.apache.tajo.engine.planner.PlanString;
+import org.apache.tajo.engine.planner.PlannerUtil;
 import org.apache.tajo.json.GsonObject;
 import org.apache.tajo.util.TUtil;
 
@@ -36,7 +37,7 @@ public abstract class LogicalNode implements Cloneable, GsonObject {
 
 	@Expose	private double cost = 0;
 
-	public LogicalNode(int pid, NodeType type) {
+	protected LogicalNode(int pid, NodeType type) {
     this.pid = pid;
     this.type = type;
 	}
@@ -120,4 +121,8 @@ public abstract class LogicalNode implements Cloneable, GsonObject {
   public abstract void postOrder(LogicalNodeVisitor visitor);
 
   public abstract PlanString getPlanString();
+
+  public String toString() {
+    return PlannerUtil.buildExplainString(this);
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/NodeType.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/NodeType.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/NodeType.java
index 32b9bc6..acaf85b 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/NodeType.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/NodeType.java
@@ -21,8 +21,6 @@
  */
 package org.apache.tajo.engine.planner.logical;
 
-import org.apache.tajo.engine.planner.InsertNode;
-
 /**
  * This indicates a logical node type.
  */

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/PartitionedTableScanNode.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/PartitionedTableScanNode.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/PartitionedTableScanNode.java
index 868c493..45cc578 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/PartitionedTableScanNode.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/PartitionedTableScanNode.java
@@ -30,12 +30,14 @@ import org.apache.tajo.util.TUtil;
 public class PartitionedTableScanNode extends ScanNode {
   @Expose Path [] inputPaths;
 
-  public PartitionedTableScanNode(int pid, ScanNode scanNode, Path[] inputPaths) {
-    super(pid, NodeType.PARTITIONS_SCAN, scanNode.getTableDesc());
-    this.setInSchema(scanNode.getInSchema());
-    this.setOutSchema(scanNode.getOutSchema());
-    this.alias = scanNode.alias;
-    this.logicalSchema = scanNode.logicalSchema;
+  public PartitionedTableScanNode(int pid) {
+    super(pid, NodeType.PARTITIONS_SCAN);
+  }
+
+  public void init(ScanNode scanNode, Path[] inputPaths) {
+    tableDesc = scanNode.tableDesc;
+    setInSchema(scanNode.getInSchema());
+    setOutSchema(scanNode.getOutSchema());
     this.qual = scanNode.qual;
     this.targets = scanNode.targets;
     this.inputPaths = inputPaths;
@@ -50,40 +52,14 @@ public class PartitionedTableScanNode extends ScanNode {
   }
 	
 	public String toString() {
-	  StringBuilder sb = new StringBuilder();	  
-	  sb.append("\"Partitions Scan\" : {\"table\":\"")
-	  .append(getTableName()).append("\"");
-	  if (hasAlias()) {
-	    sb.append(",\"alias\": \"").append(alias);
-	  }
-	  
-	  if (hasQual()) {
-	    sb.append(", \"qual\": \"").append(this.qual).append("\"");
-	  }
-	  
-	  if (hasTargets()) {
-	    sb.append(", \"target list\": ");
-      boolean first = true;
-      for (Target target : targets) {
-        if (!first) {
-          sb.append(", ");
-        }
-        sb.append(target);
-        first = false;
-      }
-	  }
-
-    if (inputPaths != null) {
-      sb.append(", \"Partition paths\": ");
-      for (Path path : inputPaths) {
-        sb.append("\n ");
-        sb.append(path);
-      }
-      sb.append("\n");
+    StringBuilder sb = new StringBuilder("Partitions Scan (table=").append(getTableName());
+    if (hasAlias()) {
+      sb.append(", alias=").append(alias);
     }
-
-	  sb.append("\n  \"out schema\": ").append(getOutSchema());
-	  sb.append("\n  \"in schema\": ").append(getInSchema());
+    if (hasQual()) {
+      sb.append(", filter=").append(qual);
+    }
+    sb.append(", path=").append(getTableDesc().getPath()).append(")");
 	  return sb.toString();
 	}
 
@@ -163,17 +139,17 @@ public class PartitionedTableScanNode extends ScanNode {
       }
     }
 
+    planStr.addDetail("out schema: ").appendDetail(getOutSchema().toString());
+    planStr.addDetail("in schema: ").appendDetail(getInSchema().toString());
+
     if (inputPaths != null) {
-      planStr.addExplan("Path list: ");
+      planStr.addExplan("num of filtered paths: ").appendExplain(""+ inputPaths.length);
       int i = 0;
       for (Path path : inputPaths) {
-        planStr.addExplan((i++) + ": ").appendExplain(path.toString());
+        planStr.addDetail((i++) + ": ").appendDetail(path.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/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/PersistentStoreNode.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/PersistentStoreNode.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/PersistentStoreNode.java
index 65fd4f5..9d2acf6 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/PersistentStoreNode.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/PersistentStoreNode.java
@@ -35,7 +35,7 @@ public abstract class PersistentStoreNode extends UnaryNode implements Cloneable
   @Expose protected StoreType storageType = StoreType.CSV;
   @Expose protected Options options;
 
-  public PersistentStoreNode(int pid, NodeType nodeType) {
+  protected PersistentStoreNode(int pid, NodeType nodeType) {
     super(pid, nodeType);
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/ProjectionNode.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/ProjectionNode.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/ProjectionNode.java
index acfaeb6..4d922ba 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/ProjectionNode.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/ProjectionNode.java
@@ -55,25 +55,9 @@ public class ProjectionNode extends UnaryNode implements Projectable {
 	}
 	
 	public String toString() {
-	  StringBuilder sb = new StringBuilder();
-	  sb.append("\"Projection\": {");
-    if (distinct) {
-      sb.append("\"distinct\": true, ");
-    }
-    sb.append("\"targets\": [");
-	  
-	  for (int i = 0; i < targets.length; i++) {
-	    sb.append("\"").append(targets[i]).append("\"");
-	    if( i < targets.length - 1) {
-	      sb.append(",");
-	    }
-	  }
-	  sb.append("],");
-	  sb.append("\n  \"out schema\": ").append(getOutSchema()).append(",");
-	  sb.append("\n  \"in schema\": ").append(getInSchema());
-	  sb.append("}");
-	  return sb.toString()+"\n"
-	      + getChild().toString();
+	  StringBuilder sb = new StringBuilder("Projection (distinct=").append(distinct);
+    sb.append(", exprs=").append(TUtil.arrayToString(targets)).append(")");
+	  return sb.toString();
 	}
 	
 	@Override

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/RelationNode.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/RelationNode.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/RelationNode.java
index 8ed247e..968da30 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/RelationNode.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/RelationNode.java
@@ -32,7 +32,7 @@ import org.apache.tajo.catalog.Schema;
  */
 public abstract class RelationNode extends LogicalNode {
 
-  public RelationNode(int pid, NodeType nodeType) {
+  protected RelationNode(int pid, NodeType nodeType) {
     super(pid, nodeType);
     assert(nodeType == NodeType.SCAN || nodeType == NodeType.PARTITIONS_SCAN || nodeType == NodeType.TABLE_SUBQUERY);
   }

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/ScanNode.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/ScanNode.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/ScanNode.java
index 0ec8110..80a0d7a 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/ScanNode.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/ScanNode.java
@@ -37,21 +37,23 @@ public class ScanNode extends RelationNode implements Projectable {
 	@Expose protected EvalNode qual;
 	@Expose protected Target[] targets;
 
-  protected ScanNode(int pid, NodeType nodeType, TableDesc desc) {
+  protected ScanNode(int pid, NodeType nodeType) {
     super(pid, nodeType);
-    this.tableDesc = desc;
   }
 
-  public ScanNode(int pid, TableDesc desc) {
+  public ScanNode(int pid) {
     super(pid, NodeType.SCAN);
+  }
+
+  public void init(TableDesc desc) {
     this.tableDesc = desc;
     this.setInSchema(tableDesc.getSchema());
     this.setOutSchema(tableDesc.getSchema());
     logicalSchema = SchemaUtil.getQualifiedLogicalSchema(tableDesc, null);
   }
   
-	public ScanNode(int pid, TableDesc desc, String alias) {
-    this(pid, desc);
+	public void init(TableDesc desc, String alias) {
+    this.tableDesc = desc;
     this.alias = CatalogUtil.normalizeIdentifier(alias);
     this.setInSchema(tableDesc.getSchema());
     this.getInSchema().setQualifier(alias);
@@ -112,33 +114,15 @@ public class ScanNode extends RelationNode implements Projectable {
   }
 	
 	public String toString() {
-	  StringBuilder sb = new StringBuilder();	  
-	  sb.append("\"Scan\" : {\"table\":\"")
-	  .append(getTableName()).append("\"");
-	  if (hasAlias()) {
-	    sb.append(",\"alias\": \"").append(alias);
-	  }
-	  
-	  if (hasQual()) {
-	    sb.append(", \"qual\": \"").append(this.qual).append("\"");
-	  }
-	  
-	  if (hasTargets()) {
-	    sb.append(", \"target list\": ");
-      boolean first = true;
-      for (Target target : targets) {
-        if (!first) {
-          sb.append(", ");
-        }
-        sb.append(target);
-        first = false;
-      }
-	  }
-
-	  sb.append(",");
-	  sb.append("\n  \"out schema\": ").append(getOutSchema());
-	  sb.append("\n  \"in schema\": ").append(getInSchema());
-	  return sb.toString();
+    StringBuilder sb = new StringBuilder("Scan (table=").append(getTableName());
+    if (hasAlias()) {
+      sb.append(", alias=").append(alias);
+    }
+    if (hasQual()) {
+      sb.append(", filter=").append(qual);
+    }
+    sb.append(", path=").append(getTableDesc().getPath()).append(")");
+    return sb.toString();
 	}
 
   @Override

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/SelectionNode.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/SelectionNode.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/SelectionNode.java
index 7a03d12..b8a9680 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/SelectionNode.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/SelectionNode.java
@@ -64,12 +64,6 @@ public class SelectionNode extends UnaryNode implements Cloneable {
   }
 
   public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("\"Selection\": {\"qual\": \"").append(qual.toString()).append("\",");
-    sb.append("\n  \"out schema\": ").append(getOutSchema()).append(",");
-    sb.append("\n  \"in schema\": ").append(getInSchema()).append("}");
-
-    return sb.toString()+"\n"
-        + getChild().toString();
+    return "Selection (filter=" + qual + ")";
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/ShuffleFileWriteNode.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/ShuffleFileWriteNode.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/ShuffleFileWriteNode.java
index e4ef49b..5399357 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/ShuffleFileWriteNode.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/ShuffleFileWriteNode.java
@@ -87,28 +87,16 @@ public class ShuffleFileWriteNode extends PersistentStoreNode implements Cloneab
   }
 
   public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("\"Store\":");
+    StringBuilder sb = new StringBuilder("Shuffle Write (type=" + shuffleType.name().toLowerCase());
     if (storageType != null) {
-      sb.append(" storage: "+ storageType.name());
+      sb.append(", storage="+ storageType.name());
     }
-    sb.append(", partnum: ").append(numOutputs).append("}")
-    .append(", ");
+    sb.append(", part number=").append(numOutputs);
     if (shuffleKeys != null) {
-      sb.append("\"partition keys: [");
-      for (int i = 0; i < shuffleKeys.length; i++) {
-        sb.append(shuffleKeys[i]);
-        if (i < shuffleKeys.length - 1)
-          sb.append(",");
-      }
-      sb.append("],");
+      sb.append(", keys: ").append(TUtil.arrayToString(shuffleKeys));
     }
+    sb.append(")");
     
-    sb.append("\n  \"out schema\": ").append(getOutSchema()).append(",")
-    .append("\n  \"in schema\": ").append(getInSchema());
-
-    sb.append("}");
-    
-    return sb.toString() + "\n" + getChild().toString();
+    return sb.toString();
   }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/StoreIndexNode.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/StoreIndexNode.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/StoreIndexNode.java
deleted file mode 100644
index fb8ae3c..0000000
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/StoreIndexNode.java
+++ /dev/null
@@ -1,27 +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;
-
-public class StoreIndexNode extends StoreTableNode {
-
-  public StoreIndexNode(int pid) {
-    super(pid);
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/StoreTableNode.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/StoreTableNode.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/StoreTableNode.java
index ff08e36..b0f7b7a 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/StoreTableNode.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/StoreTableNode.java
@@ -90,22 +90,11 @@ public class StoreTableNode extends PersistentStoreNode implements Cloneable {
   }
 
   public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("\"Store\": {\"table\": \""+tableName);
+    StringBuilder sb = new StringBuilder("Store Table (table=").append(tableName);
     if (storageType != null) {
-      sb.append(", storage: "+ storageType.name());
+      sb.append(", storage="+ storageType.name());
     }
-    
-    sb.append("\n  \"out schema\": ").append(getOutSchema()).append(",")
-    .append("\n  \"in schema\": ").append(getInSchema());
-
-    if(partitionDesc != null) {
-      sb.append(partitionDesc.toString());
-    }
-
-    sb.append("}");
-    
-    return sb.toString() + "\n"
-        + getChild().toString();
+    sb.append(")");
+    return sb.toString();
   }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/TableSubQueryNode.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/TableSubQueryNode.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/TableSubQueryNode.java
index 3f251f8..2652030 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/TableSubQueryNode.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/TableSubQueryNode.java
@@ -26,15 +26,17 @@ 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.engine.utils.SchemaUtil;
-import org.apache.tajo.util.TUtil;
 
 public class TableSubQueryNode extends RelationNode implements Projectable {
   @Expose private String tableName;
   @Expose private LogicalNode subQuery;
   @Expose private Target [] targets; // unused
 
-  public TableSubQueryNode(int pid, String tableName, LogicalNode subQuery) {
+  public TableSubQueryNode(int pid) {
     super(pid, NodeType.TABLE_SUBQUERY);
+  }
+
+  public void init(String tableName, LogicalNode subQuery) {
     this.tableName = CatalogUtil.normalizeIdentifier(tableName);
     if (subQuery != null) {
       this.subQuery = subQuery;
@@ -165,14 +167,6 @@ public class TableSubQueryNode extends RelationNode implements Projectable {
   }
 
   public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("(").append(getPID()).append(") Table Subquery (alias=").append(tableName).append(")\n");
-    if (hasTargets()) {
-      sb.append("  targets: ").append(TUtil.arrayToString(targets)).append("\n");
-    }
-    sb.append("  out schema:").append(getOutSchema()).append("\n");
-    sb.append("  input schema:").append(getInSchema()).append("\n");
-    sb.append(subQuery.toString());
-    return sb.toString();
+    return "Inline view (name=" + tableName + ")";
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/UnionNode.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/UnionNode.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/UnionNode.java
index efba1ef..49183d0 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/UnionNode.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/UnionNode.java
@@ -34,8 +34,4 @@ public class UnionNode extends BinaryNode {
     PlanString planStr = new PlanString(this);
     return planStr;
   }
-
-  public String toString() {
-    return getLeftChild().toString() + "\n UNION \n" + getRightChild().toString();
-  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/join/GreedyHeuristicJoinOrderAlgorithm.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/join/GreedyHeuristicJoinOrderAlgorithm.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/join/GreedyHeuristicJoinOrderAlgorithm.java
index 428152b..ffa95fb 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/join/GreedyHeuristicJoinOrderAlgorithm.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/join/GreedyHeuristicJoinOrderAlgorithm.java
@@ -76,20 +76,21 @@ public class GreedyHeuristicJoinOrderAlgorithm implements JoinOrderAlgorithm {
   private static JoinNode createJoinNode(LogicalPlan plan, JoinEdge joinEdge) {
     LogicalNode left = joinEdge.getLeftRelation();
     LogicalNode right = joinEdge.getRightRelation();
-    JoinNode joinNode;
+
+    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 =  new JoinNode(plan.newPID(), joinEdge.getJoinType(), right, left);
+        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 = new JoinNode(plan.newPID(), joinEdge.getJoinType(), left, right);
+        joinNode.init(joinEdge.getJoinType(), left, right);
       }
     } else {
-      joinNode = new JoinNode(plan.newPID(), joinEdge.getJoinType(), left, right);
+      joinNode.init(joinEdge.getJoinType(), left, right);
     }
 
     Schema mergedSchema = SchemaUtil.merge(joinNode.getLeftChild().getOutSchema(),

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/ColPartitionStoreExec.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/ColPartitionStoreExec.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/ColPartitionStoreExec.java
index 2ec0315..fe36905 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/ColPartitionStoreExec.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/ColPartitionStoreExec.java
@@ -24,7 +24,7 @@ import org.apache.hadoop.fs.Path;
 import org.apache.tajo.catalog.CatalogUtil;
 import org.apache.tajo.catalog.Column;
 import org.apache.tajo.catalog.TableMeta;
-import org.apache.tajo.engine.planner.InsertNode;
+import org.apache.tajo.engine.planner.logical.InsertNode;
 import org.apache.tajo.engine.planner.logical.CreateTableNode;
 import org.apache.tajo.engine.planner.logical.NodeType;
 import org.apache.tajo.engine.planner.logical.StoreTableNode;

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/StoreTableExec.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/StoreTableExec.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/StoreTableExec.java
index 786148b..1f927a6 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/StoreTableExec.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/StoreTableExec.java
@@ -23,7 +23,7 @@ package org.apache.tajo.engine.planner.physical;
 
 import org.apache.tajo.catalog.CatalogUtil;
 import org.apache.tajo.catalog.TableMeta;
-import org.apache.tajo.engine.planner.InsertNode;
+import org.apache.tajo.engine.planner.logical.InsertNode;
 import org.apache.tajo.engine.planner.logical.PersistentStoreNode;
 import org.apache.tajo.storage.Appender;
 import org.apache.tajo.storage.StorageManagerFactory;

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/rewrite/PartitionedTableRewriter.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/rewrite/PartitionedTableRewriter.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/rewrite/PartitionedTableRewriter.java
index d701935..6e78c18 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/rewrite/PartitionedTableRewriter.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/rewrite/PartitionedTableRewriter.java
@@ -354,8 +354,8 @@ public class PartitionedTableRewriter implements RewriteRule {
       try {
         Path [] filteredPaths = findFilteredPartitionPaths(scanNode);
         plan.addHistory("PartitionTableRewriter chooses " + filteredPaths.length + " of partitions");
-        PartitionedTableScanNode rewrittenScanNode =
-            new PartitionedTableScanNode(plan.newPID(), scanNode, filteredPaths);
+        PartitionedTableScanNode rewrittenScanNode = plan.createNode(PartitionedTableScanNode.class);
+        rewrittenScanNode.init(scanNode, filteredPaths);
         updateTableStat(rewrittenScanNode);
 
         // if it is topmost node, set it as the rootnode of this block.

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/Query.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/Query.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/Query.java
index 6a4eb4b..5fafe51 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/Query.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/Query.java
@@ -37,7 +37,7 @@ import org.apache.tajo.catalog.TableDesc;
 import org.apache.tajo.catalog.TableMeta;
 import org.apache.tajo.catalog.statistics.TableStats;
 import org.apache.tajo.conf.TajoConf;
-import org.apache.tajo.engine.planner.InsertNode;
+import org.apache.tajo.engine.planner.logical.InsertNode;
 import org.apache.tajo.engine.planner.global.DataChannel;
 import org.apache.tajo.engine.planner.global.ExecutionBlock;
 import org.apache.tajo.engine.planner.global.ExecutionBlockCursor;

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/5fb959b7/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/planner/TestLogicalNode.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/planner/TestLogicalNode.java b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/planner/TestLogicalNode.java
index b540868..3fe75f0 100644
--- a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/planner/TestLogicalNode.java
+++ b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/planner/TestLogicalNode.java
@@ -47,14 +47,14 @@ public class TestLogicalNode {
     schema.addColumn("age", Type.INT2);
     GroupbyNode groupbyNode = new GroupbyNode(0);
     groupbyNode.setGroupingColumns(new Column[]{schema.getColumn(1), schema.getColumn(2)});
-    ScanNode scanNode = new ScanNode(0,
-        CatalogUtil.newTableDesc("in", schema, CatalogUtil.newTableMeta(StoreType.CSV), new Path("in")));
+    ScanNode scanNode = new ScanNode(0);
+    scanNode.init(CatalogUtil.newTableDesc("in", schema, CatalogUtil.newTableMeta(StoreType.CSV), new Path("in")));
 
     GroupbyNode groupbyNode2 = new GroupbyNode(0);
     groupbyNode2.setGroupingColumns(new Column[]{schema.getColumn(1), schema.getColumn(2)});
     JoinNode joinNode = new JoinNode(0);
-    ScanNode scanNode2 = new ScanNode(0,
-        CatalogUtil.newTableDesc("in2", schema, CatalogUtil.newTableMeta(StoreType.CSV), new Path("in2")));
+    ScanNode scanNode2 = new ScanNode(0);
+    scanNode2.init(CatalogUtil.newTableDesc("in2", schema, CatalogUtil.newTableMeta(StoreType.CSV), new Path("in2")));
 
     groupbyNode.setChild(scanNode);
     groupbyNode2.setChild(joinNode);
@@ -64,8 +64,8 @@ public class TestLogicalNode {
     assertTrue(groupbyNode.equals(groupbyNode2));
     assertFalse(groupbyNode.deepEquals(groupbyNode2));
 
-    ScanNode scanNode3 = new ScanNode(0,
-        CatalogUtil.newTableDesc("in", schema, CatalogUtil.newTableMeta(StoreType.CSV), new Path("in")));
+    ScanNode scanNode3 = new ScanNode(0);
+    scanNode3.init(CatalogUtil.newTableDesc("in", schema, CatalogUtil.newTableMeta(StoreType.CSV), new Path("in")));
     groupbyNode2.setChild(scanNode3);
 
     assertTrue(groupbyNode.equals(groupbyNode2));


Mime
View raw message