You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hive.apache.org by gu...@apache.org on 2014/10/25 03:41:03 UTC

svn commit: r1634172 - in /hive/branches/branch-0.14/ql/src: java/org/apache/hadoop/hive/ql/optimizer/optiq/translator/ java/org/apache/hadoop/hive/ql/parse/ test/queries/clientpositive/ test/results/clientpositive/ test/results/clientpositive/tez/

Author: gunther
Date: Sat Oct 25 01:41:03 2014
New Revision: 1634172

URL: http://svn.apache.org/r1634172
Log:
HIVE-8433: CBO loses a column during AST conversion (Sergey Shelukhin via Gunther Hagleitner)

Added:
    hive/branches/branch-0.14/ql/src/test/queries/clientpositive/select_same_col.q
    hive/branches/branch-0.14/ql/src/test/results/clientpositive/select_same_col.q.out
Modified:
    hive/branches/branch-0.14/ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/translator/ASTConverter.java
    hive/branches/branch-0.14/ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/translator/PlanModifierForASTConv.java
    hive/branches/branch-0.14/ql/src/java/org/apache/hadoop/hive/ql/parse/RowResolver.java
    hive/branches/branch-0.14/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java
    hive/branches/branch-0.14/ql/src/test/queries/clientpositive/cbo_correctness.q
    hive/branches/branch-0.14/ql/src/test/results/clientpositive/cbo_correctness.q.out
    hive/branches/branch-0.14/ql/src/test/results/clientpositive/tez/cbo_correctness.q.out

Modified: hive/branches/branch-0.14/ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/translator/ASTConverter.java
URL: http://svn.apache.org/viewvc/hive/branches/branch-0.14/ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/translator/ASTConverter.java?rev=1634172&r1=1634171&r2=1634172&view=diff
==============================================================================
--- hive/branches/branch-0.14/ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/translator/ASTConverter.java (original)
+++ hive/branches/branch-0.14/ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/translator/ASTConverter.java Sat Oct 25 01:41:03 2014
@@ -25,6 +25,8 @@ import java.util.Map;
 
 import net.hydromatic.optiq.util.BitSets;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.hive.metastore.api.FieldSchema;
 import org.apache.hadoop.hive.ql.optimizer.optiq.OptiqSemanticException;
 import org.apache.hadoop.hive.ql.optimizer.optiq.RelOptHiveTable;
@@ -63,6 +65,7 @@ import org.eigenbase.sql.type.SqlTypeNam
 import com.google.common.collect.Iterables;
 
 public class ASTConverter {
+  private static final Log LOG = LogFactory.getLog(ASTConverter.class);
 
   private RelNode          root;
   private HiveAST          hiveAST;

Modified: hive/branches/branch-0.14/ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/translator/PlanModifierForASTConv.java
URL: http://svn.apache.org/viewvc/hive/branches/branch-0.14/ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/translator/PlanModifierForASTConv.java?rev=1634172&r1=1634171&r2=1634172&view=diff
==============================================================================
--- hive/branches/branch-0.14/ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/translator/PlanModifierForASTConv.java (original)
+++ hive/branches/branch-0.14/ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/translator/PlanModifierForASTConv.java Sat Oct 25 01:41:03 2014
@@ -22,6 +22,8 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.hive.metastore.api.FieldSchema;
 import org.apache.hadoop.hive.ql.optimizer.optiq.HiveOptiqUtil;
 import org.apache.hadoop.hive.ql.optimizer.optiq.OptiqSemanticException;
@@ -43,6 +45,7 @@ import org.eigenbase.rel.SetOpRel;
 import org.eigenbase.rel.SingleRel;
 import org.eigenbase.rel.SortRel;
 import org.eigenbase.rel.rules.MultiJoinRel;
+import org.eigenbase.relopt.RelOptUtil;
 import org.eigenbase.relopt.hep.HepRelVertex;
 import org.eigenbase.relopt.volcano.RelSubset;
 import org.eigenbase.reltype.RelDataType;
@@ -55,22 +58,39 @@ import com.google.common.collect.Immutab
 import com.google.common.collect.ImmutableMap;
 
 public class PlanModifierForASTConv {
+  private static final Log LOG = LogFactory.getLog(PlanModifierForASTConv.class);
 
   public static RelNode convertOpTree(RelNode rel, List<FieldSchema> resultSchema)
       throws OptiqSemanticException {
     RelNode newTopNode = rel;
+    if (LOG.isDebugEnabled()) {
+      LOG.debug("Original plan for PlanModifier\n " + RelOptUtil.toString(newTopNode));
+    }
 
     if (!(newTopNode instanceof ProjectRelBase) && !(newTopNode instanceof SortRel)) {
       newTopNode = introduceDerivedTable(newTopNode);
+      if (LOG.isDebugEnabled()) {
+        LOG.debug("Plan after top-level introduceDerivedTable\n "
+            + RelOptUtil.toString(newTopNode));
+      }
     }
 
     convertOpTree(newTopNode, (RelNode) null);
+    if (LOG.isDebugEnabled()) {
+      LOG.debug("Plan after nested convertOpTree\n " + RelOptUtil.toString(newTopNode));
+    }
 
     Pair<RelNode, RelNode> topSelparentPair = HiveOptiqUtil.getTopLevelSelect(newTopNode);
     fixTopOBSchema(newTopNode, topSelparentPair, resultSchema);
+    if (LOG.isDebugEnabled()) {
+      LOG.debug("Plan after fixTopOBSchema\n " + RelOptUtil.toString(newTopNode));
+    }
+
     topSelparentPair = HiveOptiqUtil.getTopLevelSelect(newTopNode);
     newTopNode = renameTopLevelSelectInResultSchema(newTopNode, topSelparentPair, resultSchema);
-
+    if (LOG.isDebugEnabled()) {
+      LOG.debug("Final plan after modifier\n " + RelOptUtil.toString(newTopNode));
+    }
     return newTopNode;
   }
 
@@ -137,36 +157,54 @@ public class PlanModifierForASTConv {
   private static void fixTopOBSchema(final RelNode rootRel,
       Pair<RelNode, RelNode> topSelparentPair, List<FieldSchema> resultSchema)
       throws OptiqSemanticException {
-    if (topSelparentPair.getKey() instanceof SortRel
-        && HiveOptiqUtil.orderRelNode(topSelparentPair.getKey())) {
-      HiveSortRel obRel = (HiveSortRel) topSelparentPair.getKey();
-      ProjectRelBase obChild = (ProjectRelBase) topSelparentPair.getValue();
-
-      if (obChild.getRowType().getFieldCount() > resultSchema.size()) {
-        RelDataType rt = obChild.getRowType();
-        Set<Integer> collationInputRefs = new HashSet(RelCollationImpl.ordinals(obRel
-            .getCollation()));
-        ImmutableMap.Builder<Integer, RexNode> inputRefToCallMapBldr = ImmutableMap.builder();
-        for (int i = resultSchema.size(); i < rt.getFieldCount(); i++) {
-          if (collationInputRefs.contains(i)) {
-            inputRefToCallMapBldr.put(i, obChild.getChildExps().get(i));
-          }
-        }
-
-        ImmutableMap<Integer, RexNode> inputRefToCallMap = inputRefToCallMapBldr.build();
-        if ((obChild.getRowType().getFieldCount() - inputRefToCallMap.size()) == resultSchema
-            .size()) {
-          HiveProjectRel replacementProjectRel = HiveProjectRel.create(obChild.getChild(), obChild
-              .getChildExps().subList(0, resultSchema.size()), obChild.getRowType().getFieldNames()
-              .subList(0, resultSchema.size()));
-          obRel.replaceInput(0, replacementProjectRel);
-          obRel.setInputRefToCallMap(inputRefToCallMap);
-        } else {
-          throw new OptiqSemanticException(
-              "Result Schema didn't match Optiq Optimized Op Tree Schema");
-        }
+    if (!(topSelparentPair.getKey() instanceof SortRel)
+        || !HiveOptiqUtil.orderRelNode(topSelparentPair.getKey())) {
+      return;
+    }
+    HiveSortRel obRel = (HiveSortRel) topSelparentPair.getKey();
+    ProjectRelBase obChild = (ProjectRelBase) topSelparentPair.getValue();
+    if (obChild.getRowType().getFieldCount() <= resultSchema.size()) {
+      return;
+    }
+
+    RelDataType rt = obChild.getRowType();
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    Set<Integer> collationInputRefs = new HashSet(
+        RelCollationImpl.ordinals(obRel.getCollation()));
+    ImmutableMap.Builder<Integer, RexNode> inputRefToCallMapBldr = ImmutableMap.builder();
+    for (int i = resultSchema.size(); i < rt.getFieldCount(); i++) {
+      if (collationInputRefs.contains(i)) {
+        inputRefToCallMapBldr.put(i, obChild.getChildExps().get(i));
       }
     }
+    ImmutableMap<Integer, RexNode> inputRefToCallMap = inputRefToCallMapBldr.build();
+
+    if ((obChild.getRowType().getFieldCount() - inputRefToCallMap.size()) != resultSchema.size()) {
+      LOG.error(generateInvalidSchemaMessage(obChild, resultSchema, inputRefToCallMap.size()));
+      throw new OptiqSemanticException("Result Schema didn't match Optimized Op Tree Schema");
+    }
+    // This removes order-by only expressions from the projections.
+    HiveProjectRel replacementProjectRel = HiveProjectRel.create(obChild.getChild(), obChild
+        .getChildExps().subList(0, resultSchema.size()), obChild.getRowType().getFieldNames()
+        .subList(0, resultSchema.size()));
+    obRel.replaceInput(0, replacementProjectRel);
+    obRel.setInputRefToCallMap(inputRefToCallMap);
+  }
+
+  private static String generateInvalidSchemaMessage(ProjectRelBase topLevelProj,
+      List<FieldSchema> resultSchema, int fieldsForOB) {
+    String errorDesc = "Result Schema didn't match Optiq Optimized Op Tree; schema: ";
+    for (FieldSchema fs : resultSchema) {
+      errorDesc += "[" + fs.getName() + ":" + fs.getType() + "], ";
+    }
+    errorDesc += " projection fields: ";
+    for (RexNode exp : topLevelProj.getChildExps()) {
+      errorDesc += "[" + exp.toString() + ":" + exp.getType() + "], ";
+    }
+    if (fieldsForOB != 0) {
+      errorDesc += fieldsForOB + " fields removed due to ORDER BY  ";
+    }
+    return errorDesc.substring(0, errorDesc.length() - 2);
   }
 
   private static RelNode renameTopLevelSelectInResultSchema(final RelNode rootRel,
@@ -179,22 +217,18 @@ public class PlanModifierForASTConv {
     // (limit)?(OB)?(ProjectRelBase)....
     List<RexNode> rootChildExps = originalProjRel.getChildExps();
     if (resultSchema.size() != rootChildExps.size()) {
-      // this is a bug in Hive where for queries like select key,value,value
-      // convertRowSchemaToResultSetSchema() only returns schema containing
-      // key,value
-      // Underlying issue is much deeper because it seems like RowResolver
-      // itself doesnt have
-      // those mappings. see limit_pushdown.q & limit_pushdown_negative.q
-      // Till Hive issue is fixed, disable CBO for such queries.
-      throw new OptiqSemanticException("Result Schema didn't match Optiq Optimized Op Tree Schema");
+      // Safeguard against potential issues in CBO RowResolver construction. Disable CBO for now.
+      LOG.error(generateInvalidSchemaMessage(originalProjRel, resultSchema, 0));
+      throw new OptiqSemanticException("Result Schema didn't match Optimized Op Tree Schema");
     }
 
     List<String> newSelAliases = new ArrayList<String>();
     String colAlias;
     for (int i = 0; i < rootChildExps.size(); i++) {
       colAlias = resultSchema.get(i).getName();
-      if (colAlias.startsWith("_"))
+      if (colAlias.startsWith("_")) {
         colAlias = colAlias.substring(1);
+      }
       newSelAliases.add(colAlias);
     }
 

Modified: hive/branches/branch-0.14/ql/src/java/org/apache/hadoop/hive/ql/parse/RowResolver.java
URL: http://svn.apache.org/viewvc/hive/branches/branch-0.14/ql/src/java/org/apache/hadoop/hive/ql/parse/RowResolver.java?rev=1634172&r1=1634171&r2=1634172&view=diff
==============================================================================
--- hive/branches/branch-0.14/ql/src/java/org/apache/hadoop/hive/ql/parse/RowResolver.java (original)
+++ hive/branches/branch-0.14/ql/src/java/org/apache/hadoop/hive/ql/parse/RowResolver.java Sat Oct 25 01:41:03 2014
@@ -119,7 +119,11 @@ public class RowResolver implements Seri
       f_map = new LinkedHashMap<String, ColumnInfo>();
       rslvMap.put(tab_alias, f_map);
     }
-    f_map.put(col_alias, colInfo);
+    ColumnInfo oldColInfo = f_map.put(col_alias, colInfo);
+    if (oldColInfo != null) {
+      LOG.warn("Duplicate column info for " + tab_alias + "." + col_alias
+          + " was overwritten in RowResolver map: " + oldColInfo + " by " + colInfo);
+    }
 
     String[] qualifiedAlias = new String[2];
     qualifiedAlias[0] = tab_alias;
@@ -339,40 +343,44 @@ public class RowResolver implements Seri
     this.expressionMap = expressionMap;
   }
 
+  private static class IntRef {
+    public int val = 0;
+  }
+
+  public static boolean add(RowResolver rrToAddTo, RowResolver rrToAddFrom, int numColumns)
+      throws SemanticException {
+    return add(rrToAddTo, rrToAddFrom, null, numColumns);
+  }
 
-  // TODO: 1) How to handle collisions? 2) Should we be cloning ColumnInfo or
-  // not?
-  public static int add(RowResolver rrToAddTo, RowResolver rrToAddFrom,
-      int outputColPos, int numColumns) throws SemanticException {
+  // TODO: 1) How to handle collisions? 2) Should we be cloning ColumnInfo or not?
+  private static boolean add(RowResolver rrToAddTo, RowResolver rrToAddFrom,
+      IntRef outputColPosRef, int numColumns) throws SemanticException {
+    boolean hasDuplicates = false;
     String tabAlias;
     String colAlias;
     String[] qualifiedColName;
     int i = 0;
 
+    int outputColPos = outputColPosRef == null ? 0 : outputColPosRef.val;
     for (ColumnInfo cInfoFrmInput : rrToAddFrom.getRowSchema().getSignature()) {
       if ( numColumns >= 0 && i == numColumns ) {
         break;
       }
       ColumnInfo newCI = null;
-      qualifiedColName = rrToAddFrom.getInvRslvMap().get(
-          cInfoFrmInput.getInternalName());
+      String internalName = cInfoFrmInput.getInternalName();
+      qualifiedColName = rrToAddFrom.reverseLookup(internalName);
       tabAlias = qualifiedColName[0];
       colAlias = qualifiedColName[1];
 
       newCI = new ColumnInfo(cInfoFrmInput);
-      newCI.setInternalName(SemanticAnalyzer
-          .getColumnInternalName(outputColPos));
+      newCI.setInternalName(SemanticAnalyzer.getColumnInternalName(outputColPos));
 
       outputColPos++;
 
-      if (rrToAddTo.get(tabAlias, colAlias) != null) {
-        LOG.debug("Found duplicate column alias in RR: " + rrToAddTo.get(tabAlias, colAlias));
-      } else {
-        rrToAddTo.put(tabAlias, colAlias, newCI);
-      }
+      boolean isUnique = rrToAddTo.putWithCheck(tabAlias, colAlias, internalName, newCI);
+      hasDuplicates |= (!isUnique);
 
-      qualifiedColName = rrToAddFrom.getAlternateMappings(cInfoFrmInput
-          .getInternalName());
+      qualifiedColName = rrToAddFrom.getAlternateMappings(internalName);
       if (qualifiedColName != null) {
         tabAlias = qualifiedColName[0];
         colAlias = qualifiedColName[1];
@@ -381,31 +389,67 @@ public class RowResolver implements Seri
       i++;
     }
 
-    return outputColPos;
-	}
+    if (outputColPosRef != null) {
+      outputColPosRef.val = outputColPos;
+    }
+    return !hasDuplicates;
+  }
 
-  public static int add(RowResolver rrToAddTo, RowResolver rrToAddFrom,
-      int outputColPos) throws SemanticException {
-    return add(rrToAddTo, rrToAddFrom, outputColPos, -1);
-  }
-
-	/**
-	 * Return a new row resolver that is combination of left RR and right RR.
-	 * The schema will be schema of left, schema of right
-	 *
-	 * @param leftRR
-	 * @param rightRR
-	 * @return
-	 * @throws SemanticException
-	 */
-	public static RowResolver getCombinedRR(RowResolver leftRR,
-			RowResolver rightRR) throws SemanticException {
-		int outputColPos = 0;
-
-		RowResolver combinedRR = new RowResolver();
-		outputColPos = add(combinedRR, leftRR, outputColPos);
-		outputColPos = add(combinedRR, rightRR, outputColPos);
+  /**
+   * Adds column to RR, checking for duplicate columns. Needed because CBO cannot handle the Hive
+   * behavior of blindly overwriting old mapping in RR and still somehow working after that.
+   * @return True if mapping was added without duplicates.
+   */
+  public boolean putWithCheck(String tabAlias, String colAlias,
+      String internalName, ColumnInfo newCI) throws SemanticException {
+    ColumnInfo existing = get(tabAlias, colAlias);
+    if (existing == null) {
+      put(tabAlias, colAlias, newCI);
+      return true;
+    }
+    LOG.warn("Found duplicate column alias in RR: " + existing + " for "
+        + tabAlias + "." + colAlias + " and " + internalName);
+    if (internalName != null) {
+      existing = get(tabAlias, internalName);
+      if (existing == null) {
+        put(tabAlias, internalName, newCI);
+        return true;
+      }
+    }
+    LOG.warn("Failed to use internal name after finding a duplicate: " + existing
+        + " for " + tabAlias + "." + internalName);
+    return false;
+  }
+
+  private static boolean add(RowResolver rrToAddTo, RowResolver rrToAddFrom,
+      IntRef outputColPosRef) throws SemanticException {
+    return add(rrToAddTo, rrToAddFrom, outputColPosRef, -1);
+  }
 
-		return combinedRR;
-	}
+  public static boolean add(RowResolver rrToAddTo, RowResolver rrToAddFrom)
+      throws SemanticException {
+    return add(rrToAddTo, rrToAddFrom, null, -1);
+  }
+
+  /**
+   * Return a new row resolver that is combination of left RR and right RR.
+   * The schema will be schema of left, schema of right
+   *
+   * @param leftRR
+   * @param rightRR
+   * @return
+   * @throws SemanticException
+   */
+  public static RowResolver getCombinedRR(RowResolver leftRR,
+      RowResolver rightRR) throws SemanticException {
+    RowResolver combinedRR = new RowResolver();
+    IntRef outputColPos = new IntRef();
+    if (!add(combinedRR, leftRR, outputColPos)) {
+      LOG.warn("Duplicates detected when adding columns to RR: see previous message");
+    }
+    if (!add(combinedRR, rightRR, outputColPos)) {
+      LOG.warn("Duplicates detected when adding columns to RR: see previous message");
+    }
+    return combinedRR;
+  }
 }

Modified: hive/branches/branch-0.14/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java
URL: http://svn.apache.org/viewvc/hive/branches/branch-0.14/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java?rev=1634172&r1=1634171&r2=1634172&view=diff
==============================================================================
--- hive/branches/branch-0.14/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java (original)
+++ hive/branches/branch-0.14/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java Sat Oct 25 01:41:03 2014
@@ -1255,8 +1255,9 @@ public class SemanticAnalyzer extends Ba
         }
         qbp.setDestForClause(ctx_1.dest, (ASTNode) ast.getChild(0));
 
-        if (qbp.getClauseNamesForDest().size() > 1)
+        if (qbp.getClauseNamesForDest().size() > 1) {
           queryProperties.setMultiDestQuery(true);
+        }
         break;
 
       case HiveParser.TOK_FROM:
@@ -2716,9 +2717,10 @@ public class SemanticAnalyzer extends Ba
   }
 
   @SuppressWarnings("nls")
-  private Integer genColListRegex(String colRegex, String tabAlias,
-      ASTNode sel, ArrayList<ExprNodeDesc> col_list, HashSet<ColumnInfo> excludeCols,
-      RowResolver input, Integer pos, RowResolver output, List<String> aliases)
+  // TODO: make aliases unique, otherwise needless rewriting takes place
+  private Integer genColListRegex(String colRegex, String tabAlias, ASTNode sel,
+    ArrayList<ExprNodeDesc> col_list, HashSet<ColumnInfo> excludeCols, RowResolver input,
+    Integer pos, RowResolver output, List<String> aliases, boolean ensureUniqueCols)
       throws SemanticException {
 
     // The table alias should exist
@@ -2790,7 +2792,14 @@ public class SemanticAnalyzer extends Ba
               colInfo.getIsVirtualCol(), colInfo.isHiddenVirtualCol());
           inputColsProcessed.put(colInfo, oColInfo);
         }
-        output.put(tmp[0], tmp[1], oColInfo);
+        if (ensureUniqueCols) {
+          if (!output.putWithCheck(tmp[0], tmp[1], null, oColInfo)) {
+            throw new OptiqSemanticException("Cannot add column to RR: " + tmp[0] + "." + tmp[1]
+                + " => " + oColInfo + " due to duplication, see previous warnings");
+          }
+        } else {
+          output.put(tmp[0], tmp[1], oColInfo);
+        }
         pos = Integer.valueOf(pos.intValue() + 1);
         matched++;
 
@@ -3441,7 +3450,7 @@ public class SemanticAnalyzer extends Ba
       }
       if (isUDTF && (selectStar = udtfExprType == HiveParser.TOK_FUNCTIONSTAR)) {
         genColListRegex(".*", null, (ASTNode) udtfExpr.getChild(0),
-            col_list, null, inputRR, pos, out_rwsch, qb.getAliases());
+            col_list, null, inputRR, pos, out_rwsch, qb.getAliases(), false);
       }
     }
 
@@ -3563,7 +3572,7 @@ public class SemanticAnalyzer extends Ba
       if (expr.getType() == HiveParser.TOK_ALLCOLREF) {
         pos = genColListRegex(".*", expr.getChildCount() == 0 ? null
             : getUnescapedName((ASTNode) expr.getChild(0)).toLowerCase(),
-            expr, col_list, null, inputRR, pos, out_rwsch, qb.getAliases());
+            expr, col_list, null, inputRR, pos, out_rwsch, qb.getAliases(), false);
         selectStar = true;
       } else if (expr.getType() == HiveParser.TOK_TABLE_OR_COL && !hasAsClause
           && !inputRR.getIsExprResolver()
@@ -3572,7 +3581,7 @@ public class SemanticAnalyzer extends Ba
         // This can only happen without AS clause
         // We don't allow this for ExprResolver - the Group By case
         pos = genColListRegex(unescapeIdentifier(expr.getChild(0).getText()),
-            null, expr, col_list, null, inputRR, pos, out_rwsch, qb.getAliases());
+            null, expr, col_list, null, inputRR, pos, out_rwsch, qb.getAliases(), false);
       } else if (expr.getType() == HiveParser.DOT
           && expr.getChild(0).getType() == HiveParser.TOK_TABLE_OR_COL
           && inputRR.hasTableAlias(unescapeIdentifier(expr.getChild(0)
@@ -3584,7 +3593,7 @@ public class SemanticAnalyzer extends Ba
         // We don't allow this for ExprResolver - the Group By case
         pos = genColListRegex(unescapeIdentifier(expr.getChild(1).getText()),
             unescapeIdentifier(expr.getChild(0).getChild(0).getText().toLowerCase()),
-             expr, col_list, null, inputRR, pos, out_rwsch, qb.getAliases());
+             expr, col_list, null, inputRR, pos, out_rwsch, qb.getAliases(), false);
       } else {
         // Case when this is an expression
         TypeCheckCtx tcCtx = new TypeCheckCtx(inputRR);
@@ -12383,12 +12392,11 @@ public class SemanticAnalyzer extends Ba
 
       if (LOG.isDebugEnabled() && !conf.getBoolVar(ConfVars.HIVE_IN_TEST)) {
         LOG.debug("CBO Planning details:\n");
-        LOG.debug("Original Plan:\n");
-        LOG.debug(RelOptUtil.toString(optiqGenPlan));
-        LOG.debug("Plan After PPD, PartPruning, ColumnPruning:\n");
-        LOG.debug(RelOptUtil.toString(optiqPreCboPlan));
-        LOG.debug("Plan After Join Reordering:\n");
-        LOG.debug(RelOptUtil.toString(optiqOptimizedPlan, SqlExplainLevel.ALL_ATTRIBUTES));
+        LOG.debug("Original Plan:\n" + RelOptUtil.toString(optiqGenPlan));
+        LOG.debug("Plan After PPD, PartPruning, ColumnPruning:\n"
+            + RelOptUtil.toString(optiqPreCboPlan));
+        LOG.debug("Plan After Join Reordering:\n"
+            + RelOptUtil.toString(optiqOptimizedPlan, SqlExplainLevel.ALL_ATTRIBUTES));
       }
 
       return optiqOptimizedPlan;
@@ -12602,7 +12610,9 @@ public class SemanticAnalyzer extends Ba
         joinRR = RowResolver.getCombinedRR(leftRR, rightRR);
       } else {
         joinRR = new RowResolver();
-        RowResolver.add(joinRR, leftRR, 0);
+        if (!RowResolver.add(joinRR, leftRR)) {
+          LOG.warn("Duplicates detected when adding columns to RR: see previous message");
+        }
       }
 
       // 2. Construct ExpressionNodeDesc representing Join Condition
@@ -13046,7 +13056,7 @@ public class SemanticAnalyzer extends Ba
     private RelNode projectLeftOuterSide(RelNode srcRel, int numColumns) throws SemanticException {
       RowResolver iRR = relToHiveRR.get(srcRel);
       RowResolver oRR = new RowResolver();
-      RowResolver.add(oRR, iRR, 0, numColumns);
+      RowResolver.add(oRR, iRR, numColumns);
 
       List<RexNode> optiqColLst = new ArrayList<RexNode>();
       List<String> oFieldNames = new ArrayList<String>();
@@ -13506,7 +13516,10 @@ public class SemanticAnalyzer extends Ba
                 }
               });
           RowResolver obSyntheticProjectRR = new RowResolver();
