Skip to content

ANY_VALUE memory regression in Comet 1.2.0 #7541

Open

Description

@judahrand

Comet 1.2.0 fails ANY_VALUE(array<string>) with an oversized memory reservation.
Spark lowers this to first, which uses DataFusion 55.2.0's
TrivialFirstValueAccumulator::merge_batch. That method retains the input's
backing buffers and counts them repeatedly across groups.

This is fixed by apache/datafusion#26743.
Could we update to a dependency containing it when released?

Reproducer

With Spark 4.1.3, Java 21, and the Comet JAR installed in $SPARK_HOME/jars,
save this as inline_repro.py:

from pyspark.sql import SparkSession

spark = (
    SparkSession.builder.config("spark.ui.enabled", "false")
    .config("spark.sql.adaptive.enabled", "false")
    .config("spark.sql.shuffle.partitions", "2")
    .config("spark.plugins", "org.apache.spark.CometPlugin")
    .config(
        "spark.shuffle.manager",
        "org.apache.spark.sql.comet.execution.shuffle.CometShuffleManager",
    )
    .config("spark.comet.enabled", "true")
    .config("spark.comet.exec.enabled", "true")
    .config("spark.comet.shuffle.enabled", "true")
    .config("spark.comet.nativeLoadRequired", "true")
    .config("spark.comet.exec.aggregate.enabled", "true")
    .config("spark.memory.offHeap.enabled", "true")
    .config("spark.memory.offHeap.size", "128m")
    .getOrCreate()
)

try:
    path = "/tmp/comet-any-value-input"
    spark.range(256, numPartitions=4).selectExpr(
        "CAST(id AS STRING) AS user_id",
        "transform(sequence(0, 199), x -> concat(lpad(CAST(id AS STRING), 8, '0'), ':', lpad(CAST(x AS STRING), 4, '0'))) AS values",
    ).write.mode("overwrite").parquet(path)
    spark.read.parquet(path).createOrReplaceTempView("input")
    result = spark.sql(
        "SELECT user_id, ANY_VALUE(values) AS values FROM input GROUP BY user_id"
    )
    result.explain()
    rows = result.collect()
    expected = {str(i): [f"{i:08d}:{j:04d}" for j in range(200)] for i in range(256)}
    assert len(rows) == 256
    assert {row.user_id: row["values"] for row in rows} == expected
finally:
    spark.stop()
"$SPARK_HOME/bin/spark-submit" --master 'local[1]' --driver-memory 1g \
  inline_repro.py

The script sets a 128 MiB native pool and two shuffle partitions. It fails in
OrderedFinalAggregateStream, requesting 80,775,440 bytes against a
67,108,864-byte share. The strings contain just 650 KiB of data.

The same script succeeds with Comet 1.1.0, or with
spark.comet.exec.aggregate.enabled set to false on 1.2.0. It checks every
output array.

Fix verification

Focused native tests use DataFusion 55.2.0 and Arrow 59.3.0. For the same
selected array, update_batch reports 3,832 bytes while merge_batch reports
1,311,296 bytes. Adding the upstream fix makes both report 3,832 bytes:

 self.first = ScalarValue::try_from_array(first, 0)?;
+self.first.compact();
 self.is_set = true;

Both native regression tests fail before this change and pass afterward,
with unchanged output values. A rebuilt Comet JAR has not yet been tested.

Activity

  1. changed the title [-]Backport the FIRST_VALUE merge compaction fix for array-valued ANY_VALUE[/-] [+]ANY_VALUE memory regression in Comet 1.2.0[/+] on Nov 6, 2026
  2. added
    bugSomething isn't working
    priority:mediumFunctional bugs, performance regressions, broken features
    area:aggregationHash aggregates, aggregate expressions
    and removed on Nov 9, 2026
  3. kazuyukitanimura commented on Nov 9, 2026

    @kazuyukitanimura
    Contributor

    This will be closed by #7249

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:aggregationHash aggregates, aggregate expressionsbugSomething isn't workingpriority:mediumFunctional bugs, performance regressions, broken features

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions