From 6bcd19fd00608e3dec8a2c211e2e5d2d9b9429ab Mon Sep 17 00:00:00 2001 From: Konstantin Bereznyakov Date: Tue, 4 Aug 2026 16:58:44 -0700 Subject: [PATCH 1/3] HIVE-29580: CBO: Ambiguous column reference not detected in some CTE/CTAS/other queries --- .../hadoop/hive/ql/exec/ColumnInfo.java | 16 +++ .../hadoop/hive/ql/parse/CalcitePlanner.java | 15 +++ .../hive/ql/parse/SemanticAnalyzer.java | 5 + .../type/JoinCondTypeCheckProcFactory.java | 2 + .../ql/parse/type/TypeCheckProcFactory.java | 10 ++ .../parse/type/TestAmbiguousColumnName.java | 58 ++++++++++ .../clientnegative/ambiguous_col_2_noncbo.q | 3 + .../ambiguous_col_aggregate_noncbo.q | 3 + .../clientnegative/ambiguous_col_cte.q | 3 + .../clientnegative/ambiguous_col_cte_noncbo.q | 4 + .../ambiguous_col_cte_unreferenced_noncbo.q | 3 + .../ambiguous_col_distinct_window.q | 1 + .../ambiguous_col_exists_having_noncbo.q | 3 + .../ambiguous_col_exists_noncbo.q | 3 + .../clientnegative/ambiguous_col_join_cond.q | 7 ++ .../ambiguous_col_join_cond_unqual.q | 5 + .../clientnegative/ambiguous_col_join_using.q | 1 + .../ambiguous_col_join_wildcard_noncbo.q | 4 + .../ambiguous_col_lateral_view_alias.q | 7 ++ .../ambiguous_col_nested_star_noncbo.q | 2 + .../clientnegative/ambiguous_col_noncbo.q | 3 + .../clientnegative/ambiguous_col_union.q | 1 + .../ambiguous_col_union_noncbo.q | 2 + .../ambiguous_col_unqualified_ref.q | 8 ++ .../ambiguous_col_unreferenced_noncbo.q | 2 + .../ambiguous_colref_in_gby_noncbo.q | 3 + .../queries/clientnegative/ctas_dup_column.q | 1 + .../clientnegative/ctas_dup_column_join.q | 3 + .../ctas_dup_column_join_noncbo.q | 4 + .../clientnegative/ctas_dup_column_noncbo.q | 2 + .../clientpositive/ambiguous_col_tolerated.q | 14 +++ .../ambiguous_col_unreferenced_tolerated.q | 13 +++ .../clientnegative/ambiguous_col.q.out | 2 +- .../clientnegative/ambiguous_col_2.q.out | 2 +- .../ambiguous_col_2_noncbo.q.out | 9 ++ .../ambiguous_col_aggregate_noncbo.q.out | 1 + .../clientnegative/ambiguous_col_cte.q.out | 1 + .../ambiguous_col_cte_noncbo.q.out | 1 + ...mbiguous_col_cte_unreferenced_noncbo.q.out | 1 + .../ambiguous_col_distinct_window.q.out | 1 + .../ambiguous_col_exists_having_noncbo.q.out | 1 + .../ambiguous_col_exists_noncbo.q.out | 1 + .../ambiguous_col_join_cond.q.out | 1 + .../ambiguous_col_join_cond_unqual.q.out | 1 + .../ambiguous_col_join_using.q.out | 1 + .../ambiguous_col_join_wildcard_noncbo.q.out | 17 +++ .../ambiguous_col_lateral_view_alias.q.out | 9 ++ .../ambiguous_col_nested_star_noncbo.q.out | 1 + .../clientnegative/ambiguous_col_noncbo.q.out | 1 + .../clientnegative/ambiguous_col_union.q.out | 1 + .../ambiguous_col_union_noncbo.q.out | 1 + .../ambiguous_col_unqualified_ref.q.out | 1 + .../ambiguous_col_unreferenced_noncbo.q.out | 1 + .../ambiguous_colref_in_gby_noncbo.q.out | 9 ++ .../cbo_ambiguous_colref_in_gby.q.out | 2 +- .../clientnegative/ctas_dup_column.q.out | 1 + .../clientnegative/ctas_dup_column_join.q.out | 17 +++ .../ctas_dup_column_join_noncbo.q.out | 17 +++ .../ctas_dup_column_noncbo.q.out | 1 + .../clientnegative/cte_col_alias_clash.q.out | 2 +- .../llap/ambiguous_col_tolerated.q.out | 101 ++++++++++++++++++ ...ambiguous_col_unreferenced_tolerated.q.out | 101 ++++++++++++++++++ 62 files changed, 513 insertions(+), 4 deletions(-) create mode 100644 ql/src/test/org/apache/hadoop/hive/ql/parse/type/TestAmbiguousColumnName.java create mode 100644 ql/src/test/queries/clientnegative/ambiguous_col_2_noncbo.q create mode 100644 ql/src/test/queries/clientnegative/ambiguous_col_aggregate_noncbo.q create mode 100644 ql/src/test/queries/clientnegative/ambiguous_col_cte.q create mode 100644 ql/src/test/queries/clientnegative/ambiguous_col_cte_noncbo.q create mode 100644 ql/src/test/queries/clientnegative/ambiguous_col_cte_unreferenced_noncbo.q create mode 100644 ql/src/test/queries/clientnegative/ambiguous_col_distinct_window.q create mode 100644 ql/src/test/queries/clientnegative/ambiguous_col_exists_having_noncbo.q create mode 100644 ql/src/test/queries/clientnegative/ambiguous_col_exists_noncbo.q create mode 100644 ql/src/test/queries/clientnegative/ambiguous_col_join_cond.q create mode 100644 ql/src/test/queries/clientnegative/ambiguous_col_join_cond_unqual.q create mode 100644 ql/src/test/queries/clientnegative/ambiguous_col_join_using.q create mode 100644 ql/src/test/queries/clientnegative/ambiguous_col_join_wildcard_noncbo.q create mode 100644 ql/src/test/queries/clientnegative/ambiguous_col_lateral_view_alias.q create mode 100644 ql/src/test/queries/clientnegative/ambiguous_col_nested_star_noncbo.q create mode 100644 ql/src/test/queries/clientnegative/ambiguous_col_noncbo.q create mode 100644 ql/src/test/queries/clientnegative/ambiguous_col_union.q create mode 100644 ql/src/test/queries/clientnegative/ambiguous_col_union_noncbo.q create mode 100644 ql/src/test/queries/clientnegative/ambiguous_col_unqualified_ref.q create mode 100644 ql/src/test/queries/clientnegative/ambiguous_col_unreferenced_noncbo.q create mode 100644 ql/src/test/queries/clientnegative/ambiguous_colref_in_gby_noncbo.q create mode 100644 ql/src/test/queries/clientnegative/ctas_dup_column.q create mode 100644 ql/src/test/queries/clientnegative/ctas_dup_column_join.q create mode 100644 ql/src/test/queries/clientnegative/ctas_dup_column_join_noncbo.q create mode 100644 ql/src/test/queries/clientnegative/ctas_dup_column_noncbo.q create mode 100644 ql/src/test/queries/clientpositive/ambiguous_col_tolerated.q create mode 100644 ql/src/test/queries/clientpositive/ambiguous_col_unreferenced_tolerated.q create mode 100644 ql/src/test/results/clientnegative/ambiguous_col_2_noncbo.q.out create mode 100644 ql/src/test/results/clientnegative/ambiguous_col_aggregate_noncbo.q.out create mode 100644 ql/src/test/results/clientnegative/ambiguous_col_cte.q.out create mode 100644 ql/src/test/results/clientnegative/ambiguous_col_cte_noncbo.q.out create mode 100644 ql/src/test/results/clientnegative/ambiguous_col_cte_unreferenced_noncbo.q.out create mode 100644 ql/src/test/results/clientnegative/ambiguous_col_distinct_window.q.out create mode 100644 ql/src/test/results/clientnegative/ambiguous_col_exists_having_noncbo.q.out create mode 100644 ql/src/test/results/clientnegative/ambiguous_col_exists_noncbo.q.out create mode 100644 ql/src/test/results/clientnegative/ambiguous_col_join_cond.q.out create mode 100644 ql/src/test/results/clientnegative/ambiguous_col_join_cond_unqual.q.out create mode 100644 ql/src/test/results/clientnegative/ambiguous_col_join_using.q.out create mode 100644 ql/src/test/results/clientnegative/ambiguous_col_join_wildcard_noncbo.q.out create mode 100644 ql/src/test/results/clientnegative/ambiguous_col_lateral_view_alias.q.out create mode 100644 ql/src/test/results/clientnegative/ambiguous_col_nested_star_noncbo.q.out create mode 100644 ql/src/test/results/clientnegative/ambiguous_col_noncbo.q.out create mode 100644 ql/src/test/results/clientnegative/ambiguous_col_union.q.out create mode 100644 ql/src/test/results/clientnegative/ambiguous_col_union_noncbo.q.out create mode 100644 ql/src/test/results/clientnegative/ambiguous_col_unqualified_ref.q.out create mode 100644 ql/src/test/results/clientnegative/ambiguous_col_unreferenced_noncbo.q.out create mode 100644 ql/src/test/results/clientnegative/ambiguous_colref_in_gby_noncbo.q.out create mode 100644 ql/src/test/results/clientnegative/ctas_dup_column.q.out create mode 100644 ql/src/test/results/clientnegative/ctas_dup_column_join.q.out create mode 100644 ql/src/test/results/clientnegative/ctas_dup_column_join_noncbo.q.out create mode 100644 ql/src/test/results/clientnegative/ctas_dup_column_noncbo.q.out create mode 100644 ql/src/test/results/clientpositive/llap/ambiguous_col_tolerated.q.out create mode 100644 ql/src/test/results/clientpositive/llap/ambiguous_col_unreferenced_tolerated.q.out diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/ColumnInfo.java b/ql/src/java/org/apache/hadoop/hive/ql/exec/ColumnInfo.java index b96936904ff2..ca132cfd00ac 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/exec/ColumnInfo.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/ColumnInfo.java @@ -59,6 +59,8 @@ public class ColumnInfo implements Serializable { private boolean isHiddenVirtualCol; + private boolean ambiguousName; + private String typeName; private final boolean nullable; @@ -129,9 +131,23 @@ public ColumnInfo(ColumnInfo columnInfo) { this.isVirtualCol = columnInfo.getIsVirtualCol(); this.isHiddenVirtualCol = columnInfo.isHiddenVirtualCol(); this.nullable = columnInfo.nullable; + this.ambiguousName = columnInfo.ambiguousName; this.setType(columnInfo.getType()); } + /** + * True when this column's alias collided with another column's at a subquery/CTE boundary: + * the column stays usable positionally (star expansion, count(*)) but any by-name reference + * is ambiguous and must be rejected. + */ + public boolean hasAmbiguousName() { + return ambiguousName; + } + + public void setAmbiguousName(boolean ambiguousName) { + this.ambiguousName = ambiguousName; + } + public String getTypeName() { return this.typeName; } diff --git a/ql/src/java/org/apache/hadoop/hive/ql/parse/CalcitePlanner.java b/ql/src/java/org/apache/hadoop/hive/ql/parse/CalcitePlanner.java index 25489f477f55..266c6b07edcf 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/parse/CalcitePlanner.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/parse/CalcitePlanner.java @@ -1556,6 +1556,11 @@ public RelNode apply(RelOptCluster cluster, RelOptSchema relOptSchema, SchemaPlu resultSchema = convertRowSchemaToResultSetSchema(relToHiveRR.get(calcitePlan), (forViewCreation || getQB().isMaterializedView()) ? false : HiveConf.getBoolVar(conf, HiveConf.ConfVars.HIVE_RESULTSET_USE_UNIQUE_COLUMN_NAMES)); + if (getQB().isCTAS()) { + // check the non-uniquified names: getNewColAlias would rename a duplicate away + ParseUtils.validateColumnNameUniqueness( + convertRowSchemaToResultSetSchema(relToHiveRR.get(calcitePlan), false)); + } } catch (SemanticException e) { semanticException = e; throw new RuntimeException(e); @@ -4545,6 +4550,7 @@ && isRegex( ColumnInfo colInfo = outputRR.getColumnInfos().get(i); ColumnInfo newColInfo = new ColumnInfo(colInfo.getInternalName(), colInfo.getType(), colInfo.getTabAlias(), colInfo.getIsVirtualCol()); + newColInfo.setAmbiguousName(colInfo.hasAmbiguousName()); groupByOutputRowResolver.put(colInfo.getTabAlias(), colInfo.getAlias(), newColInfo); if (gbyKeyExpressions != null && gbyKeyExpressions.size() == outputRR.getColumnInfos().size()) { groupByOutputRowResolver.putExpression(gbyKeyExpressions.get(i), colInfo); @@ -4887,6 +4893,15 @@ private RelNode genLogicalPlan(QB qb, boolean outerMostQB, } else if ("".equals(tmp[0]) || tmp[1] == null) { // ast expression is not a valid column name for table tmp[1] = colInfo.getInternalName(); + } else if (newRR.get(alias, tmp[1]) != null) { + // Duplicate alias escaping the subquery boundary: tolerated for positional use + // (HIVE-19770), but poison the name so a later by-name reference fails (HIVE-29580). + // Binding the duplicate to its internal name here is deliberate, not redundant: + // putWithCheck would otherwise do it via its own fallback AND call keepAmbiguousInfo, + // whose reference-time throw in RowResolver.get would then shadow this marker with a + // differently formatted message. Do not "simplify" this line away. + newRR.get(alias, tmp[1]).setAmbiguousName(true); + tmp[1] = colInfo.getInternalName(); } newRR.putWithCheck(alias, tmp[1], colInfo.getInternalName(), newCi); } diff --git a/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java b/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java index 7042cff53874..dc6143e0f0f4 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java @@ -4014,6 +4014,7 @@ Integer genColListRegex(String colRegex, String tabAlias, ASTNode sel, colList.add(Pair.of(colInfo, colSrcRR)); oColInfo = new ColumnInfo(getColumnInternalName(pos), colInfo.getType(), colInfo.getTabAlias(), colInfo.getIsVirtualCol(), colInfo.isHiddenVirtualCol()); + oColInfo.setAmbiguousName(colInfo.hasAmbiguousName()); inputColsProcessed.put(colInfo, oColInfo); } if (ensureUniqueCols) { @@ -4101,6 +4102,7 @@ Integer genColListRegex(String colRegex, String tabAlias, ASTNode sel, colList.add(Pair.of(colInfo, input)); oColInfo = new ColumnInfo(getColumnInternalName(pos), colInfo.getType(), colInfo.getTabAlias(), colInfo.getIsVirtualCol(), colInfo.isHiddenVirtualCol()); + oColInfo.setAmbiguousName(colInfo.hasAmbiguousName()); inputColsProcessed.put(colInfo, oColInfo); } assert nonNull(tmp); @@ -7988,6 +7990,9 @@ protected Operator genFileSinkPlan(String dest, QB qb, Operator input) if (tblDesc != null) { tblDesc.setCols(new ArrayList<>(fieldSchemas)); tblDesc.setPartCols(new ArrayList<>(partitionColumns)); + // must precede the column-stats auto-gather pipeline, which fails on duplicates + // with a misleading "ambiguous column reference" + ParseUtils.validateColumnNameUniqueness(tblDesc.getCols()); } else if (viewDesc != null) { viewDesc.setCols(new ArrayList<>(fieldSchemas)); viewDesc.setPartCols(new ArrayList<>(partitionColumns)); diff --git a/ql/src/java/org/apache/hadoop/hive/ql/parse/type/JoinCondTypeCheckProcFactory.java b/ql/src/java/org/apache/hadoop/hive/ql/parse/type/JoinCondTypeCheckProcFactory.java index 6ebbbb7f7bba..8586cafa07dd 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/parse/type/JoinCondTypeCheckProcFactory.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/parse/type/JoinCondTypeCheckProcFactory.java @@ -87,6 +87,7 @@ public Object process(Node nd, Stack stack, NodeProcessorCtx procCtx, if (!qualifiedAccess) { colInfo = getColInfo(ctx, null, tableOrCol, expr); // It's a column. + checkAmbiguousName(colInfo); return exprFactory.createColumnRefExpr(colInfo, ctx.getInputRRList()); } else if (hasTableAlias(ctx, tableOrCol, expr)) { return null; @@ -179,6 +180,7 @@ protected T processQualifiedColRef(TypeCheckCtx ctx, ASTNode expr, ErrorMsg.INVALID_COLUMN.getMsg(), expr.getChild(1)), expr); return null; } + checkAmbiguousName(colInfo); ColumnInfo newColumnInfo = new ColumnInfo(colInfo); newColumnInfo.setTabAlias(tableAlias); List listRR = new ArrayList<>(jctx.getInputRRList()); diff --git a/ql/src/java/org/apache/hadoop/hive/ql/parse/type/TypeCheckProcFactory.java b/ql/src/java/org/apache/hadoop/hive/ql/parse/type/TypeCheckProcFactory.java index 1eb1d17297f7..778073d8e080 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/parse/type/TypeCheckProcFactory.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/parse/type/TypeCheckProcFactory.java @@ -594,6 +594,13 @@ protected IntervalExprProcessor getIntervalExprProcessor() { return new IntervalExprProcessor(); } + static void checkAmbiguousName(ColumnInfo colInfo) throws SemanticException { + if (colInfo != null && colInfo.hasAmbiguousName()) { + throw new SemanticException(ErrorMsg.AMBIGUOUS_COLUMN.getMsg( + colInfo.getAlias() + " in " + colInfo.getTabAlias())); + } + } + /** * Processor for table columns. */ @@ -659,6 +666,7 @@ public Object process(Node nd, Stack stack, NodeProcessorCtx procCtx, return null; } // It's a column. + checkAmbiguousName(colInfo); return exprFactory.toExpr(colInfo, usedRR, offset); } else { // It's a table alias. @@ -693,6 +701,7 @@ public Object process(Node nd, Stack stack, NodeProcessorCtx procCtx, } } else { // It's a column. + checkAmbiguousName(colInfo); return exprFactory.toExpr(colInfo, usedRR, offset); } } @@ -1299,6 +1308,7 @@ protected T processQualifiedColRef(TypeCheckCtx ctx, ASTNode expr, ErrorMsg.INVALID_COLUMN.getMsg(), expr.getChild(1)), expr); return null; } + checkAmbiguousName(colInfo); return exprFactory.toExpr(colInfo, usedRR, offset); } diff --git a/ql/src/test/org/apache/hadoop/hive/ql/parse/type/TestAmbiguousColumnName.java b/ql/src/test/org/apache/hadoop/hive/ql/parse/type/TestAmbiguousColumnName.java new file mode 100644 index 000000000000..8832ffcbfd3e --- /dev/null +++ b/ql/src/test/org/apache/hadoop/hive/ql/parse/type/TestAmbiguousColumnName.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hadoop.hive.ql.parse.type; + +import org.apache.hadoop.hive.ql.exec.ColumnInfo; +import org.apache.hadoop.hive.ql.parse.SemanticException; +import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoFactory; +import org.junit.Assert; +import org.junit.Test; + +public class TestAmbiguousColumnName { + + private static ColumnInfo colInfo() { + ColumnInfo colInfo = new ColumnInfo("_col0", TypeInfoFactory.stringTypeInfo, "t", false); + colInfo.setAlias("c"); + return colInfo; + } + + @Test + public void testCopyConstructorPreservesAmbiguousName() { + ColumnInfo original = colInfo(); + original.setAmbiguousName(true); + Assert.assertTrue(new ColumnInfo(original).hasAmbiguousName()); + } + + @Test + public void testCheckAmbiguousNameThrows() { + ColumnInfo marked = colInfo(); + marked.setAmbiguousName(true); + try { + TypeCheckProcFactory.checkAmbiguousName(marked); + Assert.fail("expected SemanticException"); + } catch (SemanticException e) { + Assert.assertTrue(e.getMessage(), e.getMessage().contains("Ambiguous column reference c in t")); + } + } + + @Test + public void testCheckAmbiguousNameNoThrow() throws SemanticException { + TypeCheckProcFactory.checkAmbiguousName(colInfo()); + } +} diff --git a/ql/src/test/queries/clientnegative/ambiguous_col_2_noncbo.q b/ql/src/test/queries/clientnegative/ambiguous_col_2_noncbo.q new file mode 100644 index 000000000000..6608bac70b6e --- /dev/null +++ b/ql/src/test/queries/clientnegative/ambiguous_col_2_noncbo.q @@ -0,0 +1,3 @@ +set hive.cbo.enable=false; +create table t1nc (c1 int); +explain select t.c1 from (select t11.c1, t12.c1 from t1nc as t11 inner join t1nc as t12 on t11.c1 = t12.c1) as t; diff --git a/ql/src/test/queries/clientnegative/ambiguous_col_aggregate_noncbo.q b/ql/src/test/queries/clientnegative/ambiguous_col_aggregate_noncbo.q new file mode 100644 index 000000000000..46c7e07f7b58 --- /dev/null +++ b/ql/src/test/queries/clientnegative/ambiguous_col_aggregate_noncbo.q @@ -0,0 +1,3 @@ +--! qt:dataset:src +set hive.cbo.enable=false; +select count(*) from (select key, key from src) subq; diff --git a/ql/src/test/queries/clientnegative/ambiguous_col_cte.q b/ql/src/test/queries/clientnegative/ambiguous_col_cte.q new file mode 100644 index 000000000000..77917888fa99 --- /dev/null +++ b/ql/src/test/queries/clientnegative/ambiguous_col_cte.q @@ -0,0 +1,3 @@ +with bse as (select 'a' as delivery_date, concat('a') as delivery_date), + tpm as (select * from bse) +select tpm.delivery_date from tpm; diff --git a/ql/src/test/queries/clientnegative/ambiguous_col_cte_noncbo.q b/ql/src/test/queries/clientnegative/ambiguous_col_cte_noncbo.q new file mode 100644 index 000000000000..d70bdbf38035 --- /dev/null +++ b/ql/src/test/queries/clientnegative/ambiguous_col_cte_noncbo.q @@ -0,0 +1,4 @@ +set hive.cbo.enable=false; +with bse as (select 'a' as delivery_date, concat('a') as delivery_date), + tpm as (select * from bse) +select tpm.delivery_date from tpm; diff --git a/ql/src/test/queries/clientnegative/ambiguous_col_cte_unreferenced_noncbo.q b/ql/src/test/queries/clientnegative/ambiguous_col_cte_unreferenced_noncbo.q new file mode 100644 index 000000000000..42be3a8d6ffb --- /dev/null +++ b/ql/src/test/queries/clientnegative/ambiguous_col_cte_unreferenced_noncbo.q @@ -0,0 +1,3 @@ +set hive.cbo.enable=false; +with c1 as (select 'a' as c, 'b' as c, 'x' as d) +select d from c1; diff --git a/ql/src/test/queries/clientnegative/ambiguous_col_distinct_window.q b/ql/src/test/queries/clientnegative/ambiguous_col_distinct_window.q new file mode 100644 index 000000000000..460aee697f6b --- /dev/null +++ b/ql/src/test/queries/clientnegative/ambiguous_col_distinct_window.q @@ -0,0 +1 @@ +select x.c from (select distinct *, rank() over (order by d) r from (select 'a' as c, 'b' as c, 'x' as d) t) x; diff --git a/ql/src/test/queries/clientnegative/ambiguous_col_exists_having_noncbo.q b/ql/src/test/queries/clientnegative/ambiguous_col_exists_having_noncbo.q new file mode 100644 index 000000000000..0dcbe35d1980 --- /dev/null +++ b/ql/src/test/queries/clientnegative/ambiguous_col_exists_having_noncbo.q @@ -0,0 +1,3 @@ +--! qt:dataset:src +set hive.cbo.enable=false; +select value, count(1) from src group by value having exists (select 'x' as c, 'y' as c from src b where b.value = src.value); diff --git a/ql/src/test/queries/clientnegative/ambiguous_col_exists_noncbo.q b/ql/src/test/queries/clientnegative/ambiguous_col_exists_noncbo.q new file mode 100644 index 000000000000..10afc68f2492 --- /dev/null +++ b/ql/src/test/queries/clientnegative/ambiguous_col_exists_noncbo.q @@ -0,0 +1,3 @@ +--! qt:dataset:src +set hive.cbo.enable=false; +select key from src a where exists (select 'x' as c, 'y' as c from src b where b.key = a.key); diff --git a/ql/src/test/queries/clientnegative/ambiguous_col_join_cond.q b/ql/src/test/queries/clientnegative/ambiguous_col_join_cond.q new file mode 100644 index 000000000000..d48d8215a7f7 --- /dev/null +++ b/ql/src/test/queries/clientnegative/ambiguous_col_join_cond.q @@ -0,0 +1,7 @@ +-- the duplicate alias is referenced only in the join condition, via a qualified name. +-- Unparse translation is disabled below on purpose: when it is on, the ON clause is also +-- walked by the generic type check, which would make this test pass even if the ambiguity +-- check in JoinCondTypeCheckProcFactory were removed. +set hive.materializedview.rewriting.sql=false; +set hive.materializedview.rewriting.sql.subquery=false; +select t.d from (select 'a' as c, 'b' as c, 'x' as d) t join (select 'a' as e) u on t.c = u.e; diff --git a/ql/src/test/queries/clientnegative/ambiguous_col_join_cond_unqual.q b/ql/src/test/queries/clientnegative/ambiguous_col_join_cond_unqual.q new file mode 100644 index 000000000000..d05f686c6fc4 --- /dev/null +++ b/ql/src/test/queries/clientnegative/ambiguous_col_join_cond_unqual.q @@ -0,0 +1,5 @@ +-- same as ambiguous_col_join_cond.q but the reference is unqualified, which is resolved by a +-- different processor override. See that file for why unparse translation is disabled here. +set hive.materializedview.rewriting.sql=false; +set hive.materializedview.rewriting.sql.subquery=false; +select t.d from (select 'a' as c, 'b' as c, 'x' as d) t join (select 'a' as e) u on c = u.e; diff --git a/ql/src/test/queries/clientnegative/ambiguous_col_join_using.q b/ql/src/test/queries/clientnegative/ambiguous_col_join_using.q new file mode 100644 index 000000000000..3d87fb4c3f77 --- /dev/null +++ b/ql/src/test/queries/clientnegative/ambiguous_col_join_using.q @@ -0,0 +1 @@ +select t.c from (select * from (select 'a' as c, 'b' as c) s join (select 'a' as c) u using (c)) t; diff --git a/ql/src/test/queries/clientnegative/ambiguous_col_join_wildcard_noncbo.q b/ql/src/test/queries/clientnegative/ambiguous_col_join_wildcard_noncbo.q new file mode 100644 index 000000000000..51512c86f12a --- /dev/null +++ b/ql/src/test/queries/clientnegative/ambiguous_col_join_wildcard_noncbo.q @@ -0,0 +1,4 @@ +set hive.cbo.enable=false; +create table wj3 (k int, v int); +create table wj4 (k int, w int); +select t.v from (select a.*, b.* from wj3 a join wj4 b on a.k = b.k) t; diff --git a/ql/src/test/queries/clientnegative/ambiguous_col_lateral_view_alias.q b/ql/src/test/queries/clientnegative/ambiguous_col_lateral_view_alias.q new file mode 100644 index 000000000000..1007f67229ae --- /dev/null +++ b/ql/src/test/queries/clientnegative/ambiguous_col_lateral_view_alias.q @@ -0,0 +1,7 @@ +-- The lateral view reuses the table alias, so the exploded column collides with the base table +-- column under the same table alias. This is caught by the reference-time check in +-- RowResolver.get (ambiguousColumns), not by the duplicate-alias marker: the message form +-- "Ambiguous column reference: t.c" identifies that path. Keep this test: it is the only +-- coverage of that check, which would otherwise look like dead code and get removed. +create table lv_dup_alias (c int, arr array); +select t.c from lv_dup_alias t lateral view explode(t.arr) t as c; diff --git a/ql/src/test/queries/clientnegative/ambiguous_col_nested_star_noncbo.q b/ql/src/test/queries/clientnegative/ambiguous_col_nested_star_noncbo.q new file mode 100644 index 000000000000..117e84a6cf94 --- /dev/null +++ b/ql/src/test/queries/clientnegative/ambiguous_col_nested_star_noncbo.q @@ -0,0 +1,2 @@ +set hive.cbo.enable=false; +select * from (select * from (select 'a' as c, 'b' as c) a) b; diff --git a/ql/src/test/queries/clientnegative/ambiguous_col_noncbo.q b/ql/src/test/queries/clientnegative/ambiguous_col_noncbo.q new file mode 100644 index 000000000000..b7dd03bbcfc9 --- /dev/null +++ b/ql/src/test/queries/clientnegative/ambiguous_col_noncbo.q @@ -0,0 +1,3 @@ +--! qt:dataset:src +set hive.cbo.enable=false; +FROM (SELECT key, concat(value) AS key FROM src) a SELECT a.key; diff --git a/ql/src/test/queries/clientnegative/ambiguous_col_union.q b/ql/src/test/queries/clientnegative/ambiguous_col_union.q new file mode 100644 index 000000000000..eaa72afd8983 --- /dev/null +++ b/ql/src/test/queries/clientnegative/ambiguous_col_union.q @@ -0,0 +1 @@ +select t.c from (select 'a' as c, 'b' as c union all select 'x', 'y') t; diff --git a/ql/src/test/queries/clientnegative/ambiguous_col_union_noncbo.q b/ql/src/test/queries/clientnegative/ambiguous_col_union_noncbo.q new file mode 100644 index 000000000000..0316b7850008 --- /dev/null +++ b/ql/src/test/queries/clientnegative/ambiguous_col_union_noncbo.q @@ -0,0 +1,2 @@ +set hive.cbo.enable=false; +select t.c from (select 'a' as c, 'b' as c union all select 'x', 'y') t; diff --git a/ql/src/test/queries/clientnegative/ambiguous_col_unqualified_ref.q b/ql/src/test/queries/clientnegative/ambiguous_col_unqualified_ref.q new file mode 100644 index 000000000000..ecb497fb137e --- /dev/null +++ b/ql/src/test/queries/clientnegative/ambiguous_col_unqualified_ref.q @@ -0,0 +1,8 @@ +-- The inner CTE references the duplicated alias by an UNQUALIFIED name, which is resolved by +-- TypeCheckProcFactory.ColumnExprProcessor (the "It's a column" branch) rather than by +-- processQualifiedColRef. Every other ambiguity test uses a qualified reference, so this is the +-- only coverage of that check site. The error names the definition-site alias (bse), matching +-- what the non-CBO path reports for the same query. +with bse as (select 'a' as delivery_date, concat('a') as delivery_date), + tpm as (select delivery_date from bse) +select tpm.delivery_date from tpm; diff --git a/ql/src/test/queries/clientnegative/ambiguous_col_unreferenced_noncbo.q b/ql/src/test/queries/clientnegative/ambiguous_col_unreferenced_noncbo.q new file mode 100644 index 000000000000..544b50b90e07 --- /dev/null +++ b/ql/src/test/queries/clientnegative/ambiguous_col_unreferenced_noncbo.q @@ -0,0 +1,2 @@ +set hive.cbo.enable=false; +select t.d from (select 'a' as c, 'b' as c, 'x' as d) t; diff --git a/ql/src/test/queries/clientnegative/ambiguous_colref_in_gby_noncbo.q b/ql/src/test/queries/clientnegative/ambiguous_colref_in_gby_noncbo.q new file mode 100644 index 000000000000..72a61e4680de --- /dev/null +++ b/ql/src/test/queries/clientnegative/ambiguous_colref_in_gby_noncbo.q @@ -0,0 +1,3 @@ +set hive.cbo.enable=false; +create table t1gnc (a int); +select s.a from (select a, a from t1gnc) s group by s.a; diff --git a/ql/src/test/queries/clientnegative/ctas_dup_column.q b/ql/src/test/queries/clientnegative/ctas_dup_column.q new file mode 100644 index 000000000000..45247fdf9a89 --- /dev/null +++ b/ql/src/test/queries/clientnegative/ctas_dup_column.q @@ -0,0 +1 @@ +create table ctas_dup_col as select 'a' as c, 'b' as c; diff --git a/ql/src/test/queries/clientnegative/ctas_dup_column_join.q b/ql/src/test/queries/clientnegative/ctas_dup_column_join.q new file mode 100644 index 000000000000..f7318f6d2a9d --- /dev/null +++ b/ql/src/test/queries/clientnegative/ctas_dup_column_join.q @@ -0,0 +1,3 @@ +create table cj1 (k int, v int); +create table cj2 (k int, w int); +create table ctas_dup_join as select a.k, b.k from cj1 a join cj2 b on a.k = b.k; diff --git a/ql/src/test/queries/clientnegative/ctas_dup_column_join_noncbo.q b/ql/src/test/queries/clientnegative/ctas_dup_column_join_noncbo.q new file mode 100644 index 000000000000..6aa6e614da31 --- /dev/null +++ b/ql/src/test/queries/clientnegative/ctas_dup_column_join_noncbo.q @@ -0,0 +1,4 @@ +set hive.cbo.enable=false; +create table cj3 (k int, v int); +create table cj4 (k int, w int); +create table ctas_dup_join_nc as select a.k, b.k from cj3 a join cj4 b on a.k = b.k; diff --git a/ql/src/test/queries/clientnegative/ctas_dup_column_noncbo.q b/ql/src/test/queries/clientnegative/ctas_dup_column_noncbo.q new file mode 100644 index 000000000000..ff96420c548d --- /dev/null +++ b/ql/src/test/queries/clientnegative/ctas_dup_column_noncbo.q @@ -0,0 +1,2 @@ +set hive.cbo.enable=false; +create table ctas_dup_col_noncbo as select 'a' as c, 'b' as c; diff --git a/ql/src/test/queries/clientpositive/ambiguous_col_tolerated.q b/ql/src/test/queries/clientpositive/ambiguous_col_tolerated.q new file mode 100644 index 000000000000..1864cb885bb4 --- /dev/null +++ b/ql/src/test/queries/clientpositive/ambiguous_col_tolerated.q @@ -0,0 +1,14 @@ +select 'a' as c, 'b' as c; +select 'a' as c, 'b' as c order by c; +select * from (select 'a' as c, 'b' as c) t; +create table dup_alias_ins (x string, y string); +insert into dup_alias_ins select 'a' as c, 'b' as c; +select x, y from dup_alias_ins; + +set hive.cbo.enable=false; + +select 'a' as c, 'b' as c; +select 'a' as c, 'b' as c order by c; +select * from (select 'a' as c, 'b' as c) t; +insert into dup_alias_ins select 'c' as c, 'd' as c; +select x, y from dup_alias_ins order by x; diff --git a/ql/src/test/queries/clientpositive/ambiguous_col_unreferenced_tolerated.q b/ql/src/test/queries/clientpositive/ambiguous_col_unreferenced_tolerated.q new file mode 100644 index 000000000000..6fc2eaaf8a1e --- /dev/null +++ b/ql/src/test/queries/clientpositive/ambiguous_col_unreferenced_tolerated.q @@ -0,0 +1,13 @@ +--! qt:dataset:src +select t.d from (select 'a' as c, 'b' as c, 'x' as d) t; +with c1 as (select 'a' as c, 'b' as c, 'x' as d) +select d from c1; +select count(1) from (select 'a' as c, 'b' as c) t; +select count(*) from (select key, key from src) subq; +create table wjt1 (k int, v int); +create table wjt2 (k int, w int); +select t.v from (select a.*, b.* from wjt1 a join wjt2 b on a.k = b.k) t; +select * from (select * from (select 'a' as c, 'b' as c) a) b; +select count(*) from src a where exists (select 'x' as c, 'y' as c from src b where b.key = a.key); +select count(*) from src where exists (select 'a' as c, 'b' as c from src); +select count(*) from (select value from src group by value having exists (select 'x' as c, 'y' as c from src b where b.value = src.value)) t; diff --git a/ql/src/test/results/clientnegative/ambiguous_col.q.out b/ql/src/test/results/clientnegative/ambiguous_col.q.out index 170e277d0ee3..a2915a4a5d3d 100644 --- a/ql/src/test/results/clientnegative/ambiguous_col.q.out +++ b/ql/src/test/results/clientnegative/ambiguous_col.q.out @@ -1 +1 @@ -FAILED: SemanticException Ambiguous column reference: a.key +FAILED: SemanticException [Error 10007]: Ambiguous column reference key in a diff --git a/ql/src/test/results/clientnegative/ambiguous_col_2.q.out b/ql/src/test/results/clientnegative/ambiguous_col_2.q.out index bc6fb4d112a5..ac4bd4063f24 100644 --- a/ql/src/test/results/clientnegative/ambiguous_col_2.q.out +++ b/ql/src/test/results/clientnegative/ambiguous_col_2.q.out @@ -6,4 +6,4 @@ POSTHOOK: query: create table t1(c1 int) POSTHOOK: type: CREATETABLE POSTHOOK: Output: database:default POSTHOOK: Output: default@t1 -FAILED: SemanticException Ambiguous column reference: t.c1 +FAILED: SemanticException [Error 10007]: Ambiguous column reference c1 in t diff --git a/ql/src/test/results/clientnegative/ambiguous_col_2_noncbo.q.out b/ql/src/test/results/clientnegative/ambiguous_col_2_noncbo.q.out new file mode 100644 index 000000000000..d6ce2f43b330 --- /dev/null +++ b/ql/src/test/results/clientnegative/ambiguous_col_2_noncbo.q.out @@ -0,0 +1,9 @@ +PREHOOK: query: create table t1nc (c1 int) +PREHOOK: type: CREATETABLE +PREHOOK: Output: database:default +PREHOOK: Output: default@t1nc +POSTHOOK: query: create table t1nc (c1 int) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: database:default +POSTHOOK: Output: default@t1nc +FAILED: SemanticException [Error 10007]: Ambiguous column reference c1 in t diff --git a/ql/src/test/results/clientnegative/ambiguous_col_aggregate_noncbo.q.out b/ql/src/test/results/clientnegative/ambiguous_col_aggregate_noncbo.q.out new file mode 100644 index 000000000000..40952cdc22bb --- /dev/null +++ b/ql/src/test/results/clientnegative/ambiguous_col_aggregate_noncbo.q.out @@ -0,0 +1 @@ +FAILED: SemanticException [Error 10007]: Ambiguous column reference key in subq diff --git a/ql/src/test/results/clientnegative/ambiguous_col_cte.q.out b/ql/src/test/results/clientnegative/ambiguous_col_cte.q.out new file mode 100644 index 000000000000..19c117e1a600 --- /dev/null +++ b/ql/src/test/results/clientnegative/ambiguous_col_cte.q.out @@ -0,0 +1 @@ +FAILED: SemanticException [Error 10007]: Ambiguous column reference delivery_date in tpm diff --git a/ql/src/test/results/clientnegative/ambiguous_col_cte_noncbo.q.out b/ql/src/test/results/clientnegative/ambiguous_col_cte_noncbo.q.out new file mode 100644 index 000000000000..533d31a557c0 --- /dev/null +++ b/ql/src/test/results/clientnegative/ambiguous_col_cte_noncbo.q.out @@ -0,0 +1 @@ +FAILED: SemanticException [Error 10007]: Ambiguous column reference delivery_date in bse diff --git a/ql/src/test/results/clientnegative/ambiguous_col_cte_unreferenced_noncbo.q.out b/ql/src/test/results/clientnegative/ambiguous_col_cte_unreferenced_noncbo.q.out new file mode 100644 index 000000000000..bb9278bc19fe --- /dev/null +++ b/ql/src/test/results/clientnegative/ambiguous_col_cte_unreferenced_noncbo.q.out @@ -0,0 +1 @@ +FAILED: SemanticException [Error 10007]: Ambiguous column reference c in c1 diff --git a/ql/src/test/results/clientnegative/ambiguous_col_distinct_window.q.out b/ql/src/test/results/clientnegative/ambiguous_col_distinct_window.q.out new file mode 100644 index 000000000000..a19c1eba9da2 --- /dev/null +++ b/ql/src/test/results/clientnegative/ambiguous_col_distinct_window.q.out @@ -0,0 +1 @@ +FAILED: SemanticException [Error 10007]: Ambiguous column reference c in x diff --git a/ql/src/test/results/clientnegative/ambiguous_col_exists_having_noncbo.q.out b/ql/src/test/results/clientnegative/ambiguous_col_exists_having_noncbo.q.out new file mode 100644 index 000000000000..f18587c08360 --- /dev/null +++ b/ql/src/test/results/clientnegative/ambiguous_col_exists_having_noncbo.q.out @@ -0,0 +1 @@ +FAILED: SemanticException [Error 10007]: Ambiguous column reference c in sq_1 diff --git a/ql/src/test/results/clientnegative/ambiguous_col_exists_noncbo.q.out b/ql/src/test/results/clientnegative/ambiguous_col_exists_noncbo.q.out new file mode 100644 index 000000000000..f18587c08360 --- /dev/null +++ b/ql/src/test/results/clientnegative/ambiguous_col_exists_noncbo.q.out @@ -0,0 +1 @@ +FAILED: SemanticException [Error 10007]: Ambiguous column reference c in sq_1 diff --git a/ql/src/test/results/clientnegative/ambiguous_col_join_cond.q.out b/ql/src/test/results/clientnegative/ambiguous_col_join_cond.q.out new file mode 100644 index 000000000000..58aee7c08949 --- /dev/null +++ b/ql/src/test/results/clientnegative/ambiguous_col_join_cond.q.out @@ -0,0 +1 @@ +FAILED: SemanticException [Error 10007]: Ambiguous column reference c in t diff --git a/ql/src/test/results/clientnegative/ambiguous_col_join_cond_unqual.q.out b/ql/src/test/results/clientnegative/ambiguous_col_join_cond_unqual.q.out new file mode 100644 index 000000000000..58aee7c08949 --- /dev/null +++ b/ql/src/test/results/clientnegative/ambiguous_col_join_cond_unqual.q.out @@ -0,0 +1 @@ +FAILED: SemanticException [Error 10007]: Ambiguous column reference c in t diff --git a/ql/src/test/results/clientnegative/ambiguous_col_join_using.q.out b/ql/src/test/results/clientnegative/ambiguous_col_join_using.q.out new file mode 100644 index 000000000000..2f33a44abe85 --- /dev/null +++ b/ql/src/test/results/clientnegative/ambiguous_col_join_using.q.out @@ -0,0 +1 @@ +FAILED: SemanticException [Error 10007]: Ambiguous column reference c in s diff --git a/ql/src/test/results/clientnegative/ambiguous_col_join_wildcard_noncbo.q.out b/ql/src/test/results/clientnegative/ambiguous_col_join_wildcard_noncbo.q.out new file mode 100644 index 000000000000..d9e59b52badc --- /dev/null +++ b/ql/src/test/results/clientnegative/ambiguous_col_join_wildcard_noncbo.q.out @@ -0,0 +1,17 @@ +PREHOOK: query: create table wj3 (k int, v int) +PREHOOK: type: CREATETABLE +PREHOOK: Output: database:default +PREHOOK: Output: default@wj3 +POSTHOOK: query: create table wj3 (k int, v int) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: database:default +POSTHOOK: Output: default@wj3 +PREHOOK: query: create table wj4 (k int, w int) +PREHOOK: type: CREATETABLE +PREHOOK: Output: database:default +PREHOOK: Output: default@wj4 +POSTHOOK: query: create table wj4 (k int, w int) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: database:default +POSTHOOK: Output: default@wj4 +FAILED: SemanticException [Error 10007]: Ambiguous column reference k in t diff --git a/ql/src/test/results/clientnegative/ambiguous_col_lateral_view_alias.q.out b/ql/src/test/results/clientnegative/ambiguous_col_lateral_view_alias.q.out new file mode 100644 index 000000000000..df3a1e7efdd7 --- /dev/null +++ b/ql/src/test/results/clientnegative/ambiguous_col_lateral_view_alias.q.out @@ -0,0 +1,9 @@ +PREHOOK: query: create table lv_dup_alias (c int, arr array) +PREHOOK: type: CREATETABLE +PREHOOK: Output: database:default +PREHOOK: Output: default@lv_dup_alias +POSTHOOK: query: create table lv_dup_alias (c int, arr array) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: database:default +POSTHOOK: Output: default@lv_dup_alias +FAILED: SemanticException Ambiguous column reference: t.c diff --git a/ql/src/test/results/clientnegative/ambiguous_col_nested_star_noncbo.q.out b/ql/src/test/results/clientnegative/ambiguous_col_nested_star_noncbo.q.out new file mode 100644 index 000000000000..53d5a7a85c38 --- /dev/null +++ b/ql/src/test/results/clientnegative/ambiguous_col_nested_star_noncbo.q.out @@ -0,0 +1 @@ +FAILED: SemanticException [Error 10007]: Ambiguous column reference c in a diff --git a/ql/src/test/results/clientnegative/ambiguous_col_noncbo.q.out b/ql/src/test/results/clientnegative/ambiguous_col_noncbo.q.out new file mode 100644 index 000000000000..a2915a4a5d3d --- /dev/null +++ b/ql/src/test/results/clientnegative/ambiguous_col_noncbo.q.out @@ -0,0 +1 @@ +FAILED: SemanticException [Error 10007]: Ambiguous column reference key in a diff --git a/ql/src/test/results/clientnegative/ambiguous_col_union.q.out b/ql/src/test/results/clientnegative/ambiguous_col_union.q.out new file mode 100644 index 000000000000..58aee7c08949 --- /dev/null +++ b/ql/src/test/results/clientnegative/ambiguous_col_union.q.out @@ -0,0 +1 @@ +FAILED: SemanticException [Error 10007]: Ambiguous column reference c in t diff --git a/ql/src/test/results/clientnegative/ambiguous_col_union_noncbo.q.out b/ql/src/test/results/clientnegative/ambiguous_col_union_noncbo.q.out new file mode 100644 index 000000000000..b75f8a02dc10 --- /dev/null +++ b/ql/src/test/results/clientnegative/ambiguous_col_union_noncbo.q.out @@ -0,0 +1 @@ +FAILED: SemanticException [Error 10007]: Ambiguous column reference c in __u1-subquery1 diff --git a/ql/src/test/results/clientnegative/ambiguous_col_unqualified_ref.q.out b/ql/src/test/results/clientnegative/ambiguous_col_unqualified_ref.q.out new file mode 100644 index 000000000000..533d31a557c0 --- /dev/null +++ b/ql/src/test/results/clientnegative/ambiguous_col_unqualified_ref.q.out @@ -0,0 +1 @@ +FAILED: SemanticException [Error 10007]: Ambiguous column reference delivery_date in bse diff --git a/ql/src/test/results/clientnegative/ambiguous_col_unreferenced_noncbo.q.out b/ql/src/test/results/clientnegative/ambiguous_col_unreferenced_noncbo.q.out new file mode 100644 index 000000000000..58aee7c08949 --- /dev/null +++ b/ql/src/test/results/clientnegative/ambiguous_col_unreferenced_noncbo.q.out @@ -0,0 +1 @@ +FAILED: SemanticException [Error 10007]: Ambiguous column reference c in t diff --git a/ql/src/test/results/clientnegative/ambiguous_colref_in_gby_noncbo.q.out b/ql/src/test/results/clientnegative/ambiguous_colref_in_gby_noncbo.q.out new file mode 100644 index 000000000000..58234a65ac4f --- /dev/null +++ b/ql/src/test/results/clientnegative/ambiguous_colref_in_gby_noncbo.q.out @@ -0,0 +1,9 @@ +PREHOOK: query: create table t1gnc (a int) +PREHOOK: type: CREATETABLE +PREHOOK: Output: database:default +PREHOOK: Output: default@t1gnc +POSTHOOK: query: create table t1gnc (a int) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: database:default +POSTHOOK: Output: default@t1gnc +FAILED: SemanticException [Error 10007]: Ambiguous column reference a in s diff --git a/ql/src/test/results/clientnegative/cbo_ambiguous_colref_in_gby.q.out b/ql/src/test/results/clientnegative/cbo_ambiguous_colref_in_gby.q.out index c3b7baacdf15..8f04d4e45a4d 100644 --- a/ql/src/test/results/clientnegative/cbo_ambiguous_colref_in_gby.q.out +++ b/ql/src/test/results/clientnegative/cbo_ambiguous_colref_in_gby.q.out @@ -6,4 +6,4 @@ POSTHOOK: query: create table t1 (a int) POSTHOOK: type: CREATETABLE POSTHOOK: Output: database:default POSTHOOK: Output: default@t1 -FAILED: SemanticException Ambiguous column reference: s.a +FAILED: SemanticException [Error 10007]: Ambiguous column reference a in s diff --git a/ql/src/test/results/clientnegative/ctas_dup_column.q.out b/ql/src/test/results/clientnegative/ctas_dup_column.q.out new file mode 100644 index 000000000000..60c2f38795a2 --- /dev/null +++ b/ql/src/test/results/clientnegative/ctas_dup_column.q.out @@ -0,0 +1 @@ +FAILED: SemanticException [Error 10036]: Duplicate column name: c diff --git a/ql/src/test/results/clientnegative/ctas_dup_column_join.q.out b/ql/src/test/results/clientnegative/ctas_dup_column_join.q.out new file mode 100644 index 000000000000..8746031f6caa --- /dev/null +++ b/ql/src/test/results/clientnegative/ctas_dup_column_join.q.out @@ -0,0 +1,17 @@ +PREHOOK: query: create table cj1 (k int, v int) +PREHOOK: type: CREATETABLE +PREHOOK: Output: database:default +PREHOOK: Output: default@cj1 +POSTHOOK: query: create table cj1 (k int, v int) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: database:default +POSTHOOK: Output: default@cj1 +PREHOOK: query: create table cj2 (k int, w int) +PREHOOK: type: CREATETABLE +PREHOOK: Output: database:default +PREHOOK: Output: default@cj2 +POSTHOOK: query: create table cj2 (k int, w int) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: database:default +POSTHOOK: Output: default@cj2 +FAILED: SemanticException [Error 10036]: Duplicate column name: k diff --git a/ql/src/test/results/clientnegative/ctas_dup_column_join_noncbo.q.out b/ql/src/test/results/clientnegative/ctas_dup_column_join_noncbo.q.out new file mode 100644 index 000000000000..47007d97e78e --- /dev/null +++ b/ql/src/test/results/clientnegative/ctas_dup_column_join_noncbo.q.out @@ -0,0 +1,17 @@ +PREHOOK: query: create table cj3 (k int, v int) +PREHOOK: type: CREATETABLE +PREHOOK: Output: database:default +PREHOOK: Output: default@cj3 +POSTHOOK: query: create table cj3 (k int, v int) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: database:default +POSTHOOK: Output: default@cj3 +PREHOOK: query: create table cj4 (k int, w int) +PREHOOK: type: CREATETABLE +PREHOOK: Output: database:default +PREHOOK: Output: default@cj4 +POSTHOOK: query: create table cj4 (k int, w int) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: database:default +POSTHOOK: Output: default@cj4 +FAILED: SemanticException [Error 10036]: Duplicate column name: k diff --git a/ql/src/test/results/clientnegative/ctas_dup_column_noncbo.q.out b/ql/src/test/results/clientnegative/ctas_dup_column_noncbo.q.out new file mode 100644 index 000000000000..60c2f38795a2 --- /dev/null +++ b/ql/src/test/results/clientnegative/ctas_dup_column_noncbo.q.out @@ -0,0 +1 @@ +FAILED: SemanticException [Error 10036]: Duplicate column name: c diff --git a/ql/src/test/results/clientnegative/cte_col_alias_clash.q.out b/ql/src/test/results/clientnegative/cte_col_alias_clash.q.out index 686e3689d3cc..475dc7384b71 100644 --- a/ql/src/test/results/clientnegative/cte_col_alias_clash.q.out +++ b/ql/src/test/results/clientnegative/cte_col_alias_clash.q.out @@ -6,4 +6,4 @@ POSTHOOK: query: create table t1(int_col int, bigint_col bigint) POSTHOOK: type: CREATETABLE POSTHOOK: Output: database:default POSTHOOK: Output: default@t1 -FAILED: SemanticException Ambiguous column reference: .a +FAILED: SemanticException [Error 10007]: Ambiguous column reference a in cte1 diff --git a/ql/src/test/results/clientpositive/llap/ambiguous_col_tolerated.q.out b/ql/src/test/results/clientpositive/llap/ambiguous_col_tolerated.q.out new file mode 100644 index 000000000000..a0aa072f341a --- /dev/null +++ b/ql/src/test/results/clientpositive/llap/ambiguous_col_tolerated.q.out @@ -0,0 +1,101 @@ +PREHOOK: query: select 'a' as c, 'b' as c +PREHOOK: type: QUERY +PREHOOK: Input: _dummy_database@_dummy_table +#### A masked pattern was here #### +POSTHOOK: query: select 'a' as c, 'b' as c +POSTHOOK: type: QUERY +POSTHOOK: Input: _dummy_database@_dummy_table +#### A masked pattern was here #### +a b +PREHOOK: query: select 'a' as c, 'b' as c order by c +PREHOOK: type: QUERY +PREHOOK: Input: _dummy_database@_dummy_table +#### A masked pattern was here #### +POSTHOOK: query: select 'a' as c, 'b' as c order by c +POSTHOOK: type: QUERY +POSTHOOK: Input: _dummy_database@_dummy_table +#### A masked pattern was here #### +a b +PREHOOK: query: select * from (select 'a' as c, 'b' as c) t +PREHOOK: type: QUERY +PREHOOK: Input: _dummy_database@_dummy_table +#### A masked pattern was here #### +POSTHOOK: query: select * from (select 'a' as c, 'b' as c) t +POSTHOOK: type: QUERY +POSTHOOK: Input: _dummy_database@_dummy_table +#### A masked pattern was here #### +a b +PREHOOK: query: create table dup_alias_ins (x string, y string) +PREHOOK: type: CREATETABLE +PREHOOK: Output: database:default +PREHOOK: Output: default@dup_alias_ins +POSTHOOK: query: create table dup_alias_ins (x string, y string) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: database:default +POSTHOOK: Output: default@dup_alias_ins +PREHOOK: query: insert into dup_alias_ins select 'a' as c, 'b' as c +PREHOOK: type: QUERY +PREHOOK: Input: _dummy_database@_dummy_table +PREHOOK: Output: default@dup_alias_ins +POSTHOOK: query: insert into dup_alias_ins select 'a' as c, 'b' as c +POSTHOOK: type: QUERY +POSTHOOK: Input: _dummy_database@_dummy_table +POSTHOOK: Output: default@dup_alias_ins +POSTHOOK: Lineage: dup_alias_ins.x SIMPLE [] +POSTHOOK: Lineage: dup_alias_ins.y SIMPLE [] +PREHOOK: query: select x, y from dup_alias_ins +PREHOOK: type: QUERY +PREHOOK: Input: default@dup_alias_ins +#### A masked pattern was here #### +POSTHOOK: query: select x, y from dup_alias_ins +POSTHOOK: type: QUERY +POSTHOOK: Input: default@dup_alias_ins +#### A masked pattern was here #### +a b +PREHOOK: query: select 'a' as c, 'b' as c +PREHOOK: type: QUERY +PREHOOK: Input: _dummy_database@_dummy_table +#### A masked pattern was here #### +POSTHOOK: query: select 'a' as c, 'b' as c +POSTHOOK: type: QUERY +POSTHOOK: Input: _dummy_database@_dummy_table +#### A masked pattern was here #### +a b +PREHOOK: query: select 'a' as c, 'b' as c order by c +PREHOOK: type: QUERY +PREHOOK: Input: _dummy_database@_dummy_table +#### A masked pattern was here #### +POSTHOOK: query: select 'a' as c, 'b' as c order by c +POSTHOOK: type: QUERY +POSTHOOK: Input: _dummy_database@_dummy_table +#### A masked pattern was here #### +a b +PREHOOK: query: select * from (select 'a' as c, 'b' as c) t +PREHOOK: type: QUERY +PREHOOK: Input: _dummy_database@_dummy_table +#### A masked pattern was here #### +POSTHOOK: query: select * from (select 'a' as c, 'b' as c) t +POSTHOOK: type: QUERY +POSTHOOK: Input: _dummy_database@_dummy_table +#### A masked pattern was here #### +a b +PREHOOK: query: insert into dup_alias_ins select 'c' as c, 'd' as c +PREHOOK: type: QUERY +PREHOOK: Input: _dummy_database@_dummy_table +PREHOOK: Output: default@dup_alias_ins +POSTHOOK: query: insert into dup_alias_ins select 'c' as c, 'd' as c +POSTHOOK: type: QUERY +POSTHOOK: Input: _dummy_database@_dummy_table +POSTHOOK: Output: default@dup_alias_ins +POSTHOOK: Lineage: dup_alias_ins.x SIMPLE [] +POSTHOOK: Lineage: dup_alias_ins.y SIMPLE [] +PREHOOK: query: select x, y from dup_alias_ins order by x +PREHOOK: type: QUERY +PREHOOK: Input: default@dup_alias_ins +#### A masked pattern was here #### +POSTHOOK: query: select x, y from dup_alias_ins order by x +POSTHOOK: type: QUERY +POSTHOOK: Input: default@dup_alias_ins +#### A masked pattern was here #### +a b +c d diff --git a/ql/src/test/results/clientpositive/llap/ambiguous_col_unreferenced_tolerated.q.out b/ql/src/test/results/clientpositive/llap/ambiguous_col_unreferenced_tolerated.q.out new file mode 100644 index 000000000000..dc25bfa8bd04 --- /dev/null +++ b/ql/src/test/results/clientpositive/llap/ambiguous_col_unreferenced_tolerated.q.out @@ -0,0 +1,101 @@ +PREHOOK: query: select t.d from (select 'a' as c, 'b' as c, 'x' as d) t +PREHOOK: type: QUERY +PREHOOK: Input: _dummy_database@_dummy_table +#### A masked pattern was here #### +POSTHOOK: query: select t.d from (select 'a' as c, 'b' as c, 'x' as d) t +POSTHOOK: type: QUERY +POSTHOOK: Input: _dummy_database@_dummy_table +#### A masked pattern was here #### +x +PREHOOK: query: with c1 as (select 'a' as c, 'b' as c, 'x' as d) +select d from c1 +PREHOOK: type: QUERY +PREHOOK: Input: _dummy_database@_dummy_table +#### A masked pattern was here #### +POSTHOOK: query: with c1 as (select 'a' as c, 'b' as c, 'x' as d) +select d from c1 +POSTHOOK: type: QUERY +POSTHOOK: Input: _dummy_database@_dummy_table +#### A masked pattern was here #### +x +PREHOOK: query: select count(1) from (select 'a' as c, 'b' as c) t +PREHOOK: type: QUERY +PREHOOK: Input: _dummy_database@_dummy_table +#### A masked pattern was here #### +POSTHOOK: query: select count(1) from (select 'a' as c, 'b' as c) t +POSTHOOK: type: QUERY +POSTHOOK: Input: _dummy_database@_dummy_table +#### A masked pattern was here #### +1 +PREHOOK: query: select count(*) from (select key, key from src) subq +PREHOOK: type: QUERY +PREHOOK: Input: default@src +#### A masked pattern was here #### +POSTHOOK: query: select count(*) from (select key, key from src) subq +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +#### A masked pattern was here #### +500 +PREHOOK: query: create table wjt1 (k int, v int) +PREHOOK: type: CREATETABLE +PREHOOK: Output: database:default +PREHOOK: Output: default@wjt1 +POSTHOOK: query: create table wjt1 (k int, v int) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: database:default +POSTHOOK: Output: default@wjt1 +PREHOOK: query: create table wjt2 (k int, w int) +PREHOOK: type: CREATETABLE +PREHOOK: Output: database:default +PREHOOK: Output: default@wjt2 +POSTHOOK: query: create table wjt2 (k int, w int) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: database:default +POSTHOOK: Output: default@wjt2 +PREHOOK: query: select t.v from (select a.*, b.* from wjt1 a join wjt2 b on a.k = b.k) t +PREHOOK: type: QUERY +PREHOOK: Input: default@wjt1 +PREHOOK: Input: default@wjt2 +#### A masked pattern was here #### +POSTHOOK: query: select t.v from (select a.*, b.* from wjt1 a join wjt2 b on a.k = b.k) t +POSTHOOK: type: QUERY +POSTHOOK: Input: default@wjt1 +POSTHOOK: Input: default@wjt2 +#### A masked pattern was here #### +PREHOOK: query: select * from (select * from (select 'a' as c, 'b' as c) a) b +PREHOOK: type: QUERY +PREHOOK: Input: _dummy_database@_dummy_table +#### A masked pattern was here #### +POSTHOOK: query: select * from (select * from (select 'a' as c, 'b' as c) a) b +POSTHOOK: type: QUERY +POSTHOOK: Input: _dummy_database@_dummy_table +#### A masked pattern was here #### +a b +PREHOOK: query: select count(*) from src a where exists (select 'x' as c, 'y' as c from src b where b.key = a.key) +PREHOOK: type: QUERY +PREHOOK: Input: default@src +#### A masked pattern was here #### +POSTHOOK: query: select count(*) from src a where exists (select 'x' as c, 'y' as c from src b where b.key = a.key) +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +#### A masked pattern was here #### +500 +Warning: Shuffle Join MERGEJOIN[18][tables = [$hdt$_0, $hdt$_1]] in Stage 'Reducer 2' is a cross product +PREHOOK: query: select count(*) from src where exists (select 'a' as c, 'b' as c from src) +PREHOOK: type: QUERY +PREHOOK: Input: default@src +#### A masked pattern was here #### +POSTHOOK: query: select count(*) from src where exists (select 'a' as c, 'b' as c from src) +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +#### A masked pattern was here #### +500 +PREHOOK: query: select count(*) from (select value from src group by value having exists (select 'x' as c, 'y' as c from src b where b.value = src.value)) t +PREHOOK: type: QUERY +PREHOOK: Input: default@src +#### A masked pattern was here #### +POSTHOOK: query: select count(*) from (select value from src group by value having exists (select 'x' as c, 'y' as c from src b where b.value = src.value)) t +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +#### A masked pattern was here #### +309 From 3ce723056c48456c29c51d562b778ab8e2c76ce0 Mon Sep 17 00:00:00 2001 From: Konstantin Bereznyakov Date: Wed, 5 Aug 2026 12:51:24 -0700 Subject: [PATCH 2/3] HIVE-29580: merge fixes + CTAS corrections --- .../hadoop/hive/ql/parse/CalcitePlanner.java | 5 ----- .../hadoop/hive/ql/parse/SemanticAnalyzer.java | 3 --- .../hive/ql/parse/rewrite/MergeRewriter.java | 2 +- .../rewrite/sql/MultiInsertSqlGenerator.java | 12 ++++++++++++ .../queries/clientnegative/ambiguous_col_ctas.q | 9 +++++++++ .../queries/clientnegative/ambiguous_col_cte.q | 4 ++-- .../clientnegative/ambiguous_col_cte_noncbo.q | 4 ++-- .../ambiguous_col_unqualified_ref.q | 6 +++--- .../queries/clientnegative/ctas_dup_column.q | 1 - .../clientnegative/ctas_dup_column_join.q | 3 --- .../ctas_dup_column_join_noncbo.q | 4 ---- .../clientnegative/ctas_dup_column_noncbo.q | 2 -- .../clientnegative/ambiguous_col_ctas.q.out | 1 + .../clientnegative/ambiguous_col_cte.q.out | 2 +- .../ambiguous_col_cte_noncbo.q.out | 2 +- .../ambiguous_col_unqualified_ref.q.out | 2 +- .../clientnegative/ctas_dup_column.q.out | 1 - .../clientnegative/ctas_dup_column_join.q.out | 17 ----------------- .../ctas_dup_column_join_noncbo.q.out | 17 ----------------- .../clientnegative/ctas_dup_column_noncbo.q.out | 1 - 20 files changed, 33 insertions(+), 65 deletions(-) create mode 100644 ql/src/test/queries/clientnegative/ambiguous_col_ctas.q delete mode 100644 ql/src/test/queries/clientnegative/ctas_dup_column.q delete mode 100644 ql/src/test/queries/clientnegative/ctas_dup_column_join.q delete mode 100644 ql/src/test/queries/clientnegative/ctas_dup_column_join_noncbo.q delete mode 100644 ql/src/test/queries/clientnegative/ctas_dup_column_noncbo.q create mode 100644 ql/src/test/results/clientnegative/ambiguous_col_ctas.q.out delete mode 100644 ql/src/test/results/clientnegative/ctas_dup_column.q.out delete mode 100644 ql/src/test/results/clientnegative/ctas_dup_column_join.q.out delete mode 100644 ql/src/test/results/clientnegative/ctas_dup_column_join_noncbo.q.out delete mode 100644 ql/src/test/results/clientnegative/ctas_dup_column_noncbo.q.out diff --git a/ql/src/java/org/apache/hadoop/hive/ql/parse/CalcitePlanner.java b/ql/src/java/org/apache/hadoop/hive/ql/parse/CalcitePlanner.java index 266c6b07edcf..5edda6e42057 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/parse/CalcitePlanner.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/parse/CalcitePlanner.java @@ -1556,11 +1556,6 @@ public RelNode apply(RelOptCluster cluster, RelOptSchema relOptSchema, SchemaPlu resultSchema = convertRowSchemaToResultSetSchema(relToHiveRR.get(calcitePlan), (forViewCreation || getQB().isMaterializedView()) ? false : HiveConf.getBoolVar(conf, HiveConf.ConfVars.HIVE_RESULTSET_USE_UNIQUE_COLUMN_NAMES)); - if (getQB().isCTAS()) { - // check the non-uniquified names: getNewColAlias would rename a duplicate away - ParseUtils.validateColumnNameUniqueness( - convertRowSchemaToResultSetSchema(relToHiveRR.get(calcitePlan), false)); - } } catch (SemanticException e) { semanticException = e; throw new RuntimeException(e); diff --git a/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java b/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java index dc6143e0f0f4..d76cfb12fdcd 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java @@ -7990,9 +7990,6 @@ protected Operator genFileSinkPlan(String dest, QB qb, Operator input) if (tblDesc != null) { tblDesc.setCols(new ArrayList<>(fieldSchemas)); tblDesc.setPartCols(new ArrayList<>(partitionColumns)); - // must precede the column-stats auto-gather pipeline, which fails on duplicates - // with a misleading "ambiguous column reference" - ParseUtils.validateColumnNameUniqueness(tblDesc.getCols()); } else if (viewDesc != null) { viewDesc.setCols(new ArrayList<>(fieldSchemas)); viewDesc.setPartCols(new ArrayList<>(partitionColumns)); diff --git a/ql/src/java/org/apache/hadoop/hive/ql/parse/rewrite/MergeRewriter.java b/ql/src/java/org/apache/hadoop/hive/ql/parse/rewrite/MergeRewriter.java index f3a17b5c8b2a..1c32517f6883 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/parse/rewrite/MergeRewriter.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/parse/rewrite/MergeRewriter.java @@ -113,7 +113,7 @@ private void handleSource(boolean hasWhenNotMatchedClause, String sourceAlias, S sqlGenerator.append("FROM\n"); sqlGenerator.append("(SELECT "); sqlGenerator.appendAcidSelectColumns(Operation.MERGE); - sqlGenerator.appendAllColsOfTargetTable(); + sqlGenerator.appendNonPartitionColsOfTargetTable(); addSourceColumnsForRowLineage(isRowLineageSupported, sqlGenerator, "", conf); sqlGenerator.append(" FROM ").appendTargetTableName().append(") "); sqlGenerator.appendSubQueryAlias(); diff --git a/ql/src/java/org/apache/hadoop/hive/ql/parse/rewrite/sql/MultiInsertSqlGenerator.java b/ql/src/java/org/apache/hadoop/hive/ql/parse/rewrite/sql/MultiInsertSqlGenerator.java index 449449037a58..4b209ab531de 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/parse/rewrite/sql/MultiInsertSqlGenerator.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/parse/rewrite/sql/MultiInsertSqlGenerator.java @@ -169,6 +169,18 @@ public void appendAllColsOfTargetTable(String prefix) { public void appendAllColsOfTargetTable() { appendCols(targetTable.getAllCols(), FieldSchema::getName); } + + /** + * Appends the target table's columns, omitting the partition columns when the table uses native + * partitioning: appendAcidSelectColumns has already emitted those, and emitting them a second + * time yields a projection with duplicate column names, making any by-name reference to them + * ambiguous. Non-native tables (e.g. Iceberg) carry partition columns as regular columns, so for + * those all columns are appended. + */ + public void appendNonPartitionColsOfTargetTable() { + appendCols(targetTable.hasNonNativePartitionSupport() + ? targetTable.getAllCols() : targetTable.getCols(), FieldSchema::getName); + } public void appendCols(List columns, Function stringConverter) { appendCols(columns, null, null, stringConverter); diff --git a/ql/src/test/queries/clientnegative/ambiguous_col_ctas.q b/ql/src/test/queries/clientnegative/ambiguous_col_ctas.q new file mode 100644 index 000000000000..0183aeb93065 --- /dev/null +++ b/ql/src/test/queries/clientnegative/ambiguous_col_ctas.q @@ -0,0 +1,9 @@ +-- A CTAS whose SELECT contains a cross-alias ambiguous reference. Without the ambiguity check +-- this silently persists one arbitrarily-chosen candidate into a table ('FIRST', discarding +-- 'SECOND') and reports nothing, so every downstream reader treats the arbitrary choice as fact. +-- Keep this test if the check ever gains an exemption for statements Hive generates for itself +-- (rewritten MERGE/UPDATE/DELETE, materialised CTEs): a USER CTAS must never be exempted. +create table ctas_ambiguous_ref as + with bse as (select 'FIRST' as c, 'SECOND' as c), + tpm as (select * from bse) + select tpm.c from tpm; diff --git a/ql/src/test/queries/clientnegative/ambiguous_col_cte.q b/ql/src/test/queries/clientnegative/ambiguous_col_cte.q index 77917888fa99..4a6f15096cbb 100644 --- a/ql/src/test/queries/clientnegative/ambiguous_col_cte.q +++ b/ql/src/test/queries/clientnegative/ambiguous_col_cte.q @@ -1,3 +1,3 @@ -with bse as (select 'a' as delivery_date, concat('a') as delivery_date), +with bse as (select 'a' as c, 'b' as c), tpm as (select * from bse) -select tpm.delivery_date from tpm; +select tpm.c from tpm; diff --git a/ql/src/test/queries/clientnegative/ambiguous_col_cte_noncbo.q b/ql/src/test/queries/clientnegative/ambiguous_col_cte_noncbo.q index d70bdbf38035..8674dbde35fd 100644 --- a/ql/src/test/queries/clientnegative/ambiguous_col_cte_noncbo.q +++ b/ql/src/test/queries/clientnegative/ambiguous_col_cte_noncbo.q @@ -1,4 +1,4 @@ set hive.cbo.enable=false; -with bse as (select 'a' as delivery_date, concat('a') as delivery_date), +with bse as (select 'a' as c, 'b' as c), tpm as (select * from bse) -select tpm.delivery_date from tpm; +select tpm.c from tpm; diff --git a/ql/src/test/queries/clientnegative/ambiguous_col_unqualified_ref.q b/ql/src/test/queries/clientnegative/ambiguous_col_unqualified_ref.q index ecb497fb137e..1f9566d23afb 100644 --- a/ql/src/test/queries/clientnegative/ambiguous_col_unqualified_ref.q +++ b/ql/src/test/queries/clientnegative/ambiguous_col_unqualified_ref.q @@ -3,6 +3,6 @@ -- processQualifiedColRef. Every other ambiguity test uses a qualified reference, so this is the -- only coverage of that check site. The error names the definition-site alias (bse), matching -- what the non-CBO path reports for the same query. -with bse as (select 'a' as delivery_date, concat('a') as delivery_date), - tpm as (select delivery_date from bse) -select tpm.delivery_date from tpm; +with bse as (select 'a' as c, 'b' as c), + tpm as (select c from bse) +select tpm.c from tpm; diff --git a/ql/src/test/queries/clientnegative/ctas_dup_column.q b/ql/src/test/queries/clientnegative/ctas_dup_column.q deleted file mode 100644 index 45247fdf9a89..000000000000 --- a/ql/src/test/queries/clientnegative/ctas_dup_column.q +++ /dev/null @@ -1 +0,0 @@ -create table ctas_dup_col as select 'a' as c, 'b' as c; diff --git a/ql/src/test/queries/clientnegative/ctas_dup_column_join.q b/ql/src/test/queries/clientnegative/ctas_dup_column_join.q deleted file mode 100644 index f7318f6d2a9d..000000000000 --- a/ql/src/test/queries/clientnegative/ctas_dup_column_join.q +++ /dev/null @@ -1,3 +0,0 @@ -create table cj1 (k int, v int); -create table cj2 (k int, w int); -create table ctas_dup_join as select a.k, b.k from cj1 a join cj2 b on a.k = b.k; diff --git a/ql/src/test/queries/clientnegative/ctas_dup_column_join_noncbo.q b/ql/src/test/queries/clientnegative/ctas_dup_column_join_noncbo.q deleted file mode 100644 index 6aa6e614da31..000000000000 --- a/ql/src/test/queries/clientnegative/ctas_dup_column_join_noncbo.q +++ /dev/null @@ -1,4 +0,0 @@ -set hive.cbo.enable=false; -create table cj3 (k int, v int); -create table cj4 (k int, w int); -create table ctas_dup_join_nc as select a.k, b.k from cj3 a join cj4 b on a.k = b.k; diff --git a/ql/src/test/queries/clientnegative/ctas_dup_column_noncbo.q b/ql/src/test/queries/clientnegative/ctas_dup_column_noncbo.q deleted file mode 100644 index ff96420c548d..000000000000 --- a/ql/src/test/queries/clientnegative/ctas_dup_column_noncbo.q +++ /dev/null @@ -1,2 +0,0 @@ -set hive.cbo.enable=false; -create table ctas_dup_col_noncbo as select 'a' as c, 'b' as c; diff --git a/ql/src/test/results/clientnegative/ambiguous_col_ctas.q.out b/ql/src/test/results/clientnegative/ambiguous_col_ctas.q.out new file mode 100644 index 000000000000..a88aa731e433 --- /dev/null +++ b/ql/src/test/results/clientnegative/ambiguous_col_ctas.q.out @@ -0,0 +1 @@ +FAILED: SemanticException [Error 10007]: Ambiguous column reference c in tpm diff --git a/ql/src/test/results/clientnegative/ambiguous_col_cte.q.out b/ql/src/test/results/clientnegative/ambiguous_col_cte.q.out index 19c117e1a600..a88aa731e433 100644 --- a/ql/src/test/results/clientnegative/ambiguous_col_cte.q.out +++ b/ql/src/test/results/clientnegative/ambiguous_col_cte.q.out @@ -1 +1 @@ -FAILED: SemanticException [Error 10007]: Ambiguous column reference delivery_date in tpm +FAILED: SemanticException [Error 10007]: Ambiguous column reference c in tpm diff --git a/ql/src/test/results/clientnegative/ambiguous_col_cte_noncbo.q.out b/ql/src/test/results/clientnegative/ambiguous_col_cte_noncbo.q.out index 533d31a557c0..2a604e3b5d28 100644 --- a/ql/src/test/results/clientnegative/ambiguous_col_cte_noncbo.q.out +++ b/ql/src/test/results/clientnegative/ambiguous_col_cte_noncbo.q.out @@ -1 +1 @@ -FAILED: SemanticException [Error 10007]: Ambiguous column reference delivery_date in bse +FAILED: SemanticException [Error 10007]: Ambiguous column reference c in bse diff --git a/ql/src/test/results/clientnegative/ambiguous_col_unqualified_ref.q.out b/ql/src/test/results/clientnegative/ambiguous_col_unqualified_ref.q.out index 533d31a557c0..2a604e3b5d28 100644 --- a/ql/src/test/results/clientnegative/ambiguous_col_unqualified_ref.q.out +++ b/ql/src/test/results/clientnegative/ambiguous_col_unqualified_ref.q.out @@ -1 +1 @@ -FAILED: SemanticException [Error 10007]: Ambiguous column reference delivery_date in bse +FAILED: SemanticException [Error 10007]: Ambiguous column reference c in bse diff --git a/ql/src/test/results/clientnegative/ctas_dup_column.q.out b/ql/src/test/results/clientnegative/ctas_dup_column.q.out deleted file mode 100644 index 60c2f38795a2..000000000000 --- a/ql/src/test/results/clientnegative/ctas_dup_column.q.out +++ /dev/null @@ -1 +0,0 @@ -FAILED: SemanticException [Error 10036]: Duplicate column name: c diff --git a/ql/src/test/results/clientnegative/ctas_dup_column_join.q.out b/ql/src/test/results/clientnegative/ctas_dup_column_join.q.out deleted file mode 100644 index 8746031f6caa..000000000000 --- a/ql/src/test/results/clientnegative/ctas_dup_column_join.q.out +++ /dev/null @@ -1,17 +0,0 @@ -PREHOOK: query: create table cj1 (k int, v int) -PREHOOK: type: CREATETABLE -PREHOOK: Output: database:default -PREHOOK: Output: default@cj1 -POSTHOOK: query: create table cj1 (k int, v int) -POSTHOOK: type: CREATETABLE -POSTHOOK: Output: database:default -POSTHOOK: Output: default@cj1 -PREHOOK: query: create table cj2 (k int, w int) -PREHOOK: type: CREATETABLE -PREHOOK: Output: database:default -PREHOOK: Output: default@cj2 -POSTHOOK: query: create table cj2 (k int, w int) -POSTHOOK: type: CREATETABLE -POSTHOOK: Output: database:default -POSTHOOK: Output: default@cj2 -FAILED: SemanticException [Error 10036]: Duplicate column name: k diff --git a/ql/src/test/results/clientnegative/ctas_dup_column_join_noncbo.q.out b/ql/src/test/results/clientnegative/ctas_dup_column_join_noncbo.q.out deleted file mode 100644 index 47007d97e78e..000000000000 --- a/ql/src/test/results/clientnegative/ctas_dup_column_join_noncbo.q.out +++ /dev/null @@ -1,17 +0,0 @@ -PREHOOK: query: create table cj3 (k int, v int) -PREHOOK: type: CREATETABLE -PREHOOK: Output: database:default -PREHOOK: Output: default@cj3 -POSTHOOK: query: create table cj3 (k int, v int) -POSTHOOK: type: CREATETABLE -POSTHOOK: Output: database:default -POSTHOOK: Output: default@cj3 -PREHOOK: query: create table cj4 (k int, w int) -PREHOOK: type: CREATETABLE -PREHOOK: Output: database:default -PREHOOK: Output: default@cj4 -POSTHOOK: query: create table cj4 (k int, w int) -POSTHOOK: type: CREATETABLE -POSTHOOK: Output: database:default -POSTHOOK: Output: default@cj4 -FAILED: SemanticException [Error 10036]: Duplicate column name: k diff --git a/ql/src/test/results/clientnegative/ctas_dup_column_noncbo.q.out b/ql/src/test/results/clientnegative/ctas_dup_column_noncbo.q.out deleted file mode 100644 index 60c2f38795a2..000000000000 --- a/ql/src/test/results/clientnegative/ctas_dup_column_noncbo.q.out +++ /dev/null @@ -1 +0,0 @@ -FAILED: SemanticException [Error 10036]: Duplicate column name: c From e06b6bf9e3238eaf8b0c6a63b332e71e1c172026 Mon Sep 17 00:00:00 2001 From: Konstantin Bereznyakov Date: Thu, 6 Aug 2026 11:00:50 -0700 Subject: [PATCH 3/3] HIVE-29580: a genGBLogicalPlan tweak + more impacted tests/test rewrites --- .../hadoop/hive/ql/parse/CalcitePlanner.java | 6 +++ .../ambiguous_col_union_distinct_tolerated.q | 10 +++++ .../queries/clientpositive/cross_prod_3.q | 4 +- .../clientpositive/limit_join_transpose.q | 24 ++++++----- ...biguous_col_union_distinct_tolerated.q.out | 20 ++++++++++ .../clientpositive/llap/cross_prod_3.q.out | 4 +- .../llap/limit_join_transpose.q.out | 40 +++++++++---------- 7 files changed, 75 insertions(+), 33 deletions(-) create mode 100644 ql/src/test/queries/clientpositive/ambiguous_col_union_distinct_tolerated.q create mode 100644 ql/src/test/results/clientpositive/llap/ambiguous_col_union_distinct_tolerated.q.out diff --git a/ql/src/java/org/apache/hadoop/hive/ql/parse/CalcitePlanner.java b/ql/src/java/org/apache/hadoop/hive/ql/parse/CalcitePlanner.java index 5edda6e42057..58fd2085272b 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/parse/CalcitePlanner.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/parse/CalcitePlanner.java @@ -3616,6 +3616,12 @@ private RelNode genGBLogicalPlan(QB qb, RelNode srcRel) throws SemanticException // As we said before, here we use genSelectLogicalPlan to rewrite AllColRef srcRel = genSelectLogicalPlan(qb, srcRel, srcRel, null, null, true).getKey(); RowResolver rr = relToHiveRR.get(srcRel); + // genSelectDIAST synthesizes one reference per rslvMap entry, each unique by + // construction, so clear the HIVE-29580 ambiguity markers on this rewrite-private + // projection; the subquery's own RowResolver keeps them for user-written references. + for (ColumnInfo colInfo : rr.getColumnInfos()) { + colInfo.setAmbiguousName(false); + } qbp.setSelExprForClause(destClauseName, genSelectDIAST(rr)); } } diff --git a/ql/src/test/queries/clientpositive/ambiguous_col_union_distinct_tolerated.q b/ql/src/test/queries/clientpositive/ambiguous_col_union_distinct_tolerated.q new file mode 100644 index 000000000000..72a791aec4ec --- /dev/null +++ b/ql/src/test/queries/clientpositive/ambiguous_col_union_distinct_tolerated.q @@ -0,0 +1,10 @@ +-- SORT_QUERY_RESULTS +-- HIVE-29580: UNION DISTINCT is rewritten into SELECT DISTINCT * over an internal alias, and +-- the rewrite synthesizes by-name group-by references from the RowResolver it enumerated. +-- Duplicate output aliases in the branches must not trip the ambiguity check there: the +-- references are unique by construction. Both statements must compile, deduplicate across all +-- columns, and keep both duplicate columns' values intact. + +select 'a' as c, 'b' as c union select 'a', 'b' union select 'a', 'x'; + +select distinct * from (select 'a' as c, 'b' as c union all select 'a', 'b' union all select 'a', 'x') t; diff --git a/ql/src/test/queries/clientpositive/cross_prod_3.q b/ql/src/test/queries/clientpositive/cross_prod_3.q index a1024f42d163..9efcee56a1ed 100644 --- a/ql/src/test/queries/clientpositive/cross_prod_3.q +++ b/ql/src/test/queries/clientpositive/cross_prod_3.q @@ -11,4 +11,6 @@ insert overwrite table X_n2 select distinct * from src order by key limit 10; create table Y_n0 as select * from src order by key limit 1; -explain select * from Y_n0, (select * from X_n2 as A join X_n2 as B on A.key=B.key) as C where Y_n0.key=C.key; +-- HIVE-29580: the derived table's columns are aliased explicitly because "select *" over the +-- self-join projects two columns named key (and value), making the C.key reference ambiguous. +explain select * from Y_n0, (select A.key, A.value, B.key as key2, B.value as value2 from X_n2 as A join X_n2 as B on A.key=B.key) as C where Y_n0.key=C.key; diff --git a/ql/src/test/queries/clientpositive/limit_join_transpose.q b/ql/src/test/queries/clientpositive/limit_join_transpose.q index 4c484bd81354..2ac401f292e0 100644 --- a/ql/src/test/queries/clientpositive/limit_join_transpose.q +++ b/ql/src/test/queries/clientpositive/limit_join_transpose.q @@ -1,6 +1,10 @@ --! qt:dataset:src1 --! qt:dataset:src +-- HIVE-29580: the derived tables' columns are aliased explicitly because "select *" over the +-- src2/src3 join projects two columns named key (and value), making the src2.key references +-- ambiguous; the two key candidates are not even equal here since the join is on value. + SET hive.vectorized.execution.enabled=false; set hive.mapred.mode=nonstrict; set hive.optimize.limittranspose=false; @@ -50,7 +54,7 @@ limit 1; explain select * from src src1 right outer join ( - select * + select src2.key, src2.value, src3.key as key3, src3.value as value3 from src src2 left outer join src src3 on src2.value = src3.value) src2 on src1.key = src2.key @@ -58,7 +62,7 @@ limit 1; select * from src src1 right outer join ( - select * + select src2.key, src2.value, src3.key as key3, src3.value as value3 from src src2 left outer join src src3 on src2.value = src3.value) src2 on src1.key = src2.key @@ -71,7 +75,7 @@ set hive.optimize.limittranspose.reductiontuples=0; explain select * from src src1 right outer join ( - select * + select src2.key, src2.value, src3.key as key3, src3.value as value3 from src src2 left outer join src src3 on src2.value = src3.value) src2 on src1.key = src2.key @@ -79,7 +83,7 @@ limit 1; select * from src src1 right outer join ( - select * + select src2.key, src2.value, src3.key as key3, src3.value as value3 from src src2 left outer join src src3 on src2.value = src3.value) src2 on src1.key = src2.key @@ -107,7 +111,7 @@ limit 1; explain select * from src src1 right outer join ( - select * + select src2.key, src2.value, src3.key as key3, src3.value as value3 from src src2 left outer join src src3 on src2.value = src3.value) src2 on src1.key = src2.key @@ -115,7 +119,7 @@ limit 0; select * from src src1 right outer join ( - select * + select src2.key, src2.value, src3.key as key3, src3.value as value3 from src src2 left outer join src src3 on src2.value = src3.value) src2 on src1.key = src2.key @@ -170,7 +174,7 @@ limit 1 offset 1; explain select * from src src1 right outer join ( - select * + select src2.key, src2.value, src3.key as key3, src3.value as value3 from src src2 left outer join src src3 on src2.value = src3.value) src2 on src1.key = src2.key @@ -178,7 +182,7 @@ limit 1 offset 1; select * from src src1 right outer join ( - select * + select src2.key, src2.value, src3.key as key3, src3.value as value3 from src src2 left outer join src src3 on src2.value = src3.value) src2 on src1.key = src2.key @@ -191,7 +195,7 @@ set hive.optimize.limittranspose.reductiontuples=0; explain select * from src src1 right outer join ( - select * + select src2.key, src2.value, src3.key as key3, src3.value as value3 from src src2 left outer join src src3 on src2.value = src3.value) src2 on src1.key = src2.key @@ -199,7 +203,7 @@ limit 1 offset 1; select * from src src1 right outer join ( - select * + select src2.key, src2.value, src3.key as key3, src3.value as value3 from src src2 left outer join src src3 on src2.value = src3.value) src2 on src1.key = src2.key diff --git a/ql/src/test/results/clientpositive/llap/ambiguous_col_union_distinct_tolerated.q.out b/ql/src/test/results/clientpositive/llap/ambiguous_col_union_distinct_tolerated.q.out new file mode 100644 index 000000000000..98f54127948a --- /dev/null +++ b/ql/src/test/results/clientpositive/llap/ambiguous_col_union_distinct_tolerated.q.out @@ -0,0 +1,20 @@ +PREHOOK: query: select 'a' as c, 'b' as c union select 'a', 'b' union select 'a', 'x' +PREHOOK: type: QUERY +PREHOOK: Input: _dummy_database@_dummy_table +#### A masked pattern was here #### +POSTHOOK: query: select 'a' as c, 'b' as c union select 'a', 'b' union select 'a', 'x' +POSTHOOK: type: QUERY +POSTHOOK: Input: _dummy_database@_dummy_table +#### A masked pattern was here #### +a b +a x +PREHOOK: query: select distinct * from (select 'a' as c, 'b' as c union all select 'a', 'b' union all select 'a', 'x') t +PREHOOK: type: QUERY +PREHOOK: Input: _dummy_database@_dummy_table +#### A masked pattern was here #### +POSTHOOK: query: select distinct * from (select 'a' as c, 'b' as c union all select 'a', 'b' union all select 'a', 'x') t +POSTHOOK: type: QUERY +POSTHOOK: Input: _dummy_database@_dummy_table +#### A masked pattern was here #### +a b +a x diff --git a/ql/src/test/results/clientpositive/llap/cross_prod_3.q.out b/ql/src/test/results/clientpositive/llap/cross_prod_3.q.out index 6e6278f6f74c..78fdff96bb55 100644 --- a/ql/src/test/results/clientpositive/llap/cross_prod_3.q.out +++ b/ql/src/test/results/clientpositive/llap/cross_prod_3.q.out @@ -30,12 +30,12 @@ POSTHOOK: Output: database:default POSTHOOK: Output: default@Y_n0 POSTHOOK: Lineage: y_n0.key SIMPLE [(src)src.FieldSchema(name:key, type:string, comment:default), ] POSTHOOK: Lineage: y_n0.value SIMPLE [(src)src.FieldSchema(name:value, type:string, comment:default), ] -PREHOOK: query: explain select * from Y_n0, (select * from X_n2 as A join X_n2 as B on A.key=B.key) as C where Y_n0.key=C.key +PREHOOK: query: explain select * from Y_n0, (select A.key, A.value, B.key as key2, B.value as value2 from X_n2 as A join X_n2 as B on A.key=B.key) as C where Y_n0.key=C.key PREHOOK: type: QUERY PREHOOK: Input: default@x_n2 PREHOOK: Input: default@y_n0 #### A masked pattern was here #### -POSTHOOK: query: explain select * from Y_n0, (select * from X_n2 as A join X_n2 as B on A.key=B.key) as C where Y_n0.key=C.key +POSTHOOK: query: explain select * from Y_n0, (select A.key, A.value, B.key as key2, B.value as value2 from X_n2 as A join X_n2 as B on A.key=B.key) as C where Y_n0.key=C.key POSTHOOK: type: QUERY POSTHOOK: Input: default@x_n2 POSTHOOK: Input: default@y_n0 diff --git a/ql/src/test/results/clientpositive/llap/limit_join_transpose.q.out b/ql/src/test/results/clientpositive/llap/limit_join_transpose.q.out index e1228b6403b9..ad73abc03936 100644 --- a/ql/src/test/results/clientpositive/llap/limit_join_transpose.q.out +++ b/ql/src/test/results/clientpositive/llap/limit_join_transpose.q.out @@ -352,7 +352,7 @@ POSTHOOK: Input: default@src PREHOOK: query: explain select * from src src1 right outer join ( - select * + select src2.key, src2.value, src3.key as key3, src3.value as value3 from src src2 left outer join src src3 on src2.value = src3.value) src2 on src1.key = src2.key @@ -363,7 +363,7 @@ PREHOOK: Input: default@src POSTHOOK: query: explain select * from src src1 right outer join ( - select * + select src2.key, src2.value, src3.key as key3, src3.value as value3 from src src2 left outer join src src3 on src2.value = src3.value) src2 on src1.key = src2.key @@ -505,7 +505,7 @@ STAGE PLANS: PREHOOK: query: select * from src src1 right outer join ( - select * + select src2.key, src2.value, src3.key as key3, src3.value as value3 from src src2 left outer join src src3 on src2.value = src3.value) src2 on src1.key = src2.key @@ -515,7 +515,7 @@ PREHOOK: Input: default@src #### A masked pattern was here #### POSTHOOK: query: select * from src src1 right outer join ( - select * + select src2.key, src2.value, src3.key as key3, src3.value as value3 from src src2 left outer join src src3 on src2.value = src3.value) src2 on src1.key = src2.key @@ -527,7 +527,7 @@ POSTHOOK: Input: default@src PREHOOK: query: explain select * from src src1 right outer join ( - select * + select src2.key, src2.value, src3.key as key3, src3.value as value3 from src src2 left outer join src src3 on src2.value = src3.value) src2 on src1.key = src2.key @@ -538,7 +538,7 @@ PREHOOK: Input: default@src POSTHOOK: query: explain select * from src src1 right outer join ( - select * + select src2.key, src2.value, src3.key as key3, src3.value as value3 from src src2 left outer join src src3 on src2.value = src3.value) src2 on src1.key = src2.key @@ -693,7 +693,7 @@ STAGE PLANS: PREHOOK: query: select * from src src1 right outer join ( - select * + select src2.key, src2.value, src3.key as key3, src3.value as value3 from src src2 left outer join src src3 on src2.value = src3.value) src2 on src1.key = src2.key @@ -703,7 +703,7 @@ PREHOOK: Input: default@src #### A masked pattern was here #### POSTHOOK: query: select * from src src1 right outer join ( - select * + select src2.key, src2.value, src3.key as key3, src3.value as value3 from src src2 left outer join src src3 on src2.value = src3.value) src2 on src1.key = src2.key @@ -936,7 +936,7 @@ POSTHOOK: Input: default@src PREHOOK: query: explain select * from src src1 right outer join ( - select * + select src2.key, src2.value, src3.key as key3, src3.value as value3 from src src2 left outer join src src3 on src2.value = src3.value) src2 on src1.key = src2.key @@ -947,7 +947,7 @@ PREHOOK: Input: default@src POSTHOOK: query: explain select * from src src1 right outer join ( - select * + select src2.key, src2.value, src3.key as key3, src3.value as value3 from src src2 left outer join src src3 on src2.value = src3.value) src2 on src1.key = src2.key @@ -967,7 +967,7 @@ STAGE PLANS: PREHOOK: query: select * from src src1 right outer join ( - select * + select src2.key, src2.value, src3.key as key3, src3.value as value3 from src src2 left outer join src src3 on src2.value = src3.value) src2 on src1.key = src2.key @@ -977,7 +977,7 @@ PREHOOK: Input: default@src #### A masked pattern was here #### POSTHOOK: query: select * from src src1 right outer join ( - select * + select src2.key, src2.value, src3.key as key3, src3.value as value3 from src src2 left outer join src src3 on src2.value = src3.value) src2 on src1.key = src2.key @@ -1393,7 +1393,7 @@ POSTHOOK: Input: default@src PREHOOK: query: explain select * from src src1 right outer join ( - select * + select src2.key, src2.value, src3.key as key3, src3.value as value3 from src src2 left outer join src src3 on src2.value = src3.value) src2 on src1.key = src2.key @@ -1404,7 +1404,7 @@ PREHOOK: Input: default@src POSTHOOK: query: explain select * from src src1 right outer join ( - select * + select src2.key, src2.value, src3.key as key3, src3.value as value3 from src src2 left outer join src src3 on src2.value = src3.value) src2 on src1.key = src2.key @@ -1564,7 +1564,7 @@ STAGE PLANS: PREHOOK: query: select * from src src1 right outer join ( - select * + select src2.key, src2.value, src3.key as key3, src3.value as value3 from src src2 left outer join src src3 on src2.value = src3.value) src2 on src1.key = src2.key @@ -1574,7 +1574,7 @@ PREHOOK: Input: default@src #### A masked pattern was here #### POSTHOOK: query: select * from src src1 right outer join ( - select * + select src2.key, src2.value, src3.key as key3, src3.value as value3 from src src2 left outer join src src3 on src2.value = src3.value) src2 on src1.key = src2.key @@ -1586,7 +1586,7 @@ POSTHOOK: Input: default@src PREHOOK: query: explain select * from src src1 right outer join ( - select * + select src2.key, src2.value, src3.key as key3, src3.value as value3 from src src2 left outer join src src3 on src2.value = src3.value) src2 on src1.key = src2.key @@ -1597,7 +1597,7 @@ PREHOOK: Input: default@src POSTHOOK: query: explain select * from src src1 right outer join ( - select * + select src2.key, src2.value, src3.key as key3, src3.value as value3 from src src2 left outer join src src3 on src2.value = src3.value) src2 on src1.key = src2.key @@ -1770,7 +1770,7 @@ STAGE PLANS: PREHOOK: query: select * from src src1 right outer join ( - select * + select src2.key, src2.value, src3.key as key3, src3.value as value3 from src src2 left outer join src src3 on src2.value = src3.value) src2 on src1.key = src2.key @@ -1780,7 +1780,7 @@ PREHOOK: Input: default@src #### A masked pattern was here #### POSTHOOK: query: select * from src src1 right outer join ( - select * + select src2.key, src2.value, src3.key as key3, src3.value as value3 from src src2 left outer join src src3 on src2.value = src3.value) src2 on src1.key = src2.key