-          RowResolver.add(obSyntheticProjectRR, inputRR, 0);
+          if (!RowResolver.add(obSyntheticProjectRR, inputRR)) {
+            throw new OptiqSemanticException(
+                "Duplicates detected when adding columns to RR: see previous message");
+          }
           int vcolPos = inputRR.getRowSchema().getSignature().size();
           for (Pair<ASTNode, TypeInfo> astTypePair : vcASTTypePairs) {
             obSyntheticProjectRR.putExpression(astTypePair.getKey(), new ColumnInfo(
@@ -13517,14 +13530,23 @@ public class SemanticAnalyzer extends Ba
               obSyntheticProjectRR, srcRel);
 
           if (outermostOB) {
-            RowResolver.add(outputRR, inputRR, 0);
+            if (!RowResolver.add(outputRR, inputRR)) {
+              throw new OptiqSemanticException(
+                  "Duplicates detected when adding columns to RR: see previous message");
+            }
 
           } else {
-            RowResolver.add(outputRR, obSyntheticProjectRR, 0);
+            if (!RowResolver.add(outputRR, obSyntheticProjectRR)) {
+              throw new OptiqSemanticException(
+                  "Duplicates detected when adding columns to RR: see previous message");
+            }
             originalOBChild = srcRel;
           }
         } else {
-          RowResolver.add(outputRR, inputRR, 0);
+          if (!RowResolver.add(outputRR, inputRR)) {
+            throw new OptiqSemanticException(
+                "Duplicates detected when adding columns to RR: see previous message");
+          }
         }
 
         // 4. Construct SortRel
@@ -13559,7 +13581,10 @@ public class SemanticAnalyzer extends Ba
         sortRel = new HiveSortRel(cluster, traitSet, srcRel, canonizedCollation, null, fetch);
 
         RowResolver outputRR = new RowResolver();
-        RowResolver.add(outputRR, relToHiveRR.get(srcRel), 0);
+        if (!RowResolver.add(outputRR, relToHiveRR.get(srcRel))) {
+          throw new OptiqSemanticException(
+              "Duplicates detected when adding columns to RR: see previous message");
+        }
         ImmutableMap<String, Integer> hiveColNameOptiqPosMap = buildHiveToOptiqColumnMap(outputRR,
             sortRel);
         relToHiveRR.put(sortRel, outputRR);
@@ -13739,7 +13764,9 @@ public class SemanticAnalyzer extends Ba
 
       // 3. Construct new Row Resolver with everything from below.
       RowResolver out_rwsch = new RowResolver();
-      RowResolver.add(out_rwsch, inputRR, 0);
+      if (!RowResolver.add(out_rwsch, inputRR)) {
+        LOG.warn("Duplicates detected when adding columns to RR: see previous message");
+      }
 
       // 4. Walk through Window Expressions & Construct RexNodes for those,
       // Update out_rwsch
@@ -13863,6 +13890,7 @@ public class SemanticAnalyzer extends Ba
       QBParseInfo qbp = getQBParseInfo(qb);
       String selClauseName = qbp.getClauseNames().iterator().next();
       ASTNode selExprList = qbp.getSelForClause(selClauseName);
+      LOG.error("TODO# for select clause, got " + selExprList.dump());
 
       // 2.Row resolvers for input, output
       RowResolver out_rwsch = new RowResolver();
@@ -13944,7 +13972,7 @@ public class SemanticAnalyzer extends Ba
           pos = genColListRegex(".*",
               expr.getChildCount() == 0 ? null : getUnescapedName((ASTNode) expr.getChild(0))
                   .toLowerCase(), expr, col_list, excludedColumns, inputRR, pos, out_rwsch,
-                  tabAliasesForAllProjs);
+                  tabAliasesForAllProjs, true);
           selectStar = true;
         } else if (expr.getType() == HiveParser.TOK_TABLE_OR_COL && !hasAsClause
             && !inputRR.getIsExprResolver()
@@ -13953,7 +13981,7 @@ public class SemanticAnalyzer extends Ba
           // This can only happen without AS clause
           // We don't allow this for ExprResolver - the Group By case
           pos = genColListRegex(unescapeIdentifier(expr.getChild(0).getText()), null, expr,
-              col_list, excludedColumns, inputRR, pos, out_rwsch, tabAliasesForAllProjs);
+              col_list, excludedColumns, inputRR, pos, out_rwsch, tabAliasesForAllProjs, true);
         } else if (expr.getType() == HiveParser.DOT
             && expr.getChild(0).getType() == HiveParser.TOK_TABLE_OR_COL
             && inputRR.hasTableAlias(unescapeIdentifier(expr.getChild(0).getChild(0).getText()
@@ -13964,7 +13992,7 @@ public class SemanticAnalyzer extends Ba
           // We don't allow this for ExprResolver - the Group By case
           pos = genColListRegex(unescapeIdentifier(expr.getChild(1).getText()),
               unescapeIdentifier(expr.getChild(0).getChild(0).getText().toLowerCase()), expr,
-              col_list, excludedColumns, inputRR, pos, out_rwsch, tabAliasesForAllProjs);
+              col_list, excludedColumns, inputRR, pos, out_rwsch, tabAliasesForAllProjs, true);
         } else if (expr.toStringTree().contains("TOK_FUNCTIONDI") && !(srcRel instanceof HiveAggregateRel)) {
           // Likely a malformed query eg, select hash(distinct c1) from t1;
           throw new OptiqSemanticException("Distinct without an aggreggation.");
@@ -14136,7 +14164,10 @@ public class SemanticAnalyzer extends Ba
           }
         });
         RowResolver topConstrainingProjRR = new RowResolver();
