Skip to content

Comet writer doesn't respect OVERWRITE mode #2970

Closed

Description

@comphead

Describe the bug

Comet fails if the folder exists and cannot overwrite it

Steps to reproduce

Folder output2 exists

spark.read.parquet("/tmp/writertest/input").repartition(1).write.mode("overwrite").parquet("/tmp/writertest/output2")

25/12/23 08:31:40 ERROR CometExecIterator: Native execution for task 17 failed
org.apache.comet.CometNativeException: Failed to create output file '/tmp/writertest/output2/part-00000-00017.parquet': Is a directory (os error 21)

Expected behavior

Should overwrite the folder with new content

Additional context

No response

Activity

  1. coderfender commented on Dec 24, 2025

    @coderfender
    Contributor

    Taking a look at this

  2. comphead commented on Dec 29, 2025

    @comphead
    ContributorAuthor

    some more details on implementation

    The flow is like

        ↓
    DataFrameWriter.saveInternal() 
        ↓
    InsertIntoHadoopFsRelationCommand.run()
        ↓
    [Line 131] deleteMatchingPartitions(fs, qualifiedOutputPath, customPartitionLocations, committer)
        ↓
    [Line 238] committer.deleteWithJob(fs, staticPrefixPath, true)
        ↓
    [Line 183] fs.delete(path, recursive=true)  ← ACTUAL DELETION HAPPENS HERE
    

    This Spark implementation now

        val doInsertion = if (mode == SaveMode.Append) {
          true
        } else {
          val pathExists = fs.exists(qualifiedOutputPath)
          (mode, pathExists) match {
            case (SaveMode.ErrorIfExists, true) =>
              throw QueryCompilationErrors.outputPathAlreadyExistsError(qualifiedOutputPath)
            case (SaveMode.Overwrite, true) =>
              if (ifPartitionNotExists && matchingPartitions.nonEmpty) {
                false
              } else if (dynamicPartitionOverwrite) {
                // For dynamic partition overwrite, do not delete partition directories ahead.
                true
              } else {
                deleteMatchingPartitions(fs, qualifiedOutputPath, customPartitionLocations, committer)
                true
              }
            case (SaveMode.Overwrite, _) | (SaveMode.ErrorIfExists, false) =>
              true
            case (SaveMode.Ignore, exists) =>
              !exists
            case (s, exists) =>
              throw QueryExecutionErrors.saveModeUnsupportedError(s, exists)
          }
        }
    

    The keypoint here, we need to support dynamicPartitionOverwrite or fallback to Spark in this case

  3. coderfender commented on Feb 6, 2026

    @coderfender
    Contributor

    take

  4. added
    priority:mediumFunctional bugs, performance regressions, broken features
    on Mar 27, 2026
  5. dwsmith1983 commented on Oct 4, 2026

    @dwsmith1983
    Contributor

    Overwrite mode works on main now: #4946 added SaveMode.Overwrite handling to the native writer (CometNativeWriteExec.scala, test "SaveMode.Overwrite replaces existing parquet data" in CometParquetWriterSuite), and on Spark 4.0+ #5763 leaves SaveMode to Spark. I think this can be closed.

  6. andygrove commented on Oct 16, 2026

    @andygrove
    Member

    Overwrite mode works on main, as @dwsmith1983 found. I checked it at c230bf4: a native Parquet write with mode("overwrite") into a directory that already held an earlier write replaced it, on Spark 3.5.9 (CometNativeWriteExec) and on Spark 4.1.3 (CometWriteFilesExec). The second write succeeded, and the directory read back only its 5 rows.

    #4946 added the SaveMode.Overwrite handling on Spark 3.x, which SaveMode.Overwrite replaces existing parquet data in CometParquetWriterSuite covers, and on Spark 4.0+ #5763 leaves the save mode to Spark. Closing.

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

Metadata

Metadata

Assignees

Labels

area:writerNative Parquet writerbugSomething 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