tajo-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jihoon...@apache.org
Subject [08/10] tajo git commit: TAJO-1499: Check the bind status when EvalNode::eval() is called.
Date Mon, 06 Apr 2015 04:43:03 GMT
TAJO-1499: Check the bind status when EvalNode::eval() is called.

Closes #500


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

Branch: refs/heads/index_support
Commit: 72948b63a79cd8902381c3443699c887b2740491
Parents: 4eb8713
Author: Jihoon Son <jihoonson@apache.org>
Authored: Mon Apr 6 13:37:56 2015 +0900
Committer: Jihoon Son <jihoonson@apache.org>
Committed: Mon Apr 6 13:37:56 2015 +0900

----------------------------------------------------------------------
 CHANGES                                         |   2 +
 .../planner/physical/ComparableVector.java      |  35 +++---
 .../org/apache/tajo/engine/utils/TupleUtil.java |  31 ------
 .../apache/tajo/master/exec/QueryExecutor.java  |   1 +
 .../apache/tajo/engine/eval/TestEvalTree.java   | 107 ++++++++++++++-----
 .../tajo/engine/eval/TestEvalTreeUtil.java      |  12 +--
 .../org/apache/tajo/plan/LogicalPlanner.java    |   1 +
 .../plan/expr/AggregationFunctionCallEval.java  |   6 ++
 .../apache/tajo/plan/expr/AlgebraicUtil.java    |   6 +-
 .../tajo/plan/expr/BetweenPredicateEval.java    |   5 +-
 .../org/apache/tajo/plan/expr/BinaryEval.java   |   1 +
 .../org/apache/tajo/plan/expr/CaseWhenEval.java |   2 +
 .../org/apache/tajo/plan/expr/CastEval.java     |   1 +
 .../org/apache/tajo/plan/expr/ConstEval.java    |   1 +
 .../org/apache/tajo/plan/expr/EvalNode.java     |  13 ++-
 .../org/apache/tajo/plan/expr/FieldEval.java    |   5 +-
 .../org/apache/tajo/plan/expr/FunctionEval.java |   5 +-
 .../tajo/plan/expr/GeneralFunctionEval.java     |   1 +
 .../java/org/apache/tajo/plan/expr/InEval.java  |   3 +
 .../org/apache/tajo/plan/expr/IsNullEval.java   |   1 +
 .../java/org/apache/tajo/plan/expr/NotEval.java |   1 +
 .../plan/expr/PatternMatchPredicateEval.java    |   6 +-
 .../apache/tajo/plan/expr/RowConstantEval.java  |   1 +
 .../org/apache/tajo/plan/expr/SignedEval.java   |   1 +
 .../org/apache/tajo/plan/expr/UnaryEval.java    |   1 +
 .../tajo/plan/expr/WindowFunctionEval.java      |   3 +
 26 files changed, 165 insertions(+), 87 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tajo/blob/72948b63/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index 7ea0b5e..90fa245 100644
--- a/CHANGES
+++ b/CHANGES
@@ -11,6 +11,8 @@ Release 0.11.0 - unreleased
 
   IMPROVEMENT
 