-        RowResolver.add(topConstrainingProjRR, this.relToHiveRR.get(topConstrainingProjArgsRel), 0);
+        if (!RowResolver.add(
+            topConstrainingProjRR, this.relToHiveRR.get(topConstrainingProjArgsRel))) {
+          LOG.warn("Duplicates detected when adding columns to RR: see previous message");
+        }
         srcRel = genSelectRelNode(originalInputRefs, topConstrainingProjRR, srcRel);
       }
 
@@ -14290,7 +14321,7 @@ public class SemanticAnalyzer extends Ba
     }
 
     private List<String> getTabAliases(RowResolver inputRR) {
-      List<String> tabAliases = new ArrayList<String>();
+      List<String> tabAliases = new ArrayList<String>(); // TODO: this should be unique
       for (ColumnInfo ci : inputRR.getColumnInfos()) {
         tabAliases.add(ci.getTabAlias());
       }

Modified: hive/branches/branch-0.14/ql/src/test/queries/clientpositive/cbo_correctness.q
URL: http://svn.apache.org/viewvc/hive/branches/branch-0.14/ql/src/test/queries/clientpositive/cbo_correctness.q?rev=1634172&r1=1634171&r2=1634172&view=diff
==============================================================================
--- hive/branches/branch-0.14/ql/src/test/queries/clientpositive/cbo_correctness.q (original)
+++ hive/branches/branch-0.14/ql/src/test/queries/clientpositive/cbo_correctness.q Sat Oct 25 01:41:03 2014
@@ -251,7 +251,7 @@ drop view v3;
 drop view v4;
 
 -- 11. Union All
-select * from t1 union all select * from t2 order by key;
+select * from t1 union all select * from t2 order by key, c_boolean, value, dt;
 select key from (select key, c_int from (select * from t1 union all select * from t2 where t2.key >=0)r1 union all select key, c_int from t3)r2 where key >=0 order by key;
 select r2.key from (select key, c_int from (select key, c_int from t1 union all select key, c_int from t3 )r1 union all select key, c_int from t3)r2 join   (select key, c_int from (select * from t1 union all select * from t2 where t2.key >=0)r1 union all select key, c_int from t3)r3 on r2.key=r3.key where r3.key >=0 order by r2.key;
 
@@ -281,7 +281,7 @@ from src_cbo 
 where src_cbo.key not in  
   ( select key  from src_cbo s1 
     where s1.key > '2'
-  )
+  ) order by key
 ;
 
 -- non agg, corr

