Skip to content

Conversation

@viirya
Copy link
Member

@viirya viirya commented Aug 6, 2025

What changes were proposed in this pull request?

This patch fixes the optimization rule RemoveRedundantAggregates.

Why are the changes needed?

The optimizer rule RemoveRedundantAggregates removes redundant lower aggregation from a query plan and replace it with a project of referred non-aggregate expressions. However, if the removed aggregation is a global one, that is not correct because a project is different with a global aggregation in semantics.

For example, if the input relation is empty, a project might be optimized to an empty relation, while a global aggregation will return a single row.

Does this PR introduce any user-facing change?

Yes, this fixes a user-facing bug. Previously, a global aggregation under another aggregation might be treated as redundant and replaced as a project with non-aggregation expressions. If the input relation is empty, the replacement is incorrect and might produce incorrect result. This patch adds a new unit test to show the difference.

How was this patch tested?

Unit test, manual test.

Was this patch authored or co-authored using generative AI tooling?

No

@github-actions github-actions bot added the SQL label Aug 6, 2025
Copy link
Member

Choose a reason for hiding this comment

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

According to the JIRA issue, is this bug starting at Spark 3.4? Or, is it a long-standing bug which we have before?

Copy link
Member Author

@viirya viirya Aug 6, 2025

Choose a reason for hiding this comment

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

Yea, the issue seems there since RemoveRedundantAggregates was introduced.

Copy link
Member

@dongjoon-hyun dongjoon-hyun Aug 6, 2025

Choose a reason for hiding this comment

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

@dongjoon-hyun
Copy link
Member

Thank you, @viirya .

cc @peter-toth , too.

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.

@viirya viirya force-pushed the fix_remove_redundant_agg branch from 9c626df to 808a35c Compare August 7, 2025 05:47
.groupBy()(Literal(1).as("col1"), Literal(2).as("col2"), Literal(3).as("col3"))
.groupBy($"col1")(max($"col1"))
.analyze
val expected = relation
Copy link
Contributor

Choose a reason for hiding this comment

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

expected = query?

Copy link
Member Author

Choose a reason for hiding this comment

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

ah, as seems it doesn't look like necessary so I didn't change this to save another CI round. Thank you.

@viirya viirya closed this in 3aa8c9d Aug 7, 2025
viirya added a commit that referenced this pull request Aug 7, 2025
…ith a project

This patch fixes the optimization rule `RemoveRedundantAggregates`.

The optimizer rule `RemoveRedundantAggregates` removes redundant lower aggregation from a query plan and replace it with a project of referred non-aggregate expressions. However, if the removed aggregation is a global one, that is not correct because a project is different with a global aggregation in semantics.

For example, if the input relation is empty, a project might be optimized to an empty relation, while a global aggregation will return a single row.

Yes, this fixes a user-facing bug. Previously, a global aggregation under another aggregation might be treated as redundant and replaced as a project with non-aggregation expressions. If the input relation is empty, the replacement is incorrect and might produce incorrect result. This patch adds a new unit test to show the difference.

Unit test, manual test.

No

Closes #51884 from viirya/fix_remove_redundant_agg.

Authored-by: Liang-Chi Hsieh <[email protected]>
Signed-off-by: Liang-Chi Hsieh <[email protected]>
(cherry picked from commit 3aa8c9d)
Signed-off-by: Liang-Chi Hsieh <[email protected]>
viirya added a commit that referenced this pull request Aug 7, 2025
…ith a project

This patch fixes the optimization rule `RemoveRedundantAggregates`.

The optimizer rule `RemoveRedundantAggregates` removes redundant lower aggregation from a query plan and replace it with a project of referred non-aggregate expressions. However, if the removed aggregation is a global one, that is not correct because a project is different with a global aggregation in semantics.

For example, if the input relation is empty, a project might be optimized to an empty relation, while a global aggregation will return a single row.

Yes, this fixes a user-facing bug. Previously, a global aggregation under another aggregation might be treated as redundant and replaced as a project with non-aggregation expressions. If the input relation is empty, the replacement is incorrect and might produce incorrect result. This patch adds a new unit test to show the difference.

Unit test, manual test.

No

Closes #51884 from viirya/fix_remove_redundant_agg.

Authored-by: Liang-Chi Hsieh <[email protected]>
Signed-off-by: Liang-Chi Hsieh <[email protected]>
(cherry picked from commit 3aa8c9d)
Signed-off-by: Liang-Chi Hsieh <[email protected]>
@viirya
Copy link
Member Author

viirya commented Aug 7, 2025

Thanks @dongjoon-hyun @peter-toth

Merged to master/4.0/3.5.

@viirya viirya deleted the fix_remove_redundant_agg branch August 7, 2025 15:28
@viirya
Copy link
Member Author

viirya commented Aug 7, 2025

The CI of branch-4.0 failed on AdaptiveQueryExecSuite (SPARK-47148: AQE should avoid to submit shuffle job on cancellation) after merging this patch:

https://github.com/apache/spark/actions/runs/16808660184/job/47607970234

This patch doesn't touch any AQE or shuffle stuffs. I also verified it locally and the test passed without issue. Seems just a flaky test.

For branch-3.5, all tests were passed but just documentation build failed:

https://github.com/apache/spark/actions/runs/16808722611/job/47608228583

I think it is not related too.

zifeif2 pushed a commit to zifeif2/spark that referenced this pull request Nov 14, 2025
…ith a project

This patch fixes the optimization rule `RemoveRedundantAggregates`.

The optimizer rule `RemoveRedundantAggregates` removes redundant lower aggregation from a query plan and replace it with a project of referred non-aggregate expressions. However, if the removed aggregation is a global one, that is not correct because a project is different with a global aggregation in semantics.

For example, if the input relation is empty, a project might be optimized to an empty relation, while a global aggregation will return a single row.

Yes, this fixes a user-facing bug. Previously, a global aggregation under another aggregation might be treated as redundant and replaced as a project with non-aggregation expressions. If the input relation is empty, the replacement is incorrect and might produce incorrect result. This patch adds a new unit test to show the difference.

Unit test, manual test.

No

Closes apache#51884 from viirya/fix_remove_redundant_agg.

Authored-by: Liang-Chi Hsieh <[email protected]>
Signed-off-by: Liang-Chi Hsieh <[email protected]>
(cherry picked from commit 776b68f)
Signed-off-by: Liang-Chi Hsieh <[email protected]>
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.

3 participants