parthchandra opened a new issue, #7270:
URL: https://github.com/apache/datafusion-comet/issues/7270

   Part of #7267.
   
   ## Problem
   
   Comet picks the window operator in 
`native/core/src/execution/planner/window.rs:133`:
   if every window expression in the Spark Window node can run with bounded 
memory
   (`uses_bounded_memory()`), it builds `BoundedWindowAggExec`; otherwise it 
builds
   DataFusion's `WindowAggExec` (`window.rs:142`) for the whole node.
   
   `WindowAggExec` is used when any expression in the node:
   
   - is `percent_rank`, `cume_dist` or `ntile` (never bounded); or
   - is an aggregate (sum, avg, count, min, max, first, last) or `nth_value` 
whose frame
     ends at UNBOUNDED FOLLOWING (`physical-expr window/aggregate.rs:218`,
     `standard.rs:277`, DataFusion 55.2.0). That includes Spark's default frame 
when
     there is no ORDER BY, so a plain `sum(x) OVER (PARTITION BY k)` lands here.
   
   `WindowAggExec::compute_aggregates` buffers every input batch of the task, 
then
   runs `concat_batches` over all of them (`window_agg_exec.rs:539`). The result
   columns are concatenated the same way (`:563`), and the operator emits one 
batch
   that is never sliced to the batch size (`:573`).
   
   If the task's input holds more than 2 GiB in any string/binary column, 
including
   columns that are only passed through, the concat fails with 
`OffsetOverflowError`.
   A string result such as `max(blob) OVER (PARTITION BY k)` can also overflow 
in the
   result concat. With no PARTITION BY, Spark sends every row to one task.
   
   No batch size setting helps, because the operator always builds one batch 
from the
   whole input.
   
   ## Options
   
   1. **Emit per partition (Comet or upstream).** The input is already sorted 
by the
      partition keys, so the operator can compute and emit at each partition 
boundary
      instead of concatenating the whole task input. This bounds the concat to 
one
      window partition.
   2. **Project pass-through columns out before the window** and join them back 
by row
      position afterwards. Only the partition/order keys and the function 
inputs need
      to go through the concat. Large payload columns usually aren't in those.
   3. **Fall back to Spark** when the window input has string/binary columns 
and the
      plan can't bound their size. Simple, but over-broad: most string columns 
are
      small. Could be gated on a config.
   
   Main already routes to `BoundedWindowAggExec` whenever DataFusion allows it, 
so
   there is no cheap rerouting option.
   
   Recommendation: option 1, with option 3 as a stopgap if needed.
   
   ## Tests
   
   - Plan-level test that `sum(x) OVER (PARTITION BY k)` and `ntile` plan as
     `WindowAggExec`, then that the chosen fix applies.
   - SQL-file tests of `percent_rank`, `ntile` and `sum(x) OVER (PARTITION BY 
k)` with a
     binary pass-through column, compared with Spark.
   
   ## Notes
   
   - Risk is high: the default-frame aggregate case is common.
   


-- 
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