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