+    TAJO-1499: Check the bind status when EvalNode::eval() is called. (jihoon)
+
     TAJO-1400: Add TajoStatement::setMaxRows method support.
     (Contributed by YeonSu Han, Committed by jihoon)
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/72948b63/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/ComparableVector.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/ComparableVector.java
b/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/ComparableVector.java
index 39b8c8a..9940608 100644
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/ComparableVector.java
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/ComparableVector.java
@@ -225,24 +225,27 @@ public class ComparableVector {
 
     @Override
     public boolean equals(Object obj) {
-      ComparableTuple other = (ComparableTuple)obj;
-      for (int i = 0; i < keys.length; i++) {
-        final boolean n1 = keys[i] == null;
-        final boolean n2 = other.keys[i] == null;
-        if (n1 && n2) {
-          continue;
-        }
-        if (n1 ^ n2) {
-          return false;
-        }
-        switch (keyTypes[i]) {
-          case TEXT:
-          case CHAR:
-          case BLOB: if (!Arrays.equals((byte[])keys[i], (byte[])other.keys[i])) return false;
continue;
-          default: if (!keys[i].equals(other.keys[i])) return false; continue;
+      if (obj instanceof ComparableTuple) {
+        ComparableTuple other = (ComparableTuple)obj;
+        for (int i = 0; i < keys.length; i++) {
+          final boolean n1 = keys[i] == null;
+          final boolean n2 = other.keys[i] == null;
+          if (n1 && n2) {
+            continue;
+          }
+          if (n1 ^ n2) {
+            return false;
+          }
+          switch (keyTypes[i]) {
+            case TEXT:
+            case CHAR:
+            case BLOB: if (!Arrays.equals((byte[])keys[i], (byte[])other.keys[i])) return
false; continue;
+            default: if (!keys[i].equals(other.keys[i])) return false; continue;
+          }
         }
+        return true;
       }
-      return true;
+      return false;
     }
 
     public boolean equals(Tuple tuple) {

http://git-wip-us.apache.org/repos/asf/tajo/blob/72948b63/tajo-core/src/main/java/org/apache/tajo/engine/utils/TupleUtil.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/utils/TupleUtil.java b/tajo-core/src/main/java/org/apache/tajo/engine/utils/TupleUtil.java
index 6b2c37c..3a0a1c7 100644
--- a/tajo-core/src/main/java/org/apache/tajo/engine/utils/TupleUtil.java
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/utils/TupleUtil.java
@@ -193,35 +193,4 @@ public class TupleUtil {
     }
     return aTuple;
   }
-
-  @SuppressWarnings("unused")
-  public static Collection<Tuple> filterTuple(Schema schema, Collection<Tuple>
tupleBlock, EvalNode filterCondition) {
-    TupleBlockFilterScanner filter = new TupleBlockFilterScanner(schema, tupleBlock, filterCondition);
-    return filter.nextBlock();
-  }
-
-  private static class TupleBlockFilterScanner {
-    private EvalNode qual;
-    private Iterator<Tuple> iterator;
-    private Schema schema;
-
-    public TupleBlockFilterScanner(Schema schema, Collection<Tuple> tuples, EvalNode
qual) {
-      this.schema = schema;
-      this.qual = qual;
-      this.iterator = tuples.iterator();
-    }
-
-    public List<Tuple> nextBlock() {
-      List<Tuple> results = Lists.newArrayList();
-
-      Tuple tuple;
-      while (iterator.hasNext()) {
-        tuple = iterator.next();
-        if (qual.eval(tuple).isTrue()) {
-          results.add(tuple);
-        }
-      }
-      return results;
-    }
-  }
 }

http://git-wip-us.apache.org/repos/asf/tajo/blob/72948b63/tajo-core/src/main/java/org/apache/tajo/master/exec/QueryExecutor.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/master/exec/QueryExecutor.java b/tajo-core/src/main/java/org/apache/tajo/master/exec/QueryExecutor.java
index cec1125..2eb3c5f 100644
--- a/tajo-core/src/main/java/org/apache/tajo/master/exec/QueryExecutor.java
+++ b/tajo-core/src/main/java/org/apache/tajo/master/exec/QueryExecutor.java
@@ -274,6 +274,7 @@ public class QueryExecutor {
     final Tuple outTuple = new VTuple(targets.length);
     for (int i = 0; i < targets.length; i++) {
       EvalNode eval = targets[i].getEvalTree();
+      eval.bind(null);
       outTuple.put(i, eval.eval(null));
     }
     boolean isInsert = rootNode.getChild() != null && rootNode.getChild().getType()
== NodeType.INSERT;

http://git-wip-us.apache.org/repos/asf/tajo/blob/72948b63/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestEvalTree.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestEvalTree.java b/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestEvalTree.java
index f03988b..a2d0598 100644
--- a/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestEvalTree.java
+++ b/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestEvalTree.java
@@ -19,7 +19,9 @@
 package org.apache.tajo.engine.eval;
 
 import org.apache.tajo.catalog.CatalogUtil;
+import org.apache.tajo.catalog.Column;
 import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.common.TajoDataTypes;
 import org.apache.tajo.common.TajoDataTypes.DataType;
 import org.apache.tajo.datum.Datum;
 import org.apache.tajo.datum.DatumFactory;
@@ -31,6 +33,7 @@ import org.junit.Test;
 
 import static org.apache.tajo.common.TajoDataTypes.Type.*;
 import static org.junit.Assert.*;
+import static org.junit.Assert.fail;
 
 public class TestEvalTree extends ExprTestBase {
   @Test
@@ -79,6 +82,7 @@ public class TestEvalTree extends ExprTestBase {
 
     @Override
     public Datum eval(Tuple tuple) {
+      super.eval(tuple);
       return DatumFactory.createBool(true);
     }
 
@@ -111,6 +115,7 @@ public class TestEvalTree extends ExprTestBase {
 
     @Override
     public Datum eval(Tuple tuple) {
+      super.eval(tuple);
       return DatumFactory.createBool(false);
     }
 
@@ -156,15 +161,19 @@ public class TestEvalTree extends ExprTestBase {
     MockFalseExpr falseExpr = new MockFalseExpr();
 
     BinaryEval andExpr = new BinaryEval(EvalType.AND, trueExpr, trueExpr);
+    andExpr.bind(null);
     assertTrue(andExpr.eval(null).asBool());
 
     andExpr = new BinaryEval(EvalType.AND, falseExpr, trueExpr);
+    andExpr.bind(null);
     assertFalse(andExpr.eval(null).asBool());
 
     andExpr = new BinaryEval(EvalType.AND, trueExpr, falseExpr);
+    andExpr.bind(null);
     assertFalse(andExpr.eval(null).asBool());
 
     andExpr = new BinaryEval(EvalType.AND, falseExpr, falseExpr);
+    andExpr.bind(null);
     assertFalse(andExpr.eval(null).asBool());
   }
 
@@ -174,15 +183,19 @@ public class TestEvalTree extends ExprTestBase {
     MockFalseExpr falseExpr = new MockFalseExpr();
 
     BinaryEval orExpr = new BinaryEval(EvalType.OR, trueExpr, trueExpr);
+    orExpr.bind(null);
     assertTrue(orExpr.eval(null).asBool());
 
     orExpr = new BinaryEval(EvalType.OR, falseExpr, trueExpr);
+    orExpr.bind(null);
     assertTrue(orExpr.eval(null).asBool());
 
     orExpr = new BinaryEval(EvalType.OR, trueExpr, falseExpr);
+    orExpr.bind(null);
     assertTrue(orExpr.eval(null).asBool());
 
     orExpr = new BinaryEval(EvalType.OR, falseExpr, falseExpr);
+    orExpr.bind(null);
     assertFalse(orExpr.eval(null).asBool());
   }
 
@@ -196,41 +209,41 @@ public class TestEvalTree extends ExprTestBase {
     e1 = new ConstEval(DatumFactory.createInt4(9));
     e2 = new ConstEval(DatumFactory.createInt4(34));
     expr = new BinaryEval(EvalType.LTH, e1, e2);
-    assertTrue(expr.eval(null).asBool());
+    assertTrue(expr.bind(null).eval(null).asBool());
     expr = new BinaryEval(EvalType.LEQ, e1, e2);
-    assertTrue(expr.eval(null).asBool());
+    assertTrue(expr.bind(null).eval(null).asBool());
     expr = new BinaryEval(EvalType.LTH, e2, e1);
-    assertFalse(expr.eval(null).asBool());
+    assertFalse(expr.bind(null).eval(null).asBool());
     expr = new BinaryEval(EvalType.LEQ, e2, e1);
-    assertFalse(expr.eval(null).asBool());
+    assertFalse(expr.bind(null).eval(null).asBool());
 
     expr = new BinaryEval(EvalType.GTH, e2, e1);
-    assertTrue(expr.eval(null).asBool());
+    assertTrue(expr.bind(null).eval(null).asBool());
     expr = new BinaryEval(EvalType.GEQ, e2, e1);
-    assertTrue(expr.eval(null).asBool());
+    assertTrue(expr.bind(null).eval(null).asBool());
     expr = new BinaryEval(EvalType.GTH, e1, e2);
-    assertFalse(expr.eval(null).asBool());
+    assertFalse(expr.bind(null).eval(null).asBool());
     expr = new BinaryEval(EvalType.GEQ, e1, e2);
-    assertFalse(expr.eval(null).asBool());
+    assertFalse(expr.bind(null).eval(null).asBool());
 
     BinaryEval plus = new BinaryEval(EvalType.PLUS, e1, e2);
     expr = new BinaryEval(EvalType.LTH, e1, plus);
-    assertTrue(expr.eval(null).asBool());
+    assertTrue(expr.bind(null).eval(null).asBool());
     expr = new BinaryEval(EvalType.LEQ, e1, plus);
-    assertTrue(expr.eval(null).asBool());
+    assertTrue(expr.bind(null).eval(null).asBool());
     expr = new BinaryEval(EvalType.LTH, plus, e1);
-    assertFalse(expr.eval(null).asBool());
+    assertFalse(expr.bind(null).eval(null).asBool());
     expr = new BinaryEval(EvalType.LEQ, plus, e1);
-    assertFalse(expr.eval(null).asBool());
+    assertFalse(expr.bind(null).eval(null).asBool());
 
     expr = new BinaryEval(EvalType.GTH, plus, e1);
-    assertTrue(expr.eval(null).asBool());
+    assertTrue(expr.bind(null).eval(null).asBool());
     expr = new BinaryEval(EvalType.GEQ, plus, e1);
-    assertTrue(expr.eval(null).asBool());
+    assertTrue(expr.bind(null).eval(null).asBool());
     expr = new BinaryEval(EvalType.GTH, e1, plus);
-    assertFalse(expr.eval(null).asBool());
+    assertFalse(expr.bind(null).eval(null).asBool());
     expr = new BinaryEval(EvalType.GEQ, e1, plus);
-    assertFalse(expr.eval(null).asBool());
+    assertFalse(expr.bind(null).eval(null).asBool());
   }
 
   @Test
@@ -243,28 +256,28 @@ public class TestEvalTree extends ExprTestBase {
     e1 = new ConstEval(DatumFactory.createInt4(9));
     e2 = new ConstEval(DatumFactory.createInt4(34));
     BinaryEval expr = new BinaryEval(EvalType.PLUS, e1, e2);
-    assertEquals(expr.eval(null).asInt4(), 43);
+    assertEquals(expr.bind(null).eval(null).asInt4(), 43);
     assertCloneEqual(expr);
     
     // MINUS
     e1 = new ConstEval(DatumFactory.createInt4(5));
     e2 = new ConstEval(DatumFactory.createInt4(2));
     expr = new BinaryEval(EvalType.MINUS, e1, e2);
-    assertEquals(expr.eval(null).asInt4(), 3);
+    assertEquals(expr.bind(null).eval(null).asInt4(), 3);
     assertCloneEqual(expr);
     
     // MULTIPLY
     e1 = new ConstEval(DatumFactory.createInt4(5));
     e2 = new ConstEval(DatumFactory.createInt4(2));
     expr = new BinaryEval(EvalType.MULTIPLY, e1, e2);
-    assertEquals(expr.eval(null).asInt4(), 10);
+    assertEquals(expr.bind(null).eval(null).asInt4(), 10);
     assertCloneEqual(expr);
     
     // DIVIDE
     e1 = new ConstEval(DatumFactory.createInt4(10));
     e2 = new ConstEval(DatumFactory.createInt4(5));
     expr = new BinaryEval(EvalType.DIVIDE, e1, e2);
-    assertEquals(expr.eval(null).asInt4(), 2);
+    assertEquals(expr.bind(null).eval(null).asInt4(), 2);
     assertCloneEqual(expr);
   }
 
@@ -280,7 +293,7 @@ public class TestEvalTree extends ExprTestBase {
     assertEquals(CatalogUtil.newSimpleDataType(INT4), expr.getValueType());
 
     expr = new BinaryEval(EvalType.LTH, e1, e2);
-    assertTrue(expr.eval(null).asBool());
+    assertTrue(expr.bind(null).eval(null).asBool());
     assertEquals(CatalogUtil.newSimpleDataType(BOOLEAN), expr.getValueType());
 
     e1 = new ConstEval(DatumFactory.createFloat8(9.3));
@@ -350,11 +363,57 @@ public class TestEvalTree extends ExprTestBase {
     assertEquals(e3.getType(), eval.getLeftExpr().getType());
     assertEquals(plus3.getType(), eval.getRightExpr().getType());
     assertEquals(plus3.getLeftExpr(), ((BinaryEval)eval.getRightExpr()).getLeftExpr());
-    assertEquals(plus3.getRightExpr(), ((BinaryEval)eval.getRightExpr()).getRightExpr());
+    assertEquals(plus3.getRightExpr(), ((BinaryEval) eval.getRightExpr()).getRightExpr());
     assertEquals(plus2.getLeftExpr(), ((BinaryEval)((BinaryEval)eval.getRightExpr()).getLeftExpr()).getLeftExpr());
     assertEquals(plus2.getRightExpr(), ((BinaryEval)((BinaryEval)eval.getRightExpr()).getLeftExpr()).getRightExpr());
-    assertEquals(plus1.getLeftExpr(), ((BinaryEval)((BinaryEval)eval.getRightExpr()).getRightExpr()).getLeftExpr());
-    assertEquals(plus1.getRightExpr(), ((BinaryEval)((BinaryEval)eval.getRightExpr()).getRightExpr()).getRightExpr());
+    assertEquals(plus1.getLeftExpr(), ((BinaryEval) ((BinaryEval) eval.getRightExpr()).getRightExpr()).getLeftExpr());
+    assertEquals(plus1.getRightExpr(), ((BinaryEval) ((BinaryEval) eval.getRightExpr()).getRightExpr()).getRightExpr());
+  }
+
+  @Test
+  public final void testBindCheck() {
+    ConstEval e1;
+    ConstEval e2;
+    BinaryEval binEval;
+
+    // Constant
+    e1 = new ConstEval(DatumFactory.createInt4(9));
+    e2 = new ConstEval(DatumFactory.createInt4(34));
+    binEval = new BinaryEval(EvalType.LTH, e1, e2);
+    try {
+      binEval.eval(null);
+      fail("EvalNode is not binded");
+    } catch (IllegalStateException e) {
+      assertTrue(binEval.bind(null).eval(null).asBool());
+    }
+
+    CaseWhenEval caseWhenEval = new CaseWhenEval();
+    caseWhenEval.addIfCond(new CaseWhenEval.IfThenEval(binEval, new ConstEval(DatumFactory.createInt4(1))));
+    try {
+      caseWhenEval.eval(null);
+      fail("EvalNode is not binded");
+    } catch (IllegalStateException e) {
+      assertEquals(caseWhenEval.bind(null).eval(null).asInt4(), 1);
+    }
+
+    Schema schema = new Schema(new Column[]{new Column("test", TajoDataTypes.Type.INT4)});
+    Tuple tuple = new VTuple(new Datum[]{DatumFactory.createText("aaa")});
+    RegexPredicateEval regexEval = new RegexPredicateEval(false, new FieldEval("test",
+        CatalogUtil.newSimpleDataType(TajoDataTypes.Type.INT4)), new ConstEval(DatumFactory.createText("a*")),
false);
+    try {
+      regexEval.eval(null);
+      fail("EvalNode is not binded");
+    } catch (IllegalStateException e) {
+      assertEquals(regexEval.bind(schema).eval(tuple).asBool(), true);
+    }
+
+    RowConstantEval rowConstantEval = new RowConstantEval(new Datum[]{});
+    try {
+      rowConstantEval.eval(null);
+      fail("EvalNode is not binded");
+    } catch (IllegalStateException e) {
+      assertEquals(rowConstantEval.bind(null).eval(null).isNull(), true);
+    }
   }
   
   private void assertCloneEqual(EvalNode eval) throws CloneNotSupportedException {

http://git-wip-us.apache.org/repos/asf/tajo/blob/72948b63/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestEvalTreeUtil.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestEvalTreeUtil.java b/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestEvalTreeUtil.java
index 61c55e1..e23a34b 100644
--- a/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestEvalTreeUtil.java
+++ b/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestEvalTreeUtil.java
@@ -265,12 +265,12 @@ public class TestEvalTreeUtil {
     FieldEval field = first.getLeftExpr();
     assertEquals(col1, field.getColumnRef());
     assertEquals(EvalType.LTH, first.getType());
-    assertEquals(10, first.getRightExpr().eval(null).asInt4());
+    assertEquals(10, first.getRightExpr().bind(null).eval(null).asInt4());
     
     field = second.getRightExpr();
     assertEquals(col1, field.getColumnRef());
     assertEquals(EvalType.LTH, second.getType());
-    assertEquals(4, second.getLeftExpr().eval(null).asInt4());
+    assertEquals(4, second.getLeftExpr().bind(null).eval(null).asInt4());
   }
   
   @Test
@@ -304,10 +304,10 @@ public class TestEvalTreeUtil {
     Target [] targets = getRawTargets(QUERIES[0]);
     EvalNode node = AlgebraicUtil.eliminateConstantExprs(targets[0].getEvalTree());
     assertEquals(EvalType.CONST, node.getType());
-    assertEquals(7, node.eval(null).asInt4());
+    assertEquals(7, node.bind(null).eval(null).asInt4());
     node = AlgebraicUtil.eliminateConstantExprs(targets[1].getEvalTree());
     assertEquals(EvalType.CONST, node.getType());
-    assertTrue(7.0d == node.eval(null).asFloat8());
+    assertTrue(7.0d == node.bind(null).eval(null).asFloat8());
 
     Expr expr = analyzer.parse(QUERIES[1]);
     LogicalPlan plan = planner.createPlan(defaultContext, expr, true);
@@ -335,7 +335,7 @@ public class TestEvalTreeUtil {
     assertEquals(EvalType.GTH, transposed.getType());
     FieldEval field = transposed.getLeftExpr();
     assertEquals(col1, field.getColumnRef());
-    assertEquals(1, transposed.getRightExpr().eval(null).asInt4());
+    assertEquals(1, transposed.getRightExpr().bind(null).eval(null).asInt4());
 
     node = getRootSelection(QUERIES[4]);
     // we expect that score < 3
@@ -343,7 +343,7 @@ public class TestEvalTreeUtil {
     assertEquals(EvalType.LTH, transposed.getType());
     field = transposed.getLeftExpr();
     assertEquals(col1, field.getColumnRef());
-    assertEquals(2, transposed.getRightExpr().eval(null).asInt4());
+    assertEquals(2, transposed.getRightExpr().bind(null).eval(null).asInt4());
   }
 
   @Test

http://git-wip-us.apache.org/repos/asf/tajo/blob/72948b63/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java b/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java
index d6a04a6..d7c631b 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java
@@ -810,6 +810,7 @@ public class LogicalPlanner extends BaseAlgebraVisitor<LogicalPlanner.PlanContex
     limitNode.setInSchema(child.getOutSchema());
     limitNode.setOutSchema(child.getOutSchema());
 
+    firstFetNum.bind(null);
     limitNode.setFetchFirst(firstFetNum.eval(null).asInt8());
 
     return limitNode;

http://git-wip-us.apache.org/repos/asf/tajo/blob/72948b63/tajo-plan/src/main/java/org/apache/tajo/plan/expr/AggregationFunctionCallEval.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/AggregationFunctionCallEval.java
b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/AggregationFunctionCallEval.java
index 984d18c..5549e2e 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/AggregationFunctionCallEval.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/AggregationFunctionCallEval.java
@@ -50,6 +50,9 @@ public class AggregationFunctionCallEval extends FunctionEval implements
Cloneab
   }
 
   public void merge(FunctionContext context, Tuple tuple) {
+    if (!isBinded) {
+      throw new IllegalStateException("bind() must be called before merge()");
+    }
     mergeParam(context, evalParams(tuple));
   }
 
@@ -68,6 +71,9 @@ public class AggregationFunctionCallEval extends FunctionEval implements
Cloneab
   }
 
   public Datum terminate(FunctionContext context) {
+    if (!isBinded) {
+      throw new IllegalStateException("bind() must be called before terminate()");
+    }
     if (!finalPhase) {
       return instance.getPartialResult(context);
     } else {

http://git-wip-us.apache.org/repos/asf/tajo/blob/72948b63/tajo-plan/src/main/java/org/apache/tajo/plan/expr/AlgebraicUtil.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/AlgebraicUtil.java b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/AlgebraicUtil.java
index f697968..fb05f33 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/AlgebraicUtil.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/AlgebraicUtil.java
@@ -149,7 +149,7 @@ public class AlgebraicUtil {
       }
 
       if (lhs.getType() == EvalType.CONST && rhs.getType() == EvalType.CONST) {
-        return new ConstEval(binaryEval.eval(null));
+        return new ConstEval(binaryEval.bind(null).eval(null));
       }
 
       return binaryEval;
@@ -162,7 +162,7 @@ public class AlgebraicUtil {
       stack.pop();
 
       if (child.getType() == EvalType.CONST) {
-        return new ConstEval(unaryEval.eval(null));
+        return new ConstEval(unaryEval.bind(null).eval(null));
       }
 
       return unaryEval;
@@ -184,7 +184,7 @@ public class AlgebraicUtil {
       }
 
       if (constantOfAllDescendents && evalNode.getType() == EvalType.FUNCTION) {
-        return new ConstEval(evalNode.eval(null));
+        return new ConstEval(evalNode.bind(null).eval(null));
       } else {
         return evalNode;
       }

http://git-wip-us.apache.org/repos/asf/tajo/blob/72948b63/tajo-plan/src/main/java/org/apache/tajo/plan/expr/BetweenPredicateEval.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/BetweenPredicateEval.java b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/BetweenPredicateEval.java
index 3969f63..2db4368 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/BetweenPredicateEval.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/BetweenPredicateEval.java
@@ -227,7 +227,8 @@ public class BetweenPredicateEval extends EvalNode implements Cloneable
{
   }
 
   @Override
-  public void bind(Schema schema) {
+  public EvalNode bind(Schema schema) {
+    super.bind(schema);
     if (begin.getType() == EvalType.CONST && end.getType() == EvalType.CONST) {
       Datum beginValue = ((ConstEval)begin).getValue();
       Datum endValue = ((ConstEval)end).getValue();
@@ -245,11 +246,13 @@ public class BetweenPredicateEval extends EvalNode implements Cloneable
{
       }
     }
     checker.bind(schema);
+    return this;
   }
 
   @Override
   @SuppressWarnings("unchecked")
   public Datum eval(Tuple tuple) {
+    super.eval(tuple);
     return checker.eval(tuple);
   }
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/72948b63/tajo-plan/src/main/java/org/apache/tajo/plan/expr/BinaryEval.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/BinaryEval.java b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/BinaryEval.java
index e189a36..531cb9f 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/BinaryEval.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/BinaryEval.java
@@ -119,6 +119,7 @@ public class BinaryEval extends EvalNode implements Cloneable {
   @Override
   @SuppressWarnings("unchecked")
   public Datum eval(Tuple tuple) {
+    super.eval(tuple);
     Datum lhs = leftExpr.eval(tuple);
     Datum rhs = rightExpr.eval(tuple);
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/72948b63/tajo-plan/src/main/java/org/apache/tajo/plan/expr/CaseWhenEval.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/CaseWhenEval.java b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/CaseWhenEval.java
index c25ad45..2f40974 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/CaseWhenEval.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/CaseWhenEval.java
@@ -107,6 +107,7 @@ public class CaseWhenEval extends EvalNode implements GsonObject {
   @Override
   @SuppressWarnings("unchecked")
   public Datum eval(Tuple tuple) {
+    super.eval(tuple);
     for (IfThenEval eval : whens) {
       if (eval.checkIfCondition(tuple)) {
         return eval.eval(tuple);
@@ -233,6 +234,7 @@ public class CaseWhenEval extends EvalNode implements GsonObject {
     @Override
     @SuppressWarnings("unchecked")
     public Datum eval(Tuple tuple) {
+      super.eval(tuple);
       return result.eval(tuple);
     }
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/72948b63/tajo-plan/src/main/java/org/apache/tajo/plan/expr/CastEval.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/CastEval.java b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/CastEval.java
index 5a26593..f174b79 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/CastEval.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/CastEval.java
@@ -70,6 +70,7 @@ public class CastEval extends UnaryEval {
   @Override
   @SuppressWarnings("unchecked")
   public Datum eval(Tuple tuple) {
+    super.eval(tuple);
     Datum operandDatum = child.eval(tuple);
     if (operandDatum.isNull()) {
       return operandDatum;

http://git-wip-us.apache.org/repos/asf/tajo/blob/72948b63/tajo-plan/src/main/java/org/apache/tajo/plan/expr/ConstEval.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/ConstEval.java b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/ConstEval.java
index 82e4e8e..ff964e6 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/ConstEval.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/ConstEval.java
@@ -45,6 +45,7 @@ public class ConstEval extends EvalNode implements Comparable<ConstEval>,
Clonea
   @Override
   @SuppressWarnings("unchecked")
   public Datum eval(Tuple tuple) {
+    super.eval(tuple);
     return datum;
   }
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/72948b63/tajo-plan/src/main/java/org/apache/tajo/plan/expr/EvalNode.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/EvalNode.java b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/EvalNode.java
index f57302a..154b0fd 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/EvalNode.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/EvalNode.java
@@ -35,6 +35,7 @@ import org.apache.tajo.storage.Tuple;
  */
 public abstract class EvalNode implements Cloneable, GsonObject, ProtoObject<PlanProto.EvalNodeTree>
{
 	@Expose protected EvalType type;
+  protected boolean isBinded = false;
 
   public EvalNode() {
   }
@@ -60,13 +61,20 @@ public abstract class EvalNode implements Cloneable, GsonObject, ProtoObject<Pla
     return PlanGsonHelper.toJson(this, EvalNode.class);
 	}
 
-  public void bind(Schema schema) {
+  public EvalNode bind(Schema schema) {
     for (int i = 0; i < childNum(); i++) {
       getChild(i).bind(schema);
     }
+    isBinded = true;
+    return this;
   }
 
-	public abstract <T extends Datum> T eval(Tuple tuple);
+	public <T extends Datum> T eval(Tuple tuple) {
+    if (!isBinded) {
+      throw new IllegalStateException("bind() must be called before eval()");
+    }
+    return null;
+  }
 
   @Deprecated
   public abstract void preOrder(EvalNodeVisitor visitor);
@@ -78,6 +86,7 @@ public abstract class EvalNode implements Cloneable, GsonObject, ProtoObject<Pla
   public Object clone() throws CloneNotSupportedException {
     EvalNode evalNode = (EvalNode) super.clone();
     evalNode.type = type;
+    evalNode.isBinded = isBinded;
     return evalNode;
   }
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/72948b63/tajo-plan/src/main/java/org/apache/tajo/plan/expr/FieldEval.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/FieldEval.java b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/FieldEval.java
index 11b3b6d..83d00b9 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/FieldEval.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/FieldEval.java
@@ -40,7 +40,8 @@ public class FieldEval extends EvalNode implements Cloneable {
 	}
 
   @Override
-  public void bind(Schema schema) {
+  public EvalNode bind(Schema schema) {
+    super.bind(schema);
     // TODO - column namespace should be improved to simplify name handling and resolving.
     if (column.hasQualifier()) {
       fieldId = schema.getColumnId(column.getQualifiedName());
@@ -50,11 +51,13 @@ public class FieldEval extends EvalNode implements Cloneable {
     if (fieldId == -1) {
       throw new IllegalStateException("No Such Column Reference: " + column + ", schema:
" + schema);
     }
+    return this;
   }
 
 	@Override
   @SuppressWarnings("unchecked")
 	public Datum eval(Tuple tuple) {
+    super.eval(tuple);
 	  return tuple.get(fieldId);
   }
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/72948b63/tajo-plan/src/main/java/org/apache/tajo/plan/expr/FunctionEval.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/FunctionEval.java b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/FunctionEval.java
index 0c60c8d..4ff7548 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/FunctionEval.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/FunctionEval.java
@@ -33,7 +33,7 @@ import static org.apache.tajo.catalog.proto.CatalogProtos.FunctionType.DISTINCT_
 import static org.apache.tajo.catalog.proto.CatalogProtos.FunctionType.DISTINCT_UDA;
 
 public abstract class FunctionEval extends EvalNode implements Cloneable {
-  public static enum ParamType {
+  public enum ParamType {
     CONSTANT, VARIABLE, NULL
   }
 
@@ -49,9 +49,10 @@ public abstract class FunctionEval extends EvalNode implements Cloneable
{
 	}
 
   @Override
-  public void bind(Schema schema) {
+  public EvalNode bind(Schema schema) {
     super.bind(schema);
     this.params = new VTuple(argEvals.length);
+    return this;
   }
 
   protected final Tuple evalParams(Tuple tuple) {

http://git-wip-us.apache.org/repos/asf/tajo/blob/72948b63/tajo-plan/src/main/java/org/apache/tajo/plan/expr/GeneralFunctionEval.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/GeneralFunctionEval.java b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/GeneralFunctionEval.java
index 747e8ba..2ce7850 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/GeneralFunctionEval.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/GeneralFunctionEval.java
@@ -42,6 +42,7 @@ public class GeneralFunctionEval extends FunctionEval {
   @Override
   @SuppressWarnings("unchecked")
   public Datum eval(Tuple tuple) {
+    super.eval(tuple);
     return instance.eval(evalParams(tuple));
   }
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/72948b63/tajo-plan/src/main/java/org/apache/tajo/plan/expr/InEval.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/InEval.java b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/InEval.java
index c222bef..c968bda 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/InEval.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/InEval.java
@@ -58,6 +58,9 @@ public class InEval extends BinaryEval {
 
   @Override
   public Datum eval(Tuple tuple) {
+    if (!isBinded) {
+      throw new IllegalStateException("bind() must be called before eval()");
+    }
     if (values == null) {
       values = Sets.newHashSet(((RowConstantEval)rightExpr).getValues());
     }

http://git-wip-us.apache.org/repos/asf/tajo/blob/72948b63/tajo-plan/src/main/java/org/apache/tajo/plan/expr/IsNullEval.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/IsNullEval.java b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/IsNullEval.java
index 496f64d..72b36eb 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/IsNullEval.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/IsNullEval.java
@@ -58,6 +58,7 @@ public class IsNullEval extends UnaryEval {
   @Override
   @SuppressWarnings("unchecked")
   public Datum eval(Tuple tuple) {
+    super.eval(tuple);
     boolean isNull = child.eval(tuple).isNull();
     return DatumFactory.createBool(isNot ^ isNull);
   }

http://git-wip-us.apache.org/repos/asf/tajo/blob/72948b63/tajo-plan/src/main/java/org/apache/tajo/plan/expr/NotEval.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/NotEval.java b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/NotEval.java
index ccec0fe..088f3a5 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/NotEval.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/NotEval.java
@@ -45,6 +45,7 @@ public class NotEval extends UnaryEval implements Cloneable {
   @Override
   @SuppressWarnings("unchecked")
   public Datum eval(Tuple tuple) {
+    super.eval(tuple);
     Datum datum = child.eval(tuple);
     return !datum.isNull() ? DatumFactory.createBool(!datum.asBool()) : datum;
   }

http://git-wip-us.apache.org/repos/asf/tajo/blob/72948b63/tajo-plan/src/main/java/org/apache/tajo/plan/expr/PatternMatchPredicateEval.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/PatternMatchPredicateEval.java
b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/PatternMatchPredicateEval.java
index a5d055d..6faa667 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/PatternMatchPredicateEval.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/PatternMatchPredicateEval.java
@@ -74,13 +74,17 @@ public abstract class PatternMatchPredicateEval extends BinaryEval {
   }
 
   @Override
-  public void bind(Schema schema) {
+  public EvalNode bind(Schema schema) {
     super.bind(schema);
     compile(pattern);
+    return this;
   }
 
   @Override
   public Datum eval(Tuple tuple) {
+    if (!isBinded) {
+      throw new IllegalStateException("bind() must be called before eval()");
+    }
     Datum predicand = leftExpr.eval(tuple);
     if (predicand.isNull()) {
       return NullDatum.get();

http://git-wip-us.apache.org/repos/asf/tajo/blob/72948b63/tajo-plan/src/main/java/org/apache/tajo/plan/expr/RowConstantEval.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/RowConstantEval.java b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/RowConstantEval.java
index b81c352..153a150 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/RowConstantEval.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/RowConstantEval.java
@@ -61,6 +61,7 @@ public class RowConstantEval extends EvalNode {
   @Override
   @SuppressWarnings("unchecked")
   public Datum eval(Tuple tuple) {
+    super.eval(tuple);
     return NullDatum.get();
   }
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/72948b63/tajo-plan/src/main/java/org/apache/tajo/plan/expr/SignedEval.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/SignedEval.java b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/SignedEval.java
index 9d077ba..baa78a2 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/SignedEval.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/SignedEval.java
@@ -50,6 +50,7 @@ public class SignedEval extends UnaryEval implements Cloneable {
   @Override
   @SuppressWarnings("unchecked")
   public Datum eval(Tuple tuple) {
+    super.eval(tuple);
     NumericDatum result = child.eval(tuple);
     if (negative) {
       return result.inverseSign();

http://git-wip-us.apache.org/repos/asf/tajo/blob/72948b63/tajo-plan/src/main/java/org/apache/tajo/plan/expr/UnaryEval.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/UnaryEval.java b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/UnaryEval.java
index 237db00..4db2b90 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/UnaryEval.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/UnaryEval.java
@@ -67,6 +67,7 @@ public abstract class UnaryEval extends EvalNode implements Cloneable {
 
   @Override
   public <T extends Datum> T eval(Tuple tuple) {
+    super.eval(tuple);
     return null;
   }
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/72948b63/tajo-plan/src/main/java/org/apache/tajo/plan/expr/WindowFunctionEval.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/WindowFunctionEval.java b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/WindowFunctionEval.java
index 33f9a3d..a72d826 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/WindowFunctionEval.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/WindowFunctionEval.java
@@ -65,6 +65,9 @@ public class WindowFunctionEval extends AggregationFunctionCallEval implements
C
 
   @Override
   public Datum terminate(FunctionContext context) {
+    if (!isBinded) {
+      throw new IllegalStateException("bind() must be called before terminate()");
+    }
     return instance.terminate(context);
   }
 


Mime
View raw message