TAJO-1946: Change Projectable::setTargets and getTargets to set and get 
List<Target>.

Closes #839

Signed-off-by: Jihoon Son <[email protected]>


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

Branch: refs/heads/master
Commit: a2a5c14e412cfab316c87bfeadcddf11e6391e08
Parents: 4fd1739
Author: Dongkyu Hwangbo <[email protected]>
Authored: Wed Nov 18 15:23:13 2015 +0900
Committer: Jihoon Son <[email protected]>
Committed: Wed Nov 18 15:23:13 2015 +0900

----------------------------------------------------------------------
 CHANGES                                         |  3 +
 .../java/org/apache/tajo/util/StringUtils.java  | 80 +++++++++++++++++--
 .../org/apache/tajo/util/TestStringUtil.java    | 16 +++-
 .../apache/tajo/engine/eval/ExprTestBase.java   | 12 +--
 .../tajo/engine/eval/TestEvalTreeUtil.java      | 18 ++---
 .../tajo/engine/planner/TestLogicalPlanner.java | 55 +++++++------
 .../engine/codegen/ExecutorPreCompiler.java     |  3 +-
 .../engine/planner/PhysicalPlannerImpl.java     |  4 +-
 .../apache/tajo/engine/planner/Projector.java   | 18 +++--
 .../engine/planner/global/GlobalPlanner.java    | 50 ++++++------
 .../global/builder/DistinctGroupbyBuilder.java  | 81 ++++++++------------
 .../planner/physical/BSTIndexScanExec.java      |  3 +-
 .../engine/planner/physical/EvalExprExec.java   |  9 ++-
 .../engine/planner/physical/SeqScanExec.java    | 12 +--
 .../engine/planner/physical/WindowAggExec.java  |  6 +-
 .../exec/ExplainPlanPreprocessorForTest.java    |  6 +-
 .../apache/tajo/master/exec/QueryExecutor.java  | 14 ++--
 .../org/apache/tajo/plan/LogicalOptimizer.java  |  2 +-
 .../java/org/apache/tajo/plan/LogicalPlan.java  |  6 +-
 .../org/apache/tajo/plan/LogicalPlanner.java    | 72 +++++++++--------
 .../org/apache/tajo/plan/expr/EvalTreeUtil.java |  2 +-
 .../tajo/plan/logical/DistinctGroupbyNode.java  | 27 +++----
 .../apache/tajo/plan/logical/EvalExprNode.java  | 18 ++---
 .../apache/tajo/plan/logical/GroupbyNode.java   | 36 +++++----
 .../org/apache/tajo/plan/logical/JoinNode.java  | 18 +++--
 .../plan/logical/PartitionedTableScanNode.java  | 68 ++++++++--------
 .../apache/tajo/plan/logical/Projectable.java   |  6 +-
 .../tajo/plan/logical/ProjectionNode.java       | 30 ++++----
 .../org/apache/tajo/plan/logical/ScanNode.java  | 27 ++++---
 .../tajo/plan/logical/TableSubQueryNode.java    | 32 +++++---
 .../apache/tajo/plan/logical/WindowAggNode.java | 23 +++---
 .../tajo/plan/rewrite/BaseSchemaBuildPhase.java | 19 +++--
 .../rewrite/rules/InSubqueryRewriteRule.java    |  2 +-
 .../rewrite/rules/ProjectionPushDownRule.java   | 55 +++++++------
 .../plan/serder/LogicalNodeDeserializer.java    | 13 ++--
 .../tajo/plan/serder/LogicalNodeSerializer.java | 17 ++--
 .../org/apache/tajo/plan/util/PlannerUtil.java  | 22 +++---
 .../tajo/plan/verifier/LogicalPlanVerifier.java |  2 +-
 .../apache/tajo/storage/jdbc/SQLBuilder.java    |  5 +-
 39 files changed, 495 insertions(+), 397 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tajo/blob/a2a5c14e/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index 12b11be..8858adb 100644
--- a/CHANGES
+++ b/CHANGES
@@ -101,6 +101,9 @@ Release 0.12.0 - unreleased
 
   SUB TASKS
 
+    TAJO-1946: Change Projectable::setTargets and getTargets to set and get
+    List<Target>. (Contributed by Dongkyu Hwangbo, Committed by jihoon)
+
     TAJO-1877: Adopt try-resource statement to AbstractDBStore. 
     (Contributed by Dongkyu Hwangbo, Committed by jihoon)
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/a2a5c14e/tajo-common/src/main/java/org/apache/tajo/util/StringUtils.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/java/org/apache/tajo/util/StringUtils.java 
b/tajo-common/src/main/java/org/apache/tajo/util/StringUtils.java
index 2d57c0a..1cb25ca 100644
--- a/tajo-common/src/main/java/org/apache/tajo/util/StringUtils.java
+++ b/tajo-common/src/main/java/org/apache/tajo/util/StringUtils.java
@@ -19,6 +19,7 @@
 package org.apache.tajo.util;
 
 import com.google.common.base.Function;
+import com.google.common.collect.Iterables;
 import io.netty.util.CharsetUtil;
 import org.apache.commons.lang.CharUtils;
 import org.apache.commons.lang.StringEscapeUtils;
@@ -36,6 +37,7 @@ import java.nio.charset.CoderResult;
 import java.nio.charset.CodingErrorAction;
 import java.util.Arrays;
 import java.util.BitSet;
