Uh oh!
There was an error while loading. Please reload this page.
[SPARK-42655][SQL] Incorrect ambiguous column reference error - #40258
[SPARK-42655][SQL] Incorrect ambiguous column reference error#40258shrprasa wants to merge 1 commit into
Conversation
a637f83 to
d40293eCompare
srowen
left a comment
There was a problem hiding this comment.
I think this is too drastic and the wrong fix - you're actually changing the col names, and only on select. It's just the error that would ideally show the original col names right?
@srowen Please ignore that change. It was work in progress to check few things. val df1 = sc.parallelize(List((1,2,3,4,5),(1,2,3,4,5))).toDF("id","col2","col3","col4", "col5") df3.explain() Before the fix, attributes matched were: |
d40293e to
5d91223Comparee7114e7 to
ea5fe9bCompareshrprasa
commented
Mar 4, 2023
@srowen@dongjoon-hyun Can you please review this PR? |
Gentle Ping @srowen@dongjoon-hyun@mridulm@HyukjinKwon |
srowen
commented
Mar 7, 2023
I'm not sure about the change, not sure I'm qualified to review it. I think at best the error message should change; I am not clear that the result is 'wrong' |
shrprasa
commented
Mar 7, 2023
Thanks for replying. Can you please tag someone who should be right person to review this change? |
shrprasa
commented
Mar 8, 2023
Gentle ping @dongjoon-hyun@mridulm@HyukjinKwon@yaooqinn Can you please review this PR? |
yaooqinn
commented
Mar 8, 2023
Can you try |
Yes, I have tried it. With caseSensitive set to true, it will work as then id and ID will be treated as separate columns. |
yaooqinn
commented
Mar 8, 2023
You first defined a case-sensitive data set, then queried in a case-insensitive way, I guess the error is expected. |
In the physical plan, both id and ID columns are projected to the same column in the dataframe: _1#6 Also, in the matched attributes, results are same: attributes: Vector(id#17, id#17) If the matched attribute result was Vector(id#17, ID#17) , then it would have been valid error. And even if the dataset has columns in different cases, Spark being case insensitive by default, should consider both columns as same. |
srowen
commented
Mar 8, 2023
I don't get it, it is due to case sensitivity; that's why it becomes ambiguous and that's what you see. The issue is that the error isn't super helpful because it shows the lower-cased column right? that's what I was saying. Or: does your change still result in an error without case sensitivity? it should |
shrprasa
commented
Mar 9, 2023
The issue is not with the error message. Problem is that in this case error should not be thrown. Select query should return result. After this change, ambiguous error will not be thrown as we are fixing the duplicate attribute match. |
srowen
commented
Mar 9, 2023
Hm, how is it not ambiguous? When case insensitive, 'id' could mean one of two different columns |
shrprasa
commented
Mar 9, 2023
It's not ambiguous because the when we are selecting using list of column names, both id and ID are getting value from same column 'id' in the source dataframe. df3.explain() |
srowen
commented
Mar 9, 2023
That isn't relevant. You are selecting from a DataFrame with cols id and ID. Imagine for instance they do not come from the same source, it's clearly ambiguous. It wouldn't make sense if it were different in this case. |
shrprasa
commented
Mar 9, 2023
It's very much relevant as this is the only case which requires the fix. If they do not come from same source, the plan will reflect that and it will throw the ambiguous error even after this fix. |
srowen
commented
Mar 9, 2023
Hm, I just don't see the logic in that. It isn't how SQL works either, as far as I understand. Here's maybe another example, imagine a DataFrame defined by |
shrprasa
commented
Mar 10, 2023
If it's valid as per the plan then yes. |
Gentle ping @dongjoon-hyun@mridulm@HyukjinKwon@yaooqinn Can you please review this PR or direct it to someone who can review this PR. |
shrprasa
commented
Mar 23, 2023
@cloud-fan The example you have shared will behave the same even after this fix. It will give ambiguous error. Case 2: which doesn't work fine and the fix is to solve this issue |
yaooqinn
commented
Mar 23, 2023
@shrprasa |
cloud-fan
commented
Mar 23, 2023
@shrprasa do you know how the case 1 works? |
shrprasa
commented
Mar 23, 2023
yes. It works because the resolved column has just one match but for second case, the match result is |
cloud-fan
commented
Mar 24, 2023
But there are two id columns. Does Spark already do deduplication somewhere? |
shrprasa
commented
Mar 24, 2023
Not sure about the deduplication before, but even if it was doing it at some stage, in the second use case it might not have converted the column name to lowercase by that time, that's why that would still treat the two id and ID columns as different. |
There was a problem hiding this comment.
shall we fix def unique in this class? It should look at expr Id.
There was a problem hiding this comment.
The unique method is not used in this flow. It's used at many places while returning the result. Making any changes to unique will increase the scope.
cloud-fan
commented
Mar 24, 2023
I think case 1 works by accident. It's not an intentional design. I don't think it's a bug that case 2 doesn't work. |
@cloud-fan As I had said in previous comment : For case 1: For Case 2: Most of the places we are calling unique before returning the result. So what' the negative impact you think it will have if we return unique results for the column match also? One positive use case is it will fix this wrong ambiguous error being thrown just because the result of match has two duplicate values. |
shrprasa
commented
Mar 24, 2023
FWIW Both the use cases were working fine in Spark 2.3 |
shrprasa
commented
Mar 28, 2023
@cloud-fan Can you please check my last comments. |
cloud-fan
commented
Mar 31, 2023
Sorry I missed this point. Do you know how it worked in 2.3? Did 2.3 also call |
cloud-fan
commented
Mar 31, 2023
according to the code in 2.3, I think we should call |
shrprasa
commented
Mar 31, 2023
@cloud-fan |
cloud-fan
commented
Mar 31, 2023
If you really worry about regression, we can add a legacy config to fall back to the old code. I don't agree to make code changes that only fix the problem in one particular code path, while we know other code paths have the same problem as well. |
shrprasa
commented
Mar 31, 2023
Ok, I will update the PR with suggested change. |
ea5fe9b to
b2da643Compareb2da643 to
e4f003aCompareshrprasa
commented
Apr 1, 2023
@cloud-fan I have made the change. All Tests have passed. Can you please review? |
shrprasa
commented
Apr 4, 2023
Gentle ping @cloud-fan |
thanks, merging to master/3.4! |
**What changes were proposed in this pull request?**
The result of attribute resolution should consider only unique values for the reference. If it has duplicate values, it will incorrectly result into ambiguous reference error.
**Why are the changes needed?**
The below query fails incorrectly due to ambiguous reference error.
val df1 = sc.parallelize(List((1,2,3,4,5),(1,2,3,4,5))).toDF("id","col2","col3","col4", "col5")
val op_cols_mixed_case = List("id","col2","col3","col4", "col5", "ID")
val df3 = df1.select(op_cols_mixed_case.head, op_cols_mixed_case.tail: _*)
df3.select("id").show()
org.apache.spark.sql.AnalysisException: Reference 'id' is ambiguous, could be: id, id.
df3.explain()
== Physical Plan ==
*(1) Project [_1#6 AS id#17, _2#7 AS col2#18, _3#8 AS col3#19, _4#9 AS col4#20, _5#10 AS col5#21, _1#6 AS ID#17]
Before the fix, attributes matched were:
attributes: Vector(id#17, id#17)
Thus, it throws ambiguous reference error. But if we consider only unique matches, it will return correct result.
unique attributes: Vector(id#17)
**Does this PR introduce any user-facing change?**
Yes, Users migrating from Spark 2.3 to 3.x will face this error as the scenario used to work fine in Spark 2.3 but fails in Spark 3.2. After the fix, iit will work correctly as it was in Spark 2.3.
**How was this patch tested?**
Added unit test.
Closes#40258 from shrprasa/col_ambiguous_issue.
Authored-by: Shrikant Prasad <shrprasa@visa.com>
Signed-off-by: Wenchen Fan <wenchen@databricks.com>
(cherry picked from commit b283c6a)
Signed-off-by: Wenchen Fan <wenchen@databricks.com>shrprasa
commented
Apr 4, 2023
Thanks a lot @cloud-fan for the guidance and support in getting this issue fixed. |
**What changes were proposed in this pull request?**
The result of attribute resolution should consider only unique values for the reference. If it has duplicate values, it will incorrectly result into ambiguous reference error.
**Why are the changes needed?**
The below query fails incorrectly due to ambiguous reference error.
val df1 = sc.parallelize(List((1,2,3,4,5),(1,2,3,4,5))).toDF("id","col2","col3","col4", "col5")
val op_cols_mixed_case = List("id","col2","col3","col4", "col5", "ID")
val df3 = df1.select(op_cols_mixed_case.head, op_cols_mixed_case.tail: _*)
df3.select("id").show()
org.apache.spark.sql.AnalysisException: Reference 'id' is ambiguous, could be: id, id.
df3.explain()
== Physical Plan ==
*(1) Project [_1#6 AS id#17, _2#7 AS col2#18, _3#8 AS col3#19, _4#9 AS col4#20, _5#10 AS col5#21, _1#6 AS ID#17]
Before the fix, attributes matched were:
attributes: Vector(id#17, id#17)
Thus, it throws ambiguous reference error. But if we consider only unique matches, it will return correct result.
unique attributes: Vector(id#17)
**Does this PR introduce any user-facing change?**
Yes, Users migrating from Spark 2.3 to 3.x will face this error as the scenario used to work fine in Spark 2.3 but fails in Spark 3.2. After the fix, iit will work correctly as it was in Spark 2.3.
**How was this patch tested?**
Added unit test.
Closesapache#40258 from shrprasa/col_ambiguous_issue.
Authored-by: Shrikant Prasad <shrprasa@visa.com>
Signed-off-by: Wenchen Fan <wenchen@databricks.com>
(cherry picked from commit b283c6a)
Signed-off-by: Wenchen Fan <wenchen@databricks.com>bsikander
commented
Nov 26, 2023
@shrprasa do you think this issue is similar to the issue that i just posted: https://stackoverflow.com/questions/77553257/select-behavior-different-between-pyspark-2-4-8-and-3-3-2 Trying to understand the behavior. |
What changes were proposed in this pull request?
The result of attribute resolution should consider only unique values for the reference. If it has duplicate values, it will incorrectly result into ambiguous reference error.
Why are the changes needed?
The below query fails incorrectly due to ambiguous reference error.
val df1 = sc.parallelize(List((1,2,3,4,5),(1,2,3,4,5))).toDF("id","col2","col3","col4", "col5")
val op_cols_mixed_case = List("id","col2","col3","col4", "col5", "ID")
val df3 = df1.select(op_cols_mixed_case.head, op_cols_mixed_case.tail: _*)
df3.select("id").show()
org.apache.spark.sql.AnalysisException: Reference 'id' is ambiguous, could be: id, id.
df3.explain()
== Physical Plan ==
*(1) Project [_1#6 AS id#17, _2#7 AS col2#18, _3#8 AS col3#19, _4#9 AS col4#20, _5#10 AS col5#21, _1#6 AS ID#17]
Before the fix, attributes matched were:
attributes: Vector(id#17, id#17)
Thus, it throws ambiguous reference error. But if we consider only unique matches, it will return correct result.
unique attributes: Vector(id#17)
Does this PR introduce any user-facing change?
Yes, Users migrating from Spark 2.3 to 3.x will face this error as the scenario used to work fine in Spark 2.3 but fails in Spark 3.2. After the fix, iit will work correctly as it was in Spark 2.3.
How was this patch tested?
Added unit test.