Skip to content
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

[SPARK-32635][SQL] Fix foldable propagation #29771

Conversation

peter-toth
Copy link
Contributor

@peter-toth peter-toth commented Sep 16, 2020

What changes were proposed in this pull request?

This PR rewrites FoldablePropagation rule to replace attribute references in a node with foldables coming only from the node's children.

Before this PR in the case of this example (with settingspark.sql.optimizer.excludedRules=org.apache.spark.sql.catalyst.optimizer.ConvertToLocalRelation):

val a = Seq("1").toDF("col1").withColumn("col2", lit("1"))
val b = Seq("2").toDF("col1").withColumn("col2", lit("2"))
val aub = a.union(b)
val c = aub.filter($"col1" === "2").cache()
val d = Seq("2").toDF( "col4")
val r = d.join(aub, $"col2" === $"col4").select("col4")
val l = c.select("col2")
val df = l.join(r, $"col2" === $"col4", "LeftOuter")
df.show()

foldable propagation happens incorrectly:

 Join LeftOuter, (col2#6 = col4#34)                                                              Join LeftOuter, (col2#6 = col4#34)
!:- Project [col2#6]                                                                             :- Project [1 AS col2#6]
 :  +- InMemoryRelation [col1#4, col2#6], StorageLevel(disk, memory, deserialized, 1 replicas)   :  +- InMemoryRelation [col1#4, col2#6], StorageLevel(disk, memory, deserialized, 1 replicas)
 :        +- Union                                                                               :        +- Union
 :           :- *(1) Project [value#1 AS col1#4, 1 AS col2#6]                                    :           :- *(1) Project [value#1 AS col1#4, 1 AS col2#6]
 :           :  +- *(1) Filter (isnotnull(value#1) AND (value#1 = 2))                            :           :  +- *(1) Filter (isnotnull(value#1) AND (value#1 = 2))
 :           :     +- *(1) LocalTableScan [value#1]                                              :           :     +- *(1) LocalTableScan [value#1]
 :           +- *(2) Project [value#10 AS col1#13, 2 AS col2#15]                                 :           +- *(2) Project [value#10 AS col1#13, 2 AS col2#15]
 :              +- *(2) Filter (isnotnull(value#10) AND (value#10 = 2))                          :              +- *(2) Filter (isnotnull(value#10) AND (value#10 = 2))
 :                 +- *(2) LocalTableScan [value#10]                                             :                 +- *(2) LocalTableScan [value#10]
 +- Project [col4#34]                                                                            +- Project [col4#34]
    +- Join Inner, (col2#6 = col4#34)                                                               +- Join Inner, (col2#6 = col4#34)
       :- Project [value#31 AS col4#34]                                                                :- Project [value#31 AS col4#34]
       :  +- LocalRelation [value#31]                                                                  :  +- LocalRelation [value#31]
       +- Project [col2#6]                                                                             +- Project [col2#6]
          +- Union false, false                                                                           +- Union false, false
             :- Project [1 AS col2#6]                                                                        :- Project [1 AS col2#6]
             :  +- LocalRelation [value#1]                                                                   :  +- LocalRelation [value#1]
             +- Project [2 AS col2#15]                                                                       +- Project [2 AS col2#15]
                +- LocalRelation [value#10]                                                                     +- LocalRelation [value#10]

and so the result is wrong:

+----+----+
|col2|col4|
+----+----+
|   1|null|
+----+----+

After this PR foldable propagation will not happen incorrectly and the result is correct:

+----+----+
|col2|col4|
+----+----+
|   2|   2|
+----+----+

Why are the changes needed?

To fix a correctness issue.

Does this PR introduce any user-facing change?

Yes, fixes a correctness issue.

How was this patch tested?

Existing and new UTs.

@SparkQA
Copy link

SparkQA commented Sep 16, 2020

Test build #128764 has finished for PR 29771 at commit bc433e8.

  • This patch passes all tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

@peter-toth
Copy link
Contributor Author

peter-toth commented Sep 16, 2020

cc @cloud-fan, @maropu, @viirya

Copy link
Contributor

@cloud-fan cloud-fan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch!

@@ -2555,6 +2555,18 @@ class DataFrameSuite extends QueryTest
val df = Seq(0.0 -> -0.0).toDF("pos", "neg")
checkAnswer(df.select($"pos" > $"neg"), Row(false))
}

test("SPARK-32635: Fix foldable propagation") {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you make the title clearer? e.g., Replace references with foldables coming only from the node's children

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, fixed.

@maropu
Copy link
Member

maropu commented Sep 17, 2020

Looks ok otherwise. Nice fix.

@peter-toth peter-toth force-pushed the SPARK-32635-fix-foldable-propagation branch from 0c0a115 to 5f7bbfb Compare September 17, 2020 09:07
@peter-toth
Copy link
Contributor Author

last commit is just a minor improvement

@rednaxelafx
Copy link
Contributor

LGTM (not a Reviewer). Eliminating var FTW!

I'd like to ask about a few things though:

  1. The fix involved a bit of refactoring. Is the bug caused by "leaking" the foldableMap from a sibling node, such that it's not properly just propagating along the child->parent flow? And that the refactoring eliminated the var the threaded the propagation via returns in a recursive depth-first traversal to make sure that it's always only propagating along the child->parent flow, and otherwise the existing logic is unchanged? If so, this looks like a nice refactoring.
  2. TreeNode's transformXXX functions take care of the case where a new node is actually equal to the old one, so that after transformation the logically unchanged nodes will stay with their original identity. It looks like with the explicit recursion after this PR, that it might introduce more, unnecessary copies of the logically unchanged nodes that end up staying in the transformed tree. Is that the case? If so, can we make it better?

Thanks!

@SparkQA
Copy link

SparkQA commented Sep 17, 2020

Test build #128812 has finished for PR 29771 at commit 5f7bbfb.

  • This patch fails Spark unit tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

@cloud-fan
Copy link
Contributor

that it might introduce more, unnecessary copies of the logically unchanged nodes

Good point. mapChildren takes care of it and we should always use mapChildren instead of node.copy(child = newChild)

@peter-toth
Copy link
Contributor Author

peter-toth commented Sep 17, 2020

  1. The fix involved a bit of refactoring. Is the bug caused by "leaking" the foldableMap from a sibling node, such that it's not properly just propagating along the child->parent flow? And that the refactoring eliminated the var the threaded the propagation via returns in a recursive depth-first traversal to make sure that it's always only propagating along the child->parent flow, and otherwise the existing logic is unchanged? If so, this looks like a nice refactoring.

This is exactly what happens without this PR. Basically foldableMap is filled up with all foldables in the beginning and then we start the preorder traversal and replacing references from the map. Sometimes we narrow down the map when traversing through particular nodes, but this is still incorrect.
With this PR we do a proper fill-up and child->parent propagation of the map.

  1. TreeNode's transformXXX functions take care of the case where a new node is actually equal to the old one, so that after transformation the logically unchanged nodes will stay with their original identity. It looks like with the explicit recursion after this PR, that it might introduce more, unnecessary copies of the logically unchanged nodes that end up staying in the transformed tree. Is that the case? If so, can we make it better?

I think this is a very good point actually. mapChildren() in the "other" case seems to be ok as that method takes care of the comparison. withNewChildren() also takes care of it in UnaryNode and Join. The replaceFoldable() call after withNewChildren() is also ok because it uses transformExpressions. Finally Project and Expand, well, they can add unnecessary copies as you pointed out. But I think if there is a parent "other"/UnaryNode/Join node above these 2 in the tree then there won't be any copies in the transformed tree in the end. But let me change the copy() to avoid issues in other cases, though.

@peter-toth
Copy link
Contributor Author

Thanks @rednaxelafx, latest commit contains the fix.

@SparkQA
Copy link

SparkQA commented Sep 17, 2020

Test build #128808 has finished for PR 29771 at commit 55575de.

  • This patch passes all tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

@SparkQA
Copy link

SparkQA commented Sep 17, 2020

Test build #128810 has finished for PR 29771 at commit 0c0a115.

  • This patch passes all tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

val b = Seq("2").toDF("col1").withColumn("col2", lit("2"))
val aub = a.union(b)
val c = aub.filter($"col1" === "2").cache()
val d = Seq("2").toDF( "col4")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: extra space before "col4"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, fixed.

Copy link
Member

@viirya viirya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch!

@@ -624,67 +624,89 @@ object NullPropagation extends Rule[LogicalPlan] {
*/
object FoldablePropagation extends Rule[LogicalPlan] {
def apply(plan: LogicalPlan): LogicalPlan = {
var foldableMap = AttributeMap(plan.flatMap {
case Project(projectList, _) => projectList.collect {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about Aggregate? Why we are not handling Aggregate in the original rule?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This ticket and PR just focuses on the correctness issue found. But I think we can extend the rule to handle Aggregate in another ticket if that is ok with you.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had the same question when I first looked at the PR, but since this PR might need to be hotfixed to released branches, it's a good idea to keep it simple and don't add any new features. So I'm +1 for handling Aggregate in a separate PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 for @peter-toth and @rednaxelafx 's opinion.

@@ -2555,6 +2555,18 @@ class DataFrameSuite extends QueryTest
val df = Seq(0.0 -> -0.0).toDF("pos", "neg")
checkAnswer(df.select($"pos" > $"neg"), Row(false))
}

test("SPARK-32635: Replace references with foldables coming only from the node's children") {
Copy link
Member

@dongjoon-hyun dongjoon-hyun Sep 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although this end-to-end test is also useful, we had better have a narrow-downed test coverage at FoldablePropagationSuite in catalyst module, too. Could you add one please? If then, we can easily detect regression in catalyst module test instead of running full sql tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I will try to add a test case to FoldablePropagationSuite tomorrow.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

Copy link
Member

@dongjoon-hyun dongjoon-hyun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1, LGTM. Thanks, @peter-toth and all.
I guess most comments are already addressed. I have only one minor test related comment.

@dongjoon-hyun
Copy link
Member

dongjoon-hyun commented Sep 17, 2020

Ur, @peter-toth . Could you check the PR description once more?

scala> spark.version
res1: String = 3.0.1

scala> :paste
// Entering paste mode (ctrl-D to finish)

val a = Seq("1").toDF("col1").withColumn("col2", lit("1"))
val b = Seq("2").toDF("col1").withColumn("col2", lit("2"))
val aub = a.union(b)
val c = aub.filter($"col1" === "2").cache()
val d = Seq("2").toDF( "col4")
val r = d.join(aub, $"col2" === $"col4").select("col4")
val l = c.select("col2")
val df = l.join(r, $"col2" === $"col4", "LeftOuter")
df.show()

// Exiting paste mode, now interpreting.

+----+----+
|col2|col4|
+----+----+
|   2|   2|
+----+----+
scala> spark.version
res0: String = 2.4.7

scala> :paste
// Entering paste mode (ctrl-D to finish)

val a = Seq("1").toDF("col1").withColumn("col2", lit("1"))
val b = Seq("2").toDF("col1").withColumn("col2", lit("2"))
val aub = a.union(b)
val c = aub.filter($"col1" === "2").cache()
val d = Seq("2").toDF( "col4")
val r = d.join(aub, $"col2" === $"col4").select("col4")
val l = c.select("col2")
val df = l.join(r, $"col2" === $"col4", "LeftOuter")
df.show()

// Exiting paste mode, now interpreting.

+----+----+
|col2|col4|
+----+----+
|   2|   2|
+----+----+

@peter-toth
Copy link
Contributor Author

peter-toth commented Sep 17, 2020

Ur, @peter-toth . Could you check the PR description once more?

@dongjoon-hyun, please run the shell with --conf "spark.sql.optimizer.excludedRules=org.apache.spark.sql.catalyst.optimizer.ConvertToLocalRelation" as that test suite does.

@dongjoon-hyun
Copy link
Member

dongjoon-hyun commented Sep 17, 2020

Got it. Thanks, @peter-toth ! Please add that conf into PR description and JIRA description.

@SparkQA
Copy link

SparkQA commented Sep 17, 2020

Test build #128825 has finished for PR 29771 at commit 54f41fa.

  • This patch passes all tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

@SparkQA
Copy link

SparkQA commented Sep 17, 2020

Test build #128835 has finished for PR 29771 at commit 75d7a4c.

  • This patch passes all tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

@SparkQA
Copy link

SparkQA commented Sep 17, 2020

Test build #128837 has finished for PR 29771 at commit 61548c7.

  • This patch passes all tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

@maropu
Copy link
Member

maropu commented Sep 17, 2020

Nice suggestion, @rednaxelafx ! I checked the latest commits again and they looks okay.

maropu pushed a commit that referenced this pull request Sep 17, 2020
### What changes were proposed in this pull request?
This PR rewrites `FoldablePropagation` rule to replace attribute references in a node with foldables coming only from the node's children.

Before this PR in the case of this example (with setting`spark.sql.optimizer.excludedRules=org.apache.spark.sql.catalyst.optimizer.ConvertToLocalRelation`):
```scala
val a = Seq("1").toDF("col1").withColumn("col2", lit("1"))
val b = Seq("2").toDF("col1").withColumn("col2", lit("2"))
val aub = a.union(b)
val c = aub.filter($"col1" === "2").cache()
val d = Seq("2").toDF( "col4")
val r = d.join(aub, $"col2" === $"col4").select("col4")
val l = c.select("col2")
val df = l.join(r, $"col2" === $"col4", "LeftOuter")
df.show()
```
foldable propagation happens incorrectly:
```
 Join LeftOuter, (col2#6 = col4#34)                                                              Join LeftOuter, (col2#6 = col4#34)
!:- Project [col2#6]                                                                             :- Project [1 AS col2#6]
 :  +- InMemoryRelation [col1#4, col2#6], StorageLevel(disk, memory, deserialized, 1 replicas)   :  +- InMemoryRelation [col1#4, col2#6], StorageLevel(disk, memory, deserialized, 1 replicas)
 :        +- Union                                                                               :        +- Union
 :           :- *(1) Project [value#1 AS col1#4, 1 AS col2#6]                                    :           :- *(1) Project [value#1 AS col1#4, 1 AS col2#6]
 :           :  +- *(1) Filter (isnotnull(value#1) AND (value#1 = 2))                            :           :  +- *(1) Filter (isnotnull(value#1) AND (value#1 = 2))
 :           :     +- *(1) LocalTableScan [value#1]                                              :           :     +- *(1) LocalTableScan [value#1]
 :           +- *(2) Project [value#10 AS col1#13, 2 AS col2#15]                                 :           +- *(2) Project [value#10 AS col1#13, 2 AS col2#15]
 :              +- *(2) Filter (isnotnull(value#10) AND (value#10 = 2))                          :              +- *(2) Filter (isnotnull(value#10) AND (value#10 = 2))
 :                 +- *(2) LocalTableScan [value#10]                                             :                 +- *(2) LocalTableScan [value#10]
 +- Project [col4#34]                                                                            +- Project [col4#34]
    +- Join Inner, (col2#6 = col4#34)                                                               +- Join Inner, (col2#6 = col4#34)
       :- Project [value#31 AS col4#34]                                                                :- Project [value#31 AS col4#34]
       :  +- LocalRelation [value#31]                                                                  :  +- LocalRelation [value#31]
       +- Project [col2#6]                                                                             +- Project [col2#6]
          +- Union false, false                                                                           +- Union false, false
             :- Project [1 AS col2#6]                                                                        :- Project [1 AS col2#6]
             :  +- LocalRelation [value#1]                                                                   :  +- LocalRelation [value#1]
             +- Project [2 AS col2#15]                                                                       +- Project [2 AS col2#15]
                +- LocalRelation [value#10]                                                                     +- LocalRelation [value#10]

```
and so the result is wrong:
```
+----+----+
|col2|col4|
+----+----+
|   1|null|
+----+----+
```

After this PR foldable propagation will not happen incorrectly and the result is correct:
```
+----+----+
|col2|col4|
+----+----+
|   2|   2|
+----+----+
```

### Why are the changes needed?
To fix a correctness issue.

### Does this PR introduce _any_ user-facing change?
Yes, fixes a correctness issue.

### How was this patch tested?
Existing and new UTs.

Closes #29771 from peter-toth/SPARK-32635-fix-foldable-propagation.

Authored-by: Peter Toth <peter.toth@gmail.com>
Signed-off-by: Takeshi Yamamuro <yamamuro@apache.org>
(cherry picked from commit 4ced588)
Signed-off-by: Takeshi Yamamuro <yamamuro@apache.org>
@maropu maropu closed this in 4ced588 Sep 17, 2020
@maropu
Copy link
Member

maropu commented Sep 17, 2020

Thanks! Merged to master/3.0. Could you backport it into branch-2.4, @peter-toth ?

@maropu
Copy link
Member

maropu commented Sep 17, 2020

Also, do you want to make a PR for the @gatorsmile comment above #29771 (comment)?

@dongjoon-hyun
Copy link
Member

@maropu and @peter-toth . Please don't forget #29771 (comment) . That should be backported together.

@maropu
Copy link
Member

maropu commented Sep 18, 2020

Oh, I missed it. Could you fix it first in follow-up @peter-toth ?

@peter-toth
Copy link
Contributor Author

Thanks all for the review!

I've opened a follow-up PR: #29802 to add a new test case to FoldablePropagationSuite.

I will open a 2.4 backport PR soon and I'm happy to extend propagation to Aggregate (#29771 (comment)) as well in a separate ticket.

dongjoon-hyun pushed a commit that referenced this pull request Sep 18, 2020
### What changes were proposed in this pull request?
This is a follow-up PR to #29771 and just adds a new test case.

### Why are the changes needed?
To have better test coverage.

### Does this PR introduce _any_ user-facing change?
No.

### How was this patch tested?
New UT.

Closes #29802 from peter-toth/SPARK-32635-fix-foldable-propagation-followup.

Authored-by: Peter Toth <peter.toth@gmail.com>
Signed-off-by: Dongjoon Hyun <dhyun@apple.com>
dongjoon-hyun pushed a commit that referenced this pull request Sep 18, 2020
### What changes were proposed in this pull request?
This is a follow-up PR to #29771 and just adds a new test case.

### Why are the changes needed?
To have better test coverage.

### Does this PR introduce _any_ user-facing change?
No.

### How was this patch tested?
New UT.

Closes #29802 from peter-toth/SPARK-32635-fix-foldable-propagation-followup.

Authored-by: Peter Toth <peter.toth@gmail.com>
Signed-off-by: Dongjoon Hyun <dhyun@apple.com>
(cherry picked from commit 3309a2b)
Signed-off-by: Dongjoon Hyun <dhyun@apple.com>
@HyukjinKwon
Copy link
Member

Nice @peter-toth, LGTM too! cc @vinodkc FYI

dongjoon-hyun pushed a commit that referenced this pull request Sep 22, 2020
### What changes were proposed in this pull request?
This PR adds foldable propagation from `Aggregate` as per: #29771 (comment)

### Why are the changes needed?
This is an improvement as `Aggregate`'s `aggregateExpressions` can contain foldables that can be propagated up.

### Does this PR introduce _any_ user-facing change?
No.

### How was this patch tested?
New UT.

Closes #29816 from peter-toth/SPARK-32951-foldable-propagation-from-aggregate.

Authored-by: Peter Toth <peter.toth@gmail.com>
Signed-off-by: Dongjoon Hyun <dhyun@apple.com>
holdenk pushed a commit to holdenk/spark that referenced this pull request Oct 27, 2020
### What changes were proposed in this pull request?
This PR rewrites `FoldablePropagation` rule to replace attribute references in a node with foldables coming only from the node's children.

Before this PR in the case of this example (with setting`spark.sql.optimizer.excludedRules=org.apache.spark.sql.catalyst.optimizer.ConvertToLocalRelation`):
```scala
val a = Seq("1").toDF("col1").withColumn("col2", lit("1"))
val b = Seq("2").toDF("col1").withColumn("col2", lit("2"))
val aub = a.union(b)
val c = aub.filter($"col1" === "2").cache()
val d = Seq("2").toDF( "col4")
val r = d.join(aub, $"col2" === $"col4").select("col4")
val l = c.select("col2")
val df = l.join(r, $"col2" === $"col4", "LeftOuter")
df.show()
```
foldable propagation happens incorrectly:
```
 Join LeftOuter, (col2#6 = col4#34)                                                              Join LeftOuter, (col2#6 = col4#34)
!:- Project [col2#6]                                                                             :- Project [1 AS col2#6]
 :  +- InMemoryRelation [col1#4, col2#6], StorageLevel(disk, memory, deserialized, 1 replicas)   :  +- InMemoryRelation [col1#4, col2#6], StorageLevel(disk, memory, deserialized, 1 replicas)
 :        +- Union                                                                               :        +- Union
 :           :- *(1) Project [value#1 AS col1#4, 1 AS col2#6]                                    :           :- *(1) Project [value#1 AS col1#4, 1 AS col2#6]
 :           :  +- *(1) Filter (isnotnull(value#1) AND (value#1 = 2))                            :           :  +- *(1) Filter (isnotnull(value#1) AND (value#1 = 2))
 :           :     +- *(1) LocalTableScan [value#1]                                              :           :     +- *(1) LocalTableScan [value#1]
 :           +- *(2) Project [value#10 AS col1#13, 2 AS col2#15]                                 :           +- *(2) Project [value#10 AS col1#13, 2 AS col2#15]
 :              +- *(2) Filter (isnotnull(value#10) AND (value#10 = 2))                          :              +- *(2) Filter (isnotnull(value#10) AND (value#10 = 2))
 :                 +- *(2) LocalTableScan [value#10]                                             :                 +- *(2) LocalTableScan [value#10]
 +- Project [col4#34]                                                                            +- Project [col4#34]
    +- Join Inner, (col2#6 = col4#34)                                                               +- Join Inner, (col2#6 = col4#34)
       :- Project [value#31 AS col4#34]                                                                :- Project [value#31 AS col4#34]
       :  +- LocalRelation [value#31]                                                                  :  +- LocalRelation [value#31]
       +- Project [col2#6]                                                                             +- Project [col2#6]
          +- Union false, false                                                                           +- Union false, false
             :- Project [1 AS col2#6]                                                                        :- Project [1 AS col2#6]
             :  +- LocalRelation [value#1]                                                                   :  +- LocalRelation [value#1]
             +- Project [2 AS col2#15]                                                                       +- Project [2 AS col2#15]
                +- LocalRelation [value#10]                                                                     +- LocalRelation [value#10]

```
and so the result is wrong:
```
+----+----+
|col2|col4|
+----+----+
|   1|null|
+----+----+
```

After this PR foldable propagation will not happen incorrectly and the result is correct:
```
+----+----+
|col2|col4|
+----+----+
|   2|   2|
+----+----+
```

### Why are the changes needed?
To fix a correctness issue.

### Does this PR introduce _any_ user-facing change?
Yes, fixes a correctness issue.

### How was this patch tested?
Existing and new UTs.

Closes apache#29771 from peter-toth/SPARK-32635-fix-foldable-propagation.

Authored-by: Peter Toth <peter.toth@gmail.com>
Signed-off-by: Takeshi Yamamuro <yamamuro@apache.org>
(cherry picked from commit 4ced588)
Signed-off-by: Takeshi Yamamuro <yamamuro@apache.org>
holdenk pushed a commit to holdenk/spark that referenced this pull request Oct 27, 2020
### What changes were proposed in this pull request?
This is a follow-up PR to apache#29771 and just adds a new test case.

### Why are the changes needed?
To have better test coverage.

### Does this PR introduce _any_ user-facing change?
No.

### How was this patch tested?
New UT.

Closes apache#29802 from peter-toth/SPARK-32635-fix-foldable-propagation-followup.

Authored-by: Peter Toth <peter.toth@gmail.com>
Signed-off-by: Dongjoon Hyun <dhyun@apple.com>
(cherry picked from commit 3309a2b)
Signed-off-by: Dongjoon Hyun <dhyun@apple.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants