You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tajo.apache.org by hy...@apache.org on 2013/10/07 07:41:23 UTC

git commit: TAJO-226: Can't use group by column alias. (hyunsik)

Updated Branches:
  refs/heads/master 8b872bc17 -> e7f975710


TAJO-226: Can't use group by column alias. (hyunsik)


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

Branch: refs/heads/master
Commit: e7f975710f1abff8fd3ebf10322e6fcafac18e0e
Parents: 8b872bc
Author: Hyunsik Choi <hy...@apache.org>
Authored: Mon Oct 7 14:40:53 2013 +0900
Committer: Hyunsik Choi <hy...@apache.org>
Committed: Mon Oct 7 14:40:53 2013 +0900

----------------------------------------------------------------------
 CHANGES.txt                                     |  2 +
 .../apache/tajo/engine/planner/LogicalPlan.java | 23 +++++--
 .../tajo/engine/planner/LogicalPlanner.java     | 24 ++++----
 .../org/apache/tajo/engine/planner/Target.java  |  4 +-
 .../tajo/engine/planner/TargetListManager.java  | 63 +++++++++++++++++++-
 .../engine/planner/logical/GroupbyNode.java     |  5 +-
 .../planner/rewrite/ProjectionPushDownRule.java |  2 +-
 .../tajo/engine/query/TestGroupByQuery.java     | 38 ++++++++++++
 .../tajo/engine/query/TestSelectQuery.java      | 40 +++++++++++++
 .../apache/tajo/engine/query/TestSortQuery.java | 23 +++++++
 10 files changed, 201 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/e7f97571/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 2f16735..8625917 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -183,6 +183,8 @@ Release 0.2.0 - unreleased
 
   BUG FIXES
 
+    TAJO-226: Can't use group by column alias. (hyunsik)
+
     TAJO-203: Field delimiter does not work correctly. (jinho)
 
     TAJO-205: Repartitioner occasionally chooses a partition number as one.

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/e7f97571/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlan.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlan.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlan.java
index adb8d66..fb628d9 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlan.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlan.java
@@ -18,6 +18,8 @@
 
 package org.apache.tajo.engine.planner;
 
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
 import org.apache.tajo.algebra.*;
 import org.apache.tajo.annotation.NotThreadSafe;
 import org.apache.tajo.catalog.Column;
@@ -139,7 +141,7 @@ public class LogicalPlan {
    * It resolves a column.
    */
   public Column resolveColumn(QueryBlock block, LogicalNode currentNode, ColumnReferenceExpr columnRef)
-      throws VerifyException {
+      throws PlanningException {
 
     if (columnRef.hasQualifier()) { // if a column referenec is qualified
 
@@ -216,6 +218,16 @@ public class LogicalPlan {
     }
   }
 
+  /**
+   * replace the found column if the column is renamed to an alias name
+   */
+  public Column getColumnOrAliasedColumn(QueryBlock block, Column column) throws PlanningException {
+    if (block.targetListManager.isResolve(column)) {
+      column = block.targetListManager.getResolvedColumn(column);
+    }
+    return column;
+  }
+
   private static Column ensureUniqueColumn(List<Column> candidates)
       throws VerifyException {
     if (candidates.size() == 1) {
@@ -579,7 +591,7 @@ public class LogicalPlan {
     }
 
     public boolean isTargetResolved(int targetId) {
-      return targetListManager.isEvaluated(targetId);
+      return targetListManager.isResolved(targetId);
     }
 
     public void resolveAllTargetList() {
@@ -603,7 +615,9 @@ public class LogicalPlan {
     }
 
     public void fillTarget(int idx) throws PlanningException {
-      targetListManager.update(idx, planner.createTarget(LogicalPlan.this, this, getProjection().getTargets()[idx]));
+      Target target = planner.createTarget(LogicalPlan.this, this, getProjection().getTargets()[idx]);
+      // below code reaches only when target is created.
+      targetListManager.fill(idx, target);
     }
 
     public boolean checkIfTargetCanBeEvaluated(int targetId, LogicalNode node) {
@@ -712,7 +726,8 @@ public class LogicalPlan {
         } else if (node instanceof GroupbyNode) {
           // Set the current targets to the GroupByNode because the GroupByNode is the last projection operator.
           GroupbyNode groupbyNode = (GroupbyNode) node;
-          groupbyNode.setTargets(getCurrentTargets());
+          groupbyNode.setTargets(targetListManager.getUpdatedTarget(Sets.newHashSet(newEvaluatedTargetIds)));
+          //groupbyNode.setTargets(getCurrentTargets());
           boolean distinct = false;
           for (Target target : groupbyNode.getTargets()) {
             for (AggregationFunctionCallEval aggrFunc : EvalTreeUtil.findDistinctAggFunction(target.getEvalTree())) {

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/e7f97571/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanner.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanner.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanner.java
index 8906349..359dda3 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanner.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/LogicalPlanner.java
@@ -45,7 +45,6 @@ import org.apache.tajo.engine.query.exception.UndefinedFunctionException;
 import org.apache.tajo.engine.utils.SchemaUtil;
 import org.apache.tajo.exception.InternalException;
 
-import java.io.IOException;
 import java.util.List;
 import java.util.Stack;
 
@@ -118,7 +117,8 @@ public class LogicalPlanner extends BaseAlgebraVisitor<LogicalPlanner.PlanContex
   public LogicalNode postHook(PlanContext context, Stack<OpType> stack, Expr expr, LogicalNode current)
       throws PlanningException {
     // Post work
-    if (expr.getType() == OpType.RelationList && ((RelationList) expr).size() == 1) {
+    if ((expr.getType() == OpType.RelationList && ((RelationList) expr).size() == 1)
+        || expr.getType() == OpType.Having) {
       return current;
     }
 
@@ -454,7 +454,7 @@ public class LogicalPlanner extends BaseAlgebraVisitor<LogicalPlanner.PlanContex
       for (int i = 0; i < groupElements.length; i++) {
         annotatedElements[i] = new GroupElement(
             groupElements[i].getType(),
-            annotateGroupingColumn(plan, block.getName(), groupElements[i].getColumns(), null));
+            annotateGroupingColumn(plan, block, groupElements[i].getColumns(), null));
       }
       GroupbyNode groupingNode = new GroupbyNode(plan.newPID(), annotatedElements[0].getColumns());
       if (aggregation.hasHavingCondition()) {
@@ -472,7 +472,7 @@ public class LogicalPlanner extends BaseAlgebraVisitor<LogicalPlanner.PlanContex
       return groupingNode;
 
     } else if (groupElements[0].getType() == GroupType.Cube) { // for cube by
-      List<Column[]> cuboids  = generateCuboids(annotateGroupingColumn(plan, block.getName(),
+      List<Column[]> cuboids  = generateCuboids(annotateGroupingColumn(plan, block,
           groupElements[0].getColumns(), null));
       UnionNode topUnion = createGroupByUnion(plan, block, child, cuboids, 0);
       block.resolveGroupingRequired();
@@ -538,12 +538,14 @@ public class LogicalPlanner extends BaseAlgebraVisitor<LogicalPlanner.PlanContex
   /**
    * It transforms a list of column references into a list of annotated columns with considering aliased expressions.
    */
-  private Column[] annotateGroupingColumn(LogicalPlan plan, String blockName,
+  private Column[] annotateGroupingColumn(LogicalPlan plan, QueryBlock block,
                                            ColumnReferenceExpr[] columnRefs, LogicalNode child)
-      throws VerifyException {
+      throws PlanningException {
+
     Column[] columns = new Column[columnRefs.length];
     for (int i = 0; i < columnRefs.length; i++) {
-      columns[i] = plan.resolveColumn(plan.getBlock(blockName), null, columnRefs[i]);
+      columns[i] = plan.resolveColumn(block, null, columnRefs[i]);
+      columns[i] = plan.getColumnOrAliasedColumn(block, columns[i]);
     }
 
     return columns;
@@ -605,8 +607,8 @@ public class LogicalPlanner extends BaseAlgebraVisitor<LogicalPlanner.PlanContex
     Sort.SortSpec[] sortSpecs = sort.getSortSpecs();
     for (int i = 0; i < sort.getSortSpecs().length; i++) {
       column = plan.resolveColumn(block, null, sortSpecs[i].getKey());
-      annotatedSortSpecs[i] = new SortSpec(column, sortSpecs[i].isAscending(),
-          sortSpecs[i].isNullFirst());
+      column = plan.getColumnOrAliasedColumn(block, column);
+      annotatedSortSpecs[i] = new SortSpec(column, sortSpecs[i].isAscending(), sortSpecs[i].isNullFirst());
     }
     SortNode sortNode = new SortNode(context.plan.newPID(), annotatedSortSpecs);
 
@@ -663,7 +665,7 @@ public class LogicalPlanner extends BaseAlgebraVisitor<LogicalPlanner.PlanContex
       evalOnly.setOutSchema(getProjectedSchema(plan, evalOnly.getExprs()));
       block.setProjectionNode(evalOnly);
       for (int i = 0; i < evalOnly.getTargets().length; i++) {
-        block.targetListManager.update(i, evalOnly.getTargets()[i]);
+        block.targetListManager.fill(i, evalOnly.getTargets()[i]);
       }
       return evalOnly;
     }
@@ -1115,7 +1117,7 @@ public class LogicalPlanner extends BaseAlgebraVisitor<LogicalPlanner.PlanContex
   }
 
   private FieldEval createFieldEval(LogicalPlan plan, QueryBlock block,
-                                    ColumnReferenceExpr columnRef) throws VerifyException {
+                                    ColumnReferenceExpr columnRef) throws PlanningException {
     Column column = plan.resolveColumn(block, null, columnRef);
     return new FieldEval(column);
   }

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/e7f97571/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/Target.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/Target.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/Target.java
index 2f32372..a49451c 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/Target.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/Target.java
@@ -65,8 +65,8 @@ public class Target implements Cloneable, GsonObject {
     return column.getDataType();
   }
 
-  public EvalNode getEvalTree() {
-    return this.expr;
+  public <T extends EvalNode> T getEvalTree() {
+    return (T) this.expr;
   }
 
   public Column getColumnSchema() {

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/e7f97571/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/TargetListManager.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/TargetListManager.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/TargetListManager.java
index bc1ad61..4e1427e 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/TargetListManager.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/TargetListManager.java
@@ -18,14 +18,18 @@
 
 package org.apache.tajo.engine.planner;
 
+import com.google.common.collect.Maps;
 import org.apache.tajo.algebra.Projection;
 import org.apache.tajo.catalog.Column;
 import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.engine.eval.EvalNode;
 import org.apache.tajo.engine.eval.EvalTreeUtil;
 import org.apache.tajo.engine.eval.EvalType;
 import org.apache.tajo.engine.eval.FieldEval;
 
 import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
 
 /**
  * It manages a list of targets.
@@ -36,6 +40,7 @@ public class TargetListManager {
   private Projection projection;
   private Target[] targets;
   private Target[] unresolvedTargets;
+  private Map<Column, Integer> targetColumnToId = Maps.newHashMap();
 
   public TargetListManager(LogicalPlan plan, Projection projection) {
     this.plan = plan;
@@ -81,9 +86,18 @@ public class TargetListManager {
     return this.unresolvedTargets;
   }
 
-  public void update(int id, Target target) {
+  public void fill(int id, Target target) {
     this.targets[id] = target;
     this.unresolvedTargets[id] = target;
+
+    EvalNode evalNode = target.getEvalTree();
+    if (evalNode.getType() == EvalType.FIELD) {
+      if (target.hasAlias()) {
+        FieldEval fieldEval = (FieldEval) evalNode;
+        targetColumnToId.put(fieldEval.getColumnRef(), id);
+      }
+    }
+    targetColumnToId.put(target.getColumnSchema(), id);
   }
 
   public int size() {
@@ -100,10 +114,55 @@ public class TargetListManager {
     }
   }
 
-  public boolean isEvaluated(int id) {
+  public boolean isResolved(int id) {
     return resolvedFlags[id];
   }
 
+  /**
+   * It checks whether only column reference is resolve or not.
+   * Note that this method doesn't know if an expression is resolved.
+   *
+   * @param targetColumn A column to be checked
+   * @return True if a column reference belong to a target list and is already resolved. Otherwise, false.
+   */
+  public boolean isResolve(Column targetColumn) throws PlanningException {
+    Integer targetId = targetColumnToId.get(targetColumn);
+    if (targetId == null) {
+      return false;
+    }
+    return resolvedFlags[targetId];
+  }
+
+  public Column getResolvedColumn(Column targetColumn) throws PlanningException {
+    Integer targetId = targetColumnToId.get(targetColumn);
+    if (targetId == null) {
+      throw new PlanningException("Unknown target column: " + targetColumn);
+    }
+    return getResolvedTargetToColumn(targetId);
+  }
+
+  public Target [] getUpdatedTarget(Set<Integer> exclude) throws PlanningException {
+    Target [] updated = new Target[targets.length];
+
+    for (int i = 0; i < targets.length; i++) {
+      if (targets[i] == null) { // if it is not created
+        continue;
+      }
+
+      if (!exclude.contains(i) && resolvedFlags[i]) { // if this target was evaluated, it becomes a column target.
+        Column col = getResolvedTargetToColumn(i);
+        updated[i] = new Target(new FieldEval(col));
+      } else {
+        try {
+          updated[i] = (Target) targets[i].clone();
+        } catch (CloneNotSupportedException e) {
+          throw new PlanningException(e);
+        }
+      }
+    }
+    return updated;
+  }
+
   public Target [] getUpdatedTarget() throws PlanningException {
     Target [] updated = new Target[targets.length];
 

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/e7f97571/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/GroupbyNode.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/GroupbyNode.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/GroupbyNode.java
index 2e10353..f0afaa3 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/GroupbyNode.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/GroupbyNode.java
@@ -99,7 +99,7 @@ public class GroupbyNode extends UnaryNode implements Projectable, Cloneable {
   }
   
   public String toString() {
-    StringBuilder sb = new StringBuilder("\"GroupBy\": {\"fields\":[");
+    StringBuilder sb = new StringBuilder("\"GroupBy\": {\"grouping fields\":[");
     for (int i=0; i < columns.length; i++) {
       sb.append("\"").append(columns[i]).append("\"");
       if(i < columns.length - 1)
@@ -123,8 +123,7 @@ public class GroupbyNode extends UnaryNode implements Projectable, Cloneable {
     sb.append("\n  \"in schema\": ").append(getInSchema());
     sb.append("}");
     
-    return sb.toString() + "\n"
-        + getChild().toString();
+    return sb.toString() + "\n" + getChild().toString();
   }
   
   @Override

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/e7f97571/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/rewrite/ProjectionPushDownRule.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/rewrite/ProjectionPushDownRule.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/rewrite/ProjectionPushDownRule.java
index 6ab72cb..c5b7f7e 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/rewrite/ProjectionPushDownRule.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/rewrite/ProjectionPushDownRule.java
@@ -337,7 +337,7 @@ public class ProjectionPushDownRule extends BasicLogicalPlanVisitor<ProjectionPu
     for (int i = 0; i < targetListManager.size(); i++) {
       expr = targetListManager.getTarget(i).getEvalTree();
 
-      if (!targetListManager.isEvaluated(i) && PlannerUtil.canBeEvaluated(expr, node)) {
+      if (!targetListManager.isResolved(i) && PlannerUtil.canBeEvaluated(expr, node)) {
 
         if (node instanceof RelationNode) { // For ScanNode
 

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/e7f97571/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestGroupByQuery.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestGroupByQuery.java b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestGroupByQuery.java
index aacdb70..487d7af 100644
--- a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestGroupByQuery.java
+++ b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestGroupByQuery.java
@@ -76,6 +76,44 @@ public class TestGroupByQuery {
   }
 
   @Test
+  public final void testGroupBy3() throws Exception {
+    ResultSet res = tpch.execute(
+        "select l_orderkey as gkey from lineitem group by gkey order by gkey");
+    assertTrue(res.next());
+    assertEquals(1, res.getLong(1));
+    assertTrue(res.next());
+    assertEquals(2, res.getLong(1));
+    assertTrue(res.next());
+    assertEquals(3, res.getLong(1));
+    assertFalse(res.next());
+    res.close();
+  }
+
+  @Test
+  public final void testGroupBy4() throws Exception {
+    ResultSet res = tpch.execute(
+        "select l_orderkey as gkey, count(1) as unique_key from lineitem group by lineitem.l_orderkey");
+
+    long [][] expectedRows = new long[3][];
+    expectedRows[0] = new long [] {1,2};
+    expectedRows[1] = new long [] {2,1};
+    expectedRows[2] = new long [] {3,2};
+    Map<Long, long []> expected = Maps.newHashMap();
+    for (long [] expectedRow : expectedRows) {
+      expected.put(expectedRow[0], expectedRow);
+    }
+
+    for (int i = 0; i < expectedRows.length; i++) {
+      assertTrue(res.next());
+      long [] expectedRow = expected.get(res.getLong(1));
+      assertEquals(expectedRow[0], res.getLong(1));
+      assertEquals(expectedRow[1], res.getLong(2));
+    }
+    assertFalse(res.next());
+    res.close();
+  }
+
+  @Test
   public final void testCountDistinct() throws Exception {
     ResultSet res = tpch.execute(
         "select l_orderkey, max(l_orderkey) as maximum, count(distinct l_linenumber) as unique_key from lineitem " +

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/e7f97571/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestSelectQuery.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestSelectQuery.java b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestSelectQuery.java
index 270f915..0b3a8ce 100644
--- a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestSelectQuery.java
+++ b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestSelectQuery.java
@@ -110,6 +110,46 @@ public class TestSelectQuery {
   }
 
   @Test
+  public final void testWhereCond1() throws Exception {
+    ResultSet res = tpch.execute("select l_orderkey + l_partkey as plus from lineitem where plus = 4");
+    try {
+      assertTrue(res.next());
+      assertEquals(4, res.getInt(1));
+      assertFalse(res.next());
+    } finally {
+      res.close();
+    }
+  }
+
+  @Test
+  public final void testWhereCondWithAlias1() throws Exception {
+    ResultSet res = tpch.execute("select l_orderkey as orderkey, l_partkey from lineitem where orderkey = 1");
+    try {
+      assertTrue(res.next());
+      assertEquals(1, res.getInt(1));
+      assertTrue(res.next());
+      assertEquals(1, res.getInt(1));
+      assertFalse(res.next());
+    } finally {
+      res.close();
+    }
+  }
+
+  @Test
+  public final void testWhereCondWithAlias2() throws Exception {
+    ResultSet res = tpch.execute("select l_orderkey as orderkey from lineitem where l_orderkey = 1");
+    try {
+      assertTrue(res.next());
+      assertEquals(1, res.getInt(1));
+      assertTrue(res.next());
+      assertEquals(1, res.getInt(1));
+      assertFalse(res.next());
+    } finally {
+      res.close();
+    }
+  }
+
+  @Test
   public final void testSelectAsterik() throws Exception {
     ResultSet res = tpch.execute("select * from lineitem");
     try {

http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/e7f97571/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestSortQuery.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestSortQuery.java b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestSortQuery.java
index cb20a60..264afb7 100644
--- a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestSortQuery.java
+++ b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestSortQuery.java
@@ -94,6 +94,29 @@ public class TestSortQuery {
   }
 
   @Test
+  public final void testSortWithAliasButOriginalName() throws Exception {
+    ResultSet res = tpch.execute(
+        "select l_linenumber, l_orderkey as sortkey from lineitem order by l_orderkey");
+    try {
+      int cnt = 0;
+      Long prev = null;
+      while(res.next()) {
+        if (prev == null) {
+          prev = res.getLong(2);
+        } else {
+          assertTrue(prev <= res.getLong(2));
+          prev = res.getLong(2);
+        }
+        cnt++;
+      }
+
+      assertEquals(5, cnt);
+    } finally {
+      res.close();
+    }
+  }
+
+  @Test
   public final void testSortDesc() throws Exception {
     ResultSet res = tpch.execute(
         "select l_linenumber, l_orderkey from lineitem order by l_orderkey desc");