You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tajo.apache.org by hy...@apache.org on 2013/12/06 15:02:15 UTC

git commit: TAJO-388: limit clause does not work properly. (hyunsik)

Updated Branches:
  refs/heads/master c033d85cf -> 469c5a243


TAJO-388: limit clause does not work properly. (hyunsik)


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

Branch: refs/heads/master
Commit: 469c5a2437ded40da5675d2e87c7115583cd1b67
Parents: c033d85
Author: Hyunsik Choi <hy...@apache.org>
Authored: Fri Dec 6 22:58:37 2013 +0900
Committer: Hyunsik Choi <hy...@apache.org>
Committed: Fri Dec 6 22:58:37 2013 +0900

----------------------------------------------------------------------
 CHANGES.txt                                     |  2 +
 .../apache/tajo/engine/planner/PlannerUtil.java |  6 ++-
 .../engine/planner/global/ExecutionBlock.java   |  5 --
 .../engine/planner/global/GlobalPlanner.java    | 54 ++++++++++----------
 .../engine/planner/logical/LogicalNode.java     |  4 ++
 .../tajo/engine/query/TestSelectQuery.java      | 19 ++++---
 6 files changed, 50 insertions(+), 40 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/469c5a24/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index a3e7ae2..32735e1 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -104,6 +104,8 @@ Release 0.8.0 - unreleased
 
   BUG FIXES
 
+    TAJO-388: limit clause does not work properly. (hyunsik)
+
     TAJO-389: The LazyTuple does not work when number format exception occurs 
     in text deserializer. (jinho)
 

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/469c5a24/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 28f5725..6b23ed8 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
@@ -677,9 +677,11 @@ public class PlannerUtil {
     return copy;
   }
 
