Skip to content

CometNativeException: "arrays of different length" when using to_date on Iceberg Timestamp column #3255

Closed

Description

@boudica-dev-eng

Describe the bug

I am encountering a CometNativeException when performing standard date transformations (to_date or datediff) on a Timestamp column read from an Iceberg table.

The error message Cannot perform binary operation on arrays of different length occurs even though the table schema contains no ArrayType columns (only Scalars).

The issue appears to be related to how Comet handles the vectorisation of the Timestamp column, possibly involving dictionary encoding in the underlying Parquet files.

org.apache.spark.SparkException: Job aborted due to stage failure: Task 0 in stage X failed 4 times...
Caused by: org.apache.comet.CometNativeException: Compute error: Cannot perform binary operation on arrays of different length
    at org.apache.comet.Native.executePlan(Native Method)
    ...

When Comet is disabled, Spark executes the job flawlessly.

Steps to reproduce

  1. Read an Iceberg table containing a TIMESTAMPTZ column.
  2. Apply F.to_date() to the timestamp column.
  3. Trigger an action (e.g., .count() or a write).
# Schema is simple: id (String), ts (Timestamp) - No Arrays present
df = spark.read.format("iceberg").load("db.table")

# This crashes Comet:
df.withColumn("date_col", F.to_date(F.col("ts"))).count()

# This ALSO crashes Comet:
df.withColumn("diff", F.datediff(F.current_date(), F.col("ts"))).count()

Expected behavior

Column is added as date

Additional context

  • Comet version: built from ea26629
  • Spark version: 4.0.1_2.13 (Spark Connect, Kubernetes, no Python/PySpark)

Activity

  1. vigneshsiva11 commented on Jan 26, 2026

    @vigneshsiva11

    Hi @boudica-dev-eng,

    Thanks for the detailed report.

    To help narrow this down: do you know whether the ts column is dictionary-encoded in the underlying Parquet files (e.g., parquet.enable.dictionary=true)?

    Also, does the error disappear if dictionary encoding is disabled when writing the Iceberg table?

  2. boudica-dev-eng commented on Jan 26, 2026

    @boudica-dev-eng
    Author

    I've not explicitly enabled dictionary encoding via that config flag anywhere in the global or table configs.

  3. vigneshsiva11 commented on Jan 26, 2026

    @vigneshsiva11

    Thanks for confirming @boudica-dev-eng
    For reference, this behavior is addressed in PR #3278, which ensures datediff (and similar date functions) handle dictionary-backed inputs safely by aligning array lengths before evaluation.

    Please let me know if you’d prefer this logic to live in a shared utility or be handled at a different layer.

  4. added
    priority:highCrashes, panics, segfaults, major functional breakage
    on Mar 27, 2026
  5. self-assigned this
    on Apr 2, 2026
  6. mbutrovich commented on Jun 10, 2026

    @mbutrovich
    Contributor

    I wasn't able to reproduce this with the current Iceberg code path. I suspect this performed the scan in Iceberg Java, and then somehow they made their way over to Comet without unpacking the dictionaries. I wrote a reproducer and couldn't get it to fail. Please reopen if you re-encounter the issue. Thanks for the report!

      // https://github.com/apache/datafusion-comet/issues/3255
      // Reported as CometNativeException "Cannot perform binary operation on arrays of
      // different length" when applying to_date / datediff to a timestamp column read from
      // an Iceberg table. The suspected trigger is dictionary-encoded timestamp values, so
      // we insert many rows with few distinct timestamps to encourage dictionary encoding.
      test("to_date and datediff on Iceberg timestamp column - reproduces #3255") {
        assume(icebergAvailable, "Iceberg not available in classpath")
    
        withTempIcebergDir { warehouseDir =>
          withSQLConf(
            "spark.sql.catalog.test_cat" -> "org.apache.iceberg.spark.SparkCatalog",
            "spark.sql.catalog.test_cat.type" -> "hadoop",
            "spark.sql.catalog.test_cat.warehouse" -> warehouseDir.getAbsolutePath,
            CometConf.COMET_ENABLED.key -> "true",
            CometConf.COMET_EXEC_ENABLED.key -> "true",
            CometConf.COMET_ICEBERG_NATIVE_ENABLED.key -> "true") {
    
            // Spark TIMESTAMP maps to Iceberg timestamptz (TIMESTAMPTZ), matching the report.
            spark.sql("""
              CREATE TABLE test_cat.db.ts_date_test (
                id STRING,
                ts TIMESTAMP
              ) USING iceberg
            """)
    
            // 1000 rows over only 5 distinct timestamps -> highly compressible / dictionary-friendly.
            spark.sql("""
              INSERT INTO test_cat.db.ts_date_test
              SELECT
                CAST(id AS STRING) as id,
                CAST(CONCAT('2024-01-0', CAST(id % 5 + 1 AS STRING), ' 12:00:00') AS TIMESTAMP) as ts
              FROM range(1000)
            """)
    
            // Scalar (current_date / literal) vs dictionary-backed column: the reported crash.
            checkIcebergNativeScan("SELECT id, to_date(ts) FROM test_cat.db.ts_date_test ORDER BY id")
            checkIcebergNativeScan(
              "SELECT id, datediff(DATE '2025-01-01', ts) FROM test_cat.db.ts_date_test ORDER BY id")
            checkIcebergNativeScan(
              "SELECT COUNT(*) FROM test_cat.db.ts_date_test WHERE datediff(DATE '2025-01-01', ts) > 0")
    
            spark.sql("DROP TABLE test_cat.db.ts_date_test")
          }
        }
      }
  7. added a commit that references this issue on Oct 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingcrashNative engine crash/panic/segfaultpriority:highCrashes, panics, segfaults, major functional breakage

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions