Skip to content

[branch-56] fix: retain finer sorts above merges (backport #27060) - #27331

Open
geoffreyclaude wants to merge 1 commit into
apache:branch-56from
geoffreyclaude:backport/27060-branch-56
Open

geoffreyclaude wants to merge 1 commit into
apache:branch-56from
geoffreyclaude:backport/27060-branch-56

Conversation

@geoffreyclaude

@geoffreyclaude geoffreyclaude commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

Rationale for this change

A finer ordering pushed below SortPreservingMergeExec is lost when the merge keeps fewer keys. This produces incorrectly ordered results and can make a window query fail plan validation. Downstream testing still reproduces the failure in the 56 line.

The original fix merged after branch-56 was cut and is needed before the DataFusion 56 release candidate.

What changes are included in this PR?

Cherry-pick 3f4a37fbabdcb07705db6341268e6c0b34da0d34 from #27060. Keep the finer parent sort above the merge, together with the original regression tests.

The limit.slt conflict was append context from an unrelated test absent on branch-56; only the original #26162 regression block is added.

What is the testing strategy for this PR?

Carries the original limit.slt checks for ordered output, a window, an ordered aggregate and a UNION, plus the physical-plan regression for a merge without a fetch.

cargo fmt --all, both targeted physical-plan tests and the limit.slt checks passed. Reverting the optimizer change makes the new non-fetched-merge regression fail.

Are there any user-facing changes?

Queries retain their requested ordering above sort-preserving merges. No public API changes.

…apache#26162) (apache#27060)

## Which issue does this PR close?
- Closes apache#26162.

## Rationale for this change
In apache#26162, running `ORDER BY b, a` over a multi-partition subquery with
`ORDER BY b LIMIT n` produces incorrect ordering on `a`.

Pushing `[b, a]` down removed the outer `SortExec`, but SPM only merges
on `[b]`. As a result, `a` was not sorted in the final output.

In the discussion, @jayzhan211 suggested two possible approaches:
declining pushdown for SPM with fetch, or rewriting SPM's expressions
when pushing through it.

I chose `Ok(None)` (declining pushdown) because:
- The subquery did not explicitly request the parent's sort. When a
limit is present, forcing that sort on the entire dataset across
partitions before a limit is unnecessary work.
- Since `pushdown_requirement_to_children` only adds requirements to
children, I think a logic to rewrite SPM adds extra complexity.

## What changes are included in this PR?
- Return `Ok(None)` from `pushdown_requirement_to_children` when `plan`
is `SortPreservingMergeExec` and has a `fetch`.
- Add an SLT regression query in `limit.slt`.

## What is the testing strategy for this PR?
- query on a partitioned table in `limit.slt` reproducing apache#26162.

## Are there any user-facing changes?
Yes, bug fix: queries like `ORDER BY b, a` over a multi-partition
subquery with `ORDER BY b LIMIT n` now return correctly ordered results
on `a`. No API changes.

---------

Co-authored-by: Jay Zhan <jayzhan211@gmail.com>

(cherry picked from commit 3f4a37f)
@github-actions github-actions Bot added optimizer Optimizer rules core Core DataFusion crate sqllogictest SQL Logic Tests (.slt) labels Nov 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core Core DataFusion crate optimizer Optimizer rules sqllogictest SQL Logic Tests (.slt)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants