Skip to content

Comet writer doesn't respect OVERWRITE mode #2970

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.

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