Uh oh!
There was an error while loading. Please reload this page.
[SPARK-35742][SQL] Expression.semanticEquals should be symmetrical - #32885
[SPARK-35742][SQL] Expression.semanticEquals should be symmetrical#32885cloud-fan wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
all the subclasses of SubqueryExpression have implemented canonicalized.
cloud-fan
commented
Jun 11, 2021
There was a problem hiding this comment.
The default implementation works for AttributeReference
There was a problem hiding this comment.
It's already there, in L164
dongjoon-hyun
commented
Jun 11, 2021
BTW, could you make CI happy? |
SparkQA
commented
Jun 11, 2021
Test build #139711 has finished for PR 32885 at commit
|
SparkQA
commented
Jun 11, 2021
Kubernetes integration test unable to build dist. exiting with code: 1 |
HyukjinKwon
commented
Jun 13, 2021
Yeah, +1 if CI passes. |
| // map and/or the sort-based aggregation once it has processed a given number of input rows. | ||
| private val testFallbackStartsAt: Option[(Int, Int)] = { | ||
| sqlContext.getConf("spark.sql.TungstenAggregate.testFallbackStartsAt", null) match { | ||
| Option(sqlContext).map { sc => |
There was a problem hiding this comment.
This is a hidden bug. SubqueryExpression will be sent to the executor side and build Projection, and be put in EquivalentExpressions, which needs to call canonicalized.
This means, Spark may serialize and send HashAggregateExec to the executor side, where sqlContext should be null.
It's hidden for a long time because ScalarSubquery didn't implement canonicalized, so the bug is not triggered. However, it also means semanticHash is wrong.
I think it only affects common subquery elimination, and shouldn't be a serious bug.
There was a problem hiding this comment.
In the long term, I think we should only send an "expression evaluator" to the executor side. The semantic check should only be done in the driver side.
There was a problem hiding this comment.
Sorry for the late comment @cloud-fan, but I think I've run into this issue before:
https://github.com/apache/spark/pull/28885/files#diff-9b62cef6bfdeb6c802bb120c7a724a974d5067a69585285bebb64c48603f8d6fR105-R108. The point is that there might be other nodes where canonicalization on executor side can cause issues. SortExec.enableRadixSort is the other one I found.
There was a problem hiding this comment.
InSubqueryExec already implements canonicalized before this PR, so we need to fix these bugs anyway.
I have an idea to fix this problem in all physical plans:
- remove
SparkPlan.sqlContext, so that we can catch all the callers of it - add
@transient final val session = SparkSession.getActiveSession.orNull, to replace the previoussqlContext - override
confinSparkPlan:if (session != null) session.sessionState.conf else SQLConf.get
@peter-toth what do you think? AFAIK the only reason to access SparkPlan.sqlContext at executor side is to read a conf, and we can do that with SQLConf.get at executor side.
There was a problem hiding this comment.
I'm quite busy this week and may not have time to implement this idea recently. @peter-toth feel free to pick up this idea and open a PR if you have time, or I'll do it next or next next week. Thanks in advance!
There was a problem hiding this comment.
Ok, thanks. I will try to open a PR this week.
| HashAggregate [c_customer_sk,sum,isEmpty] [sum(CheckOverflow((promote_precision(cast(cast(ss_quantity as decimal(10,0)) as decimal(12,2))) * promote_precision(cast(ss_sales_price as decimal(12,2)))), DecimalType(18,2), true)),sum(CheckOverflow((promote_precision(cast(cast(ss_quantity as decimal(10,0)) as decimal(12,2))) * promote_precision(cast(ss_sales_price as decimal(12,2)))), DecimalType(18,2), true)),sum,isEmpty] | ||
| InputAdapter | ||
| ReusedExchange [c_customer_sk,sum,isEmpty] #8 | ||
| ReusedExchange [c_customer_sk,c_first_name,c_last_name] #19 |
There was a problem hiding this comment.
After the fix, more exchange reuse happens :)
Seems the problem was caused by ReusedSubquery.
SparkQA
commented
Jun 15, 2021
Kubernetes integration test unable to build dist. exiting with code: 1 |
SparkQA
commented
Jun 15, 2021
Test build #139789 has finished for PR 32885 at commit
|
viirya
commented
Jun 15, 2021
LGTM |
cloud-fan
commented
Jun 15, 2021
thanks for the review, merging to master! |
Currently, there are some expressions that overwrite `semanticEquals`, which makes it not symmetrical. Ideally, expressions should overwrite `canonicalized` instead of `semanticEquals`. This PR marks `semanticEquals` as final, and implement `canonicalized` for the few expressions that overwrote `semanticEquals` before. To avoid subtle bugs (I haven't found a real bug yet). no a new test Closesapache#32885 from cloud-fan/attr. Authored-by: Wenchen Fan <wenchen@databricks.com> Signed-off-by: Wenchen Fan <wenchen@databricks.com>
What changes were proposed in this pull request?
Currently, there are some expressions that overwrite
semanticEquals, which makes it not symmetrical. Ideally, expressions should overwritecanonicalizedinstead ofsemanticEquals.This PR marks
semanticEqualsas final, and implementcanonicalizedfor the few expressions that overwrotesemanticEqualsbefore.Why are the changes needed?
To avoid subtle bugs (I haven't found a real bug yet).
Does this PR introduce any user-facing change?
no
How was this patch tested?
a new test