gengliangwang commented on PR #59313:
URL: https://github.com/apache/spark/pull/59313#issuecomment-6198311277

   I have two suggestions on the DSv2 adapter:
   
   1. **Separate driver-side planning from executor-side reading.**
   
      
[`ColumnarReader`](https://github.com/apache/spark/blob/e3ff80cc6bba0bbdd63cf260bc3878f772401fc8/sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/v2/columnar/ColumnarDataSource.scala#L62-L90)
 currently combines pushdown negotiation and partition planning with 
serialization and `read(partition)` on executors. `NativeDataSourceReader` 
switches between these roles using a transient native handle and mutable 
`readerState`. Also, `ColumnarScanBuilder.build()` passes closures that capture 
the mutable builder, alongside the scan's schema and pushdown metadata.
   
      Could we keep `ColumnarTable -> ColumnarScanBuilder -> ColumnarScan`, but 
introduce a driver-only `BatchReadPlanner` whose `plan()` returns 
`PlannedBatch(partitions, readerFactory)`? The executor factory would contain 
only the library location, source name, read schema, and serialized reader 
state. `build()` could establish stable scan metadata and explicit planner 
ownership, with defined behavior for repeated calls.
   
      This can preserve the native ABI and the current lazy partition-planning 
point: call `partitions`, then `serializeReader`, and close the native reader 
in `finally`. The batch adapter would cache the planned result, and we should 
retain the existing caching of planning failures as well. Batch planner 
creation should remain lazy for streaming-only sources. Plans that never reach 
partition planning would still need the Cleaner fallback, since DSv2 has no 
general scan-close hook. The benefit is a clearer driver/executor boundary and 
resource ownership.
   
   2. **Have `Table.capabilities()` reflect the individual source's supported 
operations.**
   
      
[`ColumnarTable.capabilities()`](https://github.com/apache/spark/blob/e3ff80cc6bba0bbdd63cf260bc3878f772401fc8/sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/v2/columnar/ColumnarTable.scala#L55-L56)
 currently advertises batch/streaming reads and writes plus truncate for every 
source, including read-only libraries. Unsupported operations are then 
discovered when the corresponding native creation method is called.
   
      Could the adapter receive a source-specific capability set, so Spark can 
reject unsupported operations earlier? For native sources, this needs a 
reliable discovery contract, such as capability metadata or an explicit 
capability query, covering both packaged and installed libraries. That 
mechanism is a separate design choice: a new native query would need an ABI 
compatibility plan, while the planner/factory split above can remain entirely 
internal.
   


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