TAJO-1099: LogicalPlanner::convertDataType causes NPE in some cases.

Closes #185


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

Branch: refs/heads/block_iteration
Commit: 561edf3cb5328a5582d743e96ab596da347c1b90
Parents: f42baa0
Author: Hyunsik Choi <[email protected]>
Authored: Wed Oct 8 09:03:28 2014 -0700
Committer: Hyunsik Choi <[email protected]>
Committed: Wed Oct 8 09:03:28 2014 -0700

----------------------------------------------------------------------
 CHANGES                                         |  3 ++
 .../tajo/engine/eval/SimpleEvalNodeVisitor.java |  3 ++
 .../optimizer/eval/EvalTreeOptimizer.java       |  2 ++
 .../engine/planner/LogicalPlanPreprocessor.java | 34 ++++++++++++--------
 .../tajo/engine/planner/TypeDeterminant.java    | 17 ++++++++++
 .../engine/planner/logical/EvalExprNode.java    |  2 ++
 6 files changed, 47 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tajo/blob/561edf3c/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index 8a39f3c..8196cfe 100644
--- a/CHANGES
+++ b/CHANGES
@@ -163,6 +163,9 @@ Release 0.9.0 - unreleased
 
   BUG FIXES
 
+    TAJO-1099: LogicalPlanner::convertDataType causes NPE in some cases.
+    (hyunsik)
+
     TAJO-1102: Self-join with a partitioned table returns wrong result data.
     (Hyoungjun Kim)
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/561edf3c/tajo-core/src/main/java/org/apache/tajo/engine/eval/SimpleEvalNodeVisitor.java
----------------------------------------------------------------------
diff --git 
a/tajo-core/src/main/java/org/apache/tajo/engine/eval/SimpleEvalNodeVisitor.java
 
b/tajo-core/src/main/java/org/apache/tajo/engine/eval/SimpleEvalNodeVisitor.java
index 15b628b..7e7594a 100644
--- 
a/tajo-core/src/main/java/org/apache/tajo/engine/eval/SimpleEvalNodeVisitor.java
+++ 
b/tajo-core/src/main/java/org/apache/tajo/engine/eval/SimpleEvalNodeVisitor.java
@@ -18,6 +18,7 @@
 
 package org.apache.tajo.engine.eval;
 
+import com.google.common.base.Preconditions;
 import org.apache.tajo.exception.UnsupportedException;
 
 import java.util.Stack;
