zhuqi-lucas opened a new pull request, #25865:
URL: https://github.com/apache/datafusion/pull/25865

   ## Which issue does this PR close?
   
   - Closes #25864.
   
   ## Rationale for this change
   
   A predicate that depends only on a window's `PARTITION BY` keys is constant 
within every partition, so applying it below the window drops whole partitions 
and leaves every surviving row's window value unchanged. `push_down_filter` 
already does this, but only for plain column keys.
   
   The key set is built by mapping each partition key through 
`qualified_name()` into a `Column`, so `PARTITION BY a + b` becomes a column 
literally named `"a + b"`. A predicate on `a + b` reads the real columns `a` 
and `b`, which never match that synthesised name, so it stays above the window. 
The optimization simply does not exist for expression keys such as `a + b`, 
`NULLIF(c, '')` or `COALESCE(x, y)`.
   
   It also affects *mixed* predicates. With `PARTITION BY year, num * num`:
   
   ```sql
   SELECT * FROM (
       SELECT year, num, SUM(num) OVER (PARTITION BY year, num * num) AS s FROM 
t
   )
   WHERE year = '2021' OR num * num > 4
   ```
   
   the predicate is constant within every partition and safe to push, but its 
column refs are `{year, num}` against a key set of `{year, "num * num"}`, so 
`num` is not found and the whole conjunct is kept.
   
   ## What changes are included in this PR?
   
   **Keep a volatile predicate above the window** (first commit, independent of 
the rest)
   
   A volatile predicate that reads no columns, such as `random() < 0.5`, 
satisfies the subset test vacuously and was pushed below the window, where it 
changes which rows the window function sees. The aggregate arm already drops 
volatile group expressions before the equivalent check; this does the same 
here. Split out as its own commit so it can be taken separately.
   
   **Match against the key expressions** (second commit)
   
   The key set holds the partition key `Expr`s rather than names synthesised 
from them, and each conjunct is walked: a subtree exactly equal to one of the 
keys counts as read in full, and the predicate is rejected only on reaching a 
`Column` that no key covered.
   
   This is a strict generalization. For a plain column key, the reference to 
that column is itself a subtree equal to the key, so every predicate pushed 
today is still pushed; expression keys and mixed predicates are added on top. 
Matching is structural, so it stays conservative: a predicate written `b + a` 
does not match a key written `a + b` and is left in place.
   
   No predicate rewriting is involved. The existing comment in that arm notes 
that a window partition expression, unlike an aggregate group expression, is 
not exposed as a standalone column, so there is nothing to rewrite `a + b` 
into. The predicate is pushed unchanged.
   
   ## Are these changes tested?
   
   Yes, in `push_down_filter`'s unit tests:
   
   - `filter_expression_move_window`: a predicate on `PARTITION BY a + b` is 
now pushed. This replaces `filter_expression_keep_window`, which pinned the 
previous behavior.
   - `filter_move_window_mixed_column_and_expression_keys`: `PARTITION BY a, a 
+ b` with `a > 1 OR a + b > 10` is pushed, the case neither the old matching 
nor an expression-key-only rule could see.
   - `filter_keep_window_column_underlying_expression_key`: an expression key 
does not make the columns it reads pushable on their own, so `a > 10` under 
`PARTITION BY a + b` stays above.
   - `filter_volatile_keep_window`: the volatility case above. Verified it 
fails without the guard.
   
   The existing window tests (`filter_move_window`, 
`filter_move_partial_window`, `filter_order_keep_window`, 
`filter_multiple_windows_common_partitions`, 
`filter_multiple_windows_disjoint_partitions`, and the rest) are unchanged and 
pass, which is the evidence for the "strict generalization" claim.
   
   Still to do before this leaves draft: confirm the `sqllogictest` plan churn. 
More pushdown means some window plans change, and those are expected updates 
rather than regressions, but I want to post the actual diff here rather than 
assert it.
   
   ## Are there any user-facing changes?
   
   Better plans for window queries filtered on expression partition keys, and a 
correctness fix for volatile predicates over windows. No API changes.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to