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 2014/08/23 19:38:11 UTC

[22/25] TAJO-906: Runtime code generation for evaluating expression trees.

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-core/src/test/java/org/apache/tajo/engine/codegen/TestEvalCodeGenerator.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/codegen/TestEvalCodeGenerator.java b/tajo-core/src/test/java/org/apache/tajo/engine/codegen/TestEvalCodeGenerator.java
new file mode 100644
index 0000000..d86081a
--- /dev/null
+++ b/tajo-core/src/test/java/org/apache/tajo/engine/codegen/TestEvalCodeGenerator.java
@@ -0,0 +1,311 @@
+/**
+ * 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.codegen;
+
+
+import org.apache.tajo.catalog.CatalogUtil;
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.engine.eval.ExprTestBase;
+import org.junit.Test;
+
+import java.io.IOException;
+
+public class TestEvalCodeGenerator extends ExprTestBase {
+  private static Schema schema;
+  static {
+    schema = new Schema();
+    schema.addColumn("col0", TajoDataTypes.Type.INT1);
+    schema.addColumn("col1", TajoDataTypes.Type.INT2);
+    schema.addColumn("col2", TajoDataTypes.Type.INT4);
+    schema.addColumn("col3", TajoDataTypes.Type.INT8);
+    schema.addColumn("col4", TajoDataTypes.Type.FLOAT4);
+    schema.addColumn("col5", TajoDataTypes.Type.FLOAT8);
+    schema.addColumn("col6", TajoDataTypes.Type.TEXT);
+    schema.addColumn("col7", CatalogUtil.newDataType(TajoDataTypes.Type.CHAR, "", 3));
+    schema.addColumn("col8", TajoDataTypes.Type.BOOLEAN);
+    schema.addColumn("nullable", TajoDataTypes.Type.NULL_TYPE);
+  }
+
+  @Test
+  public void testArithmetic() throws IOException {
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 1+1;", new String [] {"2"});
+    testEval(schema, "table1", "0,1,2,3,4.5,5.5", "select col1 + col2 from table1;", new String [] {"3"});
+    testEval(schema, "table1", "0,1,2,3,4.5,5.5", "select col1 + col3 from table1;", new String [] {"4"});
+    testEval(schema, "table1", "0,1,2,3,4.5,5.5", "select col1 + col4 from table1;", new String [] {"5.5"});
+    testEval(schema, "table1", "0,1,2,3,4.5,5.5", "select col1 + col5 from table1;", new String [] {"6.5"});
+  }
+
+  @Test
+  public void testGetField() throws IOException {
+    testEval(schema, "table1", "0,1,2,3,4.5,5.5,F6", "select col1 from table1;", new String [] {"1"});
+    testEval(schema, "table1", "0,1,2,3,4.5,5.5,F6", "select col2 from table1;", new String [] {"2"});
+    testEval(schema, "table1", "0,1,2,3,4.5,5.5,F6", "select col3 from table1;", new String [] {"3"});
+    testEval(schema, "table1", "0,1,2,3,4.5,5.5,F6", "select col4 from table1;", new String [] {"4.5"});
+    testEval(schema, "table1", "0,1,2,3,4.5,5.5,F6", "select col5 from table1;", new String [] {"5.5"});
+    testEval(schema, "table1", "0,1,2,3,4.5,5.5,F6", "select col6 from table1;", new String [] {"F6"});
+    testEval(schema, "table1", "0,1,2,3,4.5,5.5,F6,abc,t", "select col8 from table1;", new String [] {"t"});
+  }
+
+  @Test
+  public void testNullHandling() throws IOException {
+    schema = new Schema();
+    schema.addColumn("col0", TajoDataTypes.Type.INT1);
+    schema.addColumn("col1", TajoDataTypes.Type.INT2);
+    schema.addColumn("col2", TajoDataTypes.Type.INT4);
+    schema.addColumn("col3", TajoDataTypes.Type.INT8);
+    schema.addColumn("col4", TajoDataTypes.Type.FLOAT4);
+    schema.addColumn("col5", TajoDataTypes.Type.FLOAT8);
+    schema.addColumn("col6", TajoDataTypes.Type.TEXT);
+    schema.addColumn("col7", CatalogUtil.newDataType(TajoDataTypes.Type.CHAR, "", 1));
+    schema.addColumn("col8", CatalogUtil.newDataType(TajoDataTypes.Type.CHAR, "", 3));
+    schema.addColumn("col9", TajoDataTypes.Type.BOOLEAN);
+    schema.addColumn("nullable", TajoDataTypes.Type.NULL_TYPE);
+
+    testEval(schema, "table1", ",1,2,3,4.5,6.5,F6,abc,abc,t", "select col0 is null from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,,2,3,4.5,6.5,F6,abc,abc,t,", "select col1 is null from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,,3,4.5,6.5,F6,abc,abc,t,", "select col2 is null from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,,4.5,6.5,F6,abc,abc,t,", "select col3 is null from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,,6.5,F6,abc,abc,t,", "select col4 is null from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,,F6,abc,abc,t,", "select col5 is null from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5,,abc,abc,t,", "select col6 is null from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5,F6,,abc,t,", "select col7 is null from table1;", new String[]{"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5,F6,abc,,t,", "select col8 is null from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5,F6,abc,abc,,", "select col9 is null from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5,F6,abc,abc,t,", "select nullable is null from table1;", new String [] {"t"});
+
+    testEval(schema, "table1", ",1,2,3,4.5,6.5,F6,abc,abc,t", "select col0 is not null from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,,2,3,4.5,6.5,F6,abc,abc,t,", "select col1 is not null from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,,3,4.5,6.5,F6,abc,abc,t,", "select col2 is not null from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,,4.5,6.5,F6,abc,abc,t,", "select col3 is not null from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,,6.5,F6,abc,abc,t,", "select col4 is not null from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,,F6,abc,abc,t,", "select col5 is not null from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5,,abc,abc,t,", "select col6 is not null from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5,F6,,abc,t,", "select col7 is not null from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5,F6,abc,,t,", "select col8 is not null from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5,F6,abc,abc,,", "select col9 is not null from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5,F6,abc,abc,t,", "select nullable is not null from table1;", new String [] {"f"});
+  }
+
+  @Test
+  public void testComparison() throws IOException {
+    Schema inetSchema = new Schema();
+    inetSchema.addColumn("addr1", TajoDataTypes.Type.INET4);
+    inetSchema.addColumn("addr2", TajoDataTypes.Type.INET4);
+
+    testSimpleEval("select (1 > null AND false)", new String[] {"f"}); // unknown - false -> false
+    testSimpleEval("select (1::int8 > null) is null", new String[] {"t"});
+
+    testSimpleEval("select 1 = null;", new String [] {""});
+    testSimpleEval("select 1 <> null;", new String [] {""});
+    testSimpleEval("select 1 > null;", new String [] {""});
+    testSimpleEval("select 1 >= null;", new String [] {""});
+    testSimpleEval("select 1 < null;", new String [] {""});
+    testSimpleEval("select 1 <= null;", new String [] {""});
+
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 1 = col1 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 1 = col2 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 1 = col3 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 1 = col4 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 1 = col5 from table1;", new String [] {"f"});
+
+    testEval(inetSchema, "table1", "192.168.0.1,192.168.0.1", "select addr1 = addr2 from table1;", new String[]{"t"});
+    testEval(inetSchema, "table1", "192.168.0.1,192.168.0.2", "select addr1 = addr2 from table1;", new String[]{"f"});
+
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 <> col1 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 <> col2 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 <> col3 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 <> col4 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 <> col5 from table1;", new String [] {"t"});
+
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 1 < col1 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 1 < col2 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 1 < col3 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 1 < col4 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 1 < col5 from table1;", new String [] {"t"});
+
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 <= col1 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 <= col2 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 <= col3 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 <= col4 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 <= col5 from table1;", new String [] {"t"});
+
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 > col1 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 > col2 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 > col3 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 > col4 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 > col5 from table1;", new String [] {"f"});
+
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 >= col1 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 >= col2 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 >= col3 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 >= col4 from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 3 >= col5 from table1;", new String [] {"f"});
+  }
+
+  @Test
+  public void testBetweenAsymmetric() throws IOException {
+    Schema schema = new Schema();
+    schema.addColumn("col1", TajoDataTypes.Type.INT4);
+    schema.addColumn("col2", TajoDataTypes.Type.INT4);
+    testEval(schema, "table1", "0,", "select col1 between 1 and 3 from table1", new String[]{"f"});
+    testEval(schema, "table1", "1,", "select col1 between 1 and 3 from table1", new String[]{"t"});
+    testEval(schema, "table1", "2,", "select col1 between 1 and 3 from table1", new String[]{"t"});
+    testEval(schema, "table1", "3,", "select col1 between 1 and 3 from table1", new String[]{"t"});
+    testEval(schema, "table1", "4,", "select col1 between 1 and 3 from table1", new String[]{"f"});
+    testEval(schema, "table1", "5,", "select (col2 between 1 and 3) is null from table1", new String[]{"t"});
+
+    testEval(schema, "table1", "0,", "select col1 between 3 and 1 from table1", new String[]{"f"});
+    testEval(schema, "table1", "1,", "select col1 between 3 and 1 from table1", new String[]{"f"});
+    testEval(schema, "table1", "2,", "select col1 between 3 and 1 from table1", new String[]{"f"});
+    testEval(schema, "table1", "3,", "select col1 between 3 and 1 from table1", new String[]{"f"});
+    testEval(schema, "table1", "4,", "select col1 between 3 and 1 from table1", new String[]{"f"});
+    testEval(schema, "table1", "5,", "select (col2 between 3 and 1) is null from table1", new String[]{"t"});
+
+    testEval(schema, "table1", "0,", "select col1 not between 1 and 3 from table1", new String[]{"t"});
+    testEval(schema, "table1", "1,", "select col1 not between 1 and 3 from table1", new String[]{"f"});
+    testEval(schema, "table1", "2,", "select col1 not between 1 and 3 from table1", new String[]{"f"});
+    testEval(schema, "table1", "3,", "select col1 not between 1 and 3 from table1", new String[]{"f"});
+    testEval(schema, "table1", "4,", "select col1 not between 1 and 3 from table1", new String[]{"t"});
+    testEval(schema, "table1", "5,", "select (col2 not between 1 and 3) is null from table1", new String[]{"t"});
+
+    testEval(schema, "table1", "0,", "select col1 not between 3 and 1 from table1", new String[]{"t"});
+    testEval(schema, "table1", "1,", "select col1 not between 3 and 1 from table1", new String[]{"t"});
+    testEval(schema, "table1", "2,", "select col1 not between 3 and 1 from table1", new String[]{"t"});
+    testEval(schema, "table1", "3,", "select col1 not between 3 and 1 from table1", new String[]{"t"});
+    testEval(schema, "table1", "4,", "select col1 not between 3 and 1 from table1", new String[]{"t"});
+    testEval(schema, "table1", "5,", "select (col2 not between 3 and 1) is null from table1", new String[]{"t"});
+  }
+
+  @Test
+  public void testBetweenSymmetric() throws IOException {
+    Schema schema = new Schema();
+    schema.addColumn("col1", TajoDataTypes.Type.INT4);
+    schema.addColumn("col2", TajoDataTypes.Type.INT4);
+    testEval(schema, "table1", "0,", "select col1 between symmetric 1 and 3 from table1", new String[]{"f"});
+    testEval(schema, "table1", "1,", "select col1 between symmetric 1 and 3 from table1", new String[]{"t"});
+    testEval(schema, "table1", "2,", "select col1 between symmetric 1 and 3 from table1", new String[]{"t"});
+    testEval(schema, "table1", "3,", "select col1 between symmetric 1 and 3 from table1", new String[]{"t"});
+    testEval(schema, "table1", "4,", "select col1 between symmetric 1 and 3 from table1", new String[]{"f"});
+    testEval(schema, "table1", "5,", "select (col2 between symmetric 1 and 3) is null from table1", new String[]{"t"});
+
+    testEval(schema, "table1", "0,", "select col1 not between symmetric 1 and 3 from table1", new String[]{"t"});
+    testEval(schema, "table1", "1,", "select col1 not between symmetric 1 and 3 from table1", new String[]{"f"});
+    testEval(schema, "table1", "2,", "select col1 not between symmetric 1 and 3 from table1", new String[]{"f"});
+    testEval(schema, "table1", "3,", "select col1 not between symmetric 1 and 3 from table1", new String[]{"f"});
+    testEval(schema, "table1", "4,", "select col1 not between symmetric 1 and 3 from table1", new String[]{"t"});
+    testEval(schema, "table1", "5,", "select (col2 not between symmetric 1 and 3) is null from table1", new String[]{"t"});
+
+    testEval(schema, "table1", "0,", "select col1 between symmetric 3 and 1 from table1", new String[]{"f"});
+    testEval(schema, "table1", "1,", "select col1 between symmetric 3 and 1 from table1", new String[]{"t"});
+    testEval(schema, "table1", "2,", "select col1 between symmetric 3 and 1 from table1", new String[]{"t"});
+    testEval(schema, "table1", "3,", "select col1 between symmetric 3 and 1 from table1", new String[]{"t"});
+    testEval(schema, "table1", "4,", "select col1 between symmetric 3 and 1 from table1", new String[]{"f"});
+    testEval(schema, "table1", "5,", "select (col2 between symmetric 3 and 1) is null from table1", new String[]{"t"});
+
+    testEval(schema, "table1", "0,", "select col1 not between symmetric 3 and 1 from table1", new String[]{"t"});
+    testEval(schema, "table1", "1,", "select col1 not between symmetric 3 and 1 from table1", new String[]{"f"});
+    testEval(schema, "table1", "2,", "select col1 not between symmetric 3 and 1 from table1", new String[]{"f"});
+    testEval(schema, "table1", "3,", "select col1 not between symmetric 3 and 1 from table1", new String[]{"f"});
+    testEval(schema, "table1", "4,", "select col1 not between symmetric 3 and 1 from table1", new String[]{"t"});
+    testEval(schema, "table1", "5,", "select (col2 not between symmetric 3 and 1) is null from table1",
+        new String[]{"t"});
+  }
+
+  @Test
+  public void testUnary() throws IOException {
+    schema = new Schema();
+    schema.addColumn("col0", TajoDataTypes.Type.INT1);
+    schema.addColumn("col1", TajoDataTypes.Type.INT2);
+    schema.addColumn("col2", TajoDataTypes.Type.INT4);
+    schema.addColumn("col3", TajoDataTypes.Type.INT8);
+    schema.addColumn("col4", TajoDataTypes.Type.FLOAT4);
+    schema.addColumn("col5", TajoDataTypes.Type.FLOAT8);
+    schema.addColumn("col6", TajoDataTypes.Type.TEXT);
+    schema.addColumn("col7", CatalogUtil.newDataType(TajoDataTypes.Type.CHAR, "", 3));
+    schema.addColumn("col8", TajoDataTypes.Type.BOOLEAN);
+
+
+    // sign test
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,t", "select +col1 from table1;", new String [] {"1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,t", "select +col2 from table1;", new String [] {"2"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,t", "select +col3 from table1;", new String [] {"3"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,t", "select +col4 from table1;", new String [] {"4.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,t", "select +col5 from table1;", new String [] {"5.1"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,t", "select -col1 from table1;", new String [] {"-1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,t", "select -col2 from table1;", new String [] {"-2"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,t", "select -col3 from table1;", new String [] {"-3"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,t", "select -col4 from table1;", new String [] {"-4.1"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,t", "select -col5 from table1;", new String [] {"-5.1"});
+
+    // not test
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,t", "select col8 from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,t", "select NOT (col8) from table1;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,t", "select NOT(NOT (col8)) from table1;", new String [] {"t"});
+
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,", "select col8 is null from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,", "select (NOT (col8)) is null from table1;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7,", "select (NOT(NOT (col8))) is null from table1;", new String [] {"t"});
+  }
+
+  @Test
+  public void testAndOr() throws IOException {
+    testSimpleEval("select true or (false or false) or false;", new String[] {"t"});
+
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select true and true;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select true and false;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select false and true;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select false and false;", new String [] {"f"});
+
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select true or true;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select true or false;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select false or true;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select false or false;", new String [] {"f"});
+
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select (true and true) and false;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select (true and false) and true;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select (false and true) and true;", new String [] {"f"});
+
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select (1 < 2) and true;", new String [] {"t"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select (1 < 2) and false;", new String [] {"f"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select (1 < 2) or false;", new String [] {"t"});
+  }
+
+  @Test
+  public void testFunction() throws IOException {
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select upper('abc');", new String [] {"ABC"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select upper('bbc');", new String [] {"BBC"});
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select upper('chs');", new String [] {"CHS"});
+
+    testSimpleEval("select ltrim('xxtrim', 'xx') ", new String[]{"trim"});
+  }
+
+  @Test
+  public void testStringConcat() throws IOException {
+    testSimpleEval("select length('123456') as col1 ", new String[]{"6"});
+
+    testEval(schema, "table1", "0,1,2,3,4.5,6.5", "select 'abc' || 'bbc'", new String [] {"abcbbc"});
+    Schema schema = new Schema();
+    schema.addColumn("col1", TajoDataTypes.Type.TEXT);
+    schema.addColumn("col2", TajoDataTypes.Type.TEXT);
+    testEval(schema, "table1", " trim, abc", "select ltrim(col1) || ltrim(col2) from table1",
+        new String[]{"trimabc"});
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-core/src/test/java/org/apache/tajo/engine/codegen/TestGeneratorAdapter.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/codegen/TestGeneratorAdapter.java b/tajo-core/src/test/java/org/apache/tajo/engine/codegen/TestGeneratorAdapter.java
new file mode 100644
index 0000000..9976d39
--- /dev/null
+++ b/tajo-core/src/test/java/org/apache/tajo/engine/codegen/TestGeneratorAdapter.java
@@ -0,0 +1,41 @@
+/**
+ * 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.codegen;
+
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.storage.Tuple;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+
+public class TestGeneratorAdapter {
+  @Test
+  public void testGetDescription() throws Exception {
+    assertEquals("I", TajoGeneratorAdapter.getDescription(int.class));
+    assertEquals("Ljava/lang/String;", TajoGeneratorAdapter.getDescription(String.class));
+  }
+
+  @Test
+  public void getMethodDescription() throws Exception {
+    assertEquals("(Lorg/apache/tajo/catalog/Schema;Lorg/apache/tajo/storage/Tuple;)Lorg/apache/tajo/datum/Datum;",
+        TajoGeneratorAdapter.getMethodDescription(Datum.class, new Class[]{Schema.class, Tuple.class}));
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-core/src/test/java/org/apache/tajo/engine/eval/ExprTestBase.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/eval/ExprTestBase.java b/tajo-core/src/test/java/org/apache/tajo/engine/eval/ExprTestBase.java
index 3bee4f3..4cbdddd 100644
--- a/tajo-core/src/test/java/org/apache/tajo/engine/eval/ExprTestBase.java
+++ b/tajo-core/src/test/java/org/apache/tajo/engine/eval/ExprTestBase.java
@@ -19,6 +19,8 @@
 package org.apache.tajo.engine.eval;
 
 import org.apache.tajo.LocalTajoTestingUtility;
+import org.apache.tajo.OverridableConf;
+import org.apache.tajo.SessionVars;
 import org.apache.tajo.TajoTestingCluster;
 import org.apache.tajo.algebra.Expr;
 import org.apache.tajo.catalog.*;
@@ -29,6 +31,8 @@ import org.apache.tajo.cli.SimpleParser;
 import org.apache.tajo.common.TajoDataTypes.Type;
 import org.apache.tajo.conf.TajoConf;
 import org.apache.tajo.datum.*;
+import org.apache.tajo.engine.codegen.EvalCodeGenerator;
+import org.apache.tajo.engine.codegen.TajoClassLoader;
 import org.apache.tajo.engine.json.CoreGsonHelper;
 import org.apache.tajo.engine.parser.SQLAnalyzer;
 import org.apache.tajo.engine.plan.EvalTreeProtoDeserializer;
@@ -38,7 +42,6 @@ import org.apache.tajo.engine.planner.*;
 import org.apache.tajo.engine.query.QueryContext;
 import org.apache.tajo.engine.utils.SchemaUtil;
 import org.apache.tajo.master.TajoMaster;
-import org.apache.tajo.master.session.Session;
 import org.apache.tajo.storage.LazyTuple;
 import org.apache.tajo.storage.Tuple;
 import org.apache.tajo.storage.VTuple;
@@ -54,12 +57,11 @@ import java.util.List;
 
 import static org.apache.tajo.TajoConstants.DEFAULT_DATABASE_NAME;
 import static org.apache.tajo.TajoConstants.DEFAULT_TABLESPACE_NAME;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.fail;
+import static org.junit.Assert.*;
 
 public class ExprTestBase {
   private static TajoTestingCluster util;
+  private static TajoConf conf;
   private static CatalogService cat;
   private static SQLAnalyzer analyzer;
   private static PreLogicalPlanVerifier preLogicalPlanVerifier;
@@ -71,9 +73,13 @@ public class ExprTestBase {
     return DateTimeUtil.getTimeZoneDisplayTime(TajoConf.getCurrentTimeZone());
   }
 
+  public ExprTestBase() {
+  }
+
   @BeforeClass
   public static void setUp() throws Exception {
     util = new TajoTestingCluster();
+    conf = util.getConfiguration();
     util.startCatalogCluster();
     cat = util.getMiniCatalogCluster().getCatalog();
     cat.createTablespace(DEFAULT_TABLESPACE_NAME, "hdfs://localhost:1234/warehouse");
@@ -100,20 +106,22 @@ public class ExprTestBase {
     assertEquals(expr, fromJson);
   }
 
+  public TajoConf getConf() {
+    return new TajoConf(conf);
+  }
+
   /**
    * verify query syntax and get raw targets.
    *
+   * @param context QueryContext
    * @param query a query for execution
    * @param condition this parameter means whether it is for success case or is not for failure case.
    * @return
    * @throws PlanningException
    */
-  private static Target[] getRawTargets(String query, boolean condition) throws PlanningException,
+  private static Target[] getRawTargets(QueryContext context, String query, boolean condition) throws PlanningException,
       InvalidStatementException {
 
-    Session session = LocalTajoTestingUtility.createDummySession();
-    QueryContext context = new QueryContext(util.getConfiguration(), session);
-
     List<ParsedResult> parsedResults = SimpleParser.parseScript(query);
     if (parsedResults.size() > 1) {
       throw new RuntimeException("this query includes two or more statements.");
@@ -162,17 +170,38 @@ public class ExprTestBase {
   }
 
   public void testSimpleEval(String query, String [] expected, boolean condition) throws IOException {
-    testEval(null, null, null, query, expected, ',', condition);
+    testEval(null, null, null, null, query, expected, ',', condition);
   }
 
   public void testEval(Schema schema, String tableName, String csvTuple, String query, String [] expected)
       throws IOException {
-    testEval(schema, tableName != null ? CatalogUtil.normalizeIdentifier(tableName) : null, csvTuple, query,
+    testEval(null, schema, tableName != null ? CatalogUtil.normalizeIdentifier(tableName) : null, csvTuple, query,
         expected, ',', true);
   }
 
-  public void testEval(Schema schema, String tableName, String csvTuple, String query, String [] expected,
-                       char delimiter, boolean condition) throws IOException {
+  public void testEval(OverridableConf overideConf, Schema schema, String tableName, String csvTuple, String query,
+                       String [] expected)
+      throws IOException {
+    testEval(overideConf, schema, tableName != null ? CatalogUtil.normalizeIdentifier(tableName) : null, csvTuple,
+        query, expected, ',', true);
+  }
+
+  public void testEval(Schema schema, String tableName, String csvTuple, String query,
+                       String [] expected, char delimiter, boolean condition) throws IOException {
+    testEval(null, schema, tableName != null ? CatalogUtil.normalizeIdentifier(tableName) : null, csvTuple,
+        query, expected, delimiter, condition);
+  }
+
+  public void testEval(OverridableConf overideConf, Schema schema, String tableName, String csvTuple, String query,
+                       String [] expected, char delimiter, boolean condition) throws IOException {
+    QueryContext context;
+    if (overideConf == null) {
+      context = LocalTajoTestingUtility.createDummyContext(conf);
+    } else {
+      context = LocalTajoTestingUtility.createDummyContext(conf);
+      context.putAll(overideConf);
+    }
+
     LazyTuple lazyTuple;
     VTuple vtuple  = null;
     String qualifiedTableName =
@@ -192,8 +221,16 @@ public class ExprTestBase {
           new LazyTuple(inputSchema, BytesUtils.splitPreserveAllTokens(csvTuple.getBytes(), delimiter, targetIdx),0);
       vtuple = new VTuple(inputSchema.size());
       for (int i = 0; i < inputSchema.size(); i++) {
+
         // If null value occurs, null datum is manually inserted to an input tuple.
-        if (lazyTuple.get(i) instanceof TextDatum && lazyTuple.get(i).asChars().equals("")) {
+        boolean nullDatum;
+        Datum datum = lazyTuple.get(i);
+        nullDatum = (datum instanceof TextDatum || datum instanceof CharDatum);
+        nullDatum = nullDatum && datum.asChars().equals("") ||
+            datum.asChars().equals(context.get(SessionVars.NULL_CHAR));
+        nullDatum |= datum.isNull();
+
+        if (nullDatum) {
           vtuple.put(i, NullDatum.get());
         } else {
           vtuple.put(i, lazyTuple.get(i));
@@ -205,15 +242,33 @@ public class ExprTestBase {
 
     Target [] targets;
 
+    TajoClassLoader classLoader = new TajoClassLoader();
+
     try {
-      targets = getRawTargets(query, condition);
+      targets = getRawTargets(context, query, condition);
+
+      EvalCodeGenerator codegen = null;
+      if (context.getBool(SessionVars.CODEGEN)) {
+        codegen = new EvalCodeGenerator(classLoader);
+      }
 
       Tuple outTuple = new VTuple(targets.length);
       for (int i = 0; i < targets.length; i++) {
         EvalNode eval = targets[i].getEvalTree();
+
+        if (context.getBool(SessionVars.CODEGEN)) {
+          eval = codegen.compile(inputSchema, eval);
+        }
+
         outTuple.put(i, eval.eval(inputSchema, vtuple));
       }
 
+      try {
+        classLoader.clean();
+      } catch (Throwable throwable) {
+        throwable.printStackTrace();
+      }
+
       for (int i = 0; i < expected.length; i++) {
         Datum datum = outTuple.get(i);
         String outTupleAsChars;

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestPredicates.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestPredicates.java b/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestPredicates.java
index 7811e69..79a287b 100644
--- a/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestPredicates.java
+++ b/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestPredicates.java
@@ -18,7 +18,9 @@
 
 package org.apache.tajo.engine.eval;
 
+import org.apache.tajo.catalog.CatalogUtil;
 import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.common.TajoDataTypes;
 import org.junit.Test;
 
 import java.io.IOException;
@@ -109,6 +111,21 @@ public class TestPredicates extends ExprTestBase {
 
   @Test
   public void testComparisonEqual() throws IOException {
+
+
+    Schema schema = new Schema();
+    schema.addColumn("col0", TajoDataTypes.Type.INT1);
+    schema.addColumn("col1", TajoDataTypes.Type.INT2);
+    schema.addColumn("col2", TajoDataTypes.Type.INT4);
+    schema.addColumn("col3", TajoDataTypes.Type.INT8);
+    schema.addColumn("col4", TajoDataTypes.Type.FLOAT4);
+    schema.addColumn("col5", TajoDataTypes.Type.FLOAT8);
+    schema.addColumn("col6", TajoDataTypes.Type.TEXT);
+    schema.addColumn("col7", CatalogUtil.newDataType(TajoDataTypes.Type.CHAR, "", 3));
+    schema.addColumn("nullable", TajoDataTypes.Type.INT4);
+
+    testEval(schema, "t1", "0,1,2,3,4.1,5.1,cmp,asm,", "SELECT col6 = 'cmp' from t1", new String [] {"t"});
+
     Schema schema1 = new Schema();
     schema1.addColumn("col1", INT4);
     schema1.addColumn("col2", INT4);

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestSQLExpression.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestSQLExpression.java b/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestSQLExpression.java
index af084d9..6c9892a 100644
--- a/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestSQLExpression.java
+++ b/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestSQLExpression.java
@@ -31,7 +31,7 @@ import org.junit.Test;
 import java.io.IOException;
 import java.util.TimeZone;
 
-import static org.apache.tajo.common.TajoDataTypes.Type.TEXT;
+import static org.apache.tajo.common.TajoDataTypes.Type.*;
 import static org.junit.Assert.fail;
 
 public class TestSQLExpression extends ExprTestBase {
@@ -93,16 +93,16 @@ public class TestSQLExpression extends ExprTestBase {
   @Test
   public void testExplicitCast() throws IOException {
     Schema schema = new Schema();
-    schema.addColumn("col0", TajoDataTypes.Type.INT1);
-    schema.addColumn("col1", TajoDataTypes.Type.INT2);
-    schema.addColumn("col2", TajoDataTypes.Type.INT4);
-    schema.addColumn("col3", TajoDataTypes.Type.INT8);
-    schema.addColumn("col4", TajoDataTypes.Type.FLOAT4);
-    schema.addColumn("col5", TajoDataTypes.Type.FLOAT8);
-    schema.addColumn("col6", TajoDataTypes.Type.TEXT);
+    schema.addColumn("col0", INT1);
+    schema.addColumn("col1", INT2);
+    schema.addColumn("col2", INT4);
+    schema.addColumn("col3", INT8);
+    schema.addColumn("col4", FLOAT4);
+    schema.addColumn("col5", FLOAT8);
+    schema.addColumn("col6", TEXT);
     schema.addColumn("col7", CatalogUtil.newDataType(TajoDataTypes.Type.CHAR, "", 3));
 
-    testSimpleEval("select cast (1 as char)", new String[] {"1"});
+    testSimpleEval("select cast (1 as char)", new String[]{"1"});
     testSimpleEval("select cast (119 as char)", new String[] {"1"});
 
     testEval(schema, "table1", "0,1,2,3,4.1,5.1,6,7", "select col0::int1 from table1;", new String [] {"0"});
@@ -866,6 +866,7 @@ public class TestSQLExpression extends ExprTestBase {
       Schema schema = new Schema();
       schema.addColumn("col1", TEXT);
       schema.addColumn("col2", TEXT);
+
       testEval(schema, "table1", "123,234", "select cast(col1 as float) as b, cast(col2 as float) as a from table1",
           new String[]{"123.0", "234.0"});
       testEval(schema, "table1", "123,234", "select col1::float, col2::float from table1",
@@ -879,7 +880,8 @@ public class TestSQLExpression extends ExprTestBase {
           new String[]{timestamp.asChars(TajoConf.getCurrentTimeZone(), true), "234.0"}
       );
 
-      testSimpleEval("select '1980-04-01 01:50:01'::timestamp;", new String[]{timestamp.asChars(TajoConf.getCurrentTimeZone(), true)});
+      testSimpleEval("select '1980-04-01 01:50:01'::timestamp;",
+          new String[]{timestamp.asChars(TajoConf.getCurrentTimeZone(), true)});
       testSimpleEval("select '1980-04-01 01:50:01'::timestamp::text", new String[]{"1980-04-01 01:50:01"});
 
       testSimpleEval("select (cast ('99999'::int8 as text))::int4 + 1", new String[]{"100000"});
@@ -901,6 +903,8 @@ public class TestSQLExpression extends ExprTestBase {
 
   @Test
   public void testNullComparisons() throws IOException {
+    testSimpleEval("select (1 > null) is null", new String[] {"t"});
+
     testSimpleEval("select null is null", new String[] {"t"});
     testSimpleEval("select null is not null", new String[] {"f"});
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-core/src/test/java/org/apache/tajo/engine/function/TestConditionalExpressions.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/function/TestConditionalExpressions.java b/tajo-core/src/test/java/org/apache/tajo/engine/function/TestConditionalExpressions.java
index ece34e7..54c8722 100644
--- a/tajo-core/src/test/java/org/apache/tajo/engine/function/TestConditionalExpressions.java
+++ b/tajo-core/src/test/java/org/apache/tajo/engine/function/TestConditionalExpressions.java
@@ -18,19 +18,134 @@
 
 package org.apache.tajo.engine.function;
 
+import org.apache.tajo.catalog.CatalogUtil;
+import org.apache.tajo.catalog.Schema;
 import org.apache.tajo.catalog.exception.NoSuchFunctionException;
+import org.apache.tajo.common.TajoDataTypes;
 import org.apache.tajo.engine.eval.ExprTestBase;
 import org.junit.Test;
 
+import java.io.IOException;
+
 import static org.junit.Assert.fail;
 
 public class TestConditionalExpressions extends ExprTestBase {
   @Test
+  public void testCaseWhens1() throws IOException {
+    Schema schema = new Schema();
+    schema.addColumn("col1", TajoDataTypes.Type.INT1);
+    schema.addColumn("col2", TajoDataTypes.Type.INT2);
+    schema.addColumn("col3", TajoDataTypes.Type.INT4);
+    schema.addColumn("col4", TajoDataTypes.Type.INT8);
+    schema.addColumn("col5", TajoDataTypes.Type.FLOAT4);
+    schema.addColumn("col6", TajoDataTypes.Type.FLOAT8);
+    schema.addColumn("col7", TajoDataTypes.Type.TEXT);
+    schema.addColumn("col8", CatalogUtil.newDataType(TajoDataTypes.Type.CHAR, "", 3));
+    schema.addColumn("col9", TajoDataTypes.Type.INT4);
+
+    testEval(schema, "table1", "1,2,3,4,5.0,6.0,text,abc,",
+        "select case when col1 between 1 and 3 then 10 else 100 end from table1;",
+        new String [] {"10"});
+    testEval(schema, "table1", "1,2,3,4,5.0,6.0,text,abc,",
+        "select case when col1 > 1 then 10 when col1 > 2 then 20 else 100 end from table1;",
+        new String [] {"100"});
+    testEval(schema, "table1", "1,2,3,4,5.0,6.0,text,abc,",
+        "select case col1 when 1 then 10 when 2 then 20 else 100 end from table1;",
+        new String [] {"10"});
+    testEval(schema, "table1", "1,2,3,4,5.0,6.0,text,abc,",
+        "select case col9 when 1 then 10 when 2 then 20 else 100 end is null from table1;",
+        new String [] {"f"});
+  }
+
+  @Test
+  public void testCaseWhensWithNullReturn() throws IOException {
+    Schema schema = new Schema();
+    schema.addColumn("col1", TajoDataTypes.Type.TEXT);
+    schema.addColumn("col2", TajoDataTypes.Type.TEXT);
+
+    testEval(schema, "table1", "str1,str2",
+        "SELECT CASE WHEN col1 IS NOT NULL THEN col2 ELSE NULL END FROM table1",
+        new String[]{"str2"});
+    testEval(schema, "table1", ",str2",
+        "SELECT CASE WHEN col1 IS NOT NULL THEN col2 ELSE NULL END FROM table1",
+        new String[]{""});
+  }
+
+  @Test
+  public void testCaseWhensWithCommonExpression() throws IOException {
+    Schema schema = new Schema();
+    schema.addColumn("col1", TajoDataTypes.Type.INT4);
+    schema.addColumn("col2", TajoDataTypes.Type.INT4);
+    schema.addColumn("col3", TajoDataTypes.Type.INT4);
+
+    testEval(schema, "table1", "1,2,3",
+        "SELECT CASE WHEN col1 = 1 THEN 1 WHEN col1 = 2 THEN 2 ELSE 3 END FROM table1",
+        new String [] {"1"});
+    testEval(schema, "table1", "1,2,3",
+        "SELECT CASE WHEN col2 = 1 THEN 1 WHEN col2 = 2 THEN 2 ELSE 3 END FROM table1",
+        new String [] {"2"});
+    testEval(schema, "table1", "1,2,3",
+        "SELECT CASE WHEN col3 = 1 THEN 1 WHEN col3 = 2 THEN 2 ELSE 3 END FROM table1",
+        new String [] {"3"});
+
+    testEval(schema, "table1", "1,2,3",
+        "SELECT CASE col1 WHEN 1 THEN 1 WHEN 2 THEN 2 ELSE 3 END FROM table1",
+        new String [] {"1"});
+    testEval(schema, "table1", "1,2,3",
+        "SELECT CASE col2 WHEN 1 THEN 1 WHEN 2 THEN 2 ELSE 3 END FROM table1",
+        new String [] {"2"});
+    testEval(schema, "table1", "1,2,3",
+        "SELECT CASE col3 WHEN 1 THEN 1 WHEN 2 THEN 2 ELSE 3 END FROM table1",
+        new String [] {"3"});
+
+    testEval(schema, "table1", "1,2,3",
+        "SELECT CASE col1 WHEN 1 THEN 'aaa' WHEN 2 THEN 'bbb' ELSE 'ccc' END FROM table1",
+        new String [] {"aaa"});
+    testEval(schema, "table1", "1,2,3",
+        "SELECT CASE col2 WHEN 1 THEN 'aaa' WHEN 2 THEN 'bbb' ELSE 'ccc' END FROM table1",
+        new String [] {"bbb"});
+    testEval(schema, "table1", "1,2,3",
+        "SELECT CASE col3 WHEN 1 THEN 'aaa' WHEN 2 THEN 'bbb' ELSE 'ccc' END FROM table1",
+        new String [] {"ccc"});
+  }
+
+  @Test
+  public void testCaseWhensWithCommonExpressionAndNull() throws IOException {
+    Schema schema = new Schema();
+    schema.addColumn("col1", TajoDataTypes.Type.INT4);
+    schema.addColumn("col2", TajoDataTypes.Type.INT4);
+    schema.addColumn("col3", TajoDataTypes.Type.INT4);
+
+    testEval(schema, "table1", "1,2,3",
+        "SELECT CASE col1 WHEN 1 THEN NULL WHEN 2 THEN 2 ELSE 3 END FROM table1",
+        new String [] {""});
+    testEval(schema, "table1", "1,2,3",
+        "SELECT CASE col2 WHEN 1 THEN NULL WHEN 2 THEN 2 ELSE 3 END FROM table1",
+        new String [] {"2"});
+    testEval(schema, "table1", "1,2,3",
+        "SELECT CASE col3 WHEN 1 THEN NULL WHEN 2 THEN 2 ELSE 3 END FROM table1",
+        new String [] {"3"});
+
+    testEval(schema, "table1", "1,2,3",
+        "SELECT CASE col1 WHEN 1 THEN 1 WHEN 2 THEN 2 ELSE NULL END FROM table1",
+        new String [] {"1"});
+    testEval(schema, "table1", "1,2,3",
+        "SELECT CASE col2 WHEN 1 THEN NULL WHEN 2 THEN 2 ELSE NULL END FROM table1",
+        new String [] {"2"});
+    testEval(schema, "table1", "1,2,3",
+        "SELECT CASE col3 WHEN 1 THEN NULL WHEN 2 THEN 2 ELSE NULL END FROM table1",
+        new String [] {""});
+  }
+
+  @Test
   public void testCoalesceText() throws Exception {
+    testSimpleEval("select coalesce('value1', 'value2');", new String[]{"value1"});
     testSimpleEval("select coalesce(null, 'value2');", new String[]{"value2"});
     testSimpleEval("select coalesce(null, null, 'value3');", new String[]{"value3"});
     testSimpleEval("select coalesce('value1', null, 'value3');", new String[]{"value1"});
     testSimpleEval("select coalesce(null, 'value2', 'value3');", new String[]{"value2"});
+    testSimpleEval("select coalesce('value1');", new String[]{"value1"});
+    testSimpleEval("select coalesce(null);", new String[]{""});
 
     //no matched function
     try {
@@ -43,10 +158,13 @@ public class TestConditionalExpressions extends ExprTestBase {
 
   @Test
   public void testCoalesceLong() throws Exception {
+    testSimpleEval("select coalesce(1, 2);", new String[]{"1"});
     testSimpleEval("select coalesce(null, 2);", new String[]{"2"});
     testSimpleEval("select coalesce(null, null, 3);", new String[]{"3"});
     testSimpleEval("select coalesce(1, null, 3);", new String[]{"1"});
     testSimpleEval("select coalesce(null, 2, 3);", new String[]{"2"});
+    testSimpleEval("select coalesce(1);", new String[]{"1"});
+    testSimpleEval("select coalesce(null);", new String[]{""});
 
     //no matched function
     try {
@@ -59,17 +177,20 @@ public class TestConditionalExpressions extends ExprTestBase {
 
   @Test
   public void testCoalesceDouble() throws Exception {
+    testSimpleEval("select coalesce(1.0, 2.0);", new String[]{"1.0"});
     testSimpleEval("select coalesce(null, 2.0);", new String[]{"2.0"});
     testSimpleEval("select coalesce(null, null, 3.0);", new String[]{"3.0"});
     testSimpleEval("select coalesce(1.0, null, 3.0);", new String[]{"1.0"});
     testSimpleEval("select coalesce(null, 2.0, 3.0);", new String[]{"2.0"});
+    testSimpleEval("select coalesce(1.0);", new String[]{"1.0"});
+    testSimpleEval("select coalesce(null);", new String[]{""});
 
     //no matched function
     try {
       testSimpleEval("select coalesce('value1', null, 3.0);", new String[]{"1.0"});
       fail("coalesce(TEXT, NULL, FLOAT8) not defined. So should throw exception.");
     } catch (NoSuchFunctionException e) {
-      //success
+      // success
     }
 
     try {

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-core/src/test/java/org/apache/tajo/engine/function/TestPatternMatchingPredicates.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/function/TestPatternMatchingPredicates.java b/tajo-core/src/test/java/org/apache/tajo/engine/function/TestPatternMatchingPredicates.java
index 7d8eba4..8aae26d 100644
--- a/tajo-core/src/test/java/org/apache/tajo/engine/function/TestPatternMatchingPredicates.java
+++ b/tajo-core/src/test/java/org/apache/tajo/engine/function/TestPatternMatchingPredicates.java
@@ -35,7 +35,7 @@ public class TestPatternMatchingPredicates extends ExprTestBase {
 
     // test for null values
     testEval(schema, "table1", ",", "select col1 like 'a%' from table1", new String[]{""});
-    //testSimpleEval("select null like 'a%'", new String[]{""});
+    testSimpleEval("select null like 'a%'", new String[]{""});
 
     testEval(schema, "table1", "abc", "select col1 like '%c' from table1", new String[]{"t"});
     testEval(schema, "table1", "abc", "select col1 like 'a%' from table1", new String[]{"t"});

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-core/src/test/java/org/apache/tajo/engine/planner/physical/TestPhysicalPlanner.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/planner/physical/TestPhysicalPlanner.java b/tajo-core/src/test/java/org/apache/tajo/engine/planner/physical/TestPhysicalPlanner.java
index 191db85..5d809f8 100644
--- a/tajo-core/src/test/java/org/apache/tajo/engine/planner/physical/TestPhysicalPlanner.java
+++ b/tajo-core/src/test/java/org/apache/tajo/engine/planner/physical/TestPhysicalPlanner.java
@@ -914,7 +914,7 @@ public class TestPhysicalPlanner {
   }
 
   @Test
-  public final void testUnionPlan() throws IOException, PlanningException {
+  public final void testUnionPlan() throws IOException, PlanningException, CloneNotSupportedException {
     FileFragment[] frags = StorageManager.splitNG(conf, "default.employee", employee.getMeta(), employee.getPath(),
         Integer.MAX_VALUE);
     Path workDir = CommonTestingUtil.getTestDir("target/test-data/testUnionPlan");
@@ -927,8 +927,8 @@ public class TestPhysicalPlanner {
     LogicalNode rootNode = optimizer.optimize(plan);
     LogicalRootNode root = (LogicalRootNode) rootNode;
     UnionNode union = plan.createNode(UnionNode.class);
-    union.setLeftChild(root.getChild());
-    union.setRightChild(root.getChild());
+    union.setLeftChild((LogicalNode) root.getChild().clone());
+    union.setRightChild((LogicalNode) root.getChild().clone());
     root.setChild(union);
 
     PhysicalPlanner phyPlanner = new PhysicalPlannerImpl(conf,sm);

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-core/src/test/java/org/apache/tajo/worker/TestFetcher.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/java/org/apache/tajo/worker/TestFetcher.java b/tajo-core/src/test/java/org/apache/tajo/worker/TestFetcher.java
index eb63c27..95c06bb 100644
--- a/tajo-core/src/test/java/org/apache/tajo/worker/TestFetcher.java
+++ b/tajo-core/src/test/java/org/apache/tajo/worker/TestFetcher.java
@@ -84,7 +84,7 @@ public class TestFetcher {
     String params = String.format("qid=%s&sid=%s&p=%s&type=%s", queryId, sid, partId, "h");
 
     Path inputPath = new Path(dataPath);
-    FSDataOutputStream stream =  LocalFileSystem.get(conf).create(inputPath, true);
+    FSDataOutputStream stream = FileSystem.getLocal(conf).create(inputPath, true);
     for (int i = 0; i < 100; i++) {
       String data = ""+rnd.nextInt();
       stream.write(data.getBytes());
@@ -124,7 +124,7 @@ public class TestFetcher {
     String dataPath = INPUT_DIR + queryId.toString() + "/output"+ "/" + sid + "/" +ta + "/output/" + partId;
     String params = String.format("qid=%s&sid=%s&p=%s&type=%s&ta=%s", queryId, sid, partId, "h", ta);
 
-    FSDataOutputStream stream =  LocalFileSystem.get(conf).create(new Path(dataPath), true);
+    FSDataOutputStream stream =  FileSystem.getLocal(conf).create(new Path(dataPath), true);
     for (int i = 0; i < 100; i++) {
       String data = ""+rnd.nextInt();
       stream.write(data.getBytes());
@@ -152,11 +152,12 @@ public class TestFetcher {
     String params = String.format("qid=%s&sid=%s&p=%s&type=%s&ta=%s", queryId, sid, partId, "h", ta);
 
     Path inputPath = new Path(dataPath);
-    if(LocalFileSystem.get(conf).exists(inputPath)){
-      LocalFileSystem.get(conf).delete(new Path(dataPath), true);
+    FileSystem fs = FileSystem.getLocal(conf);
+    if(fs.exists(inputPath)){
+      fs.delete(new Path(dataPath), true);
     }
 
-    FSDataOutputStream stream =  LocalFileSystem.get(conf).create(new Path(dataPath).getParent(), true);
+    FSDataOutputStream stream =  FileSystem.getLocal(conf).create(new Path(dataPath).getParent(), true);
     stream.close();
 
     URI uri = URI.create("http://127.0.0.1:" + pullServerService.getPort() + "/?" + params);
@@ -182,7 +183,7 @@ public class TestFetcher {
     String shuffleType = "x";
     String params = String.format("qid=%s&sid=%s&p=%s&type=%s&ta=%s", queryId, sid, partId, shuffleType, ta);
 
-    FSDataOutputStream stream =  LocalFileSystem.get(conf).create(new Path(dataPath), true);
+    FSDataOutputStream stream =  FileSystem.getLocal(conf).create(new Path(dataPath), true);
 
     for (int i = 0; i < 100; i++) {
       String data = params + rnd.nextInt();

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-core/src/test/resources/results/TestTajoCli/testHelpSessionVars.result
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/resources/results/TestTajoCli/testHelpSessionVars.result b/tajo-core/src/test/resources/results/TestTajoCli/testHelpSessionVars.result
index c294407..0b5e28f 100644
--- a/tajo-core/src/test/resources/results/TestTajoCli/testHelpSessionVars.result
+++ b/tajo-core/src/test/resources/results/TestTajoCli/testHelpSessionVars.result
@@ -32,5 +32,6 @@ Available Session Variables:
 \set HASH_GROUPBY_SIZE_LIMIT [long value] - limited size for hash groupby (mb)
 \set MAX_OUTPUT_FILE_SIZE [int value] - Maximum per-output file size (mb). 0 means infinite.
 \set NULL_CHAR [text value] - null char of text file output
+\set CODEGEN [true or false] - Runtime code generation enabled (experiment)
 \set ARITHABORT [true or false] - If true, a running query will be terminated when an overflow or divide-by-zero occurs.
 \set DEBUG_ENABLED [true or false] - (debug only) debug mode enabled
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-dist/pom.xml
----------------------------------------------------------------------
diff --git a/tajo-dist/pom.xml b/tajo-dist/pom.xml
index d893010..a0cbe9f 100644
--- a/tajo-dist/pom.xml
+++ b/tajo-dist/pom.xml
@@ -32,6 +32,28 @@
   <name>Tajo Distribution</name>
   <packaging>jar</packaging>
 
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.rat</groupId>
+        <artifactId>apache-rat-plugin</artifactId>
+        <executions>
+          <execution>
+            <phase>verify</phase>
+            <goals>
+              <goal>check</goal>
+            </goals>
+          </execution>
+        </executions>
+        <configuration>
+          <excludes>
+            <exclude>src/main/conf/workers</exclude>
+          </excludes>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
   <dependencies>
     <dependency>
       <groupId>org.apache.tajo</groupId>

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-dist/src/main/bin/tajo
----------------------------------------------------------------------
diff --git a/tajo-dist/src/main/bin/tajo b/tajo-dist/src/main/bin/tajo
index 4382a7a..f579864 100755
--- a/tajo-dist/src/main/bin/tajo
+++ b/tajo-dist/src/main/bin/tajo
@@ -180,8 +180,8 @@ fi
 # Allow alternate conf dir location.
 HADOOP_CONF_DIR="${HADOOP_CONF_DIR:-$HADOOP_HOME/etc/hadoop}"
 
-# CLASSPATH initially contains $HADOOP_CONF_DIR
-CLASSPATH="${HADOOP_CONF_DIR}"
+# CLASSPATH initially contains $HADOOP_CONF_DIR and tools.jar
+CLASSPATH="${HADOOP_CONF_DIR}:${JAVA_HOME}/lib/tools.jar"
 
 ##############################################################################
 # Hadoop Version Checking Section End

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-docs/pom.xml
----------------------------------------------------------------------
diff --git a/tajo-docs/pom.xml b/tajo-docs/pom.xml
index 5ca89c5..5e14273 100644
--- a/tajo-docs/pom.xml
+++ b/tajo-docs/pom.xml
@@ -29,6 +29,24 @@ limitations under the License.
   <build>
     <plugins>
       <plugin>
+        <groupId>org.apache.rat</groupId>
+        <artifactId>apache-rat-plugin</artifactId>
+        <executions>
+          <execution>
+            <phase>verify</phase>
+            <goals>
+              <goal>check</goal>
+            </goals>
+          </execution>
+        </executions>
+        <configuration>
+          <excludes>
+            <exclude>BUILDING</exclude>
+            <exclude>src/main/sphinx/**/*.rst</exclude>
+          </excludes>
+        </configuration>
+      </plugin>
+      <plugin>
         <groupId>org.tomdz.maven</groupId>
         <artifactId>sphinx-maven-plugin</artifactId>
         <version>1.0.2</version>

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-jdbc/pom.xml
----------------------------------------------------------------------
diff --git a/tajo-jdbc/pom.xml b/tajo-jdbc/pom.xml
index dcca6b1..1708f5a 100644
--- a/tajo-jdbc/pom.xml
+++ b/tajo-jdbc/pom.xml
@@ -57,6 +57,18 @@
         </configuration>
       </plugin>
       <plugin>
+        <groupId>org.apache.rat</groupId>
+        <artifactId>apache-rat-plugin</artifactId>
+        <executions>
+          <execution>
+            <phase>verify</phase>
+            <goals>
+              <goal>check</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-dependency-plugin</artifactId>
         <executions>
@@ -198,7 +210,6 @@
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-surefire-report-plugin</artifactId>
-        <version>2.15</version>
       </plugin>
     </plugins>
   </reporting>

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/MetaDataTuple.java
----------------------------------------------------------------------
diff --git a/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/MetaDataTuple.java b/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/MetaDataTuple.java
index 04338ca..5dae67e 100644
--- a/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/MetaDataTuple.java
+++ b/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/MetaDataTuple.java
@@ -18,6 +18,7 @@ package org.apache.tajo.jdbc; /**
 
 import org.apache.tajo.datum.Datum;
 import org.apache.tajo.datum.NullDatum;
+import org.apache.tajo.datum.ProtobufDatum;
 import org.apache.tajo.exception.UnsupportedException;
 import org.apache.tajo.storage.Tuple;
 
@@ -140,6 +141,11 @@ public class MetaDataTuple implements Tuple {
   }
 
   @Override
+  public ProtobufDatum getProtobufDatum(int fieldId) {
+    throw new UnsupportedException();
+  }
+
+  @Override
   public char[] getUnicodeChars(int fieldId) {
     return values.get(fieldId).asUnicodeChars();
   }

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-maven-plugins/pom.xml
----------------------------------------------------------------------
diff --git a/tajo-maven-plugins/pom.xml b/tajo-maven-plugins/pom.xml
index acb338d..43ff9e0 100644
--- a/tajo-maven-plugins/pom.xml
+++ b/tajo-maven-plugins/pom.xml
@@ -56,6 +56,18 @@
   <build>
     <plugins>
       <plugin>
+        <groupId>org.apache.rat</groupId>
+        <artifactId>apache-rat-plugin</artifactId>
+        <executions>
+          <execution>
+            <phase>verify</phase>
+            <goals>
+              <goal>check</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-plugin-plugin</artifactId>
         <version>${maven.dependency.version}</version>

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-project/pom.xml
----------------------------------------------------------------------
diff --git a/tajo-project/pom.xml b/tajo-project/pom.xml
index af8a361..fe5366e 100644
--- a/tajo-project/pom.xml
+++ b/tajo-project/pom.xml
@@ -393,11 +393,6 @@
         </plugin>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
-          <artifactId>maven-pmd-plugin</artifactId>
-          <version>2.7.1</version>
-        </plugin>
-        <plugin>
-          <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-site-plugin</artifactId>
           <version>3.3</version>
           <dependencies>
@@ -597,6 +592,18 @@
         </configuration>
       </plugin>
       <plugin>
+        <groupId>org.apache.rat</groupId>
+        <artifactId>apache-rat-plugin</artifactId>
+        <executions>
+          <execution>
+            <phase>verify</phase>
+            <goals>
+              <goal>check</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-enforcer-plugin</artifactId>
         <inherited>false</inherited>
@@ -758,6 +765,12 @@
         <version>${tajo.version}</version>
         <type>test-jar</type>
       </dependency>
+      <dependency>
+        <groupId>org.apache.tajo</groupId>
+        <artifactId>tajo-thirdparty-asm</artifactId>
+        <version>${tajo.version}</version>
+        <type>jar</type>
+      </dependency>
 
       <dependency>
         <groupId>org.apache.hadoop</groupId>

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-rpc/pom.xml
----------------------------------------------------------------------
diff --git a/tajo-rpc/pom.xml b/tajo-rpc/pom.xml
index 22a6b4a..06e24b9 100644
--- a/tajo-rpc/pom.xml
+++ b/tajo-rpc/pom.xml
@@ -42,6 +42,18 @@
         </configuration>
       </plugin>
       <plugin>
+        <groupId>org.apache.rat</groupId>
+        <artifactId>apache-rat-plugin</artifactId>
+        <executions>
+          <execution>
+            <phase>verify</phase>
+            <goals>
+              <goal>check</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-jar-plugin</artifactId>
         <version>2.4</version>

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-storage/pom.xml
----------------------------------------------------------------------
diff --git a/tajo-storage/pom.xml b/tajo-storage/pom.xml
index 7035b62..6f80ea5 100644
--- a/tajo-storage/pom.xml
+++ b/tajo-storage/pom.xml
@@ -61,9 +61,25 @@
         </configuration>
       </plugin>
       <plugin>
+        <groupId>org.apache.rat</groupId>
+        <artifactId>apache-rat-plugin</artifactId>
+        <executions>
+          <execution>
+            <phase>verify</phase>
+            <goals>
+              <goal>check</goal>
+            </goals>
+          </execution>
+        </executions>
+        <configuration>
+          <excludes>
+            <exclude>src/test/resources/testVariousTypes.avsc</exclude>
+          </excludes>
+        </configuration>
+      </plugin>
+      <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-surefire-plugin</artifactId>
-        <version>2.12.4</version>
         <configuration>
           <systemProperties>
             <tajo.test>TRUE</tajo.test>

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-storage/src/main/java/org/apache/tajo/storage/FrameTuple.java
----------------------------------------------------------------------
diff --git a/tajo-storage/src/main/java/org/apache/tajo/storage/FrameTuple.java b/tajo-storage/src/main/java/org/apache/tajo/storage/FrameTuple.java
index 1376a05..e0f8a2e 100644
--- a/tajo-storage/src/main/java/org/apache/tajo/storage/FrameTuple.java
+++ b/tajo-storage/src/main/java/org/apache/tajo/storage/FrameTuple.java
@@ -24,6 +24,7 @@ package org.apache.tajo.storage;
 import com.google.common.base.Preconditions;
 import org.apache.tajo.datum.Datum;
 import org.apache.tajo.datum.NullDatum;
+import org.apache.tajo.datum.ProtobufDatum;
 import org.apache.tajo.exception.UnsupportedException;
 
 /**
@@ -171,6 +172,11 @@ public class FrameTuple implements Tuple, Cloneable {
   }
 
   @Override
+  public ProtobufDatum getProtobufDatum(int fieldId) {
+    return (ProtobufDatum) get(fieldId);
+  }
+
+  @Override
   public char [] getUnicodeChars(int fieldId) {
     return get(fieldId).asUnicodeChars();
   }

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-storage/src/main/java/org/apache/tajo/storage/LazyTuple.java
----------------------------------------------------------------------
diff --git a/tajo-storage/src/main/java/org/apache/tajo/storage/LazyTuple.java b/tajo-storage/src/main/java/org/apache/tajo/storage/LazyTuple.java
index d8dca0e..167e4a8 100644
--- a/tajo-storage/src/main/java/org/apache/tajo/storage/LazyTuple.java
+++ b/tajo-storage/src/main/java/org/apache/tajo/storage/LazyTuple.java
@@ -21,6 +21,8 @@ package org.apache.tajo.storage;
 import org.apache.tajo.catalog.Schema;
 import org.apache.tajo.datum.Datum;
 import org.apache.tajo.datum.NullDatum;
+import org.apache.tajo.datum.ProtobufDatum;
+import org.apache.tajo.exception.UnsupportedException;
 
 import java.util.Arrays;
 
@@ -183,7 +185,7 @@ public class LazyTuple implements Tuple, Cloneable {
 
   @Override
   public double getFloat8(int fieldId) {
-    return get(fieldId).asInt8();
+    return get(fieldId).asFloat8();
   }
 
   @Override
@@ -192,6 +194,11 @@ public class LazyTuple implements Tuple, Cloneable {
   }
 
   @Override
+  public ProtobufDatum getProtobufDatum(int fieldId) {
+    throw new UnsupportedException();
+  }
+
+  @Override
   public char[] getUnicodeChars(int fieldId) {
     return get(fieldId).asUnicodeChars();
   }

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-storage/src/main/java/org/apache/tajo/storage/Tuple.java
----------------------------------------------------------------------
diff --git a/tajo-storage/src/main/java/org/apache/tajo/storage/Tuple.java b/tajo-storage/src/main/java/org/apache/tajo/storage/Tuple.java
index 5a173f7..c183171 100644
--- a/tajo-storage/src/main/java/org/apache/tajo/storage/Tuple.java
+++ b/tajo-storage/src/main/java/org/apache/tajo/storage/Tuple.java
@@ -19,6 +19,7 @@
 package org.apache.tajo.storage;
 
 import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.ProtobufDatum;
 
 public interface Tuple extends Cloneable {
   
@@ -64,6 +65,8 @@ public interface Tuple extends Cloneable {
 	
 	public String getText(int fieldId);
 
+  public ProtobufDatum getProtobufDatum(int fieldId);
+
   public char [] getUnicodeChars(int fieldId);
 
   public Tuple clone() throws CloneNotSupportedException;

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-storage/src/main/java/org/apache/tajo/storage/VTuple.java
----------------------------------------------------------------------
diff --git a/tajo-storage/src/main/java/org/apache/tajo/storage/VTuple.java b/tajo-storage/src/main/java/org/apache/tajo/storage/VTuple.java
index 326fb6d..4fb35f9 100644
--- a/tajo-storage/src/main/java/org/apache/tajo/storage/VTuple.java
+++ b/tajo-storage/src/main/java/org/apache/tajo/storage/VTuple.java
@@ -22,6 +22,7 @@ import com.google.gson.annotations.Expose;
 import org.apache.tajo.datum.Datum;
 import org.apache.tajo.datum.Inet4Datum;
 import org.apache.tajo.datum.NullDatum;
+import org.apache.tajo.datum.ProtobufDatum;
 import org.apache.tajo.exception.UnimplementedException;
 
 import java.net.InetAddress;
@@ -173,6 +174,11 @@ public class VTuple implements Tuple, Cloneable {
 	}
 
   @Override
+  public ProtobufDatum getProtobufDatum(int fieldId) {
+    return (ProtobufDatum) values[fieldId];
+  }
+
+  @Override
   public char[] getUnicodeChars(int fieldId) {
     return values[fieldId].asUnicodeChars();
   }

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-storage/src/main/java/org/apache/tajo/storage/parquet/ParquetAppender.java
----------------------------------------------------------------------
diff --git a/tajo-storage/src/main/java/org/apache/tajo/storage/parquet/ParquetAppender.java b/tajo-storage/src/main/java/org/apache/tajo/storage/parquet/ParquetAppender.java
index ff9e43c..3a3bb57 100644
--- a/tajo-storage/src/main/java/org/apache/tajo/storage/parquet/ParquetAppender.java
+++ b/tajo-storage/src/main/java/org/apache/tajo/storage/parquet/ParquetAppender.java
@@ -18,6 +18,7 @@
 
 package org.apache.tajo.storage.parquet;
 
+import org.apache.tajo.storage.StorageConstants;
 import parquet.hadoop.ParquetOutputFormat;
 import parquet.hadoop.metadata.CompressionCodecName;
 
@@ -56,15 +57,15 @@ public class ParquetAppender extends FileAppender {
                          Path path) throws IOException {
     super(conf, schema, meta, path);
     this.blockSize = Integer.parseInt(
-        meta.getOption(ParquetOutputFormat.BLOCK_SIZE));
+        meta.getOption(ParquetOutputFormat.BLOCK_SIZE, StorageConstants.PARQUET_DEFAULT_BLOCK_SIZE));
     this.pageSize = Integer.parseInt(
-        meta.getOption(ParquetOutputFormat.PAGE_SIZE));
+        meta.getOption(ParquetOutputFormat.PAGE_SIZE, StorageConstants.PARQUET_DEFAULT_PAGE_SIZE));
     this.compressionCodecName = CompressionCodecName.fromConf(
-        meta.getOption(ParquetOutputFormat.COMPRESSION));
+        meta.getOption(ParquetOutputFormat.COMPRESSION, StorageConstants.PARQUET_DEFAULT_COMPRESSION_CODEC_NAME));
     this.enableDictionary = Boolean.parseBoolean(
-        meta.getOption(ParquetOutputFormat.ENABLE_DICTIONARY));
+        meta.getOption(ParquetOutputFormat.ENABLE_DICTIONARY, StorageConstants.PARQUET_DEFAULT_IS_DICTIONARY_ENABLED));
     this.validating = Boolean.parseBoolean(
-        meta.getOption(ParquetOutputFormat.VALIDATION));
+        meta.getOption(ParquetOutputFormat.VALIDATION, StorageConstants.PARQUET_DEFAULT_IS_VALIDATION_ENABLED));
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-storage/src/test/java/org/apache/tajo/storage/parquet/TestReadWrite.java
----------------------------------------------------------------------
diff --git a/tajo-storage/src/test/java/org/apache/tajo/storage/parquet/TestReadWrite.java b/tajo-storage/src/test/java/org/apache/tajo/storage/parquet/TestReadWrite.java
index 1cfba86..0a01dc4 100644
--- a/tajo-storage/src/test/java/org/apache/tajo/storage/parquet/TestReadWrite.java
+++ b/tajo-storage/src/test/java/org/apache/tajo/storage/parquet/TestReadWrite.java
@@ -25,6 +25,8 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.LocalFileSystem;
 import org.apache.hadoop.fs.Path;
 import org.apache.tajo.catalog.Column;
 import org.apache.tajo.catalog.Schema;
@@ -48,7 +50,10 @@ public class TestReadWrite {
     File tmp = File.createTempFile(getClass().getSimpleName(), ".tmp");
     tmp.deleteOnExit();
     tmp.delete();
-    return new Path(tmp.getPath());
+
+    // it prevents accessing HDFS namenode of TajoTestingCluster.
+    LocalFileSystem localFS = LocalFileSystem.getLocal(new Configuration());
+    return localFS.makeQualified(new Path(tmp.getPath()));
   }
 
   private Schema createAllTypesSchema() {

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-thirdparty/asm/pom.xml
----------------------------------------------------------------------
diff --git a/tajo-thirdparty/asm/pom.xml b/tajo-thirdparty/asm/pom.xml
new file mode 100644
index 0000000..5464d49
--- /dev/null
+++ b/tajo-thirdparty/asm/pom.xml
@@ -0,0 +1,180 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed 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. See accompanying LICENSE file.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>tajo-project</artifactId>
+    <groupId>org.apache.tajo</groupId>
+    <version>0.9.0-SNAPSHOT</version>
+    <relativePath>../../tajo-project</relativePath>
+  </parent>
+
+  <artifactId>tajo-thirdparty-asm</artifactId>
+  <name>ASM (thirdparty) </name>
+  <description>ASM is a Java bytecode manipulation framework.</description>
+  <packaging>jar</packaging>
+
+  <properties>
+    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+
+  <repositories>
+    <repository>
+      <id>apache.snapshots</id>
+      <url>http://repository.apache.org/snapshots</url>
+      <snapshots>
+        <enabled>true</enabled>
+      </snapshots>
+    </repository>
+  </repositories>
+
+  <build>
+    <plugins>
+     <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <source>1.6</source>
+          <target>1.6</target>
+          <encoding>${project.build.sourceEncoding}</encoding>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.rat</groupId>
+        <artifactId>apache-rat-plugin</artifactId>
+        <executions>
+          <execution>
+            <phase>verify</phase>
+            <goals>
+              <goal>check</goal>
+            </goals>
+          </execution>
+        </executions>
+        <configuration>
+          <excludes>
+            <exclude>src/main/java/org/apache/tajo/org/objectweb/asm/**</exclude>
+          </excludes>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-report-plugin</artifactId>
+      </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+  </dependencies>
+
+  <profiles>
+    <profile>
+      <id>docs</id>
+      <activation>
+        <activeByDefault>false</activeByDefault>
+      </activation>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-javadoc-plugin</artifactId>
+            <executions>
+              <execution>
+                <!-- build javadoc jars per jar for publishing to maven -->
+                <id>module-javadocs</id>
+                <phase>package</phase>
+                <goals>
+                  <goal>jar</goal>
+                </goals>
+                <configuration>
+                  <destDir>${project.build.directory}</destDir>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+    <profile>
+      <id>dist</id>
+      <activation>
+        <activeByDefault>false</activeByDefault>
+        <property>
+          <name>tar|rpm|deb</name>
+        </property>
+      </activation>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-antrun-plugin</artifactId>
+            <executions>
+              <execution>
+                <id>dist</id>
+                <phase>package</phase>
+                <goals>
+                  <goal>run</goal>
+                </goals>
+                <configuration>
+                  <target>
+                    <echo file="${project.build.directory}/dist-layout-stitching.sh">
+                      run() {
+                      echo "\$ ${@}"
+                      "${@}"
+                      res=$?
+                      if [ $res != 0 ]; then
+                      echo
+                      echo "Failed!"
+                      echo
+                      exit $res
+                      fi
+                      }
+
+                      ROOT=`cd ${basedir}/..;pwd`
+                      echo
+                      echo "Current directory `pwd`"
+                      echo
+                      run rm -rf ${project.artifactId}-${project.version}
+                      run mkdir ${project.artifactId}-${project.version}
+                      run cd ${project.artifactId}-${project.version}
+                      run cp -r ${basedir}/target/${project.artifactId}-${project.version}*.jar .
+                      echo
+                      echo "Tajo Common dist layout available at: ${project.build.directory}/${project.artifactId}-${project.version}"
+                      echo
+                    </echo>
+                    <exec executable="sh" dir="${project.build.directory}" failonerror="true">
+                      <arg line="./dist-layout-stitching.sh"/>
+                    </exec>
+                  </target>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+
+  <reporting>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-report-plugin</artifactId>
+      </plugin>
+    </plugins>
+  </reporting>
+</project>

http://git-wip-us.apache.org/repos/asf/tajo/blob/7603a3d4/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/AnnotationVisitor.java
----------------------------------------------------------------------
diff --git a/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/AnnotationVisitor.java b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/AnnotationVisitor.java
new file mode 100644
index 0000000..c63618c
--- /dev/null
+++ b/tajo-thirdparty/asm/src/main/java/org/apache/tajo/org/objectweb/asm/AnnotationVisitor.java
@@ -0,0 +1,169 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.apache.tajo.org.objectweb.asm;
+
+/**
+ * A visitor to visit a Java annotation. The methods of this class must be
+ * called in the following order: ( <tt>visit</tt> | <tt>visitEnum</tt> |
+ * <tt>visitAnnotation</tt> | <tt>visitArray</tt> )* <tt>visitEnd</tt>.
+ * 
+ * @author Eric Bruneton
+ * @author Eugene Kuleshov
+ */
+public abstract class AnnotationVisitor {
+
+    /**
+     * The ASM API version implemented by this visitor. The value of this field
+     * must be one of {@link Opcodes#ASM4}.
+     */
+    protected final int api;
+
+    /**
+     * The annotation visitor to which this visitor must delegate method calls.
+     * May be null.
+     */
+    protected AnnotationVisitor av;
+
+    /**
+     * Constructs a new {@link AnnotationVisitor}.
+     * 
+     * @param api
+     *            the ASM API version implemented by this visitor. Must be one
+     *            of {@link Opcodes#ASM4}.
+     */
+    public AnnotationVisitor(final int api) {
+        this(api, null);
+    }
+
+    /**
+     * Constructs a new {@link AnnotationVisitor}.
+     * 
+     * @param api
+     *            the ASM API version implemented by this visitor. Must be one
+     *            of {@link Opcodes#ASM4}.
+     * @param av
+     *            the annotation visitor to which this visitor must delegate
+     *            method calls. May be null.
+     */
+    public AnnotationVisitor(final int api, final AnnotationVisitor av) {
+        if (api != Opcodes.ASM4) {
+            throw new IllegalArgumentException();
+        }
+        this.api = api;
+        this.av = av;
+    }
+
+    /**
+     * Visits a primitive value of the annotation.
+     * 
+     * @param name
+     *            the value name.
+     * @param value
+     *            the actual value, whose type must be {@link Byte},
+     *            {@link Boolean}, {@link Character}, {@link Short},
+     *            {@link Integer} , {@link Long}, {@link Float}, {@link Double},
+     *            {@link String} or {@link Type} or OBJECT or ARRAY sort. This
+     *            value can also be an array of byte, boolean, short, char, int,
+     *            long, float or double values (this is equivalent to using
+     *            {@link #visitArray visitArray} and visiting each array element
+     *            in turn, but is more convenient).
+     */
+    public void visit(String name, Object value) {
+        if (av != null) {
+            av.visit(name, value);
+        }
+    }
+
+    /**
+     * Visits an enumeration value of the annotation.
+     * 
+     * @param name
+     *            the value name.
+     * @param desc
+     *            the class descriptor of the enumeration class.
+     * @param value
+     *            the actual enumeration value.
+     */
+    public void visitEnum(String name, String desc, String value) {
+        if (av != null) {
+            av.visitEnum(name, desc, value);
+        }
+    }
+
+    /**
+     * Visits a nested annotation value of the annotation.
+     * 
+     * @param name
+     *            the value name.
+     * @param desc
+     *            the class descriptor of the nested annotation class.
+     * @return a visitor to visit the actual nested annotation value, or
+     *         <tt>null</tt> if this visitor is not interested in visiting this
+     *         nested annotation. <i>The nested annotation value must be fully
+     *         visited before calling other methods on this annotation
+     *         visitor</i>.
+     */
+    public AnnotationVisitor visitAnnotation(String name, String desc) {
+        if (av != null) {
+            return av.visitAnnotation(name, desc);
+        }
+        return null;
+    }
+
+    /**
+     * Visits an array value of the annotation. Note that arrays of primitive
+     * types (such as byte, boolean, short, char, int, long, float or double)
+     * can be passed as value to {@link #visit visit}. This is what
+     * {@link ClassReader} does.
+     * 
+     * @param name
+     *            the value name.
+     * @return a visitor to visit the actual array value elements, or
+     *         <tt>null</tt> if this visitor is not interested in visiting these
+     *         values. The 'name' parameters passed to the methods of this
+     *         visitor are ignored. <i>All the array values must be visited
+     *         before calling other methods on this annotation visitor</i>.
+     */
+    public AnnotationVisitor visitArray(String name) {
+        if (av != null) {
+            return av.visitArray(name);
+        }
+        return null;
+    }
+
+    /**
+     * Visits the end of the annotation.
+     */
+    public void visitEnd() {
+        if (av != null) {
+            av.visitEnd();
+        }
+    }
+}