Skip to content

fix: don't leak joined branch's sort into implicit ORDER BY for take#6015

Open
lukapeschke wants to merge 1 commit into
PRQL:mainfrom
lukapeschke:fix-order-by-out-of-scope-after-join-sort-take
Open

fix: don't leak joined branch's sort into implicit ORDER BY for take#6015
lukapeschke wants to merge 1 commit into
PRQL:mainfrom
lukapeschke:fix-order-by-out-of-scope-after-join-sort-take

Conversation

@lukapeschke

Copy link
Copy Markdown
Contributor

When a pipeline sorts both the left and the joined branch (both wrapped in CTEs by a preceding group) and is then truncated with take, prqlc synthesized the implicit ORDER BY for the LIMIT from the joined branch's sort column. That column is anchored to the joined branch's source table, which is no longer in scope once the branch is materialized as a CTE, producing invalid SQL (e.g. ORDER BY bar.a where bar lives inside a CTE).

The Flattener folds a join's input (left) first, setting the running sort frame to the left's order, then folds the join's with sub-pipeline, which overwrote the frame with the right branch's sort. The join transform's own sort was cleared, but self.sort was left pointing at the joined branch, so downstream transforms (take) inherited the wrong column.

Snapshot and restore the input's sort frame around folding a join/append kind, implementing the documented "a join retains the left side's order" semantic. The implicit ORDER BY now references the left CTE alias.

When a pipeline sorts both the left and the joined branch (both wrapped in
CTEs by a preceding `group`) and is then truncated with `take`, prqlc
synthesized the implicit ORDER BY for the LIMIT from the *joined* branch's
sort column. That column is anchored to the joined branch's source table,
which is no longer in scope once the branch is materialized as a CTE,
producing invalid SQL (e.g. `ORDER BY bar.a` where `bar` lives inside a CTE).

The `Flattener` folds a join's input (left) first, setting the running sort
frame to the left's order, then folds the join's `with` sub-pipeline, which
overwrote the frame with the right branch's sort. The join transform's own
sort was cleared, but `self.sort` was left pointing at the joined branch, so
downstream transforms (`take`) inherited the wrong column.

Snapshot and restore the input's sort frame around folding a join/append
kind, implementing the documented "a join retains the left side's order"
semantic. The implicit ORDER BY now references the left CTE alias.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants