Skip to content

Native Parquet write of a zero-partition RDD produces no output file #5303

Description

@andygrove

Found while reviewing #5293 against the Iceberg split-writer work in #4658.

Describe the bug

Spark's WriteFilesExec.doExecuteWrite guards against a child RDD with zero partitions (SPARK-23271):

val rddWithNonEmptyPartitions = if (rdd.partitions.length == 0) {
  session.sparkContext.parallelize(Array.empty[InternalRow], 1)
} else {
  rdd
}

Without it no write task runs at all, so the output directory ends up with no data file — not even the schema-only file Spark produces. IcebergWriteExec added in #4658 carries the same guard.

CometWriteFilesExec.doExecuteWrite has no equivalent: it calls child.executeColumnar() and goes straight to mapPartitionsInternal. With zero partitions, FileFormatWriter.writeAndCommit collects zero WriteTaskResults and commits an empty job. The result is a _SUCCESS marker over an empty directory, where Spark writes one file carrying the schema.

Note this is not a regression from #5293 — the CometNativeWriteExec it replaced had the same hole.

Steps to reproduce

Any write whose input plan yields a zero-partition RDD (for example a scan over an empty relation), with spark.comet.parquet.write.enabled=true.

Expected behavior

Match Spark: run one write task so the output carries the schema.

Harder here than in the Iceberg case because the dummy RDD must be columnar — parallelize(Array.empty[InternalRow], 1) is row-based, and CometWriteFilesExec feeds batches into an Arrow stream. Options are a single-partition empty ColumnarBatch RDD, or bypassing the native writer for this case and writing the schema-only file on the JVM.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions