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

   ### What is the problem the feature request solves?
   
   An isolated `DeletedRecordCountsHistogramAgg` query falls back to Spark on 
the
   measured Spark 4.2.0 / Delta 4.4.0 / Comet 1.2.0 runtime:
   
   ```text
   unsupported Spark aggregate function: deletedrecordcountshistogramagg
   ```
   
   Results are correct through Spark. This is a request for one private 
aggregate,
   not native deletion-vector generation or a wrong-results report.
   
   ### Describe the potential solution
   
   Add optional support for this aggregate alone. Preserve its fixed bucket
   assignment, null/empty handling, update/merge and exact serialized state.
   Use a separately agreed optional integration seam without making Delta a 
mandatory core
   dependency or coupling this change to FileSizeHistogramAgg.
   
   Acceptance for the initial supported path:
   
   - Assert native aggregate execution and exact scalar/grouped buckets against 
Delta.
   - Cover null/empty partitions, zero, bucket boundaries and counter overflow.
     Negative inputs fail the reference nonnegative requirement; `Long.MaxValue`
     belongs to the final bucket.
   - Test native partial/merge/spill state. Independently classify cross-engine
     directions; unproved directions retain safe fallback rather than becoming
     required interoperability work. The normal state has one element-count byte
     containing `10`, followed by ten `Platform.putLong` counters: 81 bytes 
total.
     The header is not a version. Preserve reference count/length validation and
     target-architecture byte order.
   - Values `0,9,10,99,100,NULL` produce buckets
     `[1,1,2,1,0,0,0,0,0,0]`.
   
   **Out of scope:** file-size histograms, DV bitmap generation, DV 
reads/writes,
   REORG/VACUUM execution, arbitrary colocated aggregates and production 
settings.
   This issue can close without completing any of those operations.
   
   ### Additional context
   
   
   [Delta's 
implementation](https://github.com/delta-io/delta/blob/v4.4.0/spark/src/main/scala/org/apache/spark/sql/delta/stats/DeletedRecordCountsHistogramUtils.scala)
   defines both bucket selection and its own serialization. Its output is not
   FileSizeHistogramAgg's boundaries/counts/bytes layout.
   [Spark 4.2 null/aggregate 
semantics](https://spark.apache.org/docs/4.2.0/sql-ref-null-semantics.html)
   remain the surrounding query oracle. Coordinate state-admission rules with 
#5975.
   
   Observed runtime: Spark 4.2.0 / Scala 2.13.18 / Java 17, Delta 4.4.0 and 
released Comet 1.2.0 (`ab46419fcc99bcd34aa4d89f7b545d5d51694a88`). Current main 
inspected at `4de6704391c9a7832a2079fc4e8d80fc09e9b209` was not executed. This 
is missing support, not a current-main regression or a wrong-results report. No 
measured native-kernel speedup is claimed. Optional integration design still 
needs maintainer agreement.
   
   <details>
   <summary>Self-contained DeletedRecordHistogramRepro reproducer and launch 
commands</summary>
   
   Save as `DeletedRecordHistogramRepro.scala`. Each mode creates its own fresh 
synthetic Parquet fixture. The Comet control must contain Comet operators 
before this expression is tested; passing expected rows alone does not 
establish native execution of the requested expression.
   
   ```scala
   package org.apache.spark.sql.comet.repro
   
   import java.nio.file.{Files, Paths}
   import org.apache.spark.sql.{Column, SparkSession}
   import org.apache.spark.sql.catalyst.analysis.UnresolvedAttribute
   import org.apache.spark.sql.classic.ClassicConversions._
   import org.apache.spark.sql.functions._
   import 
org.apache.spark.sql.delta.stats.DeletedRecordCountsHistogramUtils.DeletedRecordCountsHistogramAgg
   
   object DeletedRecordHistogramRepro {
     def main(args: Array[String]): Unit = {
       require(args.length == 2, "usage: stock|comet <fresh output>")
       val mode = args(0); require(Set("stock", "comet")(mode))
       val out = Paths.get(args(1)); Files.createDirectory(out)
       val spark = SparkSession.builder
         .config("spark.sql.extensions", 
"io.delta.sql.DeltaSparkSessionExtension" +
           (if (mode == "comet") 
",org.apache.comet.CometSparkSessionExtensions" else ""))
         .config("spark.sql.catalog.spark_catalog", 
"org.apache.spark.sql.delta.catalog.DeltaCatalog")
         .config("spark.comet.enabled", (mode == "comet").toString)
         .config("spark.comet.exec.enabled", (mode == "comet").toString)
         .config("spark.comet.explain.fallback.enabled", "true")
         .config("spark.comet.explain.fallback.log.enabled", "true")
         .config("spark.shuffle.manager", if (mode == "comet")
           "org.apache.spark.sql.comet.execution.shuffle.CometShuffleManager"
           else "org.apache.spark.shuffle.sort.SortShuffleManager")
         .config("spark.memory.offHeap.enabled", "true")
         .config("spark.memory.offHeap.size", "512m")
         .config("spark.sql.shuffle.partitions", "2")
         .getOrCreate()
       try {
         val control = spark.range(20).selectExpr("sum(id) AS total")
         require(control.collect().head.getLong(0) == 190L)
         if (mode == "comet") 
require(control.queryExecution.executedPlan.toString.contains("Comet"))
         val path = out.resolve("input").toString
         spark.sql("SELECT CAST(v AS BIGINT) v, CAST(v AS INT) x, payload FROM 
VALUES " +
           "(0,'a'),(9,'b'),(10,'c'),(99,'d'),(100,'e'),(NULL,'f') AS 
t(v,payload)")
           .repartition(2).write.parquet(path)
         val input = spark.read.parquet(path)
         val query = input.agg(Column(DeletedRecordCountsHistogramAgg(
           UnresolvedAttribute("v")).toAggregateExpression()).as("deleted"))
         require(query.collect().head.getSeq[Long](0) == 
Seq(1L,1L,2L,1L,0L,0L,0L,0L,0L,0L))
         println(query.queryExecution.executedPlan.toString)
         println("PASS: DeletedRecordHistogramRepro " + mode)
       } finally spark.stop()
     }
   }
   ```
   
   Use Spark 4.2.0 with Java 17. Maven coordinates:
   
   - `io.delta:delta-spark_4.2_2.13:4.4.0`
   - `io.delta:delta-storage:4.4.0`
   - `org.apache.datafusion:comet-spark-spark4.2_2.13:1.2.0`
   
   Set `SPARK_HOME`, `JAVA_HOME`, `DELTA_JARS` (two Delta JAR paths, comma 
separated), and `COMET_JAR` to these local artifacts. The Comet release 
contains its matching native library. No Delta contrib JAR is required for this 
reproducer. Bash commands:
   
   ```bash
   set -euo pipefail
   export SPARK_LOCAL_IP=127.0.0.1
   export COMET_WORKER_THREADS=2
   export COMET_MAX_BLOCKING_THREADS=4
   repro_root=$(mktemp -d /tmp/comet-delta-expression.XXXXXX)
   mkdir "$repro_root/classes"
   "$JAVA_HOME/bin/java" -Xmx512m -XX:ActiveProcessorCount=2 \
     -cp "$SPARK_HOME/jars/*" scala.tools.nsc.Main \
     -classpath "$SPARK_HOME/jars/*:${DELTA_JARS//,/:}" \
     -d "$repro_root/classes" DeletedRecordHistogramRepro.scala
   "$JAVA_HOME/bin/jar" cf "$repro_root/probe.jar" -C "$repro_root/classes" .
   for mode in stock comet; do
     jars="$DELTA_JARS"
     if [ "$mode" = comet ]; then jars="$jars,$COMET_JAR"; fi
     "$SPARK_HOME/bin/spark-submit" --master 'local[2]' --driver-memory 2g \
       --conf spark.driver.extraJavaOptions=-XX:ActiveProcessorCount=2 \
       --jars "$jars" --class 
org.apache.spark.sql.comet.repro.DeletedRecordHistogramRepro \
       "$repro_root/probe.jar" "$mode" "$repro_root/$mode"
   done
   ```
   
   Expected: both modes exit zero and print `PASS: DeletedRecordHistogramRepro 
<mode>`. On the measured Comet 1.2.0 runtime, the requested private expression 
remains on Spark and the fallback reason appears in the log. The source above 
pins exact expected results; it does not implement the feature.
   
   </details>
   
   ### Willingness to contribute
   
   I would be willing to contribute a fix for this bug with guidance from the 
DataFusion community.
   


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