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

   Part of #7267.
   
   ## Problem
   
   `ExplodeExec` copies every column that is not exploded once per array 
element, with `take` (`repeat_arrs_from_indices`, 
`native/operators/src/explode.rs:1291-1305`). It decides how many input rows to 
unnest at a time by output row count only (`next_chunk_rows`, `:320-342`), and 
it never splits one input row: a row whose array is longer than the batch size 
is built in one go and sliced afterwards.
   
   So the copied columns can pass 2 GiB even when the input is small. In 
`SELECT payload, explode(items) FROM t`, rows with a 300 KB `payload` and 900 
elements each are unnested nine at a time, so each chunk is 8,100 output rows 
holding 2.4 GB of `payload`. One row with a 1 MiB payload and a 2,100-element 
array overflows on its own, at any batch size. The query fails with `Arrow 
error: Offset overflow error: 2147483648`. Spark's `GenerateExec` produces one 
row at a time and succeeds.
   
   The epic lists explode as honoring the batch size. It does for rows, but the 
copying makes each output row as large as its input row, so bytes per batch are 
not bounded.
   
   A unit test on the one-row case fails with `Offset overflow error: 
2147483648` at `batch_size=8192` and at `batch_size=1024`.
   
   Line references are for main at 4e6b12290f.
   
   ## Workaround
   
   Lowering `spark.comet.batchSize` helps when many input rows share a chunk, 
but not for one row with a long array. `spark.comet.exec.explode.enabled=false` 
runs explode in Spark.
   
   ## Proposed fix
   
   - When picking the next chunk, also bound the predicted output bytes: for 
each copied variable-width column, sum the value length times the row's output 
length (`output_lens` already holds the second factor) over the chunk's rows.
   - Let one input row be split across several output batches, by taking ranges 
of its repeated indices instead of the whole row at once.
   
   ## Tests
   
   `take` computes the output size before it allocates, so the one-row case 
above fails in milliseconds today. After the fix, test the chunking with a 
small byte budget injected for the test, and check that one row with a long 
array comes out in several batches with the right values.
   


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