+import java.util.Iterator;
 
 public class StringUtils {
 
@@ -377,23 +379,87 @@ public class StringUtils {
   }
 
   /**
+   * Concatenate all objects' string with the delimiter ", "
+   *
+   * @param objects Iterable objects
+   * @return A joined string
+   */
+  public static String join(Iterable objects) {
+    return join(objects, ", ");
+  }
+
+  /**
    * Concatenate all objects' string with a delimiter string
    *
    * @param objects Iterable objects
    * @param delimiter Delimiter string
    * @return A joined string
    */
-  public static String join(Iterable objects, String delimiter) {
+  public static String join(Iterable objects, String delimiter)  {
+    return join(objects, delimiter, 0, Iterables.size(objects));
+  }
+
+  /**
+   * Concatenate all objects' string with a delimiter string
+   *
+   * @param objects object Iterable
+   * @param delimiter Delimiter string
+   * @param startIndex the begin index to join
+   * @return A joined string
+   */
+  public static String join(Iterable objects, String delimiter, int 
startIndex) {
+    return join(objects, delimiter, startIndex, Iterables.size(objects));
+  }
+
+  /**
+   * Concatenate all objects' string with a delimiter string
+   *
+   * @param objects object Iterable
+   * @param delimiter Delimiter string
+   * @param startIndex the begin index to join
+   * @param length the number of columns to be joined
+   * @return A joined string
+   */
+  public static String join(Iterable objects, String delimiter, int 
startIndex, int length) {
+    return join(objects, delimiter, startIndex, length, new Function<Object, 
String>() {
+      @Override
+      public String apply(Object input) {
+        return input.toString();
+      }
+    });
+  }
+
+  /**
+   * Concatenate all objects' string with a delimiter string
+   *
+   * @param objects object Iterable
+   * @param delimiter Delimiter string
+   * @param f convert from a type to string
+   * @return A joined string
+   */
+  public static <T> String join(Iterable<T> objects, String delimiter, 
Function<T, String> f) {
+    return join(objects, delimiter, 0, Iterables.size(objects), f);
+  }
+
+  public static <T> String join(Iterable<T> objects, String delimiter, int 
startIndex, int length, Function<T, String> f) {
     boolean first = true;
     StringBuilder sb = new StringBuilder();
-    for(Object object : objects) {
-      if (first) {
-        first = false;
-      } else {
-        sb.append(delimiter);
+    int endIndex = startIndex + length;
+    Iterator itr = objects.iterator();
+
+    for(int i = 0; i < endIndex; i++) {
+      if(i < startIndex) {
+        itr.next();
       }
+      else {
+        if (first) {
+          first = false;
+        } else {
+          sb.append(delimiter);
+        }
 
-      sb.append(object.toString());
+        sb.append(f.apply((T) itr.next()));
+      }
     }
 
     return sb.toString();

http://git-wip-us.apache.org/repos/asf/tajo/blob/a2a5c14e/tajo-common/src/test/java/org/apache/tajo/util/TestStringUtil.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/test/java/org/apache/tajo/util/TestStringUtil.java 
b/tajo-common/src/test/java/org/apache/tajo/util/TestStringUtil.java
index c4329a1..f32309b 100644
--- a/tajo-common/src/test/java/org/apache/tajo/util/TestStringUtil.java
+++ b/tajo-common/src/test/java/org/apache/tajo/util/TestStringUtil.java
@@ -18,12 +18,14 @@
 
 package org.apache.tajo.util;
 
-import java.nio.charset.Charset;
-
 import org.apache.commons.lang.CharUtils;
 import org.apache.commons.lang.StringEscapeUtils;
 import org.junit.Test;
 
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.List;
+
 import static org.junit.Assert.*;
 
 public class TestStringUtil {
@@ -149,4 +151,14 @@ public class TestStringUtil {
     assertArrayEquals(new byte[] { (byte) 0xED, (byte) 0x83, (byte) 0x80, 
(byte) 0xEC, (byte) 0xA1, (byte) 0xB0 },
         StringUtils.convertCharsToBytes(testStringArray, 
Charset.forName("UTF-8")));
   }
+
+  @Test
+  public void testJoinIterable() {
+    List<String> testList = new ArrayList<>();
+    testList.add("t");
+    testList.add("a");
+    testList.add("j");
+    testList.add("o");
+    assertTrue(StringUtils.join(testList).equals("t, a, j, o"));
+  }
 }

http://git-wip-us.apache.org/repos/asf/tajo/blob/a2a5c14e/tajo-core-tests/src/test/java/org/apache/tajo/engine/eval/ExprTestBase.java
----------------------------------------------------------------------
diff --git 
a/tajo-core-tests/src/test/java/org/apache/tajo/engine/eval/ExprTestBase.java 
b/tajo-core-tests/src/test/java/org/apache/tajo/engine/eval/ExprTestBase.java
index 7c79724..69f92f4 100644
--- 
a/tajo-core-tests/src/test/java/org/apache/tajo/engine/eval/ExprTestBase.java
+++ 
b/tajo-core-tests/src/test/java/org/apache/tajo/engine/eval/ExprTestBase.java
@@ -130,7 +130,7 @@ public class ExprTestBase {
    * @param condition this parameter means whether it is for success case or 
is not for failure case.
    * @return
    */
-  private static Target[] getRawTargets(QueryContext context, String query, 
boolean condition)
+  private static List<Target> getRawTargets(QueryContext context, String 
query, boolean condition)
       throws TajoException, InvalidStatementException {
 
     List<ParsedResult> parsedResults = SimpleParser.parseScript(query);
@@ -154,7 +154,7 @@ public class ExprTestBase {
       assertFalse(state.getErrors().get(0).getMessage(), true);
     }
 
-    Target [] targets = plan.getRootBlock().getRawTargets();
+    List<Target> targets = plan.getRootBlock().getRawTargets();
     if (targets == null) {
       throw new RuntimeException("Wrong query statement or query plan: " + 
parsedResults.get(0).getHistoryStatement());
     }
@@ -270,7 +270,7 @@ public class ExprTestBase {
       }
     }
 
-    Target [] targets;
+    List<Target> targets;
 
     TajoClassLoader classLoader = new TajoClassLoader();
     EvalContext evalContext = new EvalContext();
@@ -284,9 +284,9 @@ public class ExprTestBase {
       }
 
       QueryExecutor.startScriptExecutors(queryContext, evalContext, targets);
-      Tuple outTuple = new VTuple(targets.length);
-      for (int i = 0; i < targets.length; i++) {
-        EvalNode eval = targets[i].getEvalTree();
+      Tuple outTuple = new VTuple(targets.size());
+      for (int i = 0; i < targets.size(); i++) {
+        EvalNode eval = targets.get(i).getEvalTree();
 
         if (queryContext.getBool(SessionVars.CODEGEN)) {
           eval = codegen.compile(inputSchema, eval);

http://git-wip-us.apache.org/repos/asf/tajo/blob/a2a5c14e/tajo-core-tests/src/test/java/org/apache/tajo/engine/eval/TestEvalTreeUtil.java
----------------------------------------------------------------------
diff --git 
a/tajo-core-tests/src/test/java/org/apache/tajo/engine/eval/TestEvalTreeUtil.java
 
b/tajo-core-tests/src/test/java/org/apache/tajo/engine/eval/TestEvalTreeUtil.java
index 7bba76b..3c92842 100644
--- 
a/tajo-core-tests/src/test/java/org/apache/tajo/engine/eval/TestEvalTreeUtil.java
+++ 
b/tajo-core-tests/src/test/java/org/apache/tajo/engine/eval/TestEvalTreeUtil.java
@@ -135,7 +135,7 @@ public class TestEvalTreeUtil {
     util.shutdownCatalogCluster();
   }
 
-  public static Target [] getRawTargets(String query) {
+  public static List<Target> getRawTargets(String query) {
     LogicalPlan plan = null;
     try {
       Expr expr = analyzer.parse(query);
@@ -212,7 +212,7 @@ public class TestEvalTreeUtil {
   
   @Test
   public final void testGetSchemaFromTargets() {
-    Target [] targets = getRawTargets(QUERIES[0]);
+    List<Target> targets = getRawTargets(QUERIES[0]);
     Schema schema = EvalTreeUtil.getSchemaByTargets(null, targets);
     Column col1 = schema.getColumn(0);
     Column col2 = schema.getColumn(1);
@@ -226,17 +226,17 @@ public class TestEvalTreeUtil {
   public final void testGetContainExprs() throws CloneNotSupportedException, 
TajoException {
     Expr expr = analyzer.parse(QUERIES[1]);
     LogicalPlan plan = planner.createPlan(defaultContext, expr, true);
-    Target [] targets = plan.getRootBlock().getRawTargets();
+    List<Target> targets = plan.getRootBlock().getRawTargets();
     Column col1 = new Column("default.people.score", TajoDataTypes.Type.INT4);
     Collection<EvalNode> exprs =
-        EvalTreeUtil.getContainExpr(targets[0].getEvalTree(), col1);
+        EvalTreeUtil.getContainExpr(targets.get(0).getEvalTree(), col1);
     BinaryEval node = (BinaryEval) exprs.iterator().next();
     assertEquals(EvalType.LTH, node.getType());
     assertEquals(EvalType.PLUS, node.getLeftExpr().getType());
     assertEquals(new ConstEval(DatumFactory.createInt4(4)), 
node.getRightExpr());
 
     Column col2 = new Column("default.people.age", TajoDataTypes.Type.INT4);
-    exprs = EvalTreeUtil.getContainExpr(targets[1].getEvalTree(), col2);
+    exprs = EvalTreeUtil.getContainExpr(targets.get(1).getEvalTree(), col2);
     node = (BinaryEval) exprs.iterator().next();
     assertEquals(EvalType.GTH, node.getType());
     assertEquals("default.people.age", node.getLeftExpr().getName());
@@ -294,11 +294,11 @@ public class TestEvalTreeUtil {
   
   @Test
   public final void testSimplify() throws TajoException {
-    Target [] targets = getRawTargets(QUERIES[0]);
-    EvalNode node = 
AlgebraicUtil.eliminateConstantExprs(targets[0].getEvalTree());
+    List<Target> targets = getRawTargets(QUERIES[0]);
+    EvalNode node = 
AlgebraicUtil.eliminateConstantExprs(targets.get(0).getEvalTree());
     assertEquals(EvalType.CONST, node.getType());
     assertEquals(7, node.bind(null, null).eval(null).asInt4());
-    node = AlgebraicUtil.eliminateConstantExprs(targets[1].getEvalTree());
+    node = AlgebraicUtil.eliminateConstantExprs(targets.get(1).getEvalTree());
     assertEquals(EvalType.CONST, node.getType());
     assertTrue(7.0d == node.bind(null, null).eval(null).asFloat8());
 
@@ -307,7 +307,7 @@ public class TestEvalTreeUtil {
     targets = plan.getRootBlock().getRawTargets();
     Column col1 = new Column("default.people.score", TajoDataTypes.Type.INT4);
     Collection<EvalNode> exprs =
-        EvalTreeUtil.getContainExpr(targets[0].getEvalTree(), col1);
+        EvalTreeUtil.getContainExpr(targets.get(0).getEvalTree(), col1);
     node = exprs.iterator().next();
   }
   

http://git-wip-us.apache.org/repos/asf/tajo/blob/a2a5c14e/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/TestLogicalPlanner.java
----------------------------------------------------------------------
diff --git 
a/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/TestLogicalPlanner.java
 
b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/TestLogicalPlanner.java
index a11d9be..d291c09 100644
--- 
a/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/TestLogicalPlanner.java
+++ 
b/tajo-core-tests/src/test/java/org/apache/tajo/engine/planner/TestLogicalPlanner.java
@@ -54,7 +54,6 @@ import org.apache.tajo.storage.TablespaceManager;
 import org.apache.tajo.util.CommonTestingUtil;
 import org.apache.tajo.util.FileUtil;
 import org.apache.tajo.util.KeyValueSet;
-import org.apache.tajo.util.TUtil;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -1247,12 +1246,12 @@ public class TestLogicalPlanner {
     InsertNode insertNode = getInsertNode(plan);
 
     ProjectionNode subquery = insertNode.getChild();
-    Target[] targets = subquery.getTargets();
+    List<Target> targets = subquery.getTargets();
     // targets MUST be manager, NULL as empid, deptname
-    assertEquals(targets[0].getNamedColumn().getQualifiedName(), 
"default.dept.manager");
-    assertEquals(targets[1].getAlias(), "empid");
-    assertEquals(targets[1].getEvalTree().getType(), EvalType.CONST);
-    assertEquals(targets[2].getNamedColumn().getQualifiedName(), 
"default.dept.deptname");
+    assertEquals(targets.get(0).getNamedColumn().getQualifiedName(), 
"default.dept.manager");
+    assertEquals(targets.get(1).getAlias(), "empid");
+    assertEquals(targets.get(1).getEvalTree().getType(), EvalType.CONST);
+    assertEquals(targets.get(2).getNamedColumn().getQualifiedName(), 
"default.dept.deptname");
   }
 
   private static InsertNode getInsertNode(LogicalPlan plan) {
@@ -1408,32 +1407,32 @@ public class TestLogicalPlanner {
     testCloneLogicalNode(projectionNode);
 
     // projection column test
-    Target[] targets = projectionNode.getTargets();
-    Arrays.sort(targets, new Comparator<Target>() {
+    List<Target> targets = projectionNode.getTargets();
+    Collections.sort(targets, new Comparator<Target>() {
       @Override
       public int compare(Target o1, Target o2) {
         return o1.getCanonicalName().compareTo(o2.getCanonicalName());
       }
     });
-    assertEquals(3, targets.length);
-    assertEquals("default.self_desc_table1.dept", 
targets[0].getCanonicalName());
-    assertEquals("default.self_desc_table1.id", targets[1].getCanonicalName());
-    assertEquals("default.self_desc_table1.name", 
targets[2].getCanonicalName());
+    assertEquals(3, targets.size());
+    assertEquals("default.self_desc_table1.dept", 
targets.get(0).getCanonicalName());
+    assertEquals("default.self_desc_table1.id", 
targets.get(1).getCanonicalName());
+    assertEquals("default.self_desc_table1.name", 
targets.get(2).getCanonicalName());
 
     // scan column test
     assertEquals(NodeType.SCAN, projectionNode.getChild().getType());
     ScanNode scanNode = projectionNode.getChild();
     targets = scanNode.getTargets();
-    Arrays.sort(targets, new Comparator<Target>() {
+    Collections.sort(targets, new Comparator<Target>() {
       @Override
       public int compare(Target o1, Target o2) {
         return o1.getCanonicalName().compareTo(o2.getCanonicalName());
       }
     });
-    assertEquals(3, targets.length);
-    assertEquals("default.self_desc_table1.dept", 
targets[0].getCanonicalName());
-    assertEquals("default.self_desc_table1.id", targets[1].getCanonicalName());
-    assertEquals("default.self_desc_table1.name", 
targets[2].getCanonicalName());
+    assertEquals(3, targets.size());
+    assertEquals("default.self_desc_table1.dept", 
targets.get(0).getCanonicalName());
+    assertEquals("default.self_desc_table1.id", 
targets.get(1).getCanonicalName());
+    assertEquals("default.self_desc_table1.name", 
targets.get(2).getCanonicalName());
 
     catalog.dropTable("default.self_desc_table1");
   }
@@ -1463,16 +1462,16 @@ public class TestLogicalPlanner {
     testCloneLogicalNode(projectionNode);
 
     // projection column test
-    Target[] targets = projectionNode.getTargets();
-    Arrays.sort(targets, new Comparator<Target>() {
+    List<Target> targets = projectionNode.getTargets();
+    Collections.sort(targets, new Comparator<Target>() {
       @Override
       public int compare(Target o1, Target o2) {
         return o1.getCanonicalName().compareTo(o2.getCanonicalName());
       }
     });
-    assertEquals(2, targets.length);
-    assertEquals("default.self_desc_table1.dept", 
targets[0].getCanonicalName());
-    assertEquals("default.self_desc_table1.name", 
targets[1].getCanonicalName());
+    assertEquals(2, targets.size());
+    assertEquals("default.self_desc_table1.dept", 
targets.get(0).getCanonicalName());
+    assertEquals("default.self_desc_table1.name", 
targets.get(1).getCanonicalName());
 
     assertEquals(NodeType.SELECTION, projectionNode.getChild().getType());
     SelectionNode selectionNode = projectionNode.getChild();
@@ -1483,17 +1482,17 @@ public class TestLogicalPlanner {
     assertEquals(NodeType.SCAN, selectionNode.getChild().getType());
     ScanNode scanNode = selectionNode.getChild();
     targets = scanNode.getTargets();
-    Arrays.sort(targets, new Comparator<Target>() {
+    Collections.sort(targets, new Comparator<Target>() {
       @Override
       public int compare(Target o1, Target o2) {
         return o1.getCanonicalName().compareTo(o2.getCanonicalName());
       }
     });
-    assertEquals(4, targets.length);
-    assertEquals("?greaterthan", targets[0].getCanonicalName());
-    assertEquals("default.self_desc_table1.dept", 
targets[1].getCanonicalName());
-    assertEquals("default.self_desc_table1.id", targets[2].getCanonicalName());
-    assertEquals("default.self_desc_table1.name", 
targets[3].getCanonicalName());
+    assertEquals(4, targets.size());
+    assertEquals("?greaterthan", targets.get(0).getCanonicalName());
+    assertEquals("default.self_desc_table1.dept", 
targets.get(1).getCanonicalName());
+    assertEquals("default.self_desc_table1.id", 
targets.get(2).getCanonicalName());
+    assertEquals("default.self_desc_table1.name", 
targets.get(3).getCanonicalName());
 
     catalog.dropTable("default.self_desc_table1");
   }

http://git-wip-us.apache.org/repos/asf/tajo/blob/a2a5c14e/tajo-core/src/main/java/org/apache/tajo/engine/codegen/ExecutorPreCompiler.java
----------------------------------------------------------------------
diff --git 
a/tajo-core/src/main/java/org/apache/tajo/engine/codegen/ExecutorPreCompiler.java
 
b/tajo-core/src/main/java/org/apache/tajo/engine/codegen/ExecutorPreCompiler.java
index f63e46f..15df76a 100644
--- 
a/tajo-core/src/main/java/org/apache/tajo/engine/codegen/ExecutorPreCompiler.java
+++ 
b/tajo-core/src/main/java/org/apache/tajo/engine/codegen/ExecutorPreCompiler.java
@@ -32,6 +32,7 @@ import org.apache.tajo.plan.visitor.BasicLogicalPlanVisitor;
 import org.apache.tajo.util.Pair;
 
 import java.util.Collections;
+import java.util.List;
 import java.util.Map;
 import java.util.Stack;
 
@@ -91,7 +92,7 @@ public class ExecutorPreCompiler extends 
BasicLogicalPlanVisitor<ExecutorPreComp
   }
 
   private static void compileProjectableNode(CompilationContext context, 
Schema schema, Projectable node) {
-    Target[] targets;
+    List<Target> targets;
     if (node.hasTargets()) {
       targets = node.getTargets();
     } else {

http://git-wip-us.apache.org/repos/asf/tajo/blob/a2a5c14e/tajo-core/src/main/java/org/apache/tajo/engine/planner/PhysicalPlannerImpl.java
----------------------------------------------------------------------
diff --git 
a/tajo-core/src/main/java/org/apache/tajo/engine/planner/PhysicalPlannerImpl.java
 
b/tajo-core/src/main/java/org/apache/tajo/engine/planner/PhysicalPlannerImpl.java
index e0da9e6..c489bbb 100644
--- 
a/tajo-core/src/main/java/org/apache/tajo/engine/planner/PhysicalPlannerImpl.java
+++ 
b/tajo-core/src/main/java/org/apache/tajo/engine/planner/PhysicalPlannerImpl.java
@@ -1095,13 +1095,13 @@ public class PhysicalPlannerImpl implements 
PhysicalPlanner {
     //3 phase: groupby columns, seq, distinct1 keys, distinct2 keys,
     List<SortSpec> sortSpecs = new ArrayList<>();
     if (phase == 2) {
-      sortSpecs.add(new 
SortSpec(distinctNode.getTargets()[0].getNamedColumn()));
+      sortSpecs.add(new 
SortSpec(distinctNode.getTargets().get(0).getNamedColumn()));
     }
     for (Column eachColumn: distinctNode.getGroupingColumns()) {
       sortSpecs.add(new SortSpec(eachColumn));
     }
     if (phase == 3) {
-      sortSpecs.add(new 
SortSpec(distinctNode.getTargets()[0].getNamedColumn()));
+      sortSpecs.add(new 
SortSpec(distinctNode.getTargets().get(0).getNamedColumn()));
     }
     for (GroupbyNode eachGroupbyNode: distinctNode.getSubPlans()) {
       for (Column eachColumn: eachGroupbyNode.getGroupingColumns()) {

http://git-wip-us.apache.org/repos/asf/tajo/blob/a2a5c14e/tajo-core/src/main/java/org/apache/tajo/engine/planner/Projector.java
----------------------------------------------------------------------
diff --git 
a/tajo-core/src/main/java/org/apache/tajo/engine/planner/Projector.java 
b/tajo-core/src/main/java/org/apache/tajo/engine/planner/Projector.java
index ba8ec32..dfe823b 100644
--- a/tajo-core/src/main/java/org/apache/tajo/engine/planner/Projector.java
+++ b/tajo-core/src/main/java/org/apache/tajo/engine/planner/Projector.java
@@ -27,6 +27,8 @@ import org.apache.tajo.storage.Tuple;
 import org.apache.tajo.storage.VTuple;
 import org.apache.tajo.worker.TaskAttemptContext;
 
+import java.util.List;
+
 public class Projector {
   private final TaskAttemptContext context;
   private final Schema inSchema;
@@ -36,28 +38,28 @@ public class Projector {
 
   private final Tuple outTuple;
 
-  public Projector(TaskAttemptContext context, Schema inSchema, Schema 
outSchema, Target [] targets) {
+  public Projector(TaskAttemptContext context, Schema inSchema, Schema 
outSchema, List<Target> targets) {
     this.context = context;
     this.inSchema = inSchema;
-    Target[] realTargets;
+    List<Target> realTargets;
     if (targets == null) {
       realTargets = PlannerUtil.schemaToTargets(outSchema);
     } else {
       realTargets = targets;
     }
 
-    outTuple = new VTuple(realTargets.length);
-    evals = new EvalNode[realTargets.length];
+    outTuple = new VTuple(realTargets.size());
+    evals = new EvalNode[realTargets.size()];
 
     if (context.getQueryContext().getBool(SessionVars.CODEGEN)) {
       EvalNode eval;
-      for (int i = 0; i < realTargets.length; i++) {
-        eval = realTargets[i].getEvalTree();
+      for (int i = 0; i < realTargets.size(); i++) {
+        eval = realTargets.get(i).getEvalTree();
         evals[i] = context.getPrecompiledEval(inSchema, eval);
       }
     } else {
-      for (int i = 0; i < realTargets.length; i++) {
-        evals[i] = realTargets[i].getEvalTree();
+      for (int i = 0; i < realTargets.size(); i++) {
+        evals[i] = realTargets.get(i).getEvalTree();
       }
     }
     init();

http://git-wip-us.apache.org/repos/asf/tajo/blob/a2a5c14e/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 5f8bd11..0b42a41 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
@@ -383,12 +383,12 @@ public class GlobalPlanner {
    */
   private static class RewrittenFunctions {
     AggregationFunctionCallEval [] firstStageEvals;
-    Target[] firstStageTargets;
+    List<Target> firstStageTargets;
     AggregationFunctionCallEval secondStageEvals;
 
     public RewrittenFunctions(int firstStageEvalNum) {
       firstStageEvals = new AggregationFunctionCallEval[firstStageEvalNum];
-      firstStageTargets = new Target[firstStageEvalNum];
+      firstStageTargets = new ArrayList<>();
     }
   }
 
@@ -444,7 +444,7 @@ public class GlobalPlanner {
       }
       String referenceName = 
plan.generateUniqueColumnName(rewritten.firstStageEvals[0]);
       FieldEval fieldEval = new FieldEval(referenceName, 
rewritten.firstStageEvals[0].getValueType());
-      rewritten.firstStageTargets[0] = new Target(fieldEval);
+      rewritten.firstStageTargets.add(0, new Target(fieldEval));
       rewritten.secondStageEvals = createSumFunction(new 
EvalNode[]{fieldEval});
     } else if (function.getName().equalsIgnoreCase("sum")) {
       rewritten = new RewrittenFunctions(1);
@@ -452,7 +452,7 @@ public class GlobalPlanner {
       rewritten.firstStageEvals[0] = createSumFunction(function.getArgs());
       String referenceName = 
plan.generateUniqueColumnName(rewritten.firstStageEvals[0]);
       FieldEval fieldEval = new FieldEval(referenceName, 
rewritten.firstStageEvals[0].getValueType());
-      rewritten.firstStageTargets[0] = new Target(fieldEval);
+      rewritten.firstStageTargets.add(0, new Target(fieldEval));
       rewritten.secondStageEvals = createSumFunction(new 
EvalNode[]{fieldEval});
 
     } else if (function.getName().equals("max")) {
@@ -461,7 +461,7 @@ public class GlobalPlanner {
       rewritten.firstStageEvals[0] = createMaxFunction(function.getArgs());
       String referenceName = 
plan.generateUniqueColumnName(rewritten.firstStageEvals[0]);
       FieldEval fieldEval = new FieldEval(referenceName, 
rewritten.firstStageEvals[0].getValueType());
-      rewritten.firstStageTargets[0] = new Target(fieldEval);
+      rewritten.firstStageTargets.add(0, new Target(fieldEval));
       rewritten.secondStageEvals = createMaxFunction(new 
EvalNode[]{fieldEval});
 
     } else if (function.getName().equals("min")) {
@@ -471,7 +471,7 @@ public class GlobalPlanner {
       rewritten.firstStageEvals[0] = createMinFunction(function.getArgs());
       String referenceName = 
plan.generateUniqueColumnName(rewritten.firstStageEvals[0]);
       FieldEval fieldEval = new FieldEval(referenceName, 
rewritten.firstStageEvals[0].getValueType());
-      rewritten.firstStageTargets[0] = new Target(fieldEval);
+      rewritten.firstStageTargets.add(0, new Target(fieldEval));
       rewritten.secondStageEvals = createMinFunction(new 
EvalNode[]{fieldEval});
 
     } else {
@@ -547,17 +547,12 @@ public class GlobalPlanner {
       }
     }
 
-    int firstStageAggFunctionNum = firstStageAggFunctions.size();
-    int firstStageGroupingKeyNum = firstStageGroupingColumns.size();
-
-    int i = 0;
-    Target [] firstStageTargets = new Target[firstStageGroupingKeyNum + 
firstStageAggFunctionNum];
+    List<Target> firstStageTargets = new ArrayList<>();
     for (Column column : firstStageGroupingColumns) {
-      Target target = new Target(new FieldEval(column));
-      firstStageTargets[i++] = target;
+      firstStageTargets.add(new Target(new FieldEval(column)));
     }
     for (Target target : firstPhaseEvalNodeTargets) {
-      firstStageTargets[i++] = target;
+      firstStageTargets.add(target);
     }
 
     // Create the groupby node for the first stage and set all necessary 
descriptions
@@ -777,7 +772,7 @@ public class GlobalPlanner {
 
       secondPhaseGroupBy.setAggFunctions(secondPhaseEvals);
       firstPhaseGroupBy.setAggFunctions(firstPhaseEvals);
-      Target [] firstPhaseTargets = 
ProjectionPushDownRule.buildGroupByTarget(firstPhaseGroupBy, null,
+      List<Target> firstPhaseTargets = 
ProjectionPushDownRule.buildGroupByTarget(firstPhaseGroupBy, null,
           firstPhaseEvalNames);
       firstPhaseGroupBy.setTargets(firstPhaseTargets);
       
secondPhaseGroupBy.setInSchema(PlannerUtil.targetToSchema(firstPhaseTargets));
@@ -1298,21 +1293,21 @@ public class GlobalPlanner {
         }
         if (leftMostSubQueryNode != null) {
           // replace target column name
-          Target[] targets = leftMostSubQueryNode.getTargets();
-          int[] targetMappings = new int[targets.length];
-          for (int i = 0; i < targets.length; i++) {
-            if (targets[i].getEvalTree().getType() != EvalType.FIELD) {
+          List<Target> targets = leftMostSubQueryNode.getTargets();
+          int[] targetMappings = new int[targets.size()];
+          for (int i = 0; i < targets.size(); i++) {
+            if (targets.get(i).getEvalTree().getType() != EvalType.FIELD) {
               throw new TajoInternalError("Target of a UnionNode's subquery 
should be FieldEval.");
             }
-            int index = 
leftMostSubQueryNode.getInSchema().getColumnId(targets[i].getNamedColumn().getQualifiedName());
+            int index = 
leftMostSubQueryNode.getInSchema().getColumnId(targets.get(i).getNamedColumn().getQualifiedName());
             if (index < 0) {
               // If a target has alias, getNamedColumn() only returns alias
-              Set<Column> columns = 
EvalTreeUtil.findUniqueColumns(targets[i].getEvalTree());
+              Set<Column> columns = 
EvalTreeUtil.findUniqueColumns(targets.get(i).getEvalTree());
               Column column = columns.iterator().next();
               index = 
leftMostSubQueryNode.getInSchema().getColumnId(column.getQualifiedName());
             }
             if (index < 0) {
-              throw new TajoInternalError("Can't find matched Target in 
UnionNode's input schema: " + targets[i]
+              throw new TajoInternalError("Can't find matched Target in 
UnionNode's input schema: " + targets.get(i)
                   + "->" + leftMostSubQueryNode.getInSchema());
             }
             targetMappings[i] = index;
@@ -1322,14 +1317,15 @@ public class GlobalPlanner {
             if (eachNode.getPID() == leftMostSubQueryNode.getPID()) {
               continue;
             }
-            Target[] eachNodeTargets = eachNode.getTargets();
-            if (eachNodeTargets.length != targetMappings.length) {
+            List<Target> eachNodeTargets = eachNode.getTargets();
+            if (eachNodeTargets.size() != targetMappings.length) {
               throw new TajoInternalError("Union query can't have different 
number of target columns.");
             }
-            for (int i = 0; i < eachNodeTargets.length; i++) {
+            for (int i = 0; i < eachNodeTargets.size(); i++) {
               Column inColumn = 
eachNode.getInSchema().getColumn(targetMappings[i]);
-              
eachNodeTargets[i].setAlias(eachNodeTargets[i].getNamedColumn().getQualifiedName());
-              EvalNode evalNode = eachNodeTargets[i].getEvalTree();
+              Target t = eachNodeTargets.get(i);
+              t.setAlias(t.getNamedColumn().getQualifiedName());
+              EvalNode evalNode = eachNodeTargets.get(i).getEvalTree();
               if (evalNode.getType() != EvalType.FIELD) {
                 throw new TajoInternalError("Target of a UnionNode's subquery 
should be FieldEval.");
               }

http://git-wip-us.apache.org/repos/asf/tajo/blob/a2a5c14e/tajo-core/src/main/java/org/apache/tajo/engine/planner/global/builder/DistinctGroupbyBuilder.java
----------------------------------------------------------------------
diff --git 
a/tajo-core/src/main/java/org/apache/tajo/engine/planner/global/builder/DistinctGroupbyBuilder.java
 
b/tajo-core/src/main/java/org/apache/tajo/engine/planner/global/builder/DistinctGroupbyBuilder.java
index 058a11b..e02e06f 100644
--- 
a/tajo-core/src/main/java/org/apache/tajo/engine/planner/global/builder/DistinctGroupbyBuilder.java
+++ 
b/tajo-core/src/main/java/org/apache/tajo/engine/planner/global/builder/DistinctGroupbyBuilder.java
@@ -104,7 +104,7 @@ public class DistinctGroupbyBuilder {
         int index = 0;
         for (AggregationFunctionCallEval aggrFunction: 
lastGroupbyNode.getAggFunctions()) {
           aggrFunction.setIntermediatePhase();
-          aggrFunction.setArgs(new EvalNode[]{new 
FieldEval(lastGroupbyNode.getTargets()[index].getNamedColumn())});
+          aggrFunction.setArgs(new EvalNode[]{new 
FieldEval(lastGroupbyNode.getTargets().get(index).getNamedColumn())});
           index++;
         }
       }
@@ -113,7 +113,7 @@ public class DistinctGroupbyBuilder {
         int index = 0;
         for (AggregationFunctionCallEval aggrFunction: 
lastGroupbyNode.getAggFunctions()) {
           aggrFunction.setFirstPhase();
-          aggrFunction.setArgs(new EvalNode[]{new 
FieldEval(lastGroupbyNode.getTargets()[index].getNamedColumn())});
+          aggrFunction.setArgs(new EvalNode[]{new 
FieldEval(lastGroupbyNode.getTargets().get(index).getNamedColumn())});
           index++;
         }
       }
@@ -208,7 +208,7 @@ public class DistinctGroupbyBuilder {
     for (int aggIdx = 0; aggIdx < aggFunctions.length; aggIdx++) {
       AggregationFunctionCallEval aggFunction = aggFunctions[aggIdx];
       aggFunction.setFirstPhase();
-      Target originAggFunctionTarget = 
groupbyNode.getTargets()[originalGroupingColumns.size() + aggIdx];
+      Target originAggFunctionTarget = 
groupbyNode.getTargets().get(originalGroupingColumns.size() + aggIdx);
       Target aggFunctionTarget =
           new Target(new 
FieldEval(originAggFunctionTarget.getEvalTree().getName(), 
aggFunction.getValueType()));
 
@@ -250,17 +250,15 @@ public class DistinctGroupbyBuilder {
       GroupbyNode eachGroupbyNode = buildInfo.getGroupbyNode();
       List<AggregationFunctionCallEval> groupbyAggFunctions = 
buildInfo.getAggFunctions();
 
-      Target[] targets = new 
Target[eachGroupbyNode.getGroupingColumns().length + 
groupbyAggFunctions.size()];
-      int targetIdx = 0;
+      List<Target> targets = new ArrayList<>();
 
       for (Column column : eachGroupbyNode.getGroupingColumns()) {
         Target target = new Target(new FieldEval(column));
-        targets[targetIdx++] = target;
+        targets.add(target);
         baseGroupByTargets.add(target);
       }
-      for (Target eachAggFunctionTarget: buildInfo.getAggFunctionTargets()) {
-        targets[targetIdx++] = eachAggFunctionTarget;
-      }
+      targets.addAll(buildInfo.getAggFunctionTargets());
+
       eachGroupbyNode.setTargets(targets);
       eachGroupbyNode.setAggFunctions(groupbyAggFunctions.toArray(new 
AggregationFunctionCallEval[groupbyAggFunctions.size()]));
       eachGroupbyNode.setDistinct(true);
@@ -274,12 +272,9 @@ public class DistinctGroupbyBuilder {
       // finally this aggregation output tuple's order is GROUP_BY_COL1, COL2, 
.... + AGG_VALUE, SUM_VALUE, ...
       GroupbyNode otherGroupbyNode = new 
GroupbyNode(context.getPlan().getLogicalPlan().newPID());
 
-      Target[] targets = new Target[otherAggregationFunctionTargets.size()];
-      int targetIdx = 0;
-      for (Target eachTarget : otherAggregationFunctionTargets) {
-        targets[targetIdx++] = eachTarget;
-        baseGroupByTargets.add(eachTarget);
-      }
+      List<Target> targets = new ArrayList<>();
+      targets.addAll(otherAggregationFunctionTargets);
+      baseGroupByTargets.addAll(otherAggregationFunctionTargets);
 
       otherGroupbyNode.setTargets(targets);
       otherGroupbyNode.setGroupingColumns(new Column[]{});
@@ -290,7 +285,7 @@ public class DistinctGroupbyBuilder {
     }
 
     DistinctGroupbyNode baseDistinctNode = new 
DistinctGroupbyNode(context.getPlan().getLogicalPlan().newPID());
-    baseDistinctNode.setTargets(baseGroupByTargets.toArray(new 
Target[baseGroupByTargets.size()]));
+    baseDistinctNode.setTargets(baseGroupByTargets);
     baseDistinctNode.setGroupingColumns(groupbyNode.getGroupingColumns());
     baseDistinctNode.setInSchema(groupbyNode.getInSchema());
     baseDistinctNode.setChild(groupbyNode.getChild());
@@ -380,7 +375,7 @@ public class DistinctGroupbyBuilder {
     AggregationFunctionCallEval[] aggFunctions = groupbyNode.getAggFunctions();
     for (int aggIdx = 0; aggIdx < aggFunctions.length; aggIdx++) {
       AggregationFunctionCallEval aggFunction = aggFunctions[aggIdx];
-      Target aggFunctionTarget = 
groupbyNode.getTargets()[originalGroupingColumns.size() + aggIdx];
+      Target aggFunctionTarget = 
groupbyNode.getTargets().get(originalGroupingColumns.size() + aggIdx);
 
       if (aggFunction.isDistinct()) {
         // Create or reuse Groupby node for each Distinct expression.
@@ -414,16 +409,13 @@ public class DistinctGroupbyBuilder {
     for (DistinctGroupbyNodeBuildInfo buildInfo: 
distinctNodeBuildInfos.values()) {
       GroupbyNode eachGroupbyNode = buildInfo.getGroupbyNode();
       List<AggregationFunctionCallEval> groupbyAggFunctions = 
buildInfo.getAggFunctions();
-      Target[] targets = new 
Target[eachGroupbyNode.getGroupingColumns().length + 
groupbyAggFunctions.size()];
-      int targetIdx = 0;
+      List<Target> targets = new ArrayList<>();
 
       for (Column column : eachGroupbyNode.getGroupingColumns()) {
-        Target target = new Target(new FieldEval(column));
-        targets[targetIdx++] = target;
-      }
-      for (Target eachAggFunctionTarget: buildInfo.getAggFunctionTargets()) {
-        targets[targetIdx++] = eachAggFunctionTarget;
+        targets.add(new Target(new FieldEval(column)));
       }
+      targets.addAll(buildInfo.getAggFunctionTargets());
+
       eachGroupbyNode.setTargets(targets);
       eachGroupbyNode.setAggFunctions(groupbyAggFunctions.toArray(new 
AggregationFunctionCallEval[groupbyAggFunctions.size()]));
       eachGroupbyNode.setDistinct(true);
@@ -437,15 +429,11 @@ public class DistinctGroupbyBuilder {
       // finally this aggregation output tuple's order is GROUP_BY_COL1, COL2, 
.... + AGG_VALUE, SUM_VALUE, ...
       GroupbyNode otherGroupbyNode = new 
GroupbyNode(context.getPlan().getLogicalPlan().newPID());
 
-      Target[] targets = new Target[originalGroupingColumns.size() + 
otherAggregationFunctionTargets.size()];
-      int targetIdx = 0;
+      List<Target> targets = new ArrayList<>();
       for (Column column : originalGroupingColumns) {
-        Target target = new Target(new FieldEval(column));
-        targets[targetIdx++] = target;
-      }
-      for (Target eachTarget : otherAggregationFunctionTargets) {
-        targets[targetIdx++] = eachTarget;
+        targets.add(new Target(new FieldEval(column)));
       }
+      targets.addAll(otherAggregationFunctionTargets);
 
       otherGroupbyNode.setTargets(targets);
       otherGroupbyNode.setGroupingColumns(originalGroupingColumns.toArray(new 
Column[originalGroupingColumns.size()]));
@@ -530,14 +518,14 @@ public class DistinctGroupbyBuilder {
           Target target = new Target(new FieldEval(column));
           firstGroupbyTargets.add(target);
         }
-        firstStageGroupbyNode.setTargets(firstGroupbyTargets.toArray(new 
Target[firstGroupbyTargets.size()]));
+        firstStageGroupbyNode.setTargets(firstGroupbyTargets);
 
         // SecondStage:
         //   Set grouping column with origin groupby's columns
         //   Remove distinct group column from targets
         
secondStageGroupbyNode.setGroupingColumns(originGroupColumns.toArray(new 
Column[originGroupColumns.size()]));
 
-        Target[] oldTargets = secondStageGroupbyNode.getTargets();
+        List<Target> oldTargets = secondStageGroupbyNode.getTargets();
         List<Target> secondGroupbyTargets = new ArrayList<>();
         LinkedHashSet<Column> distinctColumns = 
EvalTreeUtil.findUniqueColumns(secondStageGroupbyNode.getAggFunctions()[0]);
         List<Column> uniqueDistinctColumn = new ArrayList<>();
@@ -548,7 +536,7 @@ public class DistinctGroupbyBuilder {
           }
         }
         for (int i = 0; i < originGroupColumns.size(); i++) {
-          secondGroupbyTargets.add(oldTargets[i]);
+          secondGroupbyTargets.add(oldTargets.get(i));
           if (grpIdx > 0) {
             columnIdIndex++;
           }
@@ -557,7 +545,7 @@ public class DistinctGroupbyBuilder {
         for (int aggFuncIdx = 0; aggFuncIdx < 
secondStageGroupbyNode.getAggFunctions().length; aggFuncIdx++) {
           secondStageGroupbyNode.getAggFunctions()[aggFuncIdx].setLastPhase();
           int targetIdx = originGroupColumns.size() + 
uniqueDistinctColumn.size() + aggFuncIdx;
-          Target aggFuncTarget = oldTargets[targetIdx];
+          Target aggFuncTarget = oldTargets.get(targetIdx);
           secondGroupbyTargets.add(aggFuncTarget);
           Column column = aggFuncTarget.getNamedColumn();
           if (column.hasQualifier()) {
@@ -567,7 +555,7 @@ public class DistinctGroupbyBuilder {
           }
           columnIdIndex++;
         }
-        secondStageGroupbyNode.setTargets(secondGroupbyTargets.toArray(new 
Target[secondGroupbyTargets.size()]));
+        secondStageGroupbyNode.setTargets(secondGroupbyTargets);
       } else {
         // FirstStage: Change target of aggFunction to function name expr
         List<Target> firstGroupbyTargets = new ArrayList<>();
@@ -587,7 +575,7 @@ public class DistinctGroupbyBuilder {
           secondStageAggFunction.setArgs(new EvalNode[] {firstEval});
           secondStageAggFunction.setLastPhase();
 
-          Target secondTarget = 
secondStageGroupbyNode.getTargets()[secondStageGroupbyNode.getGroupingColumns().length
 + aggFuncIdx];
+          Target secondTarget = 
secondStageGroupbyNode.getTargets().get(secondStageGroupbyNode.getGroupingColumns().length
 + aggFuncIdx);
           Column column = secondTarget.getNamedColumn();
           if (column.hasQualifier()) {
             
secondStageColumnIds[originOutputSchema.getColumnId(column.getQualifiedName())] 
= columnIdIndex;
@@ -597,7 +585,7 @@ public class DistinctGroupbyBuilder {
           columnIdIndex++;
           aggFuncIdx++;
         }
-        firstStageGroupbyNode.setTargets(firstGroupbyTargets.toArray(new 
Target[firstGroupbyTargets.size()]));
+        firstStageGroupbyNode.setTargets(firstGroupbyTargets);
         
secondStageGroupbyNode.setInSchema(firstStageGroupbyNode.getOutSchema());
       }
       grpIdx++;
@@ -612,12 +600,9 @@ public class DistinctGroupbyBuilder {
       lastSecondStageGroupbyNode = 
secondStageGroupbyNodes.get(secondStageGroupbyNodes.size() - 2);
       secondStageGroupbyNodes.remove(secondStageGroupbyNodes.size() - 1);
 
-      Target[] targets =
-          new Target[lastSecondStageGroupbyNode.getTargets().length + 
otherGroupbyNode.getTargets().length];
-      System.arraycopy(lastSecondStageGroupbyNode.getTargets(), 0,
-          targets, 0, lastSecondStageGroupbyNode.getTargets().length);
-      System.arraycopy(otherGroupbyNode.getTargets(), 0, targets,
-          lastSecondStageGroupbyNode.getTargets().length, 
otherGroupbyNode.getTargets().length);
+      List<Target> targets = new ArrayList<>();
+      targets.addAll(lastSecondStageGroupbyNode.getTargets());
+      targets.addAll(otherGroupbyNode.getTargets());
 
       lastSecondStageGroupbyNode.setTargets(targets);
 
@@ -648,15 +633,15 @@ public class DistinctGroupbyBuilder {
       } else {
         //add aggr function target
         columnIdIndex += firstStageGroupbyNode.getGroupingColumns().length;
-        Target[] baseGroupbyTargets = firstStageGroupbyNode.getTargets();
+        List<Target> baseGroupbyTargets = firstStageGroupbyNode.getTargets();
         for (int i = firstStageGroupbyNode.getGroupingColumns().length;
-             i < baseGroupbyTargets.length; i++) {
-          firstTargets.add(baseGroupbyTargets[i]);
+             i < baseGroupbyTargets.size(); i++) {
+          firstTargets.add(baseGroupbyTargets.get(i));
           firstStageColumnIds.add(columnIdIndex++);
         }
       }
     }
-    firstStageDistinctNode.setTargets(firstTargets.toArray(new 
Target[firstTargets.size()]));
+    firstStageDistinctNode.setTargets(firstTargets);
     
firstStageDistinctNode.setResultColumnIds(TUtil.toArray(firstStageColumnIds));
 
     //Set SecondStage ColumnId and Input schema

http://git-wip-us.apache.org/repos/asf/tajo/blob/a2a5c14e/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/BSTIndexScanExec.java
----------------------------------------------------------------------
diff --git 
a/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/BSTIndexScanExec.java
 
b/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/BSTIndexScanExec.java
index 2014274..ee3762f 100644
--- 
a/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/BSTIndexScanExec.java
+++ 
b/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/BSTIndexScanExec.java
@@ -41,6 +41,7 @@ import org.apache.tajo.worker.TaskAttemptContext;
 import java.io.IOException;
 import java.net.URI;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 
 public class BSTIndexScanExec extends ScanExec {
@@ -92,7 +93,7 @@ public class BSTIndexScanExec extends ScanExec {
     this.reader.open();
   }
 
-  private static Schema mergeSubSchemas(Schema originalSchema, Schema 
subSchema, Target[] targets, EvalNode qual) {
+  private static Schema mergeSubSchemas(Schema originalSchema, Schema 
subSchema, List<Target> targets, EvalNode qual) {
     Schema mergedSchema = new Schema();
     Set<Column> qualAndTargets = new HashSet<>();
     qualAndTargets.addAll(EvalTreeUtil.findUniqueColumns(qual));

http://git-wip-us.apache.org/repos/asf/tajo/blob/a2a5c14e/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/EvalExprExec.java
----------------------------------------------------------------------
diff --git 
a/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/EvalExprExec.java
 
b/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/EvalExprExec.java
index 4581b4a..72ab608 100644
--- 
a/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/EvalExprExec.java
+++ 
b/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/EvalExprExec.java
@@ -25,6 +25,7 @@ import org.apache.tajo.storage.VTuple;
 import org.apache.tajo.worker.TaskAttemptContext;
 
 import java.io.IOException;
+import java.util.List;
 
 public class EvalExprExec extends PhysicalExec {
   private final EvalExprNode plan;
@@ -48,10 +49,10 @@ public class EvalExprExec extends PhysicalExec {
   @Override
   public Tuple next() throws IOException {
     if (!executedOnce) {
-      Target [] targets = plan.getTargets();
-      Tuple t = new VTuple(targets.length);
-      for (int i = 0; i < targets.length; i++) {
-        t.put(i, targets[i].getEvalTree().eval(null));
+      List<Target> targets = plan.getTargets();
+      Tuple t = new VTuple(targets.size());
+      for (int i = 0; i < targets.size(); i++) {
+        t.put(i, targets.get(i).getEvalTree().eval(null));
       }
 
       executedOnce = true;

http://git-wip-us.apache.org/repos/asf/tajo/blob/a2a5c14e/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/SeqScanExec.java
----------------------------------------------------------------------
diff --git 
a/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/SeqScanExec.java
 
b/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/SeqScanExec.java
index 2572e1d..3ddad1e 100644
--- 
a/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/SeqScanExec.java
+++ 
b/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/SeqScanExec.java
@@ -116,8 +116,8 @@ public class SeqScanExec extends ScanExec {
       }
       ConstEval constExpr = new ConstEval(datum);
 
-      for (int i = 0; i < plan.getTargets().length; i++) {
-        Target target = plan.getTargets()[i];
+      for (int i = 0; i < plan.getTargets().size(); i++) {
+        Target target = plan.getTargets().get(i);
 
         if (target.getEvalTree().equals(targetExpr)) {
           if (!target.hasAlias()) {
@@ -211,7 +211,7 @@ public class SeqScanExec extends ScanExec {
   }
 
   protected void initializeProjector(Schema actualInSchema){
-    Target[] realTargets;
+    List<Target> realTargets;
     if (plan.getTargets() == null) {
       realTargets = PlannerUtil.schemaToTargets(outSchema);
     } else {
@@ -219,10 +219,10 @@ public class SeqScanExec extends ScanExec {
     }
 
     //if all column is selected and there is no have expression, projection 
can be skipped
-    if (realTargets.length == inSchema.size()) {
+    if (realTargets.size() == inSchema.size()) {
       for (int i = 0; i < inSchema.size(); i++) {
-        if (realTargets[i].getEvalTree() instanceof FieldEval) {
-          FieldEval f = realTargets[i].getEvalTree();
+        if (realTargets.get(i).getEvalTree() instanceof FieldEval) {
+          FieldEval f = realTargets.get(i).getEvalTree();
           if(!f.getColumnRef().equals(inSchema.getColumn(i))) {
             needProjection = true;
             break;

http://git-wip-us.apache.org/repos/asf/tajo/blob/a2a5c14e/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/WindowAggExec.java
----------------------------------------------------------------------
diff --git 
a/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/WindowAggExec.java
 
b/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/WindowAggExec.java
index c09e85e..ab13b59 100644
--- 
a/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/WindowAggExec.java
+++ 
b/tajo-core/src/main/java/org/apache/tajo/engine/planner/physical/WindowAggExec.java
@@ -172,10 +172,10 @@ public class WindowAggExec extends UnaryPhysicalExec {
     }
 
     evaluatedTuple = new VTuple(schemaForOrderBy.size());
-    nonFunctionColumnNum = plan.getTargets().length - functionNum;
+    nonFunctionColumnNum = plan.getTargets().size() - functionNum;
     nonFunctionColumns = new int[nonFunctionColumnNum];
-    for (int idx = 0; idx < plan.getTargets().length - functionNum; idx++) {
-      nonFunctionColumns[idx] = 
inSchema.getColumnId(plan.getTargets()[idx].getCanonicalName());
+    for (int idx = 0; idx < plan.getTargets().size() - functionNum; idx++) {
+      nonFunctionColumns[idx] = 
inSchema.getColumnId(plan.getTargets().get(idx).getCanonicalName());
     }
 
     outputColumnNum = nonFunctionColumnNum + functionNum;

http://git-wip-us.apache.org/repos/asf/tajo/blob/a2a5c14e/tajo-core/src/main/java/org/apache/tajo/master/exec/ExplainPlanPreprocessorForTest.java
----------------------------------------------------------------------
diff --git 
a/tajo-core/src/main/java/org/apache/tajo/master/exec/ExplainPlanPreprocessorForTest.java
 
b/tajo-core/src/main/java/org/apache/tajo/master/exec/ExplainPlanPreprocessorForTest.java
index b747849..2740728 100644
--- 
a/tajo-core/src/main/java/org/apache/tajo/master/exec/ExplainPlanPreprocessorForTest.java
+++ 
b/tajo-core/src/main/java/org/apache/tajo/master/exec/ExplainPlanPreprocessorForTest.java
@@ -32,6 +32,8 @@ import org.apache.tajo.plan.visitor.BasicLogicalPlanVisitor;
 import java.util.Arrays;
 import java.util.Comparator;
 import java.util.Stack;
+import java.util.List;
+import java.util.Collections;
 
 /**
  * Tajo's logical planner can generate different shapes of logical plans for 
the same query,
@@ -169,8 +171,8 @@ public class ExplainPlanPreprocessorForTest {
       return AlgebraicUtil.createSingletonExprFromCNF(cnf);
     }
 
-    private Target[] sortTargets(Target[] targets) {
-      Arrays.sort(targets, targetComparator);
+    private List<Target> sortTargets(List<Target> targets) {
+      Collections.sort(targets, targetComparator);
       return targets;
     }
   }

http://git-wip-us.apache.org/repos/asf/tajo/blob/a2a5c14e/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 e260c00..9a35ee6 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
@@ -319,16 +319,16 @@ public class QueryExecutor {
     LogicalRootNode rootNode = plan.getRootBlock().getRoot();
 
     EvalContext evalContext = new EvalContext();
-    Target[] targets = plan.getRootBlock().getRawTargets();
+    List<Target> targets = plan.getRootBlock().getRawTargets();
     if (targets == null) {
       throw new TajoInternalError("no targets");
     }
     try {
       // start script executor
       startScriptExecutors(queryContext, evalContext, targets);
-      final VTuple outTuple = new VTuple(targets.length);
-      for (int i = 0; i < targets.length; i++) {
-        EvalNode eval = targets[i].getEvalTree();
+      final VTuple outTuple = new VTuple(targets.size());
+      for (int i = 0; i < targets.size(); i++) {
+        EvalNode eval = targets.get(i).getEvalTree();
         eval.bind(evalContext, null);
         outTuple.put(i, eval.eval(null));
       }
@@ -371,10 +371,10 @@ public class QueryExecutor {
     }
   }
 
-  public static void startScriptExecutors(QueryContext queryContext, 
EvalContext evalContext, Target[] targets)
+  public static void startScriptExecutors(QueryContext queryContext, 
EvalContext evalContext, List<Target> targets)
       throws IOException {
-    for (int i = 0; i < targets.length; i++) {
-      EvalNode eval = targets[i].getEvalTree();
+    for (int i = 0; i < targets.size(); i++) {
+      EvalNode eval = targets.get(i).getEvalTree();
       if (eval instanceof GeneralFunctionEval) {
         GeneralFunctionEval functionEval = (GeneralFunctionEval) eval;
         if (functionEval.getFuncDesc().getInvocation().hasPython()) {

http://git-wip-us.apache.org/repos/asf/tajo/blob/a2a5c14e/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalOptimizer.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalOptimizer.java 
b/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalOptimizer.java
index 117de39..404e971 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalOptimizer.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalOptimizer.java
@@ -124,7 +124,7 @@ public class LogicalOptimizer {
       if (targets.size() == 0) {
         
newJoinNode.setTargets(PlannerUtil.schemaToTargets(old.getOutSchema()));
       } else {
-        newJoinNode.setTargets(targets.toArray(new Target[targets.size()]));
+        newJoinNode.setTargets(new ArrayList<>(targets));
       }
       PlannerUtil.replaceNode(plan, block.getRoot(), old, newNode);
       // End of replacement logic

http://git-wip-us.apache.org/repos/asf/tajo/blob/a2a5c14e/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlan.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlan.java 
b/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlan.java
index 87426b1..8610194 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlan.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlan.java
@@ -456,7 +456,7 @@ public class LogicalPlan {
     /** It contains a planning log for this block */
     private final List<String> planingHistory = Lists.newArrayList();
     /** It is for debugging or unit tests */
-    private Target[] rawTargets;
+    private List<Target> rawTargets;
 
     public QueryBlock(String blockName) {
       this.blockName = blockName;
@@ -487,11 +487,11 @@ public class LogicalPlan {
       return rootType;
     }
 
-    public Target [] getRawTargets() {
+    public List<Target> getRawTargets() {
       return rawTargets;
     }
 
-    public void setRawTargets(Target[] rawTargets) {
+    public void setRawTargets(List<Target> rawTargets) {
       this.rawTargets = rawTargets;
     }
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/a2a5c14e/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 78fa737..4f4d13e 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
@@ -274,7 +274,7 @@ public class LogicalPlanner extends 
BaseAlgebraVisitor<LogicalPlanner.PlanContex
     ////////////////////////////////////////////////////////
 
     ProjectionNode projectionNode;
-    Target[] targets;
+    List<Target> targets;
     targets = buildTargets(context, referenceNames);
 
     // Set ProjectionNode
@@ -302,18 +302,18 @@ public class LogicalPlanner extends 
BaseAlgebraVisitor<LogicalPlanner.PlanContex
     return projectionNode;
   }
 
-  private void setRawTargets(PlanContext context, Target[] targets, String[] 
referenceNames,
+  private void setRawTargets(PlanContext context, List<Target> targets, 
String[] referenceNames,
                              Projection projection) throws TajoException {
     LogicalPlan plan = context.plan;
     QueryBlock block = context.queryBlock;
 
     // It's for debugging or unit tests.
-    Target [] rawTargets = new Target[projection.getNamedExprs().length];
+    List<Target> rawTargets = new ArrayList<>();
     for (int i = 0; i < projection.getNamedExprs().length; i++) {
       NamedExpr namedExpr = projection.getNamedExprs()[i];
       EvalNode evalNode = exprAnnotator.createEvalNode(context, 
namedExpr.getExpr(),
           NameResolvingMode.RELS_AND_SUBEXPRS);
-      rawTargets[i] = new Target(evalNode, referenceNames[i]);
+      rawTargets.add(new Target(evalNode, referenceNames[i]));
     }
     // it's for debugging or unit testing
     block.setRawTargets(rawTargets);
@@ -465,15 +465,15 @@ public class LogicalPlanner extends 
BaseAlgebraVisitor<LogicalPlanner.PlanContex
     QueryBlock block = context.queryBlock;
 
     int finalTargetNum = projection.getNamedExprs().length;
-    Target [] targets = new Target[finalTargetNum];
+    List<Target> targets = new ArrayList<>();
 
-    for (int i = 0; i < targets.length; i++) {
+    for (int i = 0; i < finalTargetNum; i++) {
       NamedExpr namedExpr = projection.getNamedExprs()[i];
       EvalNode evalNode = exprAnnotator.createEvalNode(context, 
namedExpr.getExpr(), NameResolvingMode.RELS_ONLY);
       if (namedExpr.hasAlias()) {
-        targets[i] = new Target(evalNode, namedExpr.getAlias());
+        targets.add(new Target(evalNode, namedExpr.getAlias()));
       } else {
-        targets[i] = new Target(evalNode, 
context.plan.generateUniqueColumnName(namedExpr.getExpr()));
+        targets.add(new Target(evalNode, 
context.plan.generateUniqueColumnName(namedExpr.getExpr())));
       }
     }
     EvalExprNode evalExprNode = context.queryBlock.getNodeFromExpr(projection);
@@ -484,24 +484,24 @@ public class LogicalPlanner extends 
BaseAlgebraVisitor<LogicalPlanner.PlanContex
     return evalExprNode;
   }
 
-  private Target [] buildTargets(PlanContext context, String[] referenceNames)
+  private List<Target> buildTargets(PlanContext context, String[] 
referenceNames)
       throws TajoException {
     QueryBlock block = context.queryBlock;
 
-    Target [] targets = new Target[referenceNames.length];
+    List<Target> targets = new ArrayList<>();
 
     for (int i = 0; i < referenceNames.length; i++) {
       String refName = referenceNames[i];
       if (block.isConstReference(refName)) {
-        targets[i] = new Target(block.getConstByReference(refName), refName);
+        targets.add(new Target(block.getConstByReference(refName), refName));
       } else if (block.namedExprsMgr.isEvaluated(refName)) {
-        targets[i] = block.namedExprsMgr.getTarget(refName);
+        targets.add(block.namedExprsMgr.getTarget(refName));
       } else {
         NamedExpr namedExpr = block.namedExprsMgr.getNamedExpr(refName);
         EvalNode evalNode = exprAnnotator.createEvalNode(context, 
namedExpr.getExpr(),
             NameResolvingMode.RELS_AND_SUBEXPRS);
         block.namedExprsMgr.markAsEvaluated(refName, evalNode);
-        targets[i] = new Target(evalNode, refName);
+        targets.add(new Target(evalNode, refName));
       }
     }
     return targets;
@@ -523,8 +523,8 @@ public class LogicalPlanner extends 
BaseAlgebraVisitor<LogicalPlanner.PlanContex
         int groupingKeyNum = groupbyNode.getGroupingColumns().length;
 
         for (int i = 0; i < groupingKeyNum; i++) {
-          Target target = groupbyNode.getTargets()[i];
-          if (groupbyNode.getTargets()[i].getEvalTree().getType() == 
EvalType.FIELD) {
+          Target target = groupbyNode.getTargets().get(i);
+          if (groupbyNode.getTargets().get(i).getEvalTree().getType() == 
EvalType.FIELD) {
             FieldEval grpKeyEvalNode = target.getEvalTree();
             if 
(!groupbyNode.getInSchema().contains(grpKeyEvalNode.getColumnRef())) {
               throwCannotEvaluateException(projectable, 
grpKeyEvalNode.getName());
@@ -554,8 +554,8 @@ public class LogicalPlanner extends 
BaseAlgebraVisitor<LogicalPlanner.PlanContex
       }
 
       // verify targets except for function slots
-      for (int i = 0; i < windowAggNode.getTargets().length - 
windowAggNode.getWindowFunctions().length; i++) {
-        Target target = windowAggNode.getTargets()[i];
+      for (int i = 0; i < windowAggNode.getTargets().size() - 
windowAggNode.getWindowFunctions().length; i++) {
+        Target target = windowAggNode.getTargets().get(i);
         Set<Column> columns = 
EvalTreeUtil.findUniqueColumns(target.getEvalTree());
         for (Column c : columns) {
           if (!windowAggNode.getInSchema().contains(c)) {
@@ -717,7 +717,7 @@ public class LogicalPlanner extends 
BaseAlgebraVisitor<LogicalPlanner.PlanContex
       }
     }
 
-    Target [] targets = new Target[referenceNames.length];
+    List<Target> targets = new ArrayList<>();
     List<Integer> windowFuncIndices = Lists.newArrayList();
     Projection projection = (Projection) stack.peek();
     int windowFuncIdx = 0;
@@ -729,18 +729,17 @@ public class LogicalPlanner extends 
BaseAlgebraVisitor<LogicalPlanner.PlanContex
     }
     windowAggNode.setWindowFunctions(winFuncs.toArray(new 
WindowFunctionEval[winFuncs.size()]));
 
-    int targetIdx = 0;
     for (int i = 0; i < referenceNames.length ; i++) {
       if (!windowFuncIndices.contains(i)) {
         if (block.isConstReference(referenceNames[i])) {
-          targets[targetIdx++] = new 
Target(block.getConstByReference(referenceNames[i]), referenceNames[i]);
+          targets.add(new Target(block.getConstByReference(referenceNames[i]), 
referenceNames[i]));
         } else {
-          targets[targetIdx++] = 
block.namedExprsMgr.getTarget(referenceNames[i]);
+          targets.add(block.namedExprsMgr.getTarget(referenceNames[i]));
         }
       }
     }
     for (int i = 0; i < winFuncRefs.size(); i++) {
-      targets[targetIdx++] = block.namedExprsMgr.getTarget(winFuncRefs.get(i));
+      targets.add(block.namedExprsMgr.getTarget(winFuncRefs.get(i)));
     }
     windowAggNode.setTargets(targets);
     verifyProjectedFields(block, windowAggNode);
@@ -806,7 +805,7 @@ public class LogicalPlanner extends 
BaseAlgebraVisitor<LogicalPlanner.PlanContex
 
     groupbyNode.setDistinct(includeDistinctFunction);
     groupbyNode.setAggFunctions(aggEvals.toArray(new 
AggregationFunctionCallEval[aggEvals.size()]));
-    Target [] targets = ProjectionPushDownRule.buildGroupByTarget(groupbyNode, 
null,
+    List<Target> targets = 
ProjectionPushDownRule.buildGroupByTarget(groupbyNode, null,
         aggEvalNames.toArray(new String[aggEvalNames.size()]));
     groupbyNode.setTargets(targets);
 
@@ -1052,7 +1051,7 @@ public class LogicalPlanner extends 
BaseAlgebraVisitor<LogicalPlanner.PlanContex
     groupingNode.setDistinct(includeDistinctFunction);
     groupingNode.setAggFunctions(aggEvalNodes.toArray(new 
AggregationFunctionCallEval[aggEvalNodes.size()]));
 
-    Target [] targets = new Target[effectiveGroupingKeyNum + 
aggEvalNames.size()];
+    List<Target> targets = new ArrayList<>();
 
     // In target, grouping columns will be followed by aggregation evals.
     //
@@ -1062,12 +1061,11 @@ public class LogicalPlanner extends 
BaseAlgebraVisitor<LogicalPlanner.PlanContex
 
     // Build grouping keys
     for (int i = 0; i < effectiveGroupingKeyNum; i++) {
-      Target target = 
block.namedExprsMgr.getTarget(groupingNode.getGroupingColumns()[i].getQualifiedName());
-      targets[i] = target;
+      
targets.add(block.namedExprsMgr.getTarget(groupingNode.getGroupingColumns()[i].getQualifiedName()));
     }
 
-    for (int i = 0, targetIdx = effectiveGroupingKeyNum; i < 
aggEvalNodes.size(); i++, targetIdx++) {
-      targets[targetIdx] = block.namedExprsMgr.getTarget(aggEvalNames.get(i));
+    for (int i = 0; i < aggEvalNodes.size(); i++) {
+      targets.add(block.namedExprsMgr.getTarget(aggEvalNames.get(i)));
     }
 
     groupingNode.setTargets(targets);
@@ -1198,7 +1196,7 @@ public class LogicalPlanner extends 
BaseAlgebraVisitor<LogicalPlanner.PlanContex
     for (String newAddedExpr : newlyEvaluatedExprs) {
       targets.add(block.namedExprsMgr.getTarget(newAddedExpr, true));
     }
-    joinNode.setTargets(targets.toArray(new Target[targets.size()]));
+    joinNode.setTargets(targets);
 
     // Determine join conditions
     if (join.isNatural()) { // if natural join, it should have the equi-join 
conditions by common column names
@@ -1305,7 +1303,7 @@ public class LogicalPlanner extends 
BaseAlgebraVisitor<LogicalPlanner.PlanContex
     for (String newAddedExpr : newlyEvaluatedExprs) {
       targets.add(block.namedExprsMgr.getTarget(newAddedExpr, true));
     }
-    join.setTargets(targets.toArray(new Target[targets.size()]));
+    join.setTargets(targets);
     return join;
   }
 
@@ -1366,7 +1364,7 @@ public class LogicalPlanner extends 
BaseAlgebraVisitor<LogicalPlanner.PlanContex
       targets.add(new Target(evalNode, reference));
     }
 
-    scanNode.setTargets(targets.toArray(new Target[targets.size()]));
+    scanNode.setTargets(new ArrayList<>(targets));
 
     verifyProjectedFields(block, scanNode);
     return scanNode;
@@ -1463,7 +1461,7 @@ public class LogicalPlanner extends 
BaseAlgebraVisitor<LogicalPlanner.PlanContex
       targets.add(block.namedExprsMgr.getTarget(newAddedExpr, true));
     }
 
-    subQueryNode.setTargets(targets.toArray(new Target[targets.size()]));
+    subQueryNode.setTargets(new ArrayList<>(targets));
   }
 
     
/*===============================================================================================
@@ -1512,7 +1510,7 @@ public class LogicalPlanner extends 
BaseAlgebraVisitor<LogicalPlanner.PlanContex
     currentBlock.addRelation(setOpTableSubQueryNode);
 
     Schema setOpSchema = setOpTableSubQueryNode.getOutSchema();
-    Target[] setOpTarget = setOpTableSubQueryNode.getTargets();
+    List<Target> setOpTarget = setOpTableSubQueryNode.getTargets();
 
     // make group by node whose grouping keys are all columns of set operation
     GroupbyNode setOpGroupbyNode = context.plan.createNode(GroupbyNode.class);
@@ -1606,7 +1604,7 @@ public class LogicalPlanner extends 
BaseAlgebraVisitor<LogicalPlanner.PlanContex
     // An union statement can be derived from two query blocks.
     // For one union statement between both relations, we can ensure that each 
corresponding data domain of both
     // relations are the same. However, if necessary, the schema of left query 
block will be used as a base schema.
-    Target [] leftStrippedTargets = PlannerUtil.stripTarget(
+    List<Target> leftStrippedTargets = PlannerUtil.stripTarget(
         PlannerUtil.schemaToTargets(leftBlock.getRoot().getOutSchema()));
 
     setOp.setInSchema(leftChild.getOutSchema());
@@ -1759,13 +1757,13 @@ public class LogicalPlanner extends 
BaseAlgebraVisitor<LogicalPlanner.PlanContex
           continue;
         }
 
-        if (idxInProjectionNode >= 0 && idxInProjectionNode < 
projectionNode.getTargets().length) {
-          targets.add(projectionNode.getTargets()[idxInProjectionNode]);
+        if (idxInProjectionNode >= 0 && idxInProjectionNode < 
projectionNode.getTargets().size()) {
+          targets.add(projectionNode.getTargets().get(idxInProjectionNode));
         } else {
           targets.add(new Target(new ConstEval(NullDatum.get()), 
column.getSimpleName()));
         }
       }
-      projectionNode.setTargets(targets.toArray(new Target[targets.size()]));
+      projectionNode.setTargets(targets);
 
       insertNode.setInSchema(projectionNode.getOutSchema());
       insertNode.setOutSchema(projectionNode.getOutSchema());

http://git-wip-us.apache.org/repos/asf/tajo/blob/a2a5c14e/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 02ec615..5169136 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
@@ -144,7 +144,7 @@ public class EvalTreeUtil {
     return finder.getColumnRefs();
   }
   
-  public static Schema getSchemaByTargets(Schema inputSchema, Target[] 
targets) {
+  public static Schema getSchemaByTargets(Schema inputSchema, List<Target> 
targets) {
     Schema schema = new Schema();
     for (Target target : targets) {
       schema.addColumn(

http://git-wip-us.apache.org/repos/asf/tajo/blob/a2a5c14e/tajo-plan/src/main/java/org/apache/tajo/plan/logical/DistinctGroupbyNode.java
----------------------------------------------------------------------
diff --git 
a/tajo-plan/src/main/java/org/apache/tajo/plan/logical/DistinctGroupbyNode.java 
b/tajo-plan/src/main/java/org/apache/tajo/plan/logical/DistinctGroupbyNode.java
index 1af05e7..a36f9a4 100644
--- 
a/tajo-plan/src/main/java/org/apache/tajo/plan/logical/DistinctGroupbyNode.java
+++ 
b/tajo-plan/src/main/java/org/apache/tajo/plan/logical/DistinctGroupbyNode.java
@@ -21,15 +21,16 @@ package org.apache.tajo.plan.logical;
 import com.google.gson.annotations.Expose;
 import org.apache.tajo.catalog.Column;
 import org.apache.tajo.plan.PlanString;
-import org.apache.tajo.plan.util.PlannerUtil;
 import org.apache.tajo.plan.Target;
 import org.apache.tajo.plan.expr.AggregationFunctionCallEval;
+import org.apache.tajo.plan.util.PlannerUtil;
 import org.apache.tajo.util.StringUtils;
 import org.apache.tajo.util.TUtil;
 
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Objects;
 
 public class DistinctGroupbyNode extends UnaryNode implements Projectable, 
Cloneable {
   @Expose
@@ -39,7 +40,7 @@ public class DistinctGroupbyNode extends UnaryNode implements 
Projectable, Clone
   private List<GroupbyNode> subGroupbyPlan;
 
   @Expose
-  private Target[] targets;
+  private List<Target> targets = null;
 
   @Expose
   private Column[] groupingColumns = PlannerUtil.EMPTY_COLUMNS;
@@ -56,21 +57,21 @@ public class DistinctGroupbyNode extends UnaryNode 
implements Projectable, Clone
 
   @Override
   public boolean hasTargets() {
-    return targets.length > 0;
+    return (targets != null && !targets.isEmpty());
   }
 
   @Override
-  public void setTargets(Target[] targets) {
+  public void setTargets(List<Target> targets) {
     this.targets = targets;
     setOutSchema(PlannerUtil.targetToSchema(targets));
   }
 
   @Override
-  public Target[] getTargets() {
+  public List<Target> getTargets() {
     if (hasTargets()) {
       return targets;
     } else {
-      return new Target[0];
+      return new ArrayList<>();
     }
   }
 
@@ -131,9 +132,9 @@ public class DistinctGroupbyNode extends UnaryNode 
implements Projectable, Clone
     }
 
     if (targets != null) {
-      cloneNode.targets = new Target[targets.length];
-      for (int i = 0; i < targets.length; i++) {
-        cloneNode.targets[i] = (Target) targets[i].clone();
+      cloneNode.targets = new ArrayList<>();
+      for (Target t : targets) {
+        cloneNode.targets.add((Target) t.clone());
       }
     }
 
@@ -169,7 +170,7 @@ public class DistinctGroupbyNode extends UnaryNode 
implements Projectable, Clone
     result = prime * result + Arrays.hashCode(groupingColumns);
     result = prime * result + Arrays.hashCode(resultColumnIds);
     result = prime * result + ((subGroupbyPlan == null) ? 0 : 
subGroupbyPlan.hashCode());
-    result = prime * result + Arrays.hashCode(targets);
+    result = prime * result + Objects.hashCode(targets);
     return result;
   }
 
@@ -223,9 +224,9 @@ public class DistinctGroupbyNode extends UnaryNode 
implements Projectable, Clone
     planStr.appendExplain("exprs: ").appendExplain(sb.toString());
 
     sb = new StringBuilder("target list: ");
-    for (int i = 0; i < targets.length; i++) {
-      sb.append(targets[i]);
-      if( i < targets.length - 1) {
+    for (int i = 0; i < targets.size(); i++) {
+      sb.append(targets.get(i));
+      if( i < targets.size() - 1) {
         sb.append(", ");
       }
     }

http://git-wip-us.apache.org/repos/asf/tajo/blob/a2a5c14e/tajo-plan/src/main/java/org/apache/tajo/plan/logical/EvalExprNode.java
----------------------------------------------------------------------
diff --git 
a/tajo-plan/src/main/java/org/apache/tajo/plan/logical/EvalExprNode.java 
b/tajo-plan/src/main/java/org/apache/tajo/plan/logical/EvalExprNode.java
index 0632f68..d796443 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/logical/EvalExprNode.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/logical/EvalExprNode.java
@@ -21,18 +21,18 @@
  */
 package org.apache.tajo.plan.logical;
 
-import java.util.Arrays;
-
 import com.google.gson.annotations.Expose;
-
 import org.apache.tajo.plan.PlanString;
-import org.apache.tajo.plan.util.PlannerUtil;
 import org.apache.tajo.plan.Target;
+import org.apache.tajo.plan.util.PlannerUtil;
 import org.apache.tajo.util.StringUtils;
 import org.apache.tajo.util.TUtil;
 
+import java.util.List;
+import java.util.Objects;
+
 public class EvalExprNode extends LogicalNode implements Projectable {
-  @Expose private Target[] exprs;
+  @Expose private List<Target> exprs = null;
 
   public EvalExprNode(int pid) {
     super(pid, NodeType.EXPRS);
@@ -54,17 +54,17 @@ public class EvalExprNode extends LogicalNode implements 
Projectable {
   }
 
   @Override
-  public void setTargets(Target[] targets) {
+  public void setTargets(List<Target> targets) {
     this.exprs = targets;
     this.setOutSchema(PlannerUtil.targetToSchema(targets));
   }
 
   @Override
-  public Target[] getTargets() {
+  public List<Target> getTargets() {
     return exprs;
   }
 
-  public Target[] getExprs() {
+  public List<Target> getExprs() {
     return this.exprs;
   }
   
@@ -77,7 +77,7 @@ public class EvalExprNode extends LogicalNode implements 
Projectable {
   public int hashCode() {
     final int prime = 31;
     int result = 1;
-    result = prime * result + Arrays.hashCode(exprs);
+    result = prime * result + Objects.hashCode(exprs);
     return result;
   }
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/a2a5c14e/tajo-plan/src/main/java/org/apache/tajo/plan/logical/GroupbyNode.java
----------------------------------------------------------------------
diff --git 
a/tajo-plan/src/main/java/org/apache/tajo/plan/logical/GroupbyNode.java 
b/tajo-plan/src/main/java/org/apache/tajo/plan/logical/GroupbyNode.java
index 3966606..4845c1d 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/logical/GroupbyNode.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/logical/GroupbyNode.java
@@ -22,13 +22,16 @@ import com.google.common.base.Preconditions;
 import com.google.gson.annotations.Expose;
 import org.apache.tajo.catalog.Column;
 import org.apache.tajo.plan.PlanString;
-import org.apache.tajo.plan.util.PlannerUtil;
 import org.apache.tajo.plan.Target;
 import org.apache.tajo.plan.expr.AggregationFunctionCallEval;
+import org.apache.tajo.plan.util.PlannerUtil;
 import org.apache.tajo.util.StringUtils;
 import org.apache.tajo.util.TUtil;
 
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
 
 public class GroupbyNode extends UnaryNode implements Projectable, Cloneable {
   /** Grouping key sets */
@@ -39,7 +42,7 @@ public class GroupbyNode extends UnaryNode implements 
Projectable, Cloneable {
    * It's a list of targets. The grouping columns should be followed by 
aggregation functions.
    * aggrFunctions keep actual aggregation functions, but it only contains 
field references.
    * */
-  @Expose private Target [] targets;
+  @Expose private List<Target> targets = null;
   @Expose private boolean hasDistinct = false;
   /**
    * A flag to indicate if this groupby is for distinct block (i.e., SELECT 
DISTINCT x,y,z, ...)
@@ -105,13 +108,13 @@ public class GroupbyNode extends UnaryNode implements 
Projectable, Cloneable {
   }
 
   @Override
-  public void setTargets(Target[] targets) {
+  public void setTargets(List<Target> targets) {
     this.targets = targets;
     setOutSchema(PlannerUtil.targetToSchema(targets));
   }
 
   @Override
-  public Target[] getTargets() {
+  public List<Target> getTargets() {
     return this.targets;
   }
   
@@ -139,7 +142,7 @@ public class GroupbyNode extends UnaryNode implements 
Projectable, Cloneable {
     result = prime * result + Arrays.hashCode(aggrFunctions);
     result = prime * result + Arrays.hashCode(groupingKeys);
     result = prime * result + (hasDistinct ? 1231 : 1237);
-    result = prime * result + Arrays.hashCode(targets);
+    result = prime * result + Objects.hashCode(targets);
     return result;
   }
 
@@ -176,9 +179,9 @@ public class GroupbyNode extends UnaryNode implements 
Projectable, Cloneable {
     }
 
     if (targets != null) {
-      grp.targets = new Target[targets.length];
-      for (int i = 0; i < targets.length; i++) {
-        grp.targets[i] = (Target) targets[i].clone();
+      grp.targets = new ArrayList<>();
+      for (Target t : targets) {
+        grp.targets.add((Target) t.clone());
       }
     }
 
@@ -213,9 +216,9 @@ public class GroupbyNode extends UnaryNode implements 
Projectable, Cloneable {
 
     if (targets != null) {
       sb.append(", target list:{");
-      for (int i = 0; i < targets.length; i++) {
-        sb.append(targets[i]);
-        if (i < targets.length - 1) {
+      for (int i = 0; i < targets.size(); i++) {
+        sb.append(targets.get(i));
+        if (i < targets.size() - 1) {
           sb.append(", ");
         }
       }
@@ -261,9 +264,9 @@ public class GroupbyNode extends UnaryNode implements 
Projectable, Cloneable {
     }
 
     sb = new StringBuilder("target list: ");
-    for (int i = 0; i < targets.length; i++) {
-      sb.append(targets[i]);
-      if( i < targets.length - 1) {
+    for (int i = 0; i < targets.size(); i++) {
+      sb.append(targets.get(i));
+      if( i < targets.size() - 1) {
         sb.append(", ");
       }
     }
@@ -280,9 +283,8 @@ public class GroupbyNode extends UnaryNode implements 
Projectable, Cloneable {
    * If so, it returns TRUE. Otherwise, it returns FALSE.
    */
   public boolean isAggregationColumn(String simpleName) {
-    for (int i = groupingKeys.length; i < targets.length; i++) {
-      if (simpleName.equals(targets[i].getNamedColumn().getSimpleName()) ||
-          simpleName.equals(targets[i].getAlias())) {
+    for (Target t : targets) {
+      if (simpleName.equals(t.getNamedColumn().getSimpleName()) || 
simpleName.equals(t.getAlias())) {
         return true;
       }
     }

http://git-wip-us.apache.org/repos/asf/tajo/blob/a2a5c14e/tajo-plan/src/main/java/org/apache/tajo/plan/logical/JoinNode.java
----------------------------------------------------------------------
diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/logical/JoinNode.java 
b/tajo-plan/src/main/java/org/apache/tajo/plan/logical/JoinNode.java
index 8b843a9..4584140 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/logical/JoinNode.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/logical/JoinNode.java
@@ -29,11 +29,13 @@ import org.apache.tajo.plan.expr.EvalNode;
 import org.apache.tajo.plan.util.PlannerUtil;
 import org.apache.tajo.util.TUtil;
 
-import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
 
 public class JoinNode extends BinaryNode implements Projectable, Cloneable {
   @Expose private JoinSpec joinSpec = new JoinSpec();
-  @Expose private Target[] targets;
+  @Expose private List<Target> targets = null;
 
   public JoinNode(int pid) {
     super(pid, NodeType.JOIN);
@@ -79,12 +81,12 @@ public class JoinNode extends BinaryNode implements 
Projectable, Cloneable {
   }
 
   @Override
-  public Target[] getTargets() {
+  public List<Target> getTargets() {
     return this.targets;
   }
 
   @Override
-  public void setTargets(Target[] targets) {
+  public void setTargets(List<Target> targets) {
     this.targets = targets;
     this.setOutSchema(PlannerUtil.targetToSchema(targets));
   }
@@ -119,7 +121,7 @@ public class JoinNode extends BinaryNode implements 
Projectable, Cloneable {
     final int prime = 31;
     int result = 1;
     result = prime * result + joinSpec.hashCode();
-    result = prime * result + Arrays.hashCode(targets);
+    result = prime * result + Objects.hashCode(targets);
     return result;
   }
 
@@ -140,9 +142,9 @@ public class JoinNode extends BinaryNode implements 
Projectable, Cloneable {
     JoinNode join = (JoinNode) super.clone();
     join.joinSpec = (JoinSpec) this.joinSpec.clone();
     if (hasTargets()) {
-      join.targets = new Target[targets.length];
-      for (int i = 0; i < targets.length; i++) {
-        join.targets[i] = (Target) targets[i].clone();
+      join.targets = new ArrayList<>();
+      for (Target t : targets) {
+        join.targets.add((Target) t.clone());
       }
     }
     return join;

http://git-wip-us.apache.org/repos/asf/tajo/blob/a2a5c14e/tajo-plan/src/main/java/org/apache/tajo/plan/logical/PartitionedTableScanNode.java
----------------------------------------------------------------------
diff --git 
a/tajo-plan/src/main/java/org/apache/tajo/plan/logical/PartitionedTableScanNode.java
 
b/tajo-plan/src/main/java/org/apache/tajo/plan/logical/PartitionedTableScanNode.java
index a4bb94c..fdad342 100644
--- 
a/tajo-plan/src/main/java/org/apache/tajo/plan/logical/PartitionedTableScanNode.java
+++ 
b/tajo-plan/src/main/java/org/apache/tajo/plan/logical/PartitionedTableScanNode.java
@@ -27,6 +27,8 @@ import org.apache.tajo.plan.Target;
 import org.apache.tajo.plan.expr.EvalNode;
 import org.apache.tajo.util.TUtil;
 
+import java.util.ArrayList;
+
 public class PartitionedTableScanNode extends ScanNode {
   @Expose Path [] inputPaths;
 
@@ -72,44 +74,44 @@ public class PartitionedTableScanNode extends ScanNode {
     return Objects.hashCode(this.tableDesc, this.qual, this.targets);
   }
        
-       @Override
-       public boolean equals(Object obj) {
-         if (obj instanceof PartitionedTableScanNode) {
-           PartitionedTableScanNode other = (PartitionedTableScanNode) obj;
-           
-           boolean eq = super.equals(other); 
-           eq = eq && TUtil.checkEquals(this.tableDesc, other.tableDesc);
-           eq = eq && TUtil.checkEquals(this.qual, other.qual);
-           eq = eq && TUtil.checkEquals(this.targets, other.targets);
-      eq = eq && TUtil.checkEquals(this.inputPaths, other.inputPaths);
-           
-           return eq;
-         }       
-         
-         return false;
-       }       
-       
-       @Override
-       public Object clone() throws CloneNotSupportedException {
-         PartitionedTableScanNode unionScan = (PartitionedTableScanNode) 
super.clone();
-         
-         unionScan.tableDesc = (TableDesc) this.tableDesc.clone();
-         
-         if (hasQual()) {
-           unionScan.qual = (EvalNode) this.qual.clone();
-         }
-         
-         if (hasTargets()) {
-           unionScan.targets = new Target[targets.length];
-      for (int i = 0; i < targets.length; i++) {
-        unionScan.targets[i] = (Target) targets[i].clone();
+  @Override
+  public boolean equals(Object obj) {
+    if (obj instanceof PartitionedTableScanNode) {
+      PartitionedTableScanNode other = (PartitionedTableScanNode) obj;
+
+      boolean eq = super.equals(other);
+      eq = eq && TUtil.checkEquals(this.tableDesc, other.tableDesc);
+      eq = eq && TUtil.checkEquals(this.qual, other.qual);
+      eq = eq && TUtil.checkEquals(this.targets, other.targets);
+    eq = eq && TUtil.checkEquals(this.inputPaths, other.inputPaths);
+
+      return eq;
+    }
+
+    return false;
+  }
+
+  @Override
+  public Object clone() throws CloneNotSupportedException {
+    PartitionedTableScanNode unionScan = (PartitionedTableScanNode) 
super.clone();
+
+    unionScan.tableDesc = (TableDesc) this.tableDesc.clone();
+
+    if (hasQual()) {
+      unionScan.qual = (EvalNode) this.qual.clone();
+    }
+
+    if (hasTargets()) {
+      unionScan.targets = new ArrayList<>();
+      for (Target t : targets) {
+        unionScan.targets.add((Target) t.clone());
       }
-         }
+    }
 
     unionScan.inputPaths = inputPaths;
 
     return unionScan;
-       }
+  }
        
   @Override
   public void preOrder(LogicalNodeVisitor visitor) {

http://git-wip-us.apache.org/repos/asf/tajo/blob/a2a5c14e/tajo-plan/src/main/java/org/apache/tajo/plan/logical/Projectable.java
----------------------------------------------------------------------
diff --git 
a/tajo-plan/src/main/java/org/apache/tajo/plan/logical/Projectable.java 
b/tajo-plan/src/main/java/org/apache/tajo/plan/logical/Projectable.java
index 68d1861..858a585 100644
--- a/tajo-plan/src/main/java/org/apache/tajo/plan/logical/Projectable.java
+++ b/tajo-plan/src/main/java/org/apache/tajo/plan/logical/Projectable.java
@@ -21,6 +21,8 @@ package org.apache.tajo.plan.logical;
 import org.apache.tajo.catalog.Schema;
 import org.apache.tajo.plan.Target;
 
+import java.util.List;
+
 /**
  * Projectable is an interface for a LogicalNode which has a list of targets.
  * What a logical node has a list of targets means that the node evaluated a 
list of expressions.
@@ -49,14 +51,14 @@ public interface Projectable {
    *
    * @param targets The array of targets
    */
-  void setTargets(Target[] targets);
+  void setTargets(List<Target> targets);
 
   /**
    * Get a list of targets
    *
    * @return The array of targets
    */
-  Target [] getTargets();
+  List<Target> getTargets();
 
   /**
    * Get an input schema

Reply via email to