@@ -29,6 +30,8 @@ import java.util.Stack;
 public abstract class SimpleEvalNodeVisitor<CONTEXT> {
 
   public EvalNode visit(CONTEXT context, EvalNode evalNode, Stack<EvalNode> 
stack) {
+    Preconditions.checkNotNull(evalNode);
+
     EvalNode result;
 
     if (evalNode instanceof UnaryEval) {

http://git-wip-us.apache.org/repos/asf/tajo/blob/561edf3c/tajo-core/src/main/java/org/apache/tajo/engine/optimizer/eval/EvalTreeOptimizer.java
----------------------------------------------------------------------
diff --git 
a/tajo-core/src/main/java/org/apache/tajo/engine/optimizer/eval/EvalTreeOptimizer.java
 
b/tajo-core/src/main/java/org/apache/tajo/engine/optimizer/eval/EvalTreeOptimizer.java
index f5b4c06..3ed272e 100644
--- 
a/tajo-core/src/main/java/org/apache/tajo/engine/optimizer/eval/EvalTreeOptimizer.java
+++ 
b/tajo-core/src/main/java/org/apache/tajo/engine/optimizer/eval/EvalTreeOptimizer.java
@@ -18,6 +18,7 @@
 
 package org.apache.tajo.engine.optimizer.eval;
 
+import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -65,6 +66,7 @@ public class EvalTreeOptimizer {
   }
 
   public EvalNode optimize(LogicalPlanner.PlanContext context, EvalNode node) {
+    Preconditions.checkNotNull(node);
 
     EvalNode optimized = node;
     for (EvalTreeOptimizationRule rule : rules) {

http://git-wip-us.apache.org/repos/asf/tajo/blob/561edf3c/tajo-core/src/main/java/org/apache/tajo/engine/planner/LogicalPlanPreprocessor.java
----------------------------------------------------------------------
diff --git 
a/tajo-core/src/main/java/org/apache/tajo/engine/planner/LogicalPlanPreprocessor.java
 
b/tajo-core/src/main/java/org/apache/tajo/engine/planner/LogicalPlanPreprocessor.java
index 96758d6..5897ba6 100644
--- 
a/tajo-core/src/main/java/org/apache/tajo/engine/planner/LogicalPlanPreprocessor.java
+++ 
b/tajo-core/src/main/java/org/apache/tajo/engine/planner/LogicalPlanPreprocessor.java
@@ -162,7 +162,9 @@ public class LogicalPlanPreprocessor extends 
BaseAlgebraVisitor<LogicalPlanner.P
       throws PlanningException {
     // If Non-from statement, it immediately returns.
     if (!expr.hasChild()) {
-      return ctx.plan.createNode(EvalExprNode.class);
+      EvalExprNode exprNode = ctx.plan.createNode(EvalExprNode.class);
+      exprNode.setTargets(buildTargets(ctx, expr.getNamedExprs()));
+      return exprNode;
     }
 
     stack.push(expr); // <--- push
@@ -200,20 +202,8 @@ public class LogicalPlanPreprocessor extends 
BaseAlgebraVisitor<LogicalPlanner.P
       }
     }
 
-    Target [] targets;
-    targets = new Target[projectTargetExprs.length];
+    Target [] targets = buildTargets(ctx, expr.getNamedExprs());
 
-    for (int i = 0; i < expr.getNamedExprs().length; i++) {
-      NamedExpr namedExpr = expr.getNamedExprs()[i];
-      TajoDataTypes.DataType dataType = typeDeterminant.determineDataType(ctx, 
namedExpr.getExpr());
-
-      if (namedExpr.hasAlias()) {
-        targets[i] = new Target(new FieldEval(new Column(namedExpr.getAlias(), 
dataType)));
-      } else {
-        String generatedName = 
ctx.plan.generateUniqueColumnName(namedExpr.getExpr());
-        targets[i] = new Target(new FieldEval(new Column(generatedName, 
dataType)));
-      }
-    }
     stack.pop(); // <--- Pop
 
     ProjectionNode projectionNode = ctx.plan.createNode(ProjectionNode.class);
@@ -224,6 +214,22 @@ public class LogicalPlanPreprocessor extends 
BaseAlgebraVisitor<LogicalPlanner.P
     return projectionNode;
   }
 
+  private Target [] buildTargets(LogicalPlanner.PlanContext context, NamedExpr 
[] exprs) throws PlanningException {
+    Target [] targets = new Target[exprs.length];
+    for (int i = 0; i < exprs.length; i++) {
+      NamedExpr namedExpr = exprs[i];
+      TajoDataTypes.DataType dataType = 
typeDeterminant.determineDataType(context, namedExpr.getExpr());
+
+      if (namedExpr.hasAlias()) {
+        targets[i] = new Target(new FieldEval(new Column(namedExpr.getAlias(), 
dataType)));
+      } else {
+        String generatedName = 
context.plan.generateUniqueColumnName(namedExpr.getExpr());
+        targets[i] = new Target(new FieldEval(new Column(generatedName, 
dataType)));
+      }
+    }
+    return targets;
+  }
+
   @Override
   public LogicalNode visitLimit(LogicalPlanner.PlanContext ctx, Stack<Expr> 
stack, Limit expr)
       throws PlanningException {

http://git-wip-us.apache.org/repos/asf/tajo/blob/561edf3c/tajo-core/src/main/java/org/apache/tajo/engine/planner/TypeDeterminant.java
----------------------------------------------------------------------
diff --git 
a/tajo-core/src/main/java/org/apache/tajo/engine/planner/TypeDeterminant.java 
b/tajo-core/src/main/java/org/apache/tajo/engine/planner/TypeDeterminant.java
index 275e056..94a8d4a 100644
--- 
a/tajo-core/src/main/java/org/apache/tajo/engine/planner/TypeDeterminant.java
+++ 
b/tajo-core/src/main/java/org/apache/tajo/engine/planner/TypeDeterminant.java
@@ -18,6 +18,7 @@
 
 package org.apache.tajo.engine.planner;
 
+import com.google.common.base.Preconditions;
 import org.apache.tajo.algebra.*;
 import org.apache.tajo.catalog.CatalogService;
 import org.apache.tajo.catalog.CatalogUtil;
@@ -77,6 +78,10 @@ public class TypeDeterminant extends 
SimpleAlgebraVisitor<LogicalPlanner.PlanCon
   }
 
   public DataType computeBinaryType(OpType type, DataType lhsDataType, 
DataType rhsDataType) throws PlanningException {
+    Preconditions.checkNotNull(type);
+    Preconditions.checkNotNull(lhsDataType);
+    Preconditions.checkNotNull(rhsDataType);
+
     if(OpType.isLogicalType(type) || OpType.isComparisonType(type)) {
       return BOOL_TYPE;
     } else if (OpType.isArithmeticType(type)) {
@@ -301,4 +306,16 @@ public class TypeDeterminant extends 
SimpleAlgebraVisitor<LogicalPlanner.PlanCon
       throws PlanningException {
     return CatalogUtil.newSimpleDataType(TajoDataTypes.Type.TIME);
   }
+
+  @Override
+  public DataType visitDateLiteral(LogicalPlanner.PlanContext ctx, Stack<Expr> 
stack, DateLiteral expr)
+      throws PlanningException {
+    return CatalogUtil.newSimpleDataType(TajoDataTypes.Type.DATE);
+  }
+
+  @Override
+  public DataType visitIntervalLiteral(LogicalPlanner.PlanContext ctx, 
Stack<Expr> stack, IntervalLiteral expr)
+      throws PlanningException {
+    return CatalogUtil.newSimpleDataType(TajoDataTypes.Type.INTERVAL);
+  }
 }

http://git-wip-us.apache.org/repos/asf/tajo/blob/561edf3c/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/EvalExprNode.java
----------------------------------------------------------------------
diff --git 
a/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/EvalExprNode.java
 
b/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/EvalExprNode.java
index 6ea3f40..45ab611 100644
--- 
a/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/EvalExprNode.java
+++ 
b/tajo-core/src/main/java/org/apache/tajo/engine/planner/logical/EvalExprNode.java
@@ -23,6 +23,7 @@ package org.apache.tajo.engine.planner.logical;
 
 import com.google.gson.annotations.Expose;
 import org.apache.tajo.engine.planner.PlanString;
+import org.apache.tajo.engine.planner.PlannerUtil;
 import org.apache.tajo.engine.planner.Target;
 import org.apache.tajo.util.TUtil;
 
@@ -41,6 +42,7 @@ public class EvalExprNode extends LogicalNode implements 
Projectable {
   @Override
   public void setTargets(Target[] targets) {
     this.exprs = targets;
+    setOutSchema(PlannerUtil.targetToSchema(targets));
   }
 
   @Override

Reply via email to