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 2016/05/13 05:32:42 UTC

[2/7] tajo git commit: TAJO-2129: Apply new type implementation to Schema and Catalog.

http://git-wip-us.apache.org/repos/asf/tajo/blob/8d2bf407/tajo-core/src/main/java/org/apache/tajo/engine/codegen/EvalCodeGenContext.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/codegen/EvalCodeGenContext.java b/tajo-core/src/main/java/org/apache/tajo/engine/codegen/EvalCodeGenContext.java
index 0dea104..c2840c5 100644
--- a/tajo-core/src/main/java/org/apache/tajo/engine/codegen/EvalCodeGenContext.java
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/codegen/EvalCodeGenContext.java
@@ -116,7 +116,7 @@ public class EvalCodeGenContext extends TajoGeneratorAdapter {
       if (entry.getKey().getType() == EvalType.CONST) {
         ConstEval constEval = (ConstEval) entry.getKey();
 
-        if (constEval.getValueType().baseType() == TajoDataTypes.Type.INTERVAL) {
+        if (constEval.getValueType().kind() == TajoDataTypes.Type.INTERVAL) {
           IntervalDatum datum = (IntervalDatum) constEval.getValue();
 
           final String internalName = TajoGeneratorAdapter.getInternalName(IntervalDatum.class);
@@ -141,7 +141,7 @@ public class EvalCodeGenContext extends TajoGeneratorAdapter {
         initMethod.visitTypeInsn(Opcodes.NEW, internalName);
         consAdapter.dup();
         emitCreateEval(consAdapter, initMethod, inEval.getLeftExpr());
-        emitRowConstantEval(consAdapter, initMethod, (RowConstantEval) inEval.getRightExpr());
+        emitRowConstantEval(consAdapter, initMethod, inEval.getRightExpr());
         consAdapter.push(inEval.isNot());
         consAdapter.invokeSpecial(InEval.class, "<init>", void.class,
             new Class [] {EvalNode.class, RowConstantEval.class, boolean.class});

http://git-wip-us.apache.org/repos/asf/tajo/blob/8d2bf407/tajo-core/src/main/java/org/apache/tajo/engine/codegen/EvalCodeGenerator.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/codegen/EvalCodeGenerator.java b/tajo-core/src/main/java/org/apache/tajo/engine/codegen/EvalCodeGenerator.java
index 5ee6d82..981370b 100644
--- a/tajo-core/src/main/java/org/apache/tajo/engine/codegen/EvalCodeGenerator.java
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/codegen/EvalCodeGenerator.java
@@ -170,7 +170,7 @@ public class EvalCodeGenerator extends SimpleEvalNodeVisitor<EvalCodeGenContext>
       context.emitNullityCheck(ifNull);
 
       SignedEval signed = (SignedEval) unary;
-      switch (signed.getValueType().baseType()) {
+      switch (signed.getValueType().kind()) {
       case BOOLEAN:
       case CHAR:
       case INT1:
@@ -375,7 +375,7 @@ public class EvalCodeGenerator extends SimpleEvalNodeVisitor<EvalCodeGenContext>
       String methodName = null;
       Class returnType = null;
       Class [] paramTypes = null;
-      switch (field.getValueType().baseType()) {
+      switch (field.getValueType().kind()) {
       case BOOLEAN:
         methodName = "getByte";
         returnType = byte.class;
@@ -479,7 +479,7 @@ public class EvalCodeGenerator extends SimpleEvalNodeVisitor<EvalCodeGenContext>
   }
 
   public static int store(EvalCodeGenContext context, org.apache.tajo.type.Type type, int idx) {
-    switch (type.baseType()) {
+    switch (type.kind()) {
     case NULL_TYPE:
     case BOOLEAN:
     case CHAR:
@@ -642,7 +642,7 @@ public class EvalCodeGenerator extends SimpleEvalNodeVisitor<EvalCodeGenContext>
 
   @Override
   public EvalNode visitConst(EvalCodeGenContext context, ConstEval constEval, Stack<EvalNode> stack) {
-    switch (constEval.getValueType().baseType()) {
+    switch (constEval.getValueType().kind()) {
     case NULL_TYPE:
 
       if (stack.isEmpty()) {

http://git-wip-us.apache.org/repos/asf/tajo/blob/8d2bf407/tajo-core/src/main/java/org/apache/tajo/engine/codegen/TajoGeneratorAdapter.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/codegen/TajoGeneratorAdapter.java b/tajo-core/src/main/java/org/apache/tajo/engine/codegen/TajoGeneratorAdapter.java
index 8a958bb..d11701b 100644
--- a/tajo-core/src/main/java/org/apache/tajo/engine/codegen/TajoGeneratorAdapter.java
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/codegen/TajoGeneratorAdapter.java
@@ -162,12 +162,12 @@ class TajoGeneratorAdapter {
   }
 
   public static boolean isJVMInternalInt(org.apache.tajo.type.Type type) {
-    final TajoDataTypes.Type baseType = type.baseType();
+    final TajoDataTypes.Type baseType = type.kind();
     return baseType == BOOLEAN || baseType == INT1 || baseType == INT2 || baseType == INT4 || baseType== INET4;
   }
 
   public static int getWordSize(org.apache.tajo.type.Type type) {
-    final TajoDataTypes.Type baseType = type.baseType();
+    final TajoDataTypes.Type baseType = type.kind();
     if (baseType == INT8 || baseType == FLOAT8 || baseType == TIMESTAMP || baseType == TIME) {
       return 2;
     } else {
@@ -249,7 +249,7 @@ class TajoGeneratorAdapter {
       }
     } else {
 
-      if (type.baseType() == TEXT) {
+      if (type.kind() == TEXT) {
         invokeVirtual(String.class, "compareTo", int.class, new Class[]{String.class});
       } else {
         int opCode = TajoGeneratorAdapter.getOpCode(evalType, type);
@@ -282,7 +282,7 @@ class TajoGeneratorAdapter {
   }
 
   public void load(org.apache.tajo.type.Type type, int idx) {
-    switch (type.baseType()) {
+    switch (type.kind()) {
     case NULL_TYPE:
     case BOOLEAN:
     case CHAR:
@@ -401,7 +401,7 @@ class TajoGeneratorAdapter {
   }
 
   public void pushDummyValue(org.apache.tajo.type.Type type) {
-    TajoDataTypes.Type baseType = type.baseType();
+    TajoDataTypes.Type baseType = type.kind();
 
     if (type.isNull()) {
       pushNullOfThreeValuedLogic();
@@ -448,19 +448,19 @@ class TajoGeneratorAdapter {
   }
 
   public static boolean isPrimitiveOpCode(EvalType evalType, org.apache.tajo.type.Type returnType) {
-    return TUtil.containsInNestedMap(OpCodesMap, evalType, returnType.baseType());
+    return TUtil.containsInNestedMap(OpCodesMap, evalType, returnType.kind());
   }
 
   public static int getOpCode(EvalType evalType, org.apache.tajo.type.Type returnType) {
     if (!isPrimitiveOpCode(evalType, returnType)) {
       throw new CompilationError("No Such OpCode for " + evalType + " returning " + returnType);
     }
-    return TUtil.getFromNestedMap(OpCodesMap, evalType, returnType.baseType());
+    return TUtil.getFromNestedMap(OpCodesMap, evalType, returnType.kind());
   }
 
   public void castInsn(org.apache.tajo.type.Type srcType, org.apache.tajo.type.Type targetType) {
-    TajoDataTypes.Type srcBaseType = srcType.baseType();
-    TajoDataTypes.Type targetBaseType = targetType.baseType();
+    TajoDataTypes.Type srcBaseType = srcType.kind();
+    TajoDataTypes.Type targetBaseType = targetType.kind();
     switch(srcBaseType) {
     case BOOLEAN:
     case CHAR: {
@@ -600,7 +600,7 @@ class TajoGeneratorAdapter {
     methodvisitor.visitJumpInsn(Opcodes.IFEQ, ifNull);  // datum
 
     aload(datum);
-    switch (type.baseType()) {
+    switch (type.kind()) {
     case BOOLEAN:
     case INT1:
     case INT2:
@@ -643,7 +643,7 @@ class TajoGeneratorAdapter {
     String convertMethod;
     Class returnType;
     Class [] paramTypes;
-    switch (type.baseType()) {
+    switch (type.kind()) {
     case NULL_TYPE:
       pop();      // pop null flag
       pop(type);  // pop null datum
@@ -895,7 +895,7 @@ class TajoGeneratorAdapter {
     int varId = nextVarId;
     nextVarId += TajoGeneratorAdapter.getWordSize(type);
 
-    switch (type.baseType()) {
+    switch (type.kind()) {
     case NULL_TYPE:
     case BOOLEAN:
     case CHAR:
@@ -928,7 +928,7 @@ class TajoGeneratorAdapter {
   }
 
   public void emitBoxing(EvalCodeGenContext context, org.apache.tajo.type.Type type) {
-    switch (type.baseType()) {
+    switch (type.kind()) {
     case CHAR:
     case TEXT:
 
@@ -954,7 +954,7 @@ class TajoGeneratorAdapter {
   }
 
   public void emitUnboxing(EvalCodeGenContext context, org.apache.tajo.type.Type type) {
-    switch (type.baseType()) {
+    switch (type.kind()) {
     case CHAR:
     case TEXT:
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/8d2bf407/tajo-core/src/main/java/org/apache/tajo/engine/codegen/VariablesPreBuilder.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/codegen/VariablesPreBuilder.java b/tajo-core/src/main/java/org/apache/tajo/engine/codegen/VariablesPreBuilder.java
index 9d0f9d0..bc2ccfc 100644
--- a/tajo-core/src/main/java/org/apache/tajo/engine/codegen/VariablesPreBuilder.java
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/codegen/VariablesPreBuilder.java
@@ -55,9 +55,9 @@ class VariablesPreBuilder extends SimpleEvalNodeVisitor<EvalCodeGenContext> {
   @Override
   public EvalNode visitConst(EvalCodeGenContext context, ConstEval constEval, Stack<EvalNode> stack) {
 
-    if (constEval.getValueType().baseType() == TajoDataTypes.Type.INTERVAL) {
+    if (constEval.getValueType().kind() == TajoDataTypes.Type.INTERVAL) {
       if (!context.symbols.containsKey(constEval)) {
-        String fieldName = constEval.getValueType().baseType().name() + "_" + context.seqId++;
+        String fieldName = constEval.getValueType().kind().name() + "_" + context.seqId++;
         context.symbols.put(constEval, fieldName);
 
         context.classWriter.visitField(Opcodes.ACC_PRIVATE, fieldName,

http://git-wip-us.apache.org/repos/asf/tajo/blob/8d2bf407/tajo-core/src/main/java/org/apache/tajo/engine/planner/global/GlobalPlanner.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/planner/global/GlobalPlanner.java b/tajo-core/src/main/java/org/apache/tajo/engine/planner/global/GlobalPlanner.java
index cdab04f..fd34c46 100644
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/global/GlobalPlanner.java
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/planner/global/GlobalPlanner.java
@@ -349,13 +349,13 @@ public class GlobalPlanner {
   private AggregationFunctionCallEval createSumFunction(EvalNode[] args) throws TajoException {
     FunctionDesc functionDesc = null;
     functionDesc = getCatalog().getFunction("sum", CatalogProtos.FunctionType.AGGREGATION,
-        TypeConverter.convert(args[0].getValueType()));
+        TypeConverter.convert(args[0].getValueType()).getDataType());
     return new AggregationFunctionCallEval(functionDesc, args);
   }
 
   private AggregationFunctionCallEval createCountFunction(EvalNode [] args) throws TajoException {
     FunctionDesc functionDesc = getCatalog().getFunction("count", CatalogProtos.FunctionType.AGGREGATION,
-        TypeConverter.convert(args[0].getValueType()));
+        TypeConverter.convert(args[0].getValueType()).getDataType());
     return new AggregationFunctionCallEval(functionDesc, args);
   }
 
@@ -367,13 +367,13 @@ public class GlobalPlanner {
 
   private AggregationFunctionCallEval createMaxFunction(EvalNode [] args) throws TajoException {
     FunctionDesc functionDesc = getCatalog().getFunction("max", CatalogProtos.FunctionType.AGGREGATION,
-        TypeConverter.convert(args[0].getValueType()));
+        TypeConverter.convert(args[0].getValueType()).getDataType());
     return new AggregationFunctionCallEval(functionDesc, args);
   }
 
   private AggregationFunctionCallEval createMinFunction(EvalNode [] args) throws TajoException {
     FunctionDesc functionDesc = getCatalog().getFunction("min", CatalogProtos.FunctionType.AGGREGATION,
-        TypeConverter.convert(args[0].getValueType()));
+        TypeConverter.convert(args[0].getValueType()).getDataType());
     return new AggregationFunctionCallEval(functionDesc, args);
   }
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/8d2bf407/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java b/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java
index 22024e4..d423c04 100644
--- a/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java
+++ b/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java
@@ -54,6 +54,7 @@ import org.apache.tajo.plan.logical.ScanNode;
 import org.apache.tajo.querymaster.QueryJobEvent;
 import org.apache.tajo.rpc.BlockingRpcServer;
 import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.*;
+import org.apache.tajo.schema.IdentifierUtil;
 import org.apache.tajo.session.Session;
 import org.apache.tajo.util.KeyValueSet;
 import org.apache.tajo.util.NetUtils;
@@ -771,8 +772,8 @@ public class TajoMasterClientService extends AbstractService {
 
         String databaseName;
         String tableName;
-        if (CatalogUtil.isFQTableName(request.getValue())) {
-          String [] splitted = CatalogUtil.splitFQTableName(request.getValue());
+        if (IdentifierUtil.isFQTableName(request.getValue())) {
+          String [] splitted = IdentifierUtil.splitFQTableName(request.getValue());
           databaseName = splitted[0];
           tableName = splitted[1];
         } else {
@@ -832,8 +833,8 @@ public class TajoMasterClientService extends AbstractService {
 
         String databaseName;
         String tableName;
-        if (CatalogUtil.isFQTableName(request.getValue())) {
-          String [] splitted = CatalogUtil.splitFQTableName(request.getValue());
+        if (IdentifierUtil.isFQTableName(request.getValue())) {
+          String [] splitted = IdentifierUtil.splitFQTableName(request.getValue());
           databaseName = splitted[0];
           tableName = splitted[1];
         } else {
@@ -968,8 +969,8 @@ public class TajoMasterClientService extends AbstractService {
 
         String databaseName;
         String tableName;
-        if (CatalogUtil.isFQTableName(request.getValue())) {
-          String [] splitted = CatalogUtil.splitFQTableName(request.getValue());
+        if (IdentifierUtil.isFQTableName(request.getValue())) {
+          String [] splitted = IdentifierUtil.splitFQTableName(request.getValue());
           databaseName = splitted[0];
           tableName = splitted[1];
         } else {
@@ -997,8 +998,8 @@ public class TajoMasterClientService extends AbstractService {
         Session session = context.getSessionManager().getSession(request.getSessionId().getId());
 
         String indexName, databaseName;
-        if (CatalogUtil.isFQTableName(request.getValue())) {
-          String [] splitted = CatalogUtil.splitFQTableName(request.getValue());
+        if (IdentifierUtil.isFQTableName(request.getValue())) {
+          String [] splitted = IdentifierUtil.splitFQTableName(request.getValue());
           databaseName = splitted[0];
           indexName = splitted[1];
         } else {
@@ -1026,8 +1027,8 @@ public class TajoMasterClientService extends AbstractService {
         Session session = context.getSessionManager().getSession(request.getSessionId().getId());
 
         String indexName, databaseName;
-        if (CatalogUtil.isFQTableName(request.getValue())) {
-          String [] splitted = CatalogUtil.splitFQTableName(request.getValue());
+        if (IdentifierUtil.isFQTableName(request.getValue())) {
+          String [] splitted = IdentifierUtil.splitFQTableName(request.getValue());
           databaseName = splitted[0];
           indexName = splitted[1];
         } else {
@@ -1053,8 +1054,8 @@ public class TajoMasterClientService extends AbstractService {
         Session session = context.getSessionManager().getSession(request.getSessionId().getId());
 
         String tableName, databaseName;
-        if (CatalogUtil.isFQTableName(request.getValue())) {
-          String [] splitted = CatalogUtil.splitFQTableName(request.getValue());
+        if (IdentifierUtil.isFQTableName(request.getValue())) {
+          String [] splitted = IdentifierUtil.splitFQTableName(request.getValue());
           databaseName = splitted[0];
           tableName = splitted[1];
         } else {
@@ -1082,8 +1083,8 @@ public class TajoMasterClientService extends AbstractService {
         Session session = context.getSessionManager().getSession(request.getSessionId().getId());
 
         String tableName, databaseName;
-        if (CatalogUtil.isFQTableName(request.getValue())) {
-          String [] splitted = CatalogUtil.splitFQTableName(request.getValue());
+        if (IdentifierUtil.isFQTableName(request.getValue())) {
+          String [] splitted = IdentifierUtil.splitFQTableName(request.getValue());
           databaseName = splitted[0];
           tableName = splitted[1];
         } else {
@@ -1108,8 +1109,8 @@ public class TajoMasterClientService extends AbstractService {
         Session session = context.getSessionManager().getSession(request.getSessionId().getId());
 
         String tableName, databaseName;
-        if (CatalogUtil.isFQTableName(request.getTableName())) {
-          String [] splitted = CatalogUtil.splitFQTableName(request.getTableName());
+        if (IdentifierUtil.isFQTableName(request.getTableName())) {
+          String [] splitted = IdentifierUtil.splitFQTableName(request.getTableName());
           databaseName = splitted[0];
           tableName = splitted[1];
         } else {
@@ -1139,8 +1140,8 @@ public class TajoMasterClientService extends AbstractService {
         Session session = context.getSessionManager().getSession(request.getSessionId().getId());
 
         String tableName, databaseName;
-        if (CatalogUtil.isFQTableName(request.getTableName())) {
-          String [] splitted = CatalogUtil.splitFQTableName(request.getTableName());
+        if (IdentifierUtil.isFQTableName(request.getTableName())) {
+          String [] splitted = IdentifierUtil.splitFQTableName(request.getTableName());
           databaseName = splitted[0];
           tableName = splitted[1];
         } else {
@@ -1168,8 +1169,8 @@ public class TajoMasterClientService extends AbstractService {
         QueryContext queryContext = new QueryContext(conf, session);
 
         String indexName, databaseName;
-        if (CatalogUtil.isFQTableName(request.getValue())) {
-          String [] splitted = CatalogUtil.splitFQTableName(request.getValue());
+        if (IdentifierUtil.isFQTableName(request.getValue())) {
+          String [] splitted = IdentifierUtil.splitFQTableName(request.getValue());
           databaseName = splitted[0];
           indexName = splitted[1];
         } else {

http://git-wip-us.apache.org/repos/asf/tajo/blob/8d2bf407/tajo-core/src/main/java/org/apache/tajo/master/exec/CreateTableExecutor.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/master/exec/CreateTableExecutor.java b/tajo-core/src/main/java/org/apache/tajo/master/exec/CreateTableExecutor.java
index 55d5442..9c3a1ad 100644
--- a/tajo-core/src/main/java/org/apache/tajo/master/exec/CreateTableExecutor.java
+++ b/tajo-core/src/main/java/org/apache/tajo/master/exec/CreateTableExecutor.java
@@ -31,6 +31,7 @@ import org.apache.tajo.exception.UndefinedTableException;
 import org.apache.tajo.master.TajoMaster;
 import org.apache.tajo.plan.logical.CreateTableNode;
 import org.apache.tajo.plan.util.PlannerUtil;
+import org.apache.tajo.schema.IdentifierUtil;
 import org.apache.tajo.storage.Tablespace;
 import org.apache.tajo.storage.TablespaceManager;
 import org.apache.tajo.util.Pair;
@@ -89,7 +90,7 @@ public class CreateTableExecutor {
     Pair<String, String> separatedNames = getQualifiedName(queryContext.getCurrentDatabase(), tableName);
     String databaseName = separatedNames.getFirst();
     String simpleTableName = separatedNames.getSecond();
-    String qualifiedName = CatalogUtil.buildFQName(databaseName, simpleTableName);
+    String qualifiedName = IdentifierUtil.buildFQName(databaseName, simpleTableName);
 
     // Check if the table to be created already exists
     boolean exists = catalog.existsTable(databaseName, simpleTableName);
@@ -125,8 +126,8 @@ public class CreateTableExecutor {
   }
 
   private Pair<String, String> getQualifiedName(String currentDatabase, String tableName) {
-    if (CatalogUtil.isFQTableName(tableName)) {
-      String [] splitted = CatalogUtil.splitFQTableName(tableName);
+    if (IdentifierUtil.isFQTableName(tableName)) {
+      String [] splitted = IdentifierUtil.splitFQTableName(tableName);
       return new Pair<>(splitted[0], splitted[1]);
     } else {
       return new Pair<>(currentDatabase, tableName);

http://git-wip-us.apache.org/repos/asf/tajo/blob/8d2bf407/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java b/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java
index 6a22141..c480d04 100644
--- a/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java
+++ b/tajo-core/src/main/java/org/apache/tajo/master/exec/DDLExecutor.java
@@ -42,6 +42,7 @@ import org.apache.tajo.plan.LogicalPlan;
 import org.apache.tajo.plan.logical.*;
 import org.apache.tajo.plan.rewrite.rules.PartitionedTableRewriter;
 import org.apache.tajo.plan.util.PlannerUtil;
+import org.apache.tajo.schema.IdentifierUtil;
 import org.apache.tajo.storage.FileTablespace;
 import org.apache.tajo.storage.StorageUtil;
 import org.apache.tajo.storage.Tablespace;
@@ -138,15 +139,15 @@ public class DDLExecutor {
       throws DuplicateIndexException, UndefinedTableException, UndefinedDatabaseException {
 
     String databaseName, simpleIndexName, qualifiedIndexName;
-    if (CatalogUtil.isFQTableName(createIndexNode.getIndexName())) {
-      String[] splits = CatalogUtil.splitFQTableName(createIndexNode.getIndexName());
+    if (IdentifierUtil.isFQTableName(createIndexNode.getIndexName())) {
+      String[] splits = IdentifierUtil.splitFQTableName(createIndexNode.getIndexName());
       databaseName = splits[0];
       simpleIndexName = splits[1];
       qualifiedIndexName = createIndexNode.getIndexName();
     } else {
       databaseName = queryContext.getCurrentDatabase();
       simpleIndexName = createIndexNode.getIndexName();
-      qualifiedIndexName = CatalogUtil.buildFQName(databaseName, simpleIndexName);
+      qualifiedIndexName = IdentifierUtil.buildFQName(databaseName, simpleIndexName);
     }
 
     if (catalog.existIndexByName(databaseName, simpleIndexName)) {
@@ -158,7 +159,7 @@ public class DDLExecutor {
       throw new InternalError("Cannot find the table of the relation");
     }
 
-    IndexDesc indexDesc = new IndexDesc(databaseName, CatalogUtil.extractSimpleName(scanNode.getTableName()),
+    IndexDesc indexDesc = new IndexDesc(databaseName, IdentifierUtil.extractSimpleName(scanNode.getTableName()),
         simpleIndexName, createIndexNode.getIndexPath(),
         createIndexNode.getKeySortSpecs(), createIndexNode.getIndexMethod(),
         createIndexNode.isUnique(), false, scanNode.getLogicalSchema());
@@ -170,8 +171,8 @@ public class DDLExecutor {
       throws UndefinedIndexException, UndefinedDatabaseException {
 
     String databaseName, simpleIndexName;
-    if (CatalogUtil.isFQTableName(dropIndexNode.getIndexName())) {
-      String[] splits = CatalogUtil.splitFQTableName(dropIndexNode.getIndexName());
+    if (IdentifierUtil.isFQTableName(dropIndexNode.getIndexName())) {
+      String[] splits = IdentifierUtil.splitFQTableName(dropIndexNode.getIndexName());
       databaseName = splits[0];
       simpleIndexName = splits[1];
     } else {
@@ -293,15 +294,15 @@ public class DDLExecutor {
 
     String databaseName;
     String simpleTableName;
-    if (CatalogUtil.isFQTableName(tableName)) {
-      String[] splitted = CatalogUtil.splitFQTableName(tableName);
+    if (IdentifierUtil.isFQTableName(tableName)) {
+      String[] splitted = IdentifierUtil.splitFQTableName(tableName);
       databaseName = splitted[0];
       simpleTableName = splitted[1];
     } else {
       databaseName = queryContext.getCurrentDatabase();
       simpleTableName = tableName;
     }
-    String qualifiedName = CatalogUtil.buildFQName(databaseName, simpleTableName);
+    String qualifiedName = IdentifierUtil.buildFQName(databaseName, simpleTableName);
 
     boolean exists = catalog.existsTable(qualifiedName);
     if (!exists) {
@@ -340,15 +341,15 @@ public class DDLExecutor {
 
     List<TableDesc> tableDescList = new ArrayList<>();
     for (String eachTableName : tableNames) {
-      if (CatalogUtil.isFQTableName(eachTableName)) {
-        String[] split = CatalogUtil.splitFQTableName(eachTableName);
+      if (IdentifierUtil.isFQTableName(eachTableName)) {
+        String[] split = IdentifierUtil.splitFQTableName(eachTableName);
         databaseName = split[0];
         simpleTableName = split[1];
       } else {
         databaseName = queryContext.getCurrentDatabase();
         simpleTableName = eachTableName;
       }
-      final String qualifiedName = CatalogUtil.buildFQName(databaseName, simpleTableName);
+      final String qualifiedName = IdentifierUtil.buildFQName(databaseName, simpleTableName);
 
       if (!catalog.existsTable(databaseName, simpleTableName)) {
         throw new UndefinedTableException(qualifiedName);
@@ -404,15 +405,15 @@ public class DDLExecutor {
 
     String databaseName;
     String simpleTableName;
-    if (CatalogUtil.isFQTableName(tableName)) {
-      String[] split = CatalogUtil.splitFQTableName(tableName);
+    if (IdentifierUtil.isFQTableName(tableName)) {
+      String[] split = IdentifierUtil.splitFQTableName(tableName);
       databaseName = split[0];
       simpleTableName = split[1];
     } else {
       databaseName = queryContext.getCurrentDatabase();
       simpleTableName = tableName;
     }
-    final String qualifiedName = CatalogUtil.buildFQName(databaseName, simpleTableName);
+    final String qualifiedName = IdentifierUtil.buildFQName(databaseName, simpleTableName);
 
     if (!catalog.existsTable(databaseName, simpleTableName)) {
       throw new UndefinedTableException(qualifiedName);
@@ -573,8 +574,8 @@ public class DDLExecutor {
 
     String databaseName;
     String simpleTableName;
-    if (CatalogUtil.isFQTableName(tableName)) {
-      String[] split = CatalogUtil.splitFQTableName(tableName);
+    if (IdentifierUtil.isFQTableName(tableName)) {
+      String[] split = IdentifierUtil.splitFQTableName(tableName);
       databaseName = split[0];
       simpleTableName = split[1];
     } else {

http://git-wip-us.apache.org/repos/asf/tajo/blob/8d2bf407/tajo-core/src/main/java/org/apache/tajo/master/exec/NonForwardQueryResultSystemScanner.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/master/exec/NonForwardQueryResultSystemScanner.java b/tajo-core/src/main/java/org/apache/tajo/master/exec/NonForwardQueryResultSystemScanner.java
index c3280fa..ac917ef 100644
--- a/tajo-core/src/main/java/org/apache/tajo/master/exec/NonForwardQueryResultSystemScanner.java
+++ b/tajo-core/src/main/java/org/apache/tajo/master/exec/NonForwardQueryResultSystemScanner.java
@@ -28,7 +28,6 @@ import org.apache.tajo.TaskId;
 import org.apache.tajo.catalog.*;
 import org.apache.tajo.catalog.proto.CatalogProtos.*;
 import org.apache.tajo.catalog.statistics.TableStats;
-import org.apache.tajo.common.TajoDataTypes.DataType;
 import org.apache.tajo.conf.TajoConf;
 import org.apache.tajo.datum.DatumFactory;
 import org.apache.tajo.engine.codegen.CompilationError;
@@ -40,6 +39,7 @@ import org.apache.tajo.engine.planner.global.GlobalPlanner;
 import org.apache.tajo.engine.planner.global.MasterPlan;
 import org.apache.tajo.engine.planner.physical.PhysicalExec;
 import org.apache.tajo.engine.query.QueryContext;
+import org.apache.tajo.exception.InvalidSessionException;
 import org.apache.tajo.exception.TajoException;
 import org.apache.tajo.exception.TajoInternalError;
 import org.apache.tajo.ipc.ClientProtos.SerializedResultSet;
@@ -52,13 +52,15 @@ import org.apache.tajo.plan.logical.LogicalNode;
 import org.apache.tajo.plan.logical.ScanNode;
 import org.apache.tajo.resource.NodeResource;
 import org.apache.tajo.resource.NodeResources;
-import org.apache.tajo.exception.InvalidSessionException;
+import org.apache.tajo.schema.IdentifierUtil;
 import org.apache.tajo.storage.RowStoreUtil;
 import org.apache.tajo.storage.RowStoreUtil.RowStoreEncoder;
 import org.apache.tajo.storage.Tuple;
 import org.apache.tajo.storage.VTuple;
 import org.apache.tajo.tuple.memory.MemoryBlock;
 import org.apache.tajo.tuple.memory.MemoryRowBlock;
+import org.apache.tajo.type.Type;
+import org.apache.tajo.type.TypeProtobufEncoder;
 import org.apache.tajo.util.KeyValueSet;
 import org.apache.tajo.worker.TaskAttemptContext;
 
@@ -285,11 +287,11 @@ public class NonForwardQueryResultSystemScanner implements NonForwardQueryResult
         } else if ("ordinal_position".equalsIgnoreCase(colObj.getSimpleName())) {
           aTuple.put(fieldId, DatumFactory.createInt4(columnId));
         } else if ("data_type".equalsIgnoreCase(colObj.getSimpleName())) {
-          aTuple.put(fieldId, DatumFactory.createText(column.getDataType().getType().toString()));
+          aTuple.put(fieldId, DatumFactory.createText(column.getType().toString()));
         } else if ("type_length".equalsIgnoreCase(colObj.getSimpleName())) {
-          DataType dataType = column.getDataType();
-          if (dataType.hasLength()) {
-            aTuple.put(fieldId, DatumFactory.createInt4(dataType.getLength()));
+          Type type = TypeProtobufEncoder.decode(column.getType());
+          if (type.isValueParameterized()) {
+            aTuple.put(fieldId, DatumFactory.createInt4(type.getValueParameters().get(0)));
           } else {
             aTuple.put(fieldId, DatumFactory.createNullDatum());
           }
@@ -557,7 +559,7 @@ public class NonForwardQueryResultSystemScanner implements NonForwardQueryResult
   
   private List<Tuple> fetchSystemTable(TableDesc tableDesc, Schema inSchema) {
     List<Tuple> tuples = null;
-    String tableName = CatalogUtil.extractSimpleName(tableDesc.getName());
+    String tableName = IdentifierUtil.extractSimpleName(tableDesc.getName());
 
     if ("tablespace".equalsIgnoreCase(tableName)) {
       tuples = getTablespaces(inSchema);

http://git-wip-us.apache.org/repos/asf/tajo/blob/8d2bf407/tajo-core/src/main/java/org/apache/tajo/master/exec/QueryExecutor.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/master/exec/QueryExecutor.java b/tajo-core/src/main/java/org/apache/tajo/master/exec/QueryExecutor.java
index f0a6b76..58f4ec0 100644
--- a/tajo-core/src/main/java/org/apache/tajo/master/exec/QueryExecutor.java
+++ b/tajo-core/src/main/java/org/apache/tajo/master/exec/QueryExecutor.java
@@ -60,6 +60,7 @@ import org.apache.tajo.plan.function.python.PythonScriptEngine;
 import org.apache.tajo.plan.function.python.TajoScriptEngine;
 import org.apache.tajo.plan.logical.*;
 import org.apache.tajo.plan.util.PlannerUtil;
+import org.apache.tajo.schema.IdentifierUtil;
 import org.apache.tajo.session.Session;
 import org.apache.tajo.storage.*;
 import org.apache.tajo.tuple.memory.MemoryBlock;
@@ -595,15 +596,15 @@ public class QueryExecutor {
       throws DuplicateIndexException {
 
     String databaseName, simpleIndexName, qualifiedIndexName;
-    if (CatalogUtil.isFQTableName(createIndexNode.getIndexName())) {
-      String[] splits = CatalogUtil.splitFQTableName(createIndexNode.getIndexName());
+    if (IdentifierUtil.isFQTableName(createIndexNode.getIndexName())) {
+      String[] splits = IdentifierUtil.splitFQTableName(createIndexNode.getIndexName());
       databaseName = splits[0];
       simpleIndexName = splits[1];
       qualifiedIndexName = createIndexNode.getIndexName();
     } else {
       databaseName = queryContext.getCurrentDatabase();
       simpleIndexName = createIndexNode.getIndexName();
-      qualifiedIndexName = CatalogUtil.buildFQName(databaseName, simpleIndexName);
+      qualifiedIndexName = IdentifierUtil.buildFQName(databaseName, simpleIndexName);
     }
 
     if (catalog.existIndexByName(databaseName, simpleIndexName)) {

http://git-wip-us.apache.org/repos/asf/tajo/blob/8d2bf407/tajo-core/src/main/java/org/apache/tajo/master/exec/prehook/CreateTableHook.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/master/exec/prehook/CreateTableHook.java b/tajo-core/src/main/java/org/apache/tajo/master/exec/prehook/CreateTableHook.java
index 0c02b6e..e6fee07 100644
--- a/tajo-core/src/main/java/org/apache/tajo/master/exec/prehook/CreateTableHook.java
+++ b/tajo-core/src/main/java/org/apache/tajo/master/exec/prehook/CreateTableHook.java
@@ -18,12 +18,12 @@
 
 package org.apache.tajo.master.exec.prehook;
 
-import org.apache.tajo.catalog.CatalogUtil;
 import org.apache.tajo.engine.query.QueryContext;
 import org.apache.tajo.plan.LogicalPlan;
 import org.apache.tajo.plan.logical.CreateTableNode;
 import org.apache.tajo.plan.logical.LogicalRootNode;
 import org.apache.tajo.plan.logical.NodeType;
+import org.apache.tajo.schema.IdentifierUtil;
 
 public class CreateTableHook implements DistributedQueryHook {
 
@@ -37,8 +37,7 @@ public class CreateTableHook implements DistributedQueryHook {
   public void hook(QueryContext queryContext, LogicalPlan plan) throws Exception {
     LogicalRootNode rootNode = plan.getRootBlock().getRoot();
     CreateTableNode createTableNode = rootNode.getChild();
-    String [] splitted  = CatalogUtil.splitFQTableName(createTableNode.getTableName());
-    String databaseName = splitted[0];
+    String [] splitted  = IdentifierUtil.splitFQTableName(createTableNode.getTableName());
     String tableName = splitted[1];
     queryContext.setOutputTable(tableName);
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/8d2bf407/tajo-core/src/main/java/org/apache/tajo/parser/sql/SQLAnalyzer.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/parser/sql/SQLAnalyzer.java b/tajo-core/src/main/java/org/apache/tajo/parser/sql/SQLAnalyzer.java
index f00c85e..5c9a9db 100644
--- a/tajo-core/src/main/java/org/apache/tajo/parser/sql/SQLAnalyzer.java
+++ b/tajo-core/src/main/java/org/apache/tajo/parser/sql/SQLAnalyzer.java
@@ -1008,16 +1008,6 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
   }
 
   @Override
-  public Expr visitArray(ArrayContext ctx) {
-    int size = ctx.numeric_value_expression().size();
-    Expr[] exprs = new Expr[size];
-    for (int i = 0; i < size; i++) {
-      exprs[i] = visit(ctx.numeric_value_expression(i));
-    }
-    return new ValueListExpr(exprs);
-  }
-
-  @Override
   public Expr visitPattern_matching_predicate(Pattern_matching_predicateContext ctx) {
     Expr predicand = visitChildren(ctx.row_value_predicand());
     Expr pattern = new LiteralValue(stripQuote(ctx.Character_String_Literal().getText()),
@@ -1626,15 +1616,24 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> {
     } else if (checkIfExist(predefined_type.network_type())) {
       typeDefinition = new DataTypeExpr(Type.INET4.name());
 
+    } else if (checkIfExist(predefined_type.complex_type())) {
+      Complex_typeContext complexType = predefined_type.complex_type();
+
+      if (checkIfExist(complexType.array_type())) {
+        DataTypeExpr elementType = visitData_type(complexType.array_type().data_type());
+        typeDefinition = new DataTypeExpr(new DataTypeExpr.ArrayType(elementType));
 
-    } else if (checkIfExist(predefined_type.record_type())) {
-      ColumnDefinition [] nestedRecordDefine = getDefinitions(predefined_type.record_type().table_elements());
-      typeDefinition = new DataTypeExpr(new DataTypeExpr.RecordType(nestedRecordDefine));
+      } else if (checkIfExist(complexType.record_type())) {
+        ColumnDefinition[] nestedRecordDefine = getDefinitions(complexType.record_type().table_elements());
+        typeDefinition = new DataTypeExpr(new DataTypeExpr.RecordType(nestedRecordDefine));
 
-    } else if (checkIfExist(predefined_type.map_type())) {
-      Map_typeContext mapTypeContext = predefined_type.map_type();
-      typeDefinition = new DataTypeExpr(
-          new MapType(visitData_type(mapTypeContext.key_type), visitData_type(mapTypeContext.value_type)));
+      } else if (checkIfExist(complexType.map_type())) {
+        Map_typeContext mapTypeContext = complexType.map_type();
+        typeDefinition = new DataTypeExpr(
+            new MapType(visitData_type(mapTypeContext.key_type), visitData_type(mapTypeContext.value_type)));
+      }
+    } else {
+      throw new TajoInternalError("Reached code points that shouldn't be reached");
     }
 
     return typeDefinition;

http://git-wip-us.apache.org/repos/asf/tajo/blob/8d2bf407/tajo-core/src/main/java/org/apache/tajo/querymaster/Query.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/querymaster/Query.java b/tajo-core/src/main/java/org/apache/tajo/querymaster/Query.java
index d57040e..289d933 100644
--- a/tajo-core/src/main/java/org/apache/tajo/querymaster/Query.java
+++ b/tajo-core/src/main/java/org/apache/tajo/querymaster/Query.java
@@ -50,6 +50,7 @@ import org.apache.tajo.exception.ErrorUtil;
 import org.apache.tajo.master.event.*;
 import org.apache.tajo.plan.logical.*;
 import org.apache.tajo.plan.util.PlannerUtil;
+import org.apache.tajo.schema.IdentifierUtil;
 import org.apache.tajo.storage.StorageConstants;
 import org.apache.tajo.storage.Tablespace;
 import org.apache.tajo.storage.TablespaceManager;
@@ -544,8 +545,8 @@ public class Query implements EventHandler<QueryEvent> {
               finalOutputDir, partitions);
 
             String databaseName, simpleTableName;
-            if (CatalogUtil.isFQTableName(tableDesc.getName())) {
-              String[] split = CatalogUtil.splitFQTableName(tableDesc.getName());
+            if (IdentifierUtil.isFQTableName(tableDesc.getName())) {
+              String[] split = IdentifierUtil.splitFQTableName(tableDesc.getName());
               databaseName = split[0];
               simpleTableName = split[1];
             } else {
@@ -630,21 +631,21 @@ public class Query implements EventHandler<QueryEvent> {
 
         CreateIndexNode createIndexNode = (CreateIndexNode) lastStage.getBlock().getPlan();
         String databaseName, simpleIndexName, qualifiedIndexName;
-        if (CatalogUtil.isFQTableName(createIndexNode.getIndexName())) {
-          String [] splits = CatalogUtil.splitFQTableName(createIndexNode.getIndexName());
+        if (IdentifierUtil.isFQTableName(createIndexNode.getIndexName())) {
+          String [] splits = IdentifierUtil.splitFQTableName(createIndexNode.getIndexName());
           databaseName = splits[0];
           simpleIndexName = splits[1];
           qualifiedIndexName = createIndexNode.getIndexName();
         } else {
           databaseName = queryContext.getCurrentDatabase();
           simpleIndexName = createIndexNode.getIndexName();
-          qualifiedIndexName = CatalogUtil.buildFQName(databaseName, simpleIndexName);
+          qualifiedIndexName = IdentifierUtil.buildFQName(databaseName, simpleIndexName);
         }
         ScanNode scanNode = PlannerUtil.findTopNode(createIndexNode, NodeType.SCAN);
         if (scanNode == null) {
           throw new IOException("Cannot find the table of the relation");
         }
-        IndexDesc indexDesc = new IndexDesc(databaseName, CatalogUtil.extractSimpleName(scanNode.getTableName()),
+        IndexDesc indexDesc = new IndexDesc(databaseName, IdentifierUtil.extractSimpleName(scanNode.getTableName()),
             simpleIndexName, createIndexNode.getIndexPath(),
             createIndexNode.getKeySortSpecs(), createIndexNode.getIndexMethod(),
             createIndexNode.isUnique(), false, scanNode.getLogicalSchema());

http://git-wip-us.apache.org/repos/asf/tajo/blob/8d2bf407/tajo-core/src/main/java/org/apache/tajo/ws/rs/resources/TablesResource.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/ws/rs/resources/TablesResource.java b/tajo-core/src/main/java/org/apache/tajo/ws/rs/resources/TablesResource.java
index 3afe7c8..e5bd0f6 100644
--- a/tajo-core/src/main/java/org/apache/tajo/ws/rs/resources/TablesResource.java
+++ b/tajo-core/src/main/java/org/apache/tajo/ws/rs/resources/TablesResource.java
@@ -21,10 +21,10 @@ package org.apache.tajo.ws.rs.resources;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.tajo.catalog.CatalogService;
-import org.apache.tajo.catalog.CatalogUtil;
 import org.apache.tajo.catalog.TableDesc;
 import org.apache.tajo.exception.TajoException;
 import org.apache.tajo.master.TajoMaster.MasterContext;
+import org.apache.tajo.schema.IdentifierUtil;
 import org.apache.tajo.ws.rs.*;
 
 import javax.ws.rs.*;
@@ -174,8 +174,8 @@ public class TablesResource {
           JerseyResourceDelegateContextKey.valueOf(JerseyResourceDelegateUtil.MasterContextKey, MasterContext.class);
       MasterContext masterContext = context.get(masterContextKey);
       
-      if (CatalogUtil.isFQTableName(tableName)) {
-        tableName = CatalogUtil.extractSimpleName(tableName);
+      if (IdentifierUtil.isFQTableName(tableName)) {
+        tableName = IdentifierUtil.extractSimpleName(tableName);
       }
       
       CatalogService catalogService = masterContext.getCatalog();
@@ -239,8 +239,8 @@ public class TablesResource {
           JerseyResourceDelegateContextKey.valueOf(JerseyResourceDelegateUtil.MasterContextKey, MasterContext.class);
       MasterContext masterContext = context.get(masterContextKey);
       
-      if (CatalogUtil.isFQTableName(tableName)) {
-        tableName = CatalogUtil.extractSimpleName(tableName);
+      if (IdentifierUtil.isFQTableName(tableName)) {
+        tableName = IdentifierUtil.extractSimpleName(tableName);
       }
       
       CatalogService catalogService = masterContext.getCatalog();
@@ -249,7 +249,7 @@ public class TablesResource {
         return Response.status(Status.NOT_FOUND).build();
       }
       
-      String canonicalTableName = CatalogUtil.getCanonicalTableName(databaseName, tableName);
+      String canonicalTableName = IdentifierUtil.getCanonicalTableName(databaseName, tableName);
 
       try {
         catalogService.dropTable(canonicalTableName);

http://git-wip-us.apache.org/repos/asf/tajo/blob/8d2bf407/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoDatabaseMetaData.java
----------------------------------------------------------------------
diff --git a/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoDatabaseMetaData.java b/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoDatabaseMetaData.java
index e3cf73a..8c76aba 100644
--- a/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoDatabaseMetaData.java
+++ b/tajo-jdbc/src/main/java/org/apache/tajo/jdbc/TajoDatabaseMetaData.java
@@ -27,6 +27,7 @@ import org.apache.tajo.common.type.TajoTypeUtil;
 import org.apache.tajo.datum.Datum;
 import org.apache.tajo.datum.NullDatum;
 import org.apache.tajo.datum.TextDatum;
+import org.apache.tajo.schema.IdentifierUtil;
 import org.apache.tajo.util.VersionInfo;
 
 import java.sql.*;
@@ -110,7 +111,7 @@ public class TajoDatabaseMetaData implements DatabaseMetaData {
 
   @Override
   public String getIdentifierQuoteString() throws SQLException {
-    return CatalogConstants.IDENTIFIER_QUOTE_STRING;
+    return IdentifierUtil.IDENTIFIER_QUOTE_STRING;
   }
 
   @Override
@@ -167,7 +168,7 @@ public class TajoDatabaseMetaData implements DatabaseMetaData {
 
   @Override
   public String getCatalogSeparator() throws SQLException {
-    return CatalogConstants.IDENTIFIER_DELIMITER;
+    return IdentifierUtil.IDENTIFIER_DELIMITER;
   }
 
   @Override
@@ -182,7 +183,7 @@ public class TajoDatabaseMetaData implements DatabaseMetaData {
 
   @Override
   public int getMaxColumnNameLength() throws SQLException {
-    return CatalogConstants.MAX_IDENTIFIER_LENGTH;
+    return IdentifierUtil.MAX_IDENTIFIER_LENGTH;
   }
 
   @Override
@@ -217,7 +218,7 @@ public class TajoDatabaseMetaData implements DatabaseMetaData {
 
   @Override
   public int getMaxCursorNameLength() throws SQLException {
-    return CatalogConstants.MAX_IDENTIFIER_LENGTH;
+    return IdentifierUtil.MAX_IDENTIFIER_LENGTH;
   }
 
   @Override
@@ -227,17 +228,17 @@ public class TajoDatabaseMetaData implements DatabaseMetaData {
 
   @Override
   public int getMaxSchemaNameLength() throws SQLException {
-    return CatalogConstants.MAX_IDENTIFIER_LENGTH;
+    return IdentifierUtil.MAX_IDENTIFIER_LENGTH;
   }
 
   @Override
   public int getMaxProcedureNameLength() throws SQLException {
-    return CatalogConstants.MAX_IDENTIFIER_LENGTH;
+    return IdentifierUtil.MAX_IDENTIFIER_LENGTH;
   }
 
   @Override
   public int getMaxCatalogNameLength() throws SQLException {
-    return CatalogConstants.MAX_IDENTIFIER_LENGTH;
+    return IdentifierUtil.MAX_IDENTIFIER_LENGTH;
   }
 
   @Override
@@ -262,7 +263,7 @@ public class TajoDatabaseMetaData implements DatabaseMetaData {
 
   @Override
   public int getMaxTableNameLength() throws SQLException {
-    return CatalogConstants.MAX_IDENTIFIER_LENGTH;
+    return IdentifierUtil.MAX_IDENTIFIER_LENGTH;
   }
 
   @Override
@@ -503,7 +504,7 @@ public class TajoDatabaseMetaData implements DatabaseMetaData {
         for (String table: tables) {
           if (table.matches(regtableNamePattern)) {
             TableDesc tableDesc = conn.getCatalogAdminClient().getTableDesc(
-                CatalogUtil.buildFQName(databaseName, table));
+                IdentifierUtil.buildFQName(databaseName, table));
             int pos = 0;
 
             for (Column column: tableDesc.getLogicalSchema().getRootColumns()) {

http://git-wip-us.apache.org/repos/asf/tajo/blob/8d2bf407/tajo-jdbc/src/test/java/org/apache/tajo/jdbc/TestResultSet.java
----------------------------------------------------------------------
diff --git a/tajo-jdbc/src/test/java/org/apache/tajo/jdbc/TestResultSet.java b/tajo-jdbc/src/test/java/org/apache/tajo/jdbc/TestResultSet.java
index 050029e..17fd759 100644
--- a/tajo-jdbc/src/test/java/org/apache/tajo/jdbc/TestResultSet.java
+++ b/tajo-jdbc/src/test/java/org/apache/tajo/jdbc/TestResultSet.java
@@ -32,6 +32,7 @@ import org.apache.tajo.common.TajoDataTypes.Type;
 import org.apache.tajo.conf.TajoConf;
 import org.apache.tajo.datum.DatumFactory;
 import org.apache.tajo.ipc.ClientProtos.SerializedResultSet;
+import org.apache.tajo.schema.IdentifierUtil;
 import org.apache.tajo.storage.*;
 import org.apache.tajo.tuple.memory.MemoryBlock;
 import org.apache.tajo.tuple.memory.MemoryRowBlock;
@@ -99,7 +100,7 @@ public class TestResultSet {
     stats.setAvgRows(tupleNum);
     stats.setNumBlocks(1000);
     stats.setNumShuffleOutputs(100);
-    desc = new TableDesc(CatalogUtil.buildFQName(TajoConstants.DEFAULT_DATABASE_NAME, "score"),
+    desc = new TableDesc(IdentifierUtil.buildFQName(TajoConstants.DEFAULT_DATABASE_NAME, "score"),
         scoreSchema, scoreMeta, p.toUri());
     desc.setStats(stats);
     assertEquals(tupleNum, rowBlock.rows());

http://git-wip-us.apache.org/repos/asf/tajo/blob/8d2bf407/tajo-jdbc/src/test/java/org/apache/tajo/jdbc/TestTajoDatabaseMetaData.java
----------------------------------------------------------------------
diff --git a/tajo-jdbc/src/test/java/org/apache/tajo/jdbc/TestTajoDatabaseMetaData.java b/tajo-jdbc/src/test/java/org/apache/tajo/jdbc/TestTajoDatabaseMetaData.java
index 1b694c0..8951590 100644
--- a/tajo-jdbc/src/test/java/org/apache/tajo/jdbc/TestTajoDatabaseMetaData.java
+++ b/tajo-jdbc/src/test/java/org/apache/tajo/jdbc/TestTajoDatabaseMetaData.java
@@ -21,8 +21,8 @@ package org.apache.tajo.jdbc;
 import com.google.common.collect.Sets;
 import org.apache.tajo.QueryTestCaseBase;
 import org.apache.tajo.TajoConstants;
-import org.apache.tajo.catalog.CatalogUtil;
 import org.apache.tajo.common.type.TajoTypeUtil;
+import org.apache.tajo.schema.IdentifierUtil;
 import org.apache.tajo.util.TUtil;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -260,9 +260,9 @@ public class TestTajoDatabaseMetaData extends QueryTestCaseBase {
 
   private static String getTestColName(String dbName, String tableName, int i) {
     if (i % 2 == 1) {
-      return CatalogUtil.denormalizeIdentifier(dbName + "_" + tableName + "_col") + " int";
+      return IdentifierUtil.denormalizeIdentifier(dbName + "_" + tableName + "_col") + " int";
     } else {
-      return CatalogUtil.denormalizeIdentifier(dbName + "_" + tableName + "_COL") + " int";
+      return IdentifierUtil.denormalizeIdentifier(dbName + "_" + tableName + "_COL") + " int";
     }
   }
 
@@ -293,7 +293,7 @@ public class TestTajoDatabaseMetaData extends QueryTestCaseBase {
 
           TUtil.putToNestedList(tables, dbName, tableName);
 
-          executeString("CREATE TABLE " + dbName + "." + CatalogUtil.denormalizeIdentifier(tableName) +
+          executeString("CREATE TABLE " + dbName + "." + IdentifierUtil.denormalizeIdentifier(tableName) +
               " (" + getTestColName(dbName, tableName, 1) +
               ") PARTITION BY COLUMN (" + getTestColName(dbName, tableName, 2) + ")").close();
           assertTableExists(dbName + "." + tableName);
@@ -308,7 +308,7 @@ public class TestTajoDatabaseMetaData extends QueryTestCaseBase {
 
           TUtil.putToNestedList(tables, dbName, tableName);
 
-          executeString("CREATE TABLE " + dbName + "." + CatalogUtil.denormalizeIdentifier(tableName) +
+          executeString("CREATE TABLE " + dbName + "." + IdentifierUtil.denormalizeIdentifier(tableName) +
               " (" + getTestColName(dbName, tableName, 1) +
               ") PARTITION BY COLUMN (" + getTestColName(dbName, tableName, 2) + ")").close();
           assertTableExists(dbName + "." + tableName);

http://git-wip-us.apache.org/repos/asf/tajo/blob/8d2bf407/tajo-jdbc/src/test/java/org/apache/tajo/jdbc/TestTajoJdbc.java
----------------------------------------------------------------------
diff --git a/tajo-jdbc/src/test/java/org/apache/tajo/jdbc/TestTajoJdbc.java b/tajo-jdbc/src/test/java/org/apache/tajo/jdbc/TestTajoJdbc.java
index c36b133..c202642 100644
--- a/tajo-jdbc/src/test/java/org/apache/tajo/jdbc/TestTajoJdbc.java
+++ b/tajo-jdbc/src/test/java/org/apache/tajo/jdbc/TestTajoJdbc.java
@@ -20,10 +20,10 @@ package org.apache.tajo.jdbc;
 
 import com.google.common.collect.Maps;
 import org.apache.tajo.*;
-import org.apache.tajo.catalog.CatalogUtil;
 import org.apache.tajo.catalog.Column;
 import org.apache.tajo.catalog.TableDesc;
 import org.apache.tajo.client.QueryStatus;
+import org.apache.tajo.schema.IdentifierUtil;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -338,7 +338,7 @@ public class TestTajoJdbc extends QueryTestCaseBase {
       assertEquals(22, numCols);
       int numColumns = 0;
 
-      TableDesc tableDesc = client.getTableDesc(CatalogUtil.buildFQName(DEFAULT_DATABASE_NAME, tableName));
+      TableDesc tableDesc = client.getTableDesc(IdentifierUtil.buildFQName(DEFAULT_DATABASE_NAME, tableName));
       assertNotNull(tableDesc);
 
       List<Column> columns = tableDesc.getSchema().getRootColumns();
@@ -495,7 +495,7 @@ public class TestTajoJdbc extends QueryTestCaseBase {
 
   @Test
   public void testCreateTableWithDateAndTimestamp() throws Exception {
-    String tableName = CatalogUtil.normalizeIdentifier("testCreateTableWithDateAndTimestamp");
+    String tableName = IdentifierUtil.normalizeIdentifier("testCreateTableWithDateAndTimestamp");
 
     int result;
     Statement stmt = null;
@@ -612,7 +612,7 @@ public class TestTajoJdbc extends QueryTestCaseBase {
         conn = DriverManager.getConnection(connUri);
         assertTrue(conn.isValid(100));
 
-        String tableName = CatalogUtil.normalizeIdentifier("testAlterTablePartition");
+        String tableName = IdentifierUtil.normalizeIdentifier("testAlterTablePartition");
         resultSet = executeString(
           "create table " + tableName + " (col1 int4, col2 int4) partition by column(key float8) ");
         resultSet.close();
@@ -699,7 +699,7 @@ public class TestTajoJdbc extends QueryTestCaseBase {
 
   @Test
   public void testTableValueWithTimeZone() throws Exception {
-    String tableName = CatalogUtil.normalizeIdentifier("testTableValueWithTimeZone");
+    String tableName = IdentifierUtil.normalizeIdentifier("testTableValueWithTimeZone");
 
     Statement stmt = null;
     ResultSet res = null;

http://git-wip-us.apache.org/repos/asf/tajo/blob/8d2bf407/tajo-plan/src/main/java/org/apache/tajo/plan/ExprAnnotator.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/ExprAnnotator.java b/tajo-plan/src/main/java/org/apache/tajo/plan/ExprAnnotator.java
index d5e9354..92ba368 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/ExprAnnotator.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/ExprAnnotator.java
@@ -22,7 +22,10 @@ import com.google.common.collect.Sets;
 import org.apache.commons.collections.set.UnmodifiableSet;
 import org.apache.tajo.OverridableConf;
 import org.apache.tajo.algebra.*;
-import org.apache.tajo.catalog.*;
+import org.apache.tajo.catalog.CatalogService;
+import org.apache.tajo.catalog.CatalogUtil;
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.catalog.FunctionDesc;
 import org.apache.tajo.catalog.CatalogUtil.Direction;
 import org.apache.tajo.common.TajoDataTypes;
 import org.apache.tajo.datum.*;
@@ -109,8 +112,8 @@ public class ExprAnnotator extends BaseAlgebraVisitor<ExprAnnotator.Context, Eva
    * @return a pair including left/right hand side terms
    */
   private static Pair<EvalNode, EvalNode> convertTypesIfNecessary(Context ctx, EvalNode lhs, EvalNode rhs) {
-    Type lhsType = lhs.getValueType().baseType();
-    Type rhsType = rhs.getValueType().baseType();
+    Type lhsType = lhs.getValueType().kind();
+    Type rhsType = rhs.getValueType().kind();
 
     // If one of both is NULL, it just returns the original types without casting.
     if (lhsType == Type.NULL_TYPE || rhsType == Type.NULL_TYPE) {
@@ -145,7 +148,7 @@ public class ExprAnnotator extends BaseAlgebraVisitor<ExprAnnotator.Context, Eva
   private static EvalNode convertType(Context ctx, EvalNode evalNode, DataType toType) {
 
     // if original and toType is the same, we don't need type conversion.
-    if (evalNode.getValueType().equals(TypeConverter.convert(toType))) {
+    if (evalNode.getValueType().equals(convert(toType))) {
       return evalNode;
     }
     // the conversion to null is not allowed.
@@ -312,9 +315,9 @@ public class ExprAnnotator extends BaseAlgebraVisitor<ExprAnnotator.Context, Eva
 
     // implicit type conversion
     DataType widestType = CatalogUtil.getWidestType(
-        convert(predicand.getValueType()),
-        convert(begin.getValueType()),
-        convert(end.getValueType()));
+        convert(predicand.getValueType()).getDataType(),
+        convert(begin.getValueType()).getDataType(),
+        convert(end.getValueType()).getDataType());
 
     BetweenPredicateEval betweenEval = new BetweenPredicateEval(
         between.isNot(),
@@ -343,15 +346,15 @@ public class ExprAnnotator extends BaseAlgebraVisitor<ExprAnnotator.Context, Eva
     }
 
     // Getting the widest type from all if-then expressions and else expression.
-    DataType widestType = convert(caseWhenEval.getIfThenEvals().get(0).getResult().getValueType());
+    DataType widestType = convert(caseWhenEval.getIfThenEvals().get(0).getResult().getValueType()).getDataType();
     for (int i = 1; i < caseWhenEval.getIfThenEvals().size(); i++) {
       widestType = CatalogUtil.getWidestType(
-          convert(caseWhenEval.getIfThenEvals().get(i).getResult().getValueType()),
+          convert(caseWhenEval.getIfThenEvals().get(i).getResult().getValueType()).getDataType(),
           widestType);
     }
     if (caseWhen.hasElseResult()) {
       widestType = CatalogUtil.getWidestType(
-          widestType, convert(caseWhenEval.getElse().getValueType()));
+          widestType, convert(caseWhenEval.getElse().getValueType()).getDataType());
     }
 
     assertEval(widestType != null, "Invalid Type Conversion for CaseWhen");
@@ -439,10 +442,10 @@ public class ExprAnnotator extends BaseAlgebraVisitor<ExprAnnotator.Context, Eva
     EvalNode rhs = visit(ctx, stack, expr.getRight());
     stack.pop();
 
-    if (lhs.getValueType().baseType() != Type.TEXT) {
+    if (lhs.getValueType().kind() != Type.TEXT) {
       lhs = convertType(ctx, lhs, CatalogUtil.newSimpleDataType(Type.TEXT));
     }
-    if (rhs.getValueType().baseType() != Type.TEXT) {
+    if (rhs.getValueType().kind() != Type.TEXT) {
       rhs = convertType(ctx, rhs, CatalogUtil.newSimpleDataType(Type.TEXT));
     }
 
@@ -587,7 +590,7 @@ public class ExprAnnotator extends BaseAlgebraVisitor<ExprAnnotator.Context, Eva
 
     for (int i = 0; i < params.length; i++) {
       givenArgs[i] = visit(ctx, stack, params[i]);
-      paramTypes[i] = TypeConverter.convert(givenArgs[i].getValueType());
+      paramTypes[i] = convert(givenArgs[i].getValueType()).getDataType();
     }
 
     stack.pop(); // <--- Pop
@@ -664,7 +667,7 @@ public class ExprAnnotator extends BaseAlgebraVisitor<ExprAnnotator.Context, Eva
     if (setFunction.getSignature().equalsIgnoreCase("count")) {
       paramTypes[0] = CatalogUtil.newSimpleDataType(Type.ANY);
     } else {
-      paramTypes[0] = TypeConverter.convert(givenArgs[0].getValueType());
+      paramTypes[0] = convert(givenArgs[0].getValueType()).getDataType();
     }
 
     if (!catalog.containFunction(setFunction.getSignature(), functionType, paramTypes)) {
@@ -721,11 +724,11 @@ public class ExprAnnotator extends BaseAlgebraVisitor<ExprAnnotator.Context, Eva
       } else if (windowFunc.getSignature().equalsIgnoreCase("row_number")) {
         paramTypes[0] = CatalogUtil.newSimpleDataType(Type.INT8);
       } else {
-        paramTypes[0] = convert(givenArgs[0].getValueType());
+        paramTypes[0] = convert(givenArgs[0].getValueType()).getDataType();
       }
       for (int i = 1; i < params.length; i++) {
         givenArgs[i] = visit(ctx, stack, params[i]);
-        paramTypes[i] = convert(givenArgs[i].getValueType());
+        paramTypes[i] = convert(givenArgs[i].getValueType()).getDataType();
       }
     } else {
       if (windowFunc.getSignature().equalsIgnoreCase("rank")) {
@@ -786,10 +789,11 @@ public class ExprAnnotator extends BaseAlgebraVisitor<ExprAnnotator.Context, Eva
       // some cast operation may require earlier evaluation with timezone.
       return new ConstEval(
           DatumFactory.cast(constEval.getValue(),
-              LogicalPlanner.convertDataType(expr.getTarget()).getDataType(), ctx.timeZone));
+              convert(LogicalPlanner.convertDataType(expr.getTarget())).getDataType(), ctx.timeZone));
 
     } else {
-      return new CastEval(ctx.queryContext, child, LogicalPlanner.convertDataType(expr.getTarget()).getDataType());
+      return new CastEval(ctx.queryContext, child,
+          convert(LogicalPlanner.convertDataType(expr.getTarget())).getDataType());
     }
   }
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/8d2bf407/tajo-plan/src/main/java/org/apache/tajo/plan/ExprNormalizer.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/ExprNormalizer.java b/tajo-plan/src/main/java/org/apache/tajo/plan/ExprNormalizer.java
index d66263f..967bf8b 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/ExprNormalizer.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/ExprNormalizer.java
@@ -20,12 +20,12 @@ package org.apache.tajo.plan;
 
 import com.google.common.collect.Sets;
 import org.apache.tajo.algebra.*;
-import org.apache.tajo.catalog.CatalogUtil;
 import org.apache.tajo.exception.UndefinedColumnException;
 import org.apache.tajo.exception.TajoException;
 import org.apache.tajo.plan.nameresolver.NameResolver;
 import org.apache.tajo.plan.nameresolver.NameResolvingMode;
 import org.apache.tajo.plan.visitor.SimpleAlgebraVisitor;
+import org.apache.tajo.schema.IdentifierUtil;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -339,7 +339,7 @@ class ExprNormalizer extends SimpleAlgebraVisitor<ExprNormalizer.ExprNormalizedR
       return expr;
     }
     // if a column reference is not qualified, it finds and sets the qualified column name.
-    if (!(expr.hasQualifier() && CatalogUtil.isFQTableName(expr.getQualifier()))) {
+    if (!(expr.hasQualifier() && IdentifierUtil.isFQTableName(expr.getQualifier()))) {
       if (!ctx.block.namedExprsMgr.contains(expr.getCanonicalName()) && expr.getType() == OpType.Column) {
         try {
           String normalized =

http://git-wip-us.apache.org/repos/asf/tajo/blob/8d2bf407/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java b/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java
index 39caec7..aaf64cd 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java
@@ -21,10 +21,9 @@ package org.apache.tajo.plan;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Function;
 import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.fs.Path;
 import org.apache.tajo.BuiltinStorages;
 import org.apache.tajo.OverridableConf;
@@ -49,6 +48,10 @@ import org.apache.tajo.plan.nameresolver.NameResolvingMode;
 import org.apache.tajo.plan.rewrite.rules.ProjectionPushDownRule;
 import org.apache.tajo.plan.util.ExprFinder;
 import org.apache.tajo.plan.util.PlannerUtil;
+import org.apache.tajo.schema.Field;
+import org.apache.tajo.schema.IdentifierUtil;
+import org.apache.tajo.type.Type;
+import org.apache.tajo.type.TypeFactory;
 import org.apache.tajo.storage.StorageConstants;
 import org.apache.tajo.util.KeyValueSet;
 import org.apache.tajo.util.Pair;
@@ -62,12 +65,12 @@ import static org.apache.tajo.algebra.CreateTable.PartitionType;
 import static org.apache.tajo.plan.ExprNormalizer.ExprNormalizedResult;
 import static org.apache.tajo.plan.LogicalPlan.BlockType;
 import static org.apache.tajo.plan.verifier.SyntaxErrorUtil.makeSyntaxError;
+import static org.apache.tajo.type.Type.*;
 
 /**
  * This class creates a logical plan from a nested tajo algebra expression ({@link org.apache.tajo.algebra})
  */
 public class LogicalPlanner extends BaseAlgebraVisitor<LogicalPlanner.PlanContext, LogicalNode> {
-  private static Log LOG = LogFactory.getLog(LogicalPlanner.class);
   private final CatalogService catalog;
   private final StorageService storage;
 
@@ -1468,7 +1471,7 @@ public class LogicalPlanner extends BaseAlgebraVisitor<LogicalPlanner.PlanContex
 
     // make table subquery node which has set operation as its subquery
     TableSubQueryNode setOpTableSubQueryNode = context.plan.createNode(TableSubQueryNode.class);
-    setOpTableSubQueryNode.init(CatalogUtil.buildFQName(context.queryContext.get(SessionVars.CURRENT_DATABASE),
+    setOpTableSubQueryNode.init(IdentifierUtil.buildFQName(context.queryContext.get(SessionVars.CURRENT_DATABASE),
         context.generateUniqueSubQueryName()), setOperationNode);
     setTargetOfTableSubQuery(context, currentBlock, setOpTableSubQueryNode);
     currentBlock.registerNode(setOpTableSubQueryNode);
@@ -1619,9 +1622,9 @@ public class LogicalPlanner extends BaseAlgebraVisitor<LogicalPlanner.PlanContex
     // Get and set a target table
     String databaseName;
     String tableName;
-    if (CatalogUtil.isFQTableName(expr.getTableName())) {
-      databaseName = CatalogUtil.extractQualifier(expr.getTableName());
-      tableName = CatalogUtil.extractSimpleName(expr.getTableName());
+    if (IdentifierUtil.isFQTableName(expr.getTableName())) {
+      databaseName = IdentifierUtil.extractQualifier(expr.getTableName());
+      tableName = IdentifierUtil.extractSimpleName(expr.getTableName());
     } else {
       databaseName = context.queryContext.get(SessionVars.CURRENT_DATABASE);
       tableName = expr.getTableName();
@@ -1839,8 +1842,8 @@ public class LogicalPlanner extends BaseAlgebraVisitor<LogicalPlanner.PlanContex
     throws TajoException {
     String parentTableName = expr.getLikeParentTableName();
 
-    if (CatalogUtil.isFQTableName(parentTableName) == false) {
-      parentTableName = CatalogUtil.buildFQName(context.queryContext.get(SessionVars.CURRENT_DATABASE),
+    if (IdentifierUtil.isFQTableName(parentTableName) == false) {
+      parentTableName = IdentifierUtil.buildFQName(context.queryContext.get(SessionVars.CURRENT_DATABASE),
           parentTableName);
     }
     TableDesc baseTable = catalog.getTableDesc(parentTableName);
@@ -1870,11 +1873,11 @@ public class LogicalPlanner extends BaseAlgebraVisitor<LogicalPlanner.PlanContex
     createTableNode.setIfNotExists(expr.isIfNotExists());
 
     // Set a table name to be created.
-    if (CatalogUtil.isFQTableName(expr.getTableName())) {
+    if (IdentifierUtil.isFQTableName(expr.getTableName())) {
       createTableNode.setTableName(expr.getTableName());
     } else {
       createTableNode.setTableName(
-          CatalogUtil.buildFQName(context.queryContext.get(SessionVars.CURRENT_DATABASE), expr.getTableName()));
+          IdentifierUtil.buildFQName(context.queryContext.get(SessionVars.CURRENT_DATABASE), expr.getTableName()));
     }
     // This is CREATE TABLE <tablename> LIKE <parentTable>
     if(expr.getLikeParentTableName() != null) {
@@ -1929,8 +1932,13 @@ public class LogicalPlanner extends BaseAlgebraVisitor<LogicalPlanner.PlanContex
       // If the table schema is defined
       // ex) CREATE TABLE tbl(col1 type, col2 type) AS SELECT ...
       if (expr.hasTableElements()) {
-        createTableNode.setOutSchema(convertTableElementsSchema(expr.getTableElements()));
-        createTableNode.setTableSchema(convertTableElementsSchema(expr.getTableElements()));
+        createTableNode.setOutSchema(SchemaBuilder.builder()
+            .addAll2(convertTableElementsSchema(expr.getTableElements()))
+            .build());
+
+        createTableNode.setTableSchema(SchemaBuilder.builder()
+            .addAll2(convertTableElementsSchema(expr.getTableElements()))
+            .build());
       } else {
         // if no table definition, the select clause's output schema will be used.
         // ex) CREATE TABLE tbl AS SELECT ...
@@ -1997,11 +2005,11 @@ public class LogicalPlanner extends BaseAlgebraVisitor<LogicalPlanner.PlanContex
     } else {
 
       String tableName = createTable.getTableName();
-      String databaseName = CatalogUtil.isFQTableName(tableName) ?
-          CatalogUtil.extractQualifier(tableName) : context.queryContext.get(SessionVars.CURRENT_DATABASE);
+      String databaseName = IdentifierUtil.isFQTableName(tableName) ?
+          IdentifierUtil.extractQualifier(tableName) : context.queryContext.get(SessionVars.CURRENT_DATABASE);
 
       return storage.getTableURI(
-          createTable.getTableSpaceName(), databaseName, CatalogUtil.extractSimpleName(tableName));
+          createTable.getTableSpaceName(), databaseName, IdentifierUtil.extractSimpleName(tableName));
     }
   }
 
@@ -2043,13 +2051,12 @@ public class LogicalPlanner extends BaseAlgebraVisitor<LogicalPlanner.PlanContex
    * @param elements to be transformed
    * @return schema transformed from table definition elements
    */
-  private static Schema convertTableElementsSchema(ColumnDefinition[] elements) {
-    return SchemaBuilder.builder().addAll(elements, new Function<ColumnDefinition, Column>() {
-      @Override
-      public Column apply(@Nullable ColumnDefinition input) {
-        return convertColumn(input);
-      }
-    }).build();
+  private static Collection<Field> convertTableElementsSchema(ColumnDefinition[] elements) {
+    ImmutableList.Builder<Field> list = ImmutableList.builder();
+    for (ColumnDefinition colDef : elements) {
+      list.add(FieldConverter.convert(convertColumn(colDef)));
+    }
+    return list.build();
   }
 
   /**
@@ -2096,40 +2103,50 @@ public class LogicalPlanner extends BaseAlgebraVisitor<LogicalPlanner.PlanContex
     return new Column(columnDefinition.getColumnName(), convertDataType(columnDefinition));
   }
 
-  public static TypeDesc convertDataType(DataTypeExpr dataType) {
+  public static Type convertDataType(DataTypeExpr dataType) {
     TajoDataTypes.Type type = TajoDataTypes.Type.valueOf(dataType.getTypeName());
 
-    TajoDataTypes.DataType.Builder builder = TajoDataTypes.DataType.newBuilder();
-    builder.setType(type);
-
-    if (dataType.hasLengthOrPrecision()) {
-      builder.setLength(dataType.getLengthOrPrecision());
-    } else {
-      if (type == TajoDataTypes.Type.CHAR) {
-        builder.setLength(1);
+    if (type == TajoDataTypes.Type.CHAR || type == TajoDataTypes.Type.NCHAR) {
+      if (dataType.hasLengthOrPrecision()) {
+        return Char(dataType.getLengthOrPrecision());
+      } else {
+        // Default length is 1. It's because of compatibility with the legacy code.
+        return Char(1);
+      }
+    } else if (type == TajoDataTypes.Type.VARCHAR || type == TajoDataTypes.Type.NVARCHAR) {
+      if (dataType.hasLengthOrPrecision()) {
+        return Char(dataType.getLengthOrPrecision());
+      } else {
+        // Default length is 1. It's because of compatibility with the legacy code.
+        return Varchar(1);
+      }
+    } else if (type == TajoDataTypes.Type.ARRAY) {
+      return Array(convertDataType(dataType.getElementType()));
+    } else if (type == TajoDataTypes.Type.RECORD) {
+      return Record(convertTableElementsSchema(dataType.getNestedRecordTypes()));
+    } else if (type == TajoDataTypes.Type.MAP) {
+      return Map(convertDataType(dataType.getKeyType()), convertDataType(dataType.getValueType()));
+    } else if (type == TajoDataTypes.Type.NUMERIC) {
+      if (dataType.hasLengthOrPrecision() && dataType.hasScale()) {
+        return Numeric(dataType.getLengthOrPrecision(), dataType.getScale());
+      } else if (dataType.hasLengthOrPrecision()) {
+        return Numeric(dataType.getLengthOrPrecision());
+      } else {
+        return Numeric();
       }
-    }
-
-    TypeDesc typeDesc;
-    if (type == TajoDataTypes.Type.RECORD) {
-      Schema nestedRecordSchema = convertTableElementsSchema(dataType.getNestedRecordTypes());
-      typeDesc = new TypeDesc(nestedRecordSchema);
     } else {
-      typeDesc = new TypeDesc(builder.build());
+      return TypeFactory.create(type);
     }
-
-    return typeDesc;
   }
 
-
   @Override
   public LogicalNode visitDropTable(PlanContext context, Stack<Expr> stack, DropTable dropTable) {
     DropTableNode dropTableNode = context.queryBlock.getNodeFromExpr(dropTable);
     String qualified;
-    if (CatalogUtil.isFQTableName(dropTable.getTableName())) {
+    if (IdentifierUtil.isFQTableName(dropTable.getTableName())) {
       qualified = dropTable.getTableName();
     } else {
-      qualified = CatalogUtil.buildFQName(
+      qualified = IdentifierUtil.buildFQName(
           context.queryContext.get(SessionVars.CURRENT_DATABASE), dropTable.getTableName());
     }
     dropTableNode.init(qualified, dropTable.isIfExists(), dropTable.isPurge());
@@ -2189,11 +2206,11 @@ public class LogicalPlanner extends BaseAlgebraVisitor<LogicalPlanner.PlanContex
 
     QueryBlock block = context.queryBlock;
     CreateIndexNode createIndexNode = block.getNodeFromExpr(createIndex);
-    if (CatalogUtil.isFQTableName(createIndex.getIndexName())) {
+    if (IdentifierUtil.isFQTableName(createIndex.getIndexName())) {
       createIndexNode.setIndexName(createIndex.getIndexName());
     } else {
       createIndexNode.setIndexName(
-          CatalogUtil.buildFQName(context.queryContext.get(SessionVars.CURRENT_DATABASE), createIndex.getIndexName()));
+          IdentifierUtil.buildFQName(context.queryContext.get(SessionVars.CURRENT_DATABASE), createIndex.getIndexName()));
     }
     createIndexNode.setUnique(createIndex.isUnique());
     Sort.SortSpec[] sortSpecs = createIndex.getSortSpecs();

http://git-wip-us.apache.org/repos/asf/tajo/blob/8d2bf407/tajo-plan/src/main/java/org/apache/tajo/plan/NamedExprsManager.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/NamedExprsManager.java b/tajo-plan/src/main/java/org/apache/tajo/plan/NamedExprsManager.java
index 53f2610..ee47700 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/NamedExprsManager.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/NamedExprsManager.java
@@ -315,14 +315,15 @@ public class NamedExprsManager {
       // But, if this reference name is not primary name, it cannot use the reference name.
       // It changes the given reference name to the primary name.
       if (evalNode.getType() != EvalType.CONST && isEvaluated(normalized) && !isPrimaryName(refId, referenceName)) {
-        return new Target(new FieldEval(getPrimaryName(refId), convert(evalNode.getValueType())), referenceName);
+        return new Target(new FieldEval(getPrimaryName(refId), convert(evalNode.getValueType()).getDataType()),
+            referenceName);
       }
 
       EvalNode referredEval;
       if (evalNode.getType() == EvalType.CONST) {
         referredEval = evalNode;
       } else {
-        referredEval = new FieldEval(idToNamesMap.get(refId).get(0), convert(evalNode.getValueType()));
+        referredEval = new FieldEval(idToNamesMap.get(refId).get(0), convert(evalNode.getValueType()).getDataType());
       }
       return new Target(referredEval, referenceName);
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/8d2bf407/tajo-plan/src/main/java/org/apache/tajo/plan/TypeDeterminant.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/TypeDeterminant.java b/tajo-plan/src/main/java/org/apache/tajo/plan/TypeDeterminant.java
index 9fc5c0d..f67b50f 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/TypeDeterminant.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/TypeDeterminant.java
@@ -60,14 +60,14 @@ public class TypeDeterminant extends SimpleAlgebraVisitor<LogicalPlanner.PlanCon
   public DataType visitUnaryOperator(LogicalPlanner.PlanContext ctx, Stack<Expr> stack, UnaryOperator expr)
       throws TajoException {
     stack.push(expr);
-    DataType dataType = null;
+    DataType dataType;
     switch (expr.getType()) {
     case IsNullPredicate:
     case ExistsPredicate:
       dataType = BOOL_TYPE;
       break;
     case Cast:
-      dataType = LogicalPlanner.convertDataType(((CastExpr)expr).getTarget()).getDataType();
+      dataType = convert(LogicalPlanner.convertDataType(((CastExpr)expr).getTarget())).getDataType();
       break;
     default:
       dataType = visit(ctx, stack, expr.getChild());
@@ -83,7 +83,7 @@ public class TypeDeterminant extends SimpleAlgebraVisitor<LogicalPlanner.PlanCon
     DataType lhsType = visit(ctx, stack, expr.getLeft());
     DataType rhsType = visit(ctx, stack, expr.getRight());
     stack.pop();
-    return convert(computeBinaryType(expr.getType(), convert(lhsType), convert(rhsType)));
+    return convert(computeBinaryType(expr.getType(), convert(lhsType), convert(rhsType))).getDataType();
   }
 
   public Type computeBinaryType(OpType type, Type lhsDataType, Type rhsDataType) throws TajoException {
@@ -278,7 +278,7 @@ public class TypeDeterminant extends SimpleAlgebraVisitor<LogicalPlanner.PlanCon
   @Override
   public DataType visitDataType(LogicalPlanner.PlanContext ctx, Stack<Expr> stack, DataTypeExpr expr)
       throws TajoException {
-    return LogicalPlanner.convertDataType(expr).getDataType();
+    return convert(LogicalPlanner.convertDataType(expr)).getDataType();
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/tajo/blob/8d2bf407/tajo-plan/src/main/java/org/apache/tajo/plan/expr/ConstEval.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/ConstEval.java b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/ConstEval.java
index 25c12d4..4f1ece6 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/ConstEval.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/ConstEval.java
@@ -20,10 +20,10 @@ package org.apache.tajo.plan.expr;
 
 import com.google.common.base.Objects;
 import com.google.gson.annotations.Expose;
-import org.apache.tajo.catalog.TypeConverter;
 import org.apache.tajo.datum.Datum;
 import org.apache.tajo.storage.Tuple;
 import org.apache.tajo.type.Type;
+import org.apache.tajo.type.TypeFactory;
 
 public class ConstEval extends EvalNode implements Comparable<ConstEval>, Cloneable {
 	@Expose Datum datum = null;
@@ -51,7 +51,7 @@ public class ConstEval extends EvalNode implements Comparable<ConstEval>, Clonea
 
   @Override
 	public Type getValueType() {
-    return TypeConverter.convert(datum.type());
+    return TypeFactory.create(datum.type());
 	}
 
   @Override

http://git-wip-us.apache.org/repos/asf/tajo/blob/8d2bf407/tajo-plan/src/main/java/org/apache/tajo/plan/expr/EvalTreeUtil.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/EvalTreeUtil.java b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/EvalTreeUtil.java
index a83c5bd..f4b706f 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/EvalTreeUtil.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/EvalTreeUtil.java
@@ -33,6 +33,7 @@ import org.apache.tajo.exception.TajoInternalError;
 import org.apache.tajo.plan.LogicalPlan;
 import org.apache.tajo.plan.Target;
 import org.apache.tajo.plan.util.ExprFinder;
+import org.apache.tajo.schema.IdentifierUtil;
 
 import java.util.*;
 
@@ -180,7 +181,7 @@ public class EvalTreeUtil {
     case DIVIDE:
     case CONST:
     case FUNCTION:
-        return TypeConverter.convert(expr.getValueType());
+        return TypeConverter.convert(expr.getValueType()).getDataType();
 
     case FIELD:
       FieldEval fieldEval = (FieldEval) expr;
@@ -393,14 +394,14 @@ public class EvalTreeUtil {
 
   private static boolean isJoinQualWithOnlyColumns(@Nullable LogicalPlan.QueryBlock block,
                                                    Column left, Column right) {
-    String leftQualifier = CatalogUtil.extractQualifier(left.getQualifiedName());
-    String rightQualifier = CatalogUtil.extractQualifier(right.getQualifiedName());
+    String leftQualifier = IdentifierUtil.extractQualifier(left.getQualifiedName());
+    String rightQualifier = IdentifierUtil.extractQualifier(right.getQualifiedName());
 
     // if block is given, it will track an original expression of each term in order to decide whether
     // this expression is a join condition, or not.
     if (block != null) {
-      boolean leftQualified = CatalogUtil.isFQColumnName(left.getQualifiedName());
-      boolean rightQualified = CatalogUtil.isFQColumnName(right.getQualifiedName());
+      boolean leftQualified = IdentifierUtil.isFQColumnName(left.getQualifiedName());
+      boolean rightQualified = IdentifierUtil.isFQColumnName(right.getQualifiedName());
 
       if (!leftQualified) { // if left one is aliased name
 
@@ -410,7 +411,7 @@ public class EvalTreeUtil {
 
         // ensure there is only one column of an original expression
         if (foundColumns.size() == 1) {
-          leftQualifier = CatalogUtil.extractQualifier(foundColumns.iterator().next().getCanonicalName());
+          leftQualifier = IdentifierUtil.extractQualifier(foundColumns.iterator().next().getCanonicalName());
         }
       }
       if (!rightQualified) { // if right one is aliased name
@@ -421,7 +422,7 @@ public class EvalTreeUtil {
 
         // ensure there is only one column of an original expression
         if (foundColumns.size() == 1) {
-          rightQualifier = CatalogUtil.extractQualifier(foundColumns.iterator().next().getCanonicalName());
+          rightQualifier = IdentifierUtil.extractQualifier(foundColumns.iterator().next().getCanonicalName());
         }
       }
     }

http://git-wip-us.apache.org/repos/asf/tajo/blob/8d2bf407/tajo-plan/src/main/java/org/apache/tajo/plan/expr/FieldEval.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/FieldEval.java b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/FieldEval.java
index 60144ce..b527780 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/FieldEval.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/FieldEval.java
@@ -18,45 +18,52 @@
 
 package org.apache.tajo.plan.expr;
 
-import com.google.gson.annotations.Expose;
 import org.apache.tajo.catalog.Column;
+import org.apache.tajo.catalog.FieldConverter;
 import org.apache.tajo.catalog.Schema;
 import org.apache.tajo.catalog.TypeConverter;
 import org.apache.tajo.common.TajoDataTypes.DataType;
 import org.apache.tajo.datum.Datum;
+import org.apache.tajo.schema.Field;
+import org.apache.tajo.schema.IdentifierUtil;
 import org.apache.tajo.storage.Tuple;
 import org.apache.tajo.type.Type;
 
+import static org.apache.tajo.schema.Field.Field;
+import static org.apache.tajo.schema.QualifiedIdentifier.$;
+
 public class FieldEval extends EvalNode implements Cloneable {
-	@Expose private Column column;
-	@Expose	private int fieldId = -1;
+	private Field field;
+	private int fieldId = -1;
 	
-	public FieldEval(String columnName, DataType domain) {
+	public FieldEval(String columnName, DataType type) {
 		super(EvalType.FIELD);
-		this.column = new Column(columnName, domain);
+		this.field = Field($(columnName), TypeConverter.convert(type));
 	}
 
   public FieldEval(String columnName, Type type) {
     super(EvalType.FIELD);
-    this.column = new Column(columnName, TypeConverter.convert(type));
+    this.field = Field($(columnName), type);
   }
 	
-	public FieldEval(Column column) {
+	public FieldEval(Column field) {
 	  super(EvalType.FIELD);
-	  this.column = column;
+	  this.field = FieldConverter.convert(field);
 	}
 
   @Override
   public EvalNode bind(EvalContext evalContext, Schema schema) {
     super.bind(evalContext, schema);
     // TODO - column namespace should be improved to simplify name handling and resolving.
-    if (column.hasQualifier()) {
-      fieldId = schema.getColumnId(column.getQualifiedName());
-    } else {
-      fieldId = schema.getColumnIdByName(column.getSimpleName());
+
+    fieldId = schema.getColumnId(field.name().interned());
+
+    if (fieldId == -1) { // fallback
+      fieldId = schema.getColumnIdByName(field.name().interned());
     }
+
     if (fieldId == -1) {
-      throw new IllegalStateException("No Such Column Reference: " + column + ", schema: " + schema);
+      throw new IllegalStateException("No Such Column Reference: " + field + ", schema: " + schema);
     }
     return this;
   }
@@ -70,7 +77,7 @@ public class FieldEval extends EvalNode implements Cloneable {
 
   @Override
 	public Type getValueType() {
-		return TypeConverter.convert(column.getDataType());
+		return field.type();
 	}
 
   @Override
@@ -84,48 +91,47 @@ public class FieldEval extends EvalNode implements Cloneable {
   }
 
   public Column getColumnRef() {
-    return column;
+    return FieldConverter.convert(field);
   }
 	
 	public String getQualifier() {
-	  return column.getQualifier();
+	  return IdentifierUtil.extractQualifier(field.name().interned());
 	}
 	
 	public String getColumnName() {
-	  return column.getSimpleName();
+    return IdentifierUtil.extractSimpleName(field.name().interned());
 	}
 	
 	public void replaceColumnRef(String columnName) {
-	  this.column = new Column(columnName, this.column.getDataType());
+	  this.field = Field(columnName, this.field.type());
 	}
 
 	@Override
 	public String getName() {
-		return this.column.getQualifiedName();
+		return this.field.name().interned();
 	}
 
 	public String toString() {
-	  return this.column.toString();
+	  return this.field.toString();
 	}
 	
   public boolean equals(Object obj) {
-    if (obj instanceof FieldEval) {
-      FieldEval other = (FieldEval) obj;
-      
-      return column.equals(other.column);      
+    if (this == obj) {
+      return true;
     }
-    return false;
+
+    return obj instanceof FieldEval && field.equals(((FieldEval) obj).field);
   }
   
   @Override
   public int hashCode() {
-    return column.hashCode();
+    return field.hashCode();
   }
   
   @Override
   public Object clone() throws CloneNotSupportedException {
     FieldEval eval = (FieldEval) super.clone();
-    eval.column = this.column;
+    eval.field = this.field;
     eval.fieldId = fieldId;
     
     return eval;

http://git-wip-us.apache.org/repos/asf/tajo/blob/8d2bf407/tajo-plan/src/main/java/org/apache/tajo/plan/expr/RowConstantEval.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/RowConstantEval.java b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/RowConstantEval.java
index aaaba22..21d3517 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/expr/RowConstantEval.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/expr/RowConstantEval.java
@@ -19,11 +19,11 @@
 package org.apache.tajo.plan.expr;
 
 import com.google.gson.annotations.Expose;
-import org.apache.tajo.catalog.TypeConverter;
 import org.apache.tajo.datum.Datum;
 import org.apache.tajo.datum.NullDatum;
 import org.apache.tajo.storage.Tuple;
 import org.apache.tajo.type.Type;
+import org.apache.tajo.type.TypeFactory;
 import org.apache.tajo.util.StringUtils;
 import org.apache.tajo.util.TUtil;
 
@@ -39,7 +39,7 @@ public class RowConstantEval extends ValueSetEval {
 
   @Override
   public Type getValueType() {
-    return TypeConverter.convert(values[0].type());
+    return TypeFactory.create(values[0].type());
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/tajo/blob/8d2bf407/tajo-plan/src/main/java/org/apache/tajo/plan/logical/CreateDatabaseNode.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/logical/CreateDatabaseNode.java b/tajo-plan/src/main/java/org/apache/tajo/plan/logical/CreateDatabaseNode.java
index 28bd4cd..404dd33 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/logical/CreateDatabaseNode.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/logical/CreateDatabaseNode.java
@@ -19,8 +19,8 @@
 package org.apache.tajo.plan.logical;
 
 import com.google.common.base.Objects;
-import org.apache.tajo.catalog.CatalogUtil;
 import org.apache.tajo.plan.PlanString;
+import org.apache.tajo.schema.IdentifierUtil;
 
 public class CreateDatabaseNode extends LogicalNode implements Cloneable {
   private String databaseName;
@@ -82,7 +82,7 @@ public class CreateDatabaseNode extends LogicalNode implements Cloneable {
   @Override
   public String toString() {
     return "CREATE DATABASE " + (ifNotExists ? " IF NOT EXISTS " : "")
-        + CatalogUtil.denormalizeIdentifier(databaseName);
+        + IdentifierUtil.denormalizeIdentifier(databaseName);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/tajo/blob/8d2bf407/tajo-plan/src/main/java/org/apache/tajo/plan/logical/JoinSpec.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/logical/JoinSpec.java b/tajo-plan/src/main/java/org/apache/tajo/plan/logical/JoinSpec.java
index 643aa3d..06afd68 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/logical/JoinSpec.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/logical/JoinSpec.java
@@ -31,7 +31,7 @@ public class JoinSpec implements Cloneable {
 
     @Override
     public int compare(EvalNode e1, EvalNode e2) {
-      return e1.toJson().compareTo(e2.toJson());
+      return e1.toString().compareTo(e2.toString());
     }
   }
 
@@ -69,7 +69,7 @@ public class JoinSpec implements Cloneable {
     return predicates.size() > 0;
   }
 
-  public void setPredicates(Set<EvalNode> predicates) {
+  public void setPredicates(Collection<EvalNode> predicates) {
     this.predicates.clear();
     if (predicates == null || predicates.isEmpty()) {
       if (type == JoinType.INNER) {
@@ -81,7 +81,7 @@ public class JoinSpec implements Cloneable {
   }
 
   public void setSingletonPredicate(EvalNode predicates) {
-    this.setPredicates(new HashSet<>(Arrays.asList(AlgebraicUtil.toConjunctiveNormalFormArray(predicates))));
+    this.setPredicates(Arrays.asList(AlgebraicUtil.toConjunctiveNormalFormArray(predicates)));
   }
 
   public EvalNode getSingletonPredicate() {