-
Notifications
You must be signed in to change notification settings - Fork 4.8k
HIVE-29580: CBO: Ambiguous column reference not detected in some CTE/CTAS/other queries #6676
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
234ead5
9b0aa9b
e0a74eb
4fba833
023de39
282f343
882e494
42d53eb
61329c0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -170,6 +170,15 @@ public void appendAllColsOfTargetTable(String prefix) { | |
| public void appendAllColsOfTargetTable() { | ||
| appendCols(targetTable.getAllCols(), FieldSchema::getName); | ||
| } | ||
|
|
||
| /** | ||
| * Appends the target table's non-partition columns. For a natively partitioned MERGE target | ||
| * the partition columns are already emitted by appendAcidSelectColumns; emitting them again | ||
| * would give the rewritten projection duplicate column names (HIVE-29580). | ||
| */ | ||
| public void appendNonPartitionColsOfTargetTable() { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: Consider renaming this method as the name suggests "non-partition columns" whereas we do append "all columns" sometimes.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed the name lied for the non-native arm — but renaming would have meant naming a mode branch that really belongs to the caller, so I dissolved it instead: |
||
| appendCols(targetTable.getCols(), FieldSchema::getName); | ||
| } | ||
|
|
||
| public <T> void appendCols(List<T> columns, Function<T, String> stringConverter) { | ||
| appendCols(columns, null, null, stringConverter); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -595,6 +595,19 @@ protected IntervalExprProcessor getIntervalExprProcessor() { | |
| return new IntervalExprProcessor(); | ||
| } | ||
|
|
||
| /** | ||
| * Rejects a by-name reference to a column marked ambiguous at a subquery/CTE boundary | ||
| * (HIVE-29580). Call after each by-name resolution of a user-written column reference; | ||
| * expression-map resolutions (processGByExpr) stay unchecked so Hive's own rewrites can | ||
| * reference marked columns. | ||
| */ | ||
| static void checkAmbiguousName(ColumnInfo colInfo) throws SemanticException { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please document when this method should be called.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added a javadoc: call after each by-name resolution of a user-written column reference; expression-map resolutions ( |
||
| if (colInfo != null && colInfo.hasAmbiguousName()) { | ||
| throw new SemanticException(ErrorMsg.AMBIGUOUS_COLUMN.getMsg( | ||
| colInfo.getAlias() + " in " + colInfo.getTabAlias())); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Processor for table columns. | ||
| */ | ||
|
|
@@ -660,6 +673,7 @@ public Object process(Node nd, Stack<Node> stack, NodeProcessorCtx procCtx, | |
| return null; | ||
| } | ||
| // It's a column. | ||
| checkAmbiguousName(colInfo); | ||
| return exprFactory.toExpr(colInfo, usedRR, offset); | ||
| } else { | ||
| // It's a table alias. | ||
|
|
@@ -694,6 +708,7 @@ public Object process(Node nd, Stack<Node> stack, NodeProcessorCtx procCtx, | |
| } | ||
| } else { | ||
| // It's a column. | ||
| checkAmbiguousName(colInfo); | ||
| return exprFactory.toExpr(colInfo, usedRR, offset); | ||
| } | ||
| } | ||
|
|
@@ -1300,6 +1315,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); | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| /* | ||
| * 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.exec; | ||
|
|
||
| import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoFactory; | ||
| import org.junit.Assert; | ||
| import org.junit.Test; | ||
|
|
||
| public class TestColumnInfo { | ||
|
|
||
| @Test | ||
| public void testAmbiguousNameDefaultsToFalse() { | ||
| ColumnInfo colInfo = new ColumnInfo("_col0", TypeInfoFactory.stringTypeInfo, "t", false); | ||
| Assert.assertFalse(colInfo.hasAmbiguousName()); | ||
| } | ||
|
|
||
| @Test | ||
| public void testCopyConstructorPreservesAmbiguousName() { | ||
| ColumnInfo original = new ColumnInfo("_col0", TypeInfoFactory.stringTypeInfo, "t", false); | ||
| original.setAmbiguousName(true); | ||
| Assert.assertTrue(new ColumnInfo(original).hasAmbiguousName()); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add a note saying that
ambiguousNameis intentionally excluded from equals and hashcode? Also add a brief reasoning for future devs.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a note on the field: it is deliberately excluded from
equals/hashCode/isSameColumnForRR— a marked and an unmarked copy of a column are still the same column for RowResolver purposes, so including the flag would change RR dedup semantics.