Added: hive/branches/branch-0.14/ql/src/test/queries/clientpositive/select_same_col.q
URL: http://svn.apache.org/viewvc/hive/branches/branch-0.14/ql/src/test/queries/clientpositive/select_same_col.q?rev=1634172&view=auto
==============================================================================
--- hive/branches/branch-0.14/ql/src/test/queries/clientpositive/select_same_col.q (added)
+++ hive/branches/branch-0.14/ql/src/test/queries/clientpositive/select_same_col.q Sat Oct 25 01:41:03 2014
@@ -0,0 +1,19 @@
+
+set hive.cbo.enable=true;
+
+drop table srclimit;
+create table srclimit as select * from src limit 10;
+
+select cast(value as binary), value from srclimit;
+
+select cast(value as binary), value from srclimit order by value;
+
+select cast(value as binary), value from srclimit order by value limit 5;
+
+select cast(value as binary), value, key from srclimit order by value limit 5;
+
+select *, key, value from srclimit;
+
+select * from (select *, key, value from srclimit) t;
+
+drop table srclimit;
\ No newline at end of file

Modified: hive/branches/branch-0.14/ql/src/test/results/clientpositive/cbo_correctness.q.out
URL: http://svn.apache.org/viewvc/hive/branches/branch-0.14/ql/src/test/results/clientpositive/cbo_correctness.q.out?rev=1634172&r1=1634171&r2=1634172&view=diff
==============================================================================
--- hive/branches/branch-0.14/ql/src/test/results/clientpositive/cbo_correctness.q.out (original)
+++ hive/branches/branch-0.14/ql/src/test/results/clientpositive/cbo_correctness.q.out Sat Oct 25 01:41:03 2014
@@ -16719,7 +16719,7 @@ POSTHOOK: type: DROPVIEW
 POSTHOOK: Input: default@v4
 POSTHOOK: Output: default@v4
 PREHOOK: query: -- 11. Union All
-select * from t1 union all select * from t2 order by key
+select * from t1 union all select * from t2 order by key, c_boolean, value, dt
 PREHOOK: type: QUERY
 PREHOOK: Input: default@t1
 PREHOOK: Input: default@t1@dt=2014
@@ -16727,7 +16727,7 @@ PREHOOK: Input: default@t2
 PREHOOK: Input: default@t2@dt=2014
 #### A masked pattern was here ####
 POSTHOOK: query: -- 11. Union All
-select * from t1 union all select * from t2 order by key
+select * from t1 union all select * from t2 order by key, c_boolean, value, dt
 POSTHOOK: type: QUERY
 POSTHOOK: Input: default@t1
 POSTHOOK: Input: default@t1@dt=2014
@@ -16738,13 +16738,13 @@ POSTHOOK: Input: default@t2@dt=2014
  1	 1	1	1.0	true	2014
  1 	 1 	1	1.0	true	2014
  1 	 1 	1	1.0	true	2014
-1	1	1	1.0	true	2014
 1	1	1	1.0	false	2014
-1	1	1	1.0	true	2014
 1	1	1	1.0	false	2014
 1	1	1	1.0	true	2014
 1	1	1	1.0	true	2014
 1	1	1	1.0	true	2014
+1	1	1	1.0	true	2014
+1	1	1	1.0	true	2014
 1 	1 	1	1.0	true	2014
 1 	1 	1	1.0	true	2014
 2	2	2	2.0	true	2014
@@ -18142,7 +18142,7 @@ from src_cbo 
 where src_cbo.key not in  
   ( select key  from src_cbo s1 
     where s1.key > '2'
-  )
+  ) order by key
 PREHOOK: type: QUERY
 PREHOOK: Input: default@src_cbo
 #### A masked pattern was here ####
@@ -18153,7 +18153,7 @@ from src_cbo 
 where src_cbo.key not in  
   ( select key  from src_cbo s1 
     where s1.key > '2'
-  )
+  ) order by key
 POSTHOOK: type: QUERY
 POSTHOOK: Input: default@src_cbo
 #### A masked pattern was here ####