-  public static <T extends LogicalNode> T clone(LogicalNode node) {
+  public static <T extends LogicalNode> T clone(LogicalPlan plan, LogicalNode node) {
     try {
-      return (T) node.clone();
+      T copy = (T) node.clone();
+      copy.setPID(plan.newPID());
+      return copy;
     } catch (CloneNotSupportedException e) {
       throw new RuntimeException(e);
     }

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/469c5a24/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/global/ExecutionBlock.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/global/ExecutionBlock.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/global/ExecutionBlock.java
index efa1c7f..4f936fc 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/global/ExecutionBlock.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/global/ExecutionBlock.java
@@ -15,7 +15,6 @@
 package org.apache.tajo.engine.planner.global;
 
 import org.apache.tajo.ExecutionBlockId;
-import org.apache.tajo.catalog.Schema;
 import org.apache.tajo.engine.planner.enforce.Enforcer;
 import org.apache.tajo.engine.planner.logical.*;
 
@@ -97,10 +96,6 @@ public class ExecutionBlock {
     return this.scanlist.toArray(new ScanNode[scanlist.size()]);
   }
 
-  public Schema getOutputSchema() {
-    return store.getOutSchema();
-  }
-
   public boolean hasJoin() {
     return hasJoinPlan;
   }

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/469c5a24/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 f85b170..f10408d 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
@@ -53,8 +53,6 @@ public class GlobalPlanner {
 
   public class GlobalPlanContext {
     MasterPlan plan;
-    LogicalNode topmost;
-
     Map<Integer, ExecutionBlock> execBlockMap = Maps.newHashMap();
   }
 
@@ -68,7 +66,8 @@ public class GlobalPlanner {
     globalPlanContext.plan = masterPlan;
     LOG.info(masterPlan.getLogicalPlan());
 
-    LogicalNode inputPlan = PlannerUtil.clone(masterPlan.getLogicalPlan().getRootBlock().getRoot());
+    LogicalNode inputPlan = PlannerUtil.clone(masterPlan.getLogicalPlan(),
+        masterPlan.getLogicalPlan().getRootBlock().getRoot());
     LogicalNode lastNode = planner.visitChild(globalPlanContext, masterPlan.getLogicalPlan(), inputPlan,
         new Stack<LogicalNode>());
 
@@ -240,11 +239,11 @@ public class GlobalPlanner {
           dataChannel.setSchema(firstPhaseGroupBy.getOutSchema());
 
           ExecutionBlock subBlock = masterPlan.getExecBlock(dataChannel.getSrcId());
-          GroupbyNode g1 = PlannerUtil.clone(firstPhaseGroupBy);
+          GroupbyNode g1 = PlannerUtil.clone(context.plan.getLogicalPlan(), firstPhaseGroupBy);
           g1.setChild(subBlock.getPlan());
           subBlock.setPlan(g1);
 
-          GroupbyNode g2 = PlannerUtil.clone(groupbyNode);
+          GroupbyNode g2 = PlannerUtil.clone(context.plan.getLogicalPlan(), groupbyNode);
           ScanNode scanNode = buildInputExecutor(masterPlan.getLogicalPlan(), dataChannel);
           g2.setChild(scanNode);
           currentBlock.setPlan(g2);
@@ -274,10 +273,11 @@ public class GlobalPlanner {
     return currentBlock;
   }
 
-  private ExecutionBlock buildSortPlan(MasterPlan masterPlan, ExecutionBlock childBlock, SortNode currentNode) {
+  private ExecutionBlock buildSortPlan(GlobalPlanContext context, ExecutionBlock childBlock, SortNode currentNode) {
+    MasterPlan masterPlan = context.plan;
     ExecutionBlock currentBlock;
 
-    SortNode firstSortNode = PlannerUtil.clone(currentNode);
+    SortNode firstSortNode = PlannerUtil.clone(context.plan.getLogicalPlan(), currentNode);
     childBlock.setPlan(firstSortNode);
 
     currentBlock = masterPlan.newExecutionBlock();
@@ -308,7 +308,13 @@ public class GlobalPlanner {
                                        Stack<LogicalNode> stack) throws PlanningException {
       LogicalNode child = super.visitProjection(context, plan, node, stack);
 
-      return handleUnaryNode(context, child, node);
+      ExecutionBlock execBlock = context.execBlockMap.remove(child.getPID());
+
+      node.setChild(execBlock.getPlan());
+      node.setInSchema(execBlock.getPlan().getOutSchema());
+      execBlock.setPlan(node);
+      context.execBlockMap.put(node.getPID(), execBlock);
+      return node;
     }
 
     @Override
@@ -316,14 +322,14 @@ public class GlobalPlanner {
         throws PlanningException {
       LogicalNode child = super.visitLimit(context, plan, node, stack);
 
-      ExecutionBlock block = null;
+      ExecutionBlock block;
       block = context.execBlockMap.remove(child.getPID());
       if (child.getType() == NodeType.SORT) {
         node.setChild(block.getPlan());
         block.setPlan(node);
 
         ExecutionBlock childBlock = context.plan.getChild(block, 0);
-        LimitNode childLimit = PlannerUtil.clone(node);
+        LimitNode childLimit = PlannerUtil.clone(context.plan.getLogicalPlan(), node);
         childLimit.setChild(childBlock.getPlan());
         childBlock.setPlan(childLimit);
 
@@ -339,14 +345,14 @@ public class GlobalPlanner {
         newChannel.setPartitionKey(new Column[]{});
         newChannel.setSchema(node.getOutSchema());
         ScanNode scanNode = buildInputExecutor(plan, newChannel);
-        LimitNode parentLimit = PlannerUtil.clone(node);
+        LimitNode parentLimit = PlannerUtil.clone(context.plan.getLogicalPlan(), node);
         parentLimit.setChild(scanNode);
         newExecBlock.setPlan(parentLimit);
         context.plan.addConnect(newChannel);
-        context.execBlockMap.put(node.getPID(), newExecBlock);
+        context.execBlockMap.put(parentLimit.getPID(), newExecBlock);
+        node = parentLimit;
       }
 
-
       return node;
     }
 
@@ -357,7 +363,7 @@ public class GlobalPlanner {
       LogicalNode child = super.visitSort(context, plan, node, stack);
 
       ExecutionBlock childBlock = context.execBlockMap.remove(child.getPID());
-      ExecutionBlock newExecBlock = buildSortPlan(context.plan, childBlock, node);
+      ExecutionBlock newExecBlock = buildSortPlan(context, childBlock, node);
       context.execBlockMap.put(node.getPID(), newExecBlock);
 
       return node;
@@ -380,9 +386,11 @@ public class GlobalPlanner {
                                    Stack<LogicalNode> stack) throws PlanningException {
       LogicalNode child = super.visitFilter(context, plan, node, stack);
 
-      ExecutionBlock childBlock = context.execBlockMap.remove(child.getPID());
-      childBlock.setPlan(child);
-      context.execBlockMap.put(node.getPID(), childBlock);
+      ExecutionBlock execBlock = context.execBlockMap.remove(child.getPID());
+      node.setChild(execBlock.getPlan());
+      node.setInSchema(execBlock.getPlan().getOutSchema());
+      execBlock.setPlan(node);
+      context.execBlockMap.put(node.getPID(), execBlock);
 
       return node;
     }
@@ -461,8 +469,6 @@ public class GlobalPlanner {
     public LogicalNode visitExcept(GlobalPlanContext context, LogicalPlan plan, ExceptNode node,
                                    Stack<LogicalNode> stack) throws PlanningException {
       LogicalNode child = super.visitExcept(context, plan, node, stack);
-      context.topmost = node;
-
       return handleUnaryNode(context, child, node);
     }
 
@@ -470,8 +476,6 @@ public class GlobalPlanner {
     public LogicalNode visitIntersect(GlobalPlanContext context, LogicalPlan plan, IntersectNode node,
                                       Stack<LogicalNode> stack) throws PlanningException {
       LogicalNode child = super.visitIntersect(context, plan, node, stack);
-      context.topmost = node;
-
       return handleUnaryNode(context, child, node);
     }
 
@@ -479,15 +483,12 @@ public class GlobalPlanner {
     public LogicalNode visitTableSubQuery(GlobalPlanContext context, LogicalPlan plan, TableSubQueryNode node,
                                           Stack<LogicalNode> stack) throws PlanningException {
       LogicalNode child = super.visitTableSubQuery(context, plan, node, stack);
-
       return handleUnaryNode(context, child, node);
     }
 
     @Override
     public LogicalNode visitScan(GlobalPlanContext context, LogicalPlan plan, ScanNode node, Stack<LogicalNode> stack)
         throws PlanningException {
-      context.topmost = node;
-
       ExecutionBlock newExecBlock = context.plan.newExecutionBlock();
       newExecBlock.setPlan(node);
       context.execBlockMap.put(node.getPID(), newExecBlock);
@@ -498,9 +499,10 @@ public class GlobalPlanner {
     public LogicalNode visitStoreTable(GlobalPlanContext context, LogicalPlan plan, StoreTableNode node,
                                        Stack<LogicalNode> stack) throws PlanningException {
       LogicalNode child = super.visitStoreTable(context, plan, node, stack);
-      context.topmost = node;
 
       ExecutionBlock execBlock = context.execBlockMap.remove(child.getPID());
+      node.setChild(execBlock.getPlan());
+      node.setInSchema(execBlock.getPlan().getOutSchema());
       execBlock.setPlan(node);
       context.execBlockMap.put(node.getPID(), execBlock);
 
@@ -512,8 +514,6 @@ public class GlobalPlanner {
                                    Stack<LogicalNode> stack)
         throws PlanningException {
       LogicalNode child = super.visitInsert(context, plan, node, stack);
-      context.topmost = node;
-
       ExecutionBlock execBlock = context.execBlockMap.remove(child.getPID());
       execBlock.setPlan(node);
       context.execBlockMap.put(node.getPID(), execBlock);

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/469c5a24/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 8b1a82a..4e9721f 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
@@ -44,6 +44,10 @@ public abstract class LogicalNode implements Cloneable, GsonObject {
   public int getPID() {
     return pid;
   }
+
+  public void setPID(int pid) {
+    this.pid = pid;
+  }
 	
 	public NodeType getType() {
 		return this.type;

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/469c5a24/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestSelectQuery.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestSelectQuery.java b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestSelectQuery.java
index 369b4c6..4a4ec81 100644
--- a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestSelectQuery.java
+++ b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestSelectQuery.java
@@ -444,7 +444,6 @@ public class TestSelectQuery {
     } finally {
       res.close();
     }
-
   }
 
   @Test
@@ -461,13 +460,21 @@ public class TestSelectQuery {
 
   @Test
   public final void testLimit() throws Exception {
-    ResultSet res = tpch.execute("select l_orderkey from lineitem limit 3");
+    ResultSet res = tpch.execute("select l_orderkey, l_suppkey from lineitem limit 3");
+
+    int result [][] = {
+        new int [] {1,7706},
+        new int [] {1,7311},
+        new int [] {2,1191},
+    };
+
     try {
-      int count = 0;
-      for (;res.next();) {
-        count++;
+      for (int i = 0; i < 3; i++) {
+        res.next();
+        assertTrue(res.getInt(1) == result[i][0]);
+        assertTrue(res.getInt(2) == result[i][1]);
       }
-      assertEquals(3, count);
+      assertFalse(res.next());
     } finally {
       res.close();
     }