comphead commented on code in PR #7536:
URL: https://github.com/apache/datafusion-comet/pull/7536#discussion_r4532980821


##########
spark/src/main/scala/org/apache/spark/sql/comet/CometIcebergWriteExec.scala:
##########
@@ -230,29 +231,41 @@ case class CometIcebergWriteExec(
 
   override def doExecuteColumnar(): RDD[ColumnarBatch] = {
     val schedulerProbe = IcebergSchedulerTestProbe.current
-    val inputRDD = if (child.supportsColumnar) {
-      child.executeColumnar()
-    } else {
-      throw new UnsupportedOperationException(
-        "CometIcebergWriteExec requires a columnar (Comet native) child; got " 
+
-          child.getClass.getName)
+    // One Arrow stream per partition, which native consumes through the C 
Stream Interface.
+    val streamRDD: RDD[ArrowArrayStream] = child match {
+      // Native reads the source's Arrow stream, as it does for a native 
operator's input. The
+      // source reuses its vectors for the next batch, and wrapping its 
`executeColumnar` batches
+      // below closes each batch once native has it; closing a struct vector 
drops its children,
+      // so the next batch would lose them (#7239). The scheduler probe counts 
rows as batches.
+      case source: CometNativeArrowSource if schedulerProbe.isEmpty =>

Review Comment:
   As the description says, on `main` this failure no longer happens since 
#7325, so the comment describes the release branches only. Could it say why the 
stream route is still preferred on `main` (it skips the per-batch 
`VectorSchemaRoot` re-wrap and unload/load in `readerBatchIter` and 
`ColumnarBatchArrowReader`) and point to #7239 for the older branches?



##########
spark/src/main/scala/org/apache/spark/sql/comet/CometIcebergWriteExec.scala:
##########
@@ -230,29 +231,41 @@ case class CometIcebergWriteExec(
 
   override def doExecuteColumnar(): RDD[ColumnarBatch] = {
     val schedulerProbe = IcebergSchedulerTestProbe.current
-    val inputRDD = if (child.supportsColumnar) {
-      child.executeColumnar()
-    } else {
-      throw new UnsupportedOperationException(
-        "CometIcebergWriteExec requires a columnar (Comet native) child; got " 
+
-          child.getClass.getName)
+    // One Arrow stream per partition, which native consumes through the C 
Stream Interface.
+    val streamRDD: RDD[ArrowArrayStream] = child match {
+      // Native reads the source's Arrow stream, as it does for a native 
operator's input. The
+      // source reuses its vectors for the next batch, and wrapping its 
`executeColumnar` batches
+      // below closes each batch once native has it; closing a struct vector 
drops its children,
+      // so the next batch would lose them (#7239). The scheduler probe counts 
rows as batches.
+      case source: CometNativeArrowSource if schedulerProbe.isEmpty =>

Review Comment:
   With `schedulerProbe.isEmpty` in the match, every test that installs the 
probe over a VALUES or RDD write (`CometLocalTableScanExec` and 
`CometSparkToColumnarExec` are both `CometNativeArrowSource`) now takes the 
wrapped route. So the speculation, executor-loss and scheduler failure tests no 
longer exercise the route production uses for those children. Which suites 
cover failure and cleanup on the stream route, for example the handoff 
failpoint tests, which do not install the probe?



##########
spark/src/test/scala/org/apache/comet/CometIcebergWriteActionSuite.scala:
##########
@@ -412,6 +413,45 @@ class CometIcebergWriteActionSuite
     }
   }
 
+  // https://github.com/apache/datafusion-comet/issues/7239. A conversion of 
Spark rows writes
+  // every batch into the same vectors, and closing a struct vector drops its 
children. The write
+  // reads the conversion's Arrow stream, as native shuffle does, rather than 
batches it would
+  // close once native had them, which left the second batch of a partition 
without them.
+  test("native write reads a struct column that a conversion writes over 
several batches") {

Review Comment:
   On `main` the old route already hands out independent vectors since #7325, 
so I expect this test to pass there with and without the change (I have not run 
it). It guards the release branches, so could the backport PRs confirm it fails 
there without the fix? The #6689 test also ran a local table scan 
(`CometLocalTableScanExec`), which reaches the same branch through the trait. 
Looping over both, with more than one partition, would cover the new case fully.



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