Added: hive/branches/branch-0.14/ql/src/test/results/clientpositive/select_same_col.q.out
URL: http://svn.apache.org/viewvc/hive/branches/branch-0.14/ql/src/test/results/clientpositive/select_same_col.q.out?rev=1634172&view=auto
==============================================================================
--- hive/branches/branch-0.14/ql/src/test/results/clientpositive/select_same_col.q.out (added)
+++ hive/branches/branch-0.14/ql/src/test/results/clientpositive/select_same_col.q.out Sat Oct 25 01:41:03 2014
@@ -0,0 +1,120 @@
+PREHOOK: query: drop table srclimit
+PREHOOK: type: DROPTABLE
+POSTHOOK: query: drop table srclimit
+POSTHOOK: type: DROPTABLE
+PREHOOK: query: create table srclimit as select * from src limit 10
+PREHOOK: type: CREATETABLE_AS_SELECT
+PREHOOK: Input: default@src
+PREHOOK: Output: database:default
+PREHOOK: Output: default@srclimit
+POSTHOOK: query: create table srclimit as select * from src limit 10
+POSTHOOK: type: CREATETABLE_AS_SELECT
+POSTHOOK: Input: default@src
+POSTHOOK: Output: database:default
+POSTHOOK: Output: default@srclimit
+PREHOOK: query: select cast(value as binary), value from srclimit
+PREHOOK: type: QUERY
+PREHOOK: Input: default@srclimit
+#### A masked pattern was here ####
+POSTHOOK: query: select cast(value as binary), value from srclimit
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@srclimit
+#### A masked pattern was here ####
+val_484	val_484
+val_98	val_98
+val_278	val_278
+val_255	val_255
+val_409	val_409
+val_165	val_165
+val_27	val_27
+val_311	val_311
+val_86	val_86
+val_238	val_238
+PREHOOK: query: select cast(value as binary), value from srclimit order by value
+PREHOOK: type: QUERY
+PREHOOK: Input: default@srclimit
+#### A masked pattern was here ####
+POSTHOOK: query: select cast(value as binary), value from srclimit order by value
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@srclimit
+#### A masked pattern was here ####
+val_165	val_165
+val_238	val_238
+val_255	val_255
+val_27	val_27
+val_278	val_278
+val_311	val_311
+val_409	val_409
+val_484	val_484
+val_86	val_86
+val_98	val_98
+PREHOOK: query: select cast(value as binary), value from srclimit order by value limit 5
+PREHOOK: type: QUERY
+PREHOOK: Input: default@srclimit
+#### A masked pattern was here ####
+POSTHOOK: query: select cast(value as binary), value from srclimit order by value limit 5
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@srclimit
+#### A masked pattern was here ####
+val_165	val_165
+val_238	val_238
+val_255	val_255
+val_27	val_27
+val_278	val_278
+PREHOOK: query: select cast(value as binary), value, key from srclimit order by value limit 5
+PREHOOK: type: QUERY
+PREHOOK: Input: default@srclimit
+#### A masked pattern was here ####
+POSTHOOK: query: select cast(value as binary), value, key from srclimit order by value limit 5
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@srclimit
+#### A masked pattern was here ####
+val_165	val_165	165
+val_238	val_238	238
+val_255	val_255	255
+val_27	val_27	27
+val_278	val_278	278
+PREHOOK: query: select *, key, value from srclimit
+PREHOOK: type: QUERY
+PREHOOK: Input: default@srclimit
+#### A masked pattern was here ####
+POSTHOOK: query: select *, key, value from srclimit
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@srclimit
+#### A masked pattern was here ####
+484	val_484	484	val_484
+98	val_98	98	val_98
+278	val_278	278	val_278
+255	val_255	255	val_255
+409	val_409	409	val_409
+165	val_165	165	val_165
+27	val_27	27	val_27
+311	val_311	311	val_311
+86	val_86	86	val_86
+238	val_238	238	val_238
+PREHOOK: query: select * from (select *, key, value from srclimit) t
+PREHOOK: type: QUERY
+PREHOOK: Input: default@srclimit
+#### A masked pattern was here ####
+POSTHOOK: query: select * from (select *, key, value from srclimit) t
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@srclimit
+#### A masked pattern was here ####
+484	val_484	484	val_484
+98	val_98	98	val_98
+278	val_278	278	val_278
+255	val_255	255	val_255
+409	val_409	409	val_409
+165	val_165	165	val_165
+27	val_27	27	val_27
+311	val_311	311	val_311
+86	val_86	86	val_86
+238	val_238	238	val_238
+PREHOOK: query: drop table srclimit
+PREHOOK: type: DROPTABLE
+PREHOOK: Input: default@srclimit
+PREHOOK: Output: default@srclimit
+POSTHOOK: query: drop table srclimit
+POSTHOOK: type: DROPTABLE
+POSTHOOK: Input: default@srclimit
+POSTHOOK: Output: default@srclimit

Modified: hive/branches/branch-0.14/ql/src/test/results/clientpositive/tez/cbo_correctness.q.out
URL: http://svn.apache.org/viewvc/hive/branches/branch-0.14/ql/src/test/results/clientpositive/tez/cbo_correctness.q.out?rev=1634172&r1=1634171&r2=1634172&view=diff
==============================================================================
--- hive/branches/branch-0.14/ql/src/test/results/clientpositive/tez/cbo_correctness.q.out (original)
+++ hive/branches/branch-0.14/ql/src/test/results/clientpositive/tez/cbo_correctness.q.out Sat Oct 25 01:41:03 2014
@@ -16719,7 +16719,7 @@ POSTHOOK: type: DROPVIEW
 POSTHOOK: Input: default@v4
 POSTHOOK: Output: default@v4
 PREHOOK: query: -- 11. Union All
-select * from t1 union all select * from t2 order by key
+select * from t1 union all select * from t2 order by key, c_boolean, value, dt
 PREHOOK: type: QUERY
 PREHOOK: Input: default@t1
 PREHOOK: Input: default@t1@dt=2014
@@ -16727,41 +16727,21 @@ PREHOOK: Input: default@t2
 PREHOOK: Input: default@t2@dt=2014
 #### A masked pattern was here ####
 POSTHOOK: query: -- 11. Union All
-select * from t1 union all select * from t2 order by key
+select * from t1 union all select * from t2 order by key, c_boolean, value, dt
 POSTHOOK: type: QUERY
 POSTHOOK: Input: default@t1
 POSTHOOK: Input: default@t1@dt=2014
 POSTHOOK: Input: default@t2
 POSTHOOK: Input: default@t2@dt=2014
 #### A masked pattern was here ####
-1	1	1	1.0	true	2014
-1	1	1	1.0	true	2014
-1	1	1	1.0	true	2014
-1	1	1	1.0	true	2014
-1	1	1	1.0	true	2014
-1	1	1	1.0	true	2014
-1	1	1	1.0	true	2014
-1	1	1	1.0	true	2014
-1	1	1	1.0	true	2014
-1	1	1	1.0	true	2014
  1	 1	1	1.0	true	2014
  1	 1	1	1.0	true	2014
  1 	 1 	1	1.0	true	2014
  1 	 1 	1	1.0	true	2014
-1 	1 	1	1.0	true	2014
-1 	1 	1	1.0	true	2014
 1	1	1	1.0	false	2014
 1	1	1	1.0	false	2014
