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/09/03 04:31:22 UTC

git commit: TAJO-139: In predicate support. (hyunsik)

Updated Branches:
  refs/heads/master bc8e1804c -> 3703a7c36


TAJO-139: In predicate support. (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/3703a7c3
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tajo/tree/3703a7c3
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tajo/diff/3703a7c3

Branch: refs/heads/master
Commit: 3703a7c3617584f157d485f735e374f17d9f27fd
Parents: bc8e180
Author: Hyunsik Choi <hy...@apache.org>
Authored: Tue Sep 3 11:18:58 2013 +0900
Committer: Hyunsik Choi <hy...@apache.org>
Committed: Tue Sep 3 11:31:07 2013 +0900

----------------------------------------------------------------------
 CHANGES.txt                                     |   2 +
 .../org/apache/tajo/algebra/InPredicate.java    |   8 +-
 .../java/org/apache/tajo/datum/ArrayDatum.java  |  20 ++++
 .../org/apache/tajo/datum/DatumFactory.java     |   3 -
 .../org/apache/tajo/engine/eval/EvalType.java   |   4 +-
 .../org/apache/tajo/engine/eval/InEval.java     | 113 +++++++++++++++++++
 .../apache/tajo/engine/eval/RowConstant.java    |  89 +++++++++++++++
 .../apache/tajo/engine/parser/SQLAnalyzer.java  |  12 +-
 .../tajo/engine/planner/LogicalPlanner.java     |  20 ++++
 .../master/querymaster/QueryJobManager.java     |   4 +-
 .../master/querymaster/QueryMasterTask.java     |   4 +-
 .../apache/tajo/engine/eval/TestEvalTree.java   |  24 ++++
 .../tajo/engine/query/TestSelectQuery.java      |  62 ++++++++++
 .../org/apache/tajo/rpc/TestProtoAsyncRpc.java  |   2 +-
 .../apache/tajo/rpc/TestProtoBlockingRpc.java   |  11 +-
 15 files changed, 356 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/3703a7c3/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 9f96db0..62c2a1f 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -4,6 +4,8 @@ Release 0.2.0 - unreleased
 
   NEW FEATURES
 
+    TAJO-139: TAJO-139: In predicate support. (hyunsik)
+
     TAJO-134: Support for compression/decompression of CSVFile. (jinho)
 
     TAJO-59: Implement Char Datum Type. (jihoon)

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/3703a7c3/tajo-algebra/src/main/java/org/apache/tajo/algebra/InPredicate.java
----------------------------------------------------------------------
diff --git a/tajo-algebra/src/main/java/org/apache/tajo/algebra/InPredicate.java b/tajo-algebra/src/main/java/org/apache/tajo/algebra/InPredicate.java
index abdcc86..4eafe6e 100644
--- a/tajo-algebra/src/main/java/org/apache/tajo/algebra/InPredicate.java
+++ b/tajo-algebra/src/main/java/org/apache/tajo/algebra/InPredicate.java
@@ -19,9 +19,15 @@
 package org.apache.tajo.algebra;
 
 public class InPredicate extends BinaryOperator {
+  private boolean not;
 
-  public InPredicate(Expr predicand, Expr in_values) {
+  public InPredicate(Expr predicand, Expr in_values, boolean not) {
     super(OpType.InPredicate, predicand, in_values);
+    this.not = not;
+  }
+
+  public boolean isNot() {
+    return this.not;
   }
 
   public Expr getPredicand() {

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/3703a7c3/tajo-common/src/main/java/org/apache/tajo/datum/ArrayDatum.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/java/org/apache/tajo/datum/ArrayDatum.java b/tajo-common/src/main/java/org/apache/tajo/datum/ArrayDatum.java
index 24c38c4..37c6dfa 100644
--- a/tajo-common/src/main/java/org/apache/tajo/datum/ArrayDatum.java
+++ b/tajo-common/src/main/java/org/apache/tajo/datum/ArrayDatum.java
@@ -72,4 +72,24 @@ public class ArrayDatum extends Datum {
 
     return sb.toString();
   }
+
+  public boolean equals(Object obj) {
+    if (obj instanceof ArrayDatum) {
+      ArrayDatum other = (ArrayDatum) obj;
+      if (data.length != other.data.length) {
+        return false;
+      }
+
+
+      for (int i = 0; i < data.length; i++) {
+        if (!data[i].equals(other.data[i])) {
+          return false;
+        }
+      }
+
+      return true;
+    }
+
+    return false;
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/3703a7c3/tajo-common/src/main/java/org/apache/tajo/datum/DatumFactory.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/java/org/apache/tajo/datum/DatumFactory.java b/tajo-common/src/main/java/org/apache/tajo/datum/DatumFactory.java
index 72dfc15..84bc576 100644
--- a/tajo-common/src/main/java/org/apache/tajo/datum/DatumFactory.java
+++ b/tajo-common/src/main/java/org/apache/tajo/datum/DatumFactory.java
@@ -18,13 +18,10 @@
 
 package org.apache.tajo.datum;
 
-import org.apache.tajo.common.TajoDataTypes;
 import org.apache.tajo.common.TajoDataTypes.DataType;
 import org.apache.tajo.common.TajoDataTypes.Type;
 import org.apache.tajo.util.Bytes;
 
-import java.io.UnsupportedEncodingException;
-
 public class DatumFactory {
 
   public static Datum create(DataType type, byte[] val) {

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/3703a7c3/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/eval/EvalType.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/eval/EvalType.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/eval/EvalType.java
index a22da0f..a3fcf40 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/eval/EvalType.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/eval/EvalType.java
@@ -46,10 +46,12 @@ public enum EvalType {
   LIKE(LikeEval.class),
   CASE(CaseWhenEval.class),
   WHEN(CaseWhenEval.WhenEval.class),
+  IN(InEval.class),
 
   // Value or Reference
   FIELD(FieldEval.class),
-  CONST(ConstEval.class);
+  CONST(ConstEval.class),
+  ROW_CONSTANT(RowConstant.class);
 
   private Class<? extends EvalNode> baseClass;
 

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/3703a7c3/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/eval/InEval.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/eval/InEval.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/eval/InEval.java
new file mode 100644
index 0000000..6b04948
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/eval/InEval.java
@@ -0,0 +1,113 @@
+/**
+ * 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.eval;
+
+
+import com.google.gson.annotations.Expose;
+import org.apache.tajo.catalog.CatalogUtil;
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.datum.BooleanDatum;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.storage.Tuple;
+
+public class InEval extends BinaryEval {
+  private static final TajoDataTypes.DataType[] RES_TYPE
+      = CatalogUtil.newDataTypesWithoutLen(TajoDataTypes.Type.BOOLEAN);
+
+  @Expose private boolean not;
+  private Integer fieldId = null;
+  Datum [] values;
+
+  public InEval(FieldEval columnRef, RowConstant valueList, boolean not) {
+    super(EvalType.IN, columnRef, valueList);
+    this.not = not;
+  }
+
+  public boolean isNot() {
+    return this.not;
+  }
+
+  @Override
+  public EvalContext newContext() {
+    return new InEvalCtx();
+  }
+
+  @Override
+  public TajoDataTypes.DataType[] getValueType() {
+    return RES_TYPE;
+  }
+
+  @Override
+  public String getName() {
+    return "?";
+  }
+
+  @Override
+  public void eval(EvalContext ctx, Schema schema, Tuple tuple) {
+    InEvalCtx isNullCtx = (InEvalCtx) ctx;
+    if (fieldId == null) {
+      fieldId = schema.getColumnId(((FieldEval)leftExpr).getColumnRef().getQualifiedName());
+      values = ((RowConstant)rightExpr).getValues();
+    }
+
+    boolean isIncluded = false;
+
+    Datum value = tuple.get(fieldId);
+    for (Datum datum : values) {
+      if (value.equals(datum)) {
+        isIncluded = true;
+        break;
+      }
+    }
+
+    if (not) {
+      isNullCtx.result.setValue(!isIncluded);
+    } else {
+      isNullCtx.result.setValue(isIncluded);
+    }
+  }
+
+  @Override
+  public Datum terminate(EvalContext ctx) {
+    return ((InEvalCtx)ctx).result;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj instanceof InEval) {
+      InEval other = (InEval) obj;
+      return super.equals(obj) && not == other.not;
+    }
+    return false;
+  }
+
+  public String toString() {
+    return leftExpr + " IN " + rightExpr;
+  }
+
+  private class InEvalCtx implements EvalContext {
+    BooleanDatum result;
+
+    InEvalCtx() {
+      this.result = DatumFactory.createBool(false);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/3703a7c3/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/eval/RowConstant.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/eval/RowConstant.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/eval/RowConstant.java
new file mode 100644
index 0000000..4e473ed
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/eval/RowConstant.java
@@ -0,0 +1,89 @@
+/**
+ * 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.eval;
+
+import com.google.gson.annotations.Expose;
+import org.apache.tajo.catalog.CatalogUtil;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.datum.ArrayDatum;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.util.TUtil;
+
+public class RowConstant extends EvalNode {
+  @Expose ArrayDatum values;
+
+  public RowConstant(Datum [] values) {
+    super(EvalType.ROW_CONSTANT);
+    this.values = new ArrayDatum(values);
+  }
+
+  @Override
+  public EvalContext newContext() {
+    return null;
+  }
+
+  @Override
+  public TajoDataTypes.DataType[] getValueType() {
+    return new TajoDataTypes.DataType[] {CatalogUtil.newDataTypeWithoutLen(values.get(0).type())};
+  }
+
+  @Override
+  public String getName() {
+    return "ROW";
+  }
+
+  @Override
+  public Datum terminate(EvalContext ctx) {
+    return values;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj instanceof RowConstant) {
+      RowConstant other = (RowConstant) obj;
+      return TUtil.checkEquals(values, other.values);
+    }
+
+    return false;
+  }
+
+  public String toString() {
+    StringBuilder sb = new StringBuilder("(");
+    for (int i = 0; i < values.toArray().length; i++) {
+      if (i != 0) {
+        sb.append(",");
+      }
+      sb.append(values.get(i).toString());
+    }
+    sb.append(")");
+    return sb.toString();
+  }
+
+  public Datum [] getValues() {
+    return values.toArray();
+  }
+
+  public void preOrder(EvalNodeVisitor visitor) {
+    visitor.visit(this);
+  }
+
+  public void postOrder(EvalNodeVisitor visitor) {
+    visitor.visit(this);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/3703a7c3/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java
index ed62171..cc762f0 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java
@@ -557,15 +557,15 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
   @Override
   public InPredicate visitIn_predicate(SQLParser.In_predicateContext ctx) {
     return new InPredicate(visitChildren(ctx.numeric_value_expression()),
-        visitChildren(ctx.in_predicate_value()));
+        visitIn_predicate_value(ctx.in_predicate_value()), ctx.NOT() != null);
   }
 
   @Override
-  public ValueListExpr visitIn_value_list(SQLParser.In_value_listContext ctx) {
-    int size = ctx.numeric_value_expression().size();
+  public ValueListExpr visitIn_predicate_value(SQLParser.In_predicate_valueContext ctx) {
+    int size = ctx.in_value_list().numeric_value_expression().size();
     Expr [] exprs = new Expr[size];
     for (int i = 0; i < size; i++) {
-      exprs[i] = visit(ctx.numeric_value_expression(i));
+      exprs[i] = visit(ctx.in_value_list().numeric_value_expression(i));
     }
     return new ValueListExpr(exprs);
   }
@@ -592,10 +592,8 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
 
   @Override
   public IsNullPredicate visitNull_predicate(SQLParser.Null_predicateContext ctx) {
-    boolean not = ctx.NOT() != null;
-
     ColumnReferenceExpr predicand = (ColumnReferenceExpr) visit(ctx.numeric_value_expression());
-    return new IsNullPredicate(not, predicand);
+    return new IsNullPredicate(ctx.NOT() != null, predicand);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/3703a7c3/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 f78b367..6d4673a 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
@@ -31,6 +31,7 @@ import org.apache.tajo.catalog.function.GeneralFunction;
 import org.apache.tajo.catalog.proto.CatalogProtos;
 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;
 import org.apache.tajo.engine.eval.*;
 import org.apache.tajo.engine.eval.EvalType;
@@ -854,6 +855,17 @@ public class LogicalPlanner extends BaseAlgebraVisitor<LogicalPlanner.PlanContex
             throw new RuntimeException("Unsupported type: " + literal.getValueType());
         }
 
+      case ValueList: {
+        ValueListExpr valueList = (ValueListExpr) expr;
+        Datum[] values = new Datum[valueList.getValues().length];
+        ConstEval [] constEvals = new ConstEval[valueList.getValues().length];
+        for (int i = 0; i < valueList.getValues().length; i++) {
+          constEvals[i] = (ConstEval) createEvalTree(plan, blockName, valueList.getValues()[i]);
+          values[i] = constEvals[i].getValue();
+        }
+        return new RowConstant(values);
+      }
+
         // unary expression
       case Not:
         NotExpr notExpr = (NotExpr) expr;
@@ -866,6 +878,14 @@ public class LogicalPlanner extends BaseAlgebraVisitor<LogicalPlanner.PlanContex
         ConstEval pattern = (ConstEval) createEvalTree(plan, blockName, like.getPattern());
         return new LikeEval(like.isNot(), field, pattern);
 
+      case InPredicate: {
+        InPredicate inPredicate = (InPredicate) expr;
+        FieldEval predicand =
+            new FieldEval(plan.findColumn(blockName, (ColumnReferenceExpr) inPredicate.getPredicand()));
+        RowConstant rowConstant = (RowConstant) createEvalTree(plan, blockName, inPredicate.getInValue());
+        return new InEval(predicand, rowConstant, inPredicate.isNot());
+      }
+
       case Is:
         break;
 

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/3703a7c3/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/QueryJobManager.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/QueryJobManager.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/QueryJobManager.java
index d5a4021..16008fc 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/QueryJobManager.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/QueryJobManager.java
@@ -123,7 +123,7 @@ public class QueryJobManager extends CompositeService {
   }
 
   public void stopQuery(QueryId queryId) {
-    LOG.info("====>Stop QueryInProgress:" + queryId);
+    LOG.info("Stop QueryInProgress:" + queryId);
     QueryInProgress queryInProgress = getQueryInProgress(queryId);
     if(queryInProgress != null) {
       queryInProgress.stop();
@@ -132,7 +132,7 @@ public class QueryJobManager extends CompositeService {
         finishedQueries.put(queryId, queryInProgress);
       }
     } else {
-      LOG.warn("====> No QueryInProgress while query stopping: " + queryId);
+      LOG.warn("No QueryInProgress while query stopping: " + queryId);
     }
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/3703a7c3/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/QueryMasterTask.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/QueryMasterTask.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/QueryMasterTask.java
index 0c1d056..cfea8a2 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/QueryMasterTask.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/QueryMasterTask.java
@@ -151,14 +151,14 @@ public class QueryMasterTask extends CompositeService {
     }
     stopped.set(true);
 
-    LOG.info("====> Stopping QueryMasterTask:" + queryId);
+    LOG.info("Stopping QueryMasterTask:" + queryId);
 
     queryMasterContext.getWorkerContext().getTajoMasterRpcClient()
         .stopQueryMaster(null, queryId.getProto(), NullCallback.get());
 
     super.stop();
 
-    LOG.info("====> Stopped QueryMasterTask:" + queryId);
+    LOG.info("Stopped QueryMasterTask:" + queryId);
   }
 
   public void handleTaskRequestEvent(TaskRequestEvent event) {

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/3703a7c3/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/eval/TestEvalTree.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/eval/TestEvalTree.java b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/eval/TestEvalTree.java
index 20dea3d..2efaadc 100644
--- a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/eval/TestEvalTree.java
+++ b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/eval/TestEvalTree.java
@@ -675,6 +675,29 @@ public class TestEvalTree {
     assertIsNull(expr);
   }
 
+  static String[] IN_PREDICATE = {
+      "select name, score, age from people where name in ('abc', 'def', 'ghi')", // 0
+      "select name, score, age from people where score in (1, 2, 3)", // 1
+      "select name, score, age from people where score not in (1, 2, 3)", // 2
+  };
+
+  @Test
+  public void testInEval() {
+    EvalNode expr;
+
+    expr = getRootSelection(IN_PREDICATE[0]);
+    assertEquals(EvalType.IN, expr.getType());
+    InEval inEval = (InEval) expr;
+
+    expr = getRootSelection(IN_PREDICATE[1]);
+    assertEquals(EvalType.IN, expr.getType());
+
+    expr = getRootSelection(IN_PREDICATE[2]);
+    assertEquals(EvalType.IN, expr.getType());
+    inEval = (InEval) expr;
+    assertTrue(inEval.isNot());
+  }
+
   private void assertIsNull(EvalNode isNullEval) {
     assertEquals(EvalType.IS_NULL, isNullEval.getType());
     assertEquals(EvalType.FIELD, isNullEval.getLeftExpr().getType());
@@ -685,6 +708,7 @@ public class TestEvalTree {
 
   private static void assertJsonSerDer(EvalNode expr) {
     String json = expr.toJson();
+    System.out.println(json);
     EvalNode fromJson = CoreGsonHelper.fromJson(json, EvalNode.class);
     assertEquals(expr, fromJson);
   }

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/3703a7c3/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 2a189f8..e96f7e5 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
@@ -312,6 +312,68 @@ public class TestSelectQuery {
   }
 
   @Test
+  public final void testInClause() throws Exception {
+    ResultSet res = tpch.execute(
+        "select l_orderkey from lineitem where l_partkey in (2,3)");
+    try {
+      assertTrue(res.next());
+      assertEquals(2, res.getInt(1));
+      assertTrue(res.next());
+      assertEquals(3, res.getInt(1));
+      assertTrue(res.next());
+      assertEquals(3, res.getInt(1));
+      assertFalse(res.next());
+    } finally {
+      res.close();
+    }
+  }
+
+  @Test
+  public final void testInStrClause() throws Exception {
+    ResultSet res = tpch.execute(
+        "select l_orderkey from lineitem where l_returnflag in ('R', 'S')");
+    try {
+      assertTrue(res.next());
+      assertEquals(3, res.getInt(1));
+      assertTrue(res.next());
+      assertEquals(3, res.getInt(1));
+      assertFalse(res.next());
+    } finally {
+      res.close();
+    }
+  }
+
+  @Test
+  public final void testNotInStrClause() throws Exception {
+    ResultSet res = tpch.execute(
+        "select l_orderkey from lineitem where l_returnflag not in ('N', 'S')");
+    try {
+      assertTrue(res.next());
+      assertEquals(3, res.getInt(1));
+      assertTrue(res.next());
+      assertEquals(3, res.getInt(1));
+      assertFalse(res.next());
+    } finally {
+      res.close();
+    }
+  }
+
+  @Test
+  public final void testNotInClause() throws Exception {
+    ResultSet res = tpch.execute(
+        "select l_orderkey from lineitem where l_partkey not in (2,3)");
+    try {
+      assertTrue(res.next());
+      assertEquals(1, res.getInt(1));
+      assertTrue(res.next());
+      assertEquals(1, res.getInt(1));
+      assertFalse(res.next());
+    } finally {
+      res.close();
+    }
+  }
+
+  @Test
   public final void testUnion1() throws Exception {
     ResultSet res = tpch.execute(
         "select o_custkey as num from orders union select c_custkey as num from customer");

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/3703a7c3/tajo-rpc/src/test/java/org/apache/tajo/rpc/TestProtoAsyncRpc.java
----------------------------------------------------------------------
diff --git a/tajo-rpc/src/test/java/org/apache/tajo/rpc/TestProtoAsyncRpc.java b/tajo-rpc/src/test/java/org/apache/tajo/rpc/TestProtoAsyncRpc.java
index a7bc4d0..0d01a49 100644
--- a/tajo-rpc/src/test/java/org/apache/tajo/rpc/TestProtoAsyncRpc.java
+++ b/tajo-rpc/src/test/java/org/apache/tajo/rpc/TestProtoAsyncRpc.java
@@ -55,7 +55,7 @@ public class TestProtoAsyncRpc {
   public void setUp() throws Exception {
     service = new DummyProtocolAsyncImpl();
     server = new ProtoAsyncRpcServer(DummyProtocol.class,
-        service, new InetSocketAddress(0));
+        service, new InetSocketAddress("127.0.0.1", 0));
     server.start();
     client = new ProtoAsyncRpcClient(DummyProtocol.class,
         NetUtils.getConnectAddress(server.getListenAddress()));

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/3703a7c3/tajo-rpc/src/test/java/org/apache/tajo/rpc/TestProtoBlockingRpc.java
----------------------------------------------------------------------
diff --git a/tajo-rpc/src/test/java/org/apache/tajo/rpc/TestProtoBlockingRpc.java b/tajo-rpc/src/test/java/org/apache/tajo/rpc/TestProtoBlockingRpc.java
index 2defc96..732f7f1 100644
--- a/tajo-rpc/src/test/java/org/apache/tajo/rpc/TestProtoBlockingRpc.java
+++ b/tajo-rpc/src/test/java/org/apache/tajo/rpc/TestProtoBlockingRpc.java
@@ -18,14 +18,16 @@
 
 package org.apache.tajo.rpc;
 
-import com.google.protobuf.RpcController;
-import org.junit.*;
 import org.apache.tajo.rpc.test.DummyProtocol;
 import org.apache.tajo.rpc.test.DummyProtocol.DummyProtocolService.BlockingInterface;
 import org.apache.tajo.rpc.test.TestProtos.EchoMessage;
 import org.apache.tajo.rpc.test.TestProtos.SumRequest;
 import org.apache.tajo.rpc.test.TestProtos.SumResponse;
 import org.apache.tajo.rpc.test.impl.DummyProtocolBlockingImpl;
+import org.apache.tajo.util.NetUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
 
 import java.net.InetSocketAddress;
 import java.util.concurrent.CountDownLatch;
@@ -45,11 +47,10 @@ public class TestProtoBlockingRpc {
   public void setUp() throws Exception {
     service = new DummyProtocolBlockingImpl();
     server = new ProtoBlockingRpcServer(DummyProtocol.class, service,
-        new InetSocketAddress(10000));
+        new InetSocketAddress("127.0.0.1", 0));
     server.start();
-
     client = new ProtoBlockingRpcClient(DummyProtocol.class,
-        new InetSocketAddress(10000));
+        NetUtils.getConnectAddress(server.getListenAddress()));
     stub = client.getStub();
   }