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

   ### What is the problem the feature request solves?
   
   A `GenerateExec` whose generator is user-defined falls back to Spark. This 
covers Hive `GenericUDTF`s (`CREATE FUNCTION ... AS 'com.example.MyUDTF'` used 
in `LATERAL VIEW`, planned as `HiveGenericUDTF`) and custom Catalyst 
`Generator` expressions injected through session extensions. The fallback costs 
a columnar-to-row transition before the generator and a row-to-columnar 
transition after it, and the rest of the stage, often an aggregate over the 
generated rows, runs in Spark.
   
   The generator would still run on the JVM one row at a time, so the generator 
itself would not get faster. The gain is keeping the stage native around it.
   
   Comet already runs scalar `ScalaUDF`s in the native pipeline through codegen 
dispatch, but that path rejects any `Generator` 
(`CometBatchKernelCodegen.canHandle`), because its kernel contract is one 
output value per input row.
   
   ### Describe the potential solution
   
   A native generate operator that calls back into the JVM through the existing 
UDF bridge:
   
   1. Native code sends an input batch. The JVM side evaluates the bound 
generator's interpreted `eval` once per row, reading through the Arrow-backed 
row getters that codegen dispatch already uses, and writes the generated rows 
into Arrow vectors with the existing output writers.
   2. The JVM returns the generated columns plus a parent-row index for each 
output row. Native code builds the output by running `take` on the 
carried-forward columns with those indices and appending the generated columns. 
`outer` (one row of NULLs when the generator yields nothing) is an index with a 
null generated row.
   3. The bridge gains two lifecycle pieces it lacks today:
      - per-partition generator state that lives across batches, with 
`Nondeterministic.initialize(partitionIndex)`, as the per-plan kernel cache 
already does for `Rand`;
      - an end-of-input call so `terminate()` can emit its rows. `GenerateExec` 
pairs those rows with the carried-forward columns of the partition's last input 
row, matching Hive, so native code must keep that row.
   
   `HiveGenericUDTF` is `CodegenFallback` and converts through its own 
`ObjectInspector`s inside `eval`, so it needs nothing Hive-specific beyond what 
`eval` already does.
   
   ### Additional context
   
   - Python UDTFs (`@udtf`) plan as their own Python UDTF exec nodes, not 
`GenerateExec`, and belong with the Arrow Python UDF work (#5386, #5123).
   - #7251 (for #5125) runs `inline` and `stack` natively. The 
generated-columns-plus-parent-index shape here could also replace the list 
unnesting those use, though `ExplodeExec` already handles them well.
   


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