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

   Part of #7267.
   
   ## Problem
   
   Comet builds DataFusion's `FilterExec` with `FilterExec::try_new(predicate, 
child)`
   in `native/core/src/execution/planner.rs` (the `OpStruct::Filter` arm) and 
never
   sets its batch size. `FilterExec` merges its output with a 
`LimitedBatchCoalescer`
   whose target is `FilterExec::batch_size`. That field defaults to
   `FILTER_EXEC_DEFAULT_BATCH_SIZE = 8192` (DataFusion 55.2.0, `filter.rs:80`).
   
   DataFusion's own physical planner sets it from the session config
   (`physical_planner.rs`, 
`FilterExecBuilder::with_batch_size(session_state.config().batch_size())`).
   Comet skips that step, so:
   
   - `spark.comet.batchSize` has no effect on filter output. The scan honors 
it, then
     the filter merges batches back up to 8192 rows.
   - With large string/binary values, 8192 rows can exceed 2 GiB and the merge 
fails
     with `Offset overflow error` inside `concat_bytes` ->
     `GenericByteBuilder::append_array`.
   
   This match arm is the only place Comet creates a `FilterExec`
   (`planner.rs:1694` on main). Every later rebuild keeps the field:
   
   - The filter/projection fusion in 
`native/core/src/execution/operators/projection.rs:68-79`
     rebuilds it with `FilterExecBuilder::from`, which copies `batch_size`
     (DataFusion `filter.rs:225-232`).
   - `CometFilterExec` (now `MetricOwningExec<FilterExec>`, 
`native/operators/src/filter.rs:28`,
     built only in `planner/join.rs:373-381`) wraps a clone. Its 
`replace_input`,
     `with_fetch` and `with_execution_input` go through 
`FilterExec::replace_children`
     and `with_fetch`, which keep the value (`filter.rs:555-575, 822-832`).
   
   So one planner change covers all of them.
   
   ## Proposed fix
   
   ```rust
   let filter = FilterExecBuilder::new(predicate, 
Arc::clone(&child.native_plan))
       .with_batch_size(self.session_ctx.copied_config().batch_size())
       .build()?;
   ```
   
   ## Tests
   
   - Rust planner test: plan a Filter with a session batch size of N and assert 
the
     native `FilterExec::batch_size() == N`. Also cover the filter+projection 
fusion path.
   - Batch-size test: with `spark.comet.batchSize=10`, filter a table where 
most rows
     pass, and assert no native output batch has more than 10 rows. This fails 
before
     the fix (batches of up to 8192 rows). It can't be a SQL-file test because 
SQL
     can't see batch sizes.
   - Result check: a SQL-file test with a binary column of values a few hundred 
KB in
     size, under a filter, at a small batch size, compared with Spark.
   
   ## Scope and limits
   
   - `spark.comet.batchSize` defaults to 8192, the same as DataFusion's filter 
default,
     so at default settings this change does nothing at runtime. It makes 
lowering
     `spark.comet.batchSize` work as a workaround.
   - Still row-based. At 8192 rows, any string/binary column averaging more 
than ~256
     KiB per value still overflows. Users must lower `spark.comet.batchSize` 
until
     sub-issue 4 lands.
   - `LimitedBatchCoalescer` passes an input batch larger than half the target 
through
     unmerged when nothing is buffered (DataFusion `coalesce/mod.rs:63-64`), so 
filter
     output batches can be up to the scan's batch size, which is also the 
session value.
   - Users who raised `spark.comet.batchSize` above 8192 now get bigger filter 
batches,
     matching what other operators already do with the session value.
   - Touches the planner, so run `dev/local-ci.sh spark sql_core-1` or apply the
     `run-spark-4.1-tests` label before merging.
   


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