-null	null	NULL	NULL	NULL	2014
-null	null	NULL	NULL	NULL	2014
- 1	 1	1	1.0	true	2014
- 1	 1	1	1.0	true	2014
- 1 	 1 	1	1.0	true	2014
- 1 	 1 	1	1.0	true	2014
 1	1	1	1.0	true	2014
-1	1	1	1.0	false	2014
 1	1	1	1.0	true	2014
-1	1	1	1.0	false	2014
 1	1	1	1.0	true	2014
 1	1	1	1.0	true	2014
 1	1	1	1.0	true	2014
@@ -16774,6 +16754,26 @@ null	null	NULL	NULL	NULL	2014
 2	2	2	2.0	true	2014
 null	null	NULL	NULL	NULL	2014
 null	null	NULL	NULL	NULL	2014
+1	1	1	1.0	true	2014
+1	1	1	1.0	true	2014
+1	1	1	1.0	true	2014
+1	1	1	1.0	true	2014
+1	1	1	1.0	true	2014
+1	1	1	1.0	true	2014
+1	1	1	1.0	true	2014
+1	1	1	1.0	true	2014
+1	1	1	1.0	true	2014
+1	1	1	1.0	true	2014
+ 1	 1	1	1.0	true	2014
+ 1	 1	1	1.0	true	2014
+ 1 	 1 	1	1.0	true	2014
+ 1 	 1 	1	1.0	true	2014
+1 	1 	1	1.0	true	2014
+1 	1 	1	1.0	true	2014
+1	1	1	1.0	false	2014
+1	1	1	1.0	false	2014
+null	null	NULL	NULL	NULL	2014
+null	null	NULL	NULL	NULL	2014
 PREHOOK: query: select key from (select key, c_int from (select * from t1 union all select * from t2 where t2.key >=0)r1 union all select key, c_int from t3)r2 where key >=0 order by key
 PREHOOK: type: QUERY
 PREHOOK: Input: default@t1
@@ -18142,7 +18142,7 @@ from src_cbo 
 where src_cbo.key not in  
   ( select key  from src_cbo s1 
     where s1.key > '2'
-  )
+  ) order by key
 PREHOOK: type: QUERY
 PREHOOK: Input: default@src_cbo
 #### A masked pattern was here ####
@@ -18153,129 +18153,129 @@ from src_cbo 
 where src_cbo.key not in  
   ( select key  from src_cbo s1 
     where s1.key > '2'
-  )
+  ) order by key
 POSTHOOK: type: QUERY
 POSTHOOK: Input: default@src_cbo
 #### A masked pattern was here ####
-2	val_2
-199	val_199
-199	val_199
-199	val_199
-197	val_197
-197	val_197
-196	val_196
-195	val_195
-195	val_195
-194	val_194
-193	val_193
-193	val_193
-193	val_193
-192	val_192
-191	val_191
-191	val_191
-190	val_190
-19	val_19
-189	val_189
-187	val_187
-187	val_187
-187	val_187
-186	val_186
-183	val_183
-181	val_181
-180	val_180
-18	val_18
-18	val_18
-179	val_179
-179	val_179
-178	val_178
-177	val_177
-176	val_176
-176	val_176
-175	val_175
-175	val_175
-174	val_174
-174	val_174
-172	val_172
-172	val_172
-170	val_170
-17	val_17
-169	val_169
-169	val_169
-169	val_169
-169	val_169
-168	val_168
-167	val_167
-167	val_167
-167	val_167
-166	val_166
-165	val_165
-165	val_165
-164	val_164
-164	val_164
-163	val_163
-162	val_162
-160	val_160
-158	val_158
-157	val_157
-156	val_156
-155	val_155
-153	val_153
-152	val_152
-152	val_152
-150	val_150
-15	val_15
-15	val_15
-149	val_149
-149	val_149
-146	val_146
-146	val_146
-145	val_145
-143	val_143
+0	val_0
+0	val_0
+0	val_0
+10	val_10
+100	val_100
+100	val_100
+103	val_103
+103	val_103
+104	val_104
+104	val_104
+105	val_105
+11	val_11
+111	val_111
+113	val_113
+113	val_113
+114	val_114
+116	val_116
+118	val_118
+118	val_118
+119	val_119
+119	val_119
+119	val_119
+12	val_12
+12	val_12
+120	val_120
+120	val_120
+125	val_125
+125	val_125
+126	val_126
+128	val_128
+128	val_128
+128	val_128
+129	val_129
+129	val_129
+131	val_131
+133	val_133
+134	val_134
+134	val_134
+136	val_136
+137	val_137
+137	val_137
 138	val_138
 138	val_138
 138	val_138
 138	val_138
-137	val_137
-137	val_137
-136	val_136
-134	val_134
-134	val_134
-133	val_133
-131	val_131
-129	val_129
-129	val_129
-128	val_128
-128	val_128
-128	val_128
-126	val_126
-125	val_125
-125	val_125
-120	val_120
-120	val_120
-12	val_12
-12	val_12
-119	val_119
-119	val_119
-119	val_119
-118	val_118
-118	val_118
-116	val_116
-114	val_114
-113	val_113
-113	val_113
-111	val_111
-11	val_11
-105	val_105
-104	val_104
-104	val_104
-103	val_103
-103	val_103
-100	val_100
-100	val_100
-10	val_10
-0	val_0
-0	val_0
-0	val_0
+143	val_143
+145	val_145
+146	val_146
+146	val_146
+149	val_149
+149	val_149
+15	val_15
+15	val_15
+150	val_150
+152	val_152
+152	val_152
+153	val_153
+155	val_155
+156	val_156
+157	val_157
+158	val_158
+160	val_160
+162	val_162
+163	val_163
+164	val_164
+164	val_164
+165	val_165
+165	val_165
+166	val_166
+167	val_167
+167	val_167
+167	val_167
+168	val_168
+169	val_169
+169	val_169
+169	val_169
+169	val_169
+17	val_17
+170	val_170
+172	val_172
+172	val_172
+174	val_174
+174	val_174
+175	val_175
+175	val_175
+176	val_176
+176	val_176
+177	val_177
+178	val_178
+179	val_179
+179	val_179
+18	val_18
+18	val_18
+180	val_180
+181	val_181
+183	val_183
+186	val_186
+187	val_187
+187	val_187
+187	val_187
+189	val_189
+19	val_19
+190	val_190
+191	val_191
+191	val_191
+192	val_192
+193	val_193
+193	val_193
+193	val_193
+194	val_194
+195	val_195
+195	val_195
+196	val_196
+197	val_197
+197	val_197
+199	val_199
+199	val_199
+199	val_199
+2	val_2
 PREHOOK: query: -- non agg, corr
 select p_mfgr, b.p_name, p_size 
 from part b