[ 
https://issues.apache.org/jira/browse/SPARK-60324?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

ASF GitHub Bot updated SPARK-60324:
-----------------------------------
    Labels: pull-request-available  (was: )

> Partitioned write fails with FileAlreadyExistsException when a FLOAT or 
> DOUBLE partition column holds 0.0 and -0.0
> ------------------------------------------------------------------------------------------------------------------
>
>                 Key: SPARK-60324
>                 URL: https://issues.apache.org/jira/browse/SPARK-60324
>             Project: Spark
>          Issue Type: Bug
>          Components: SQL
>    Affects Versions: 3.5.3, 4.2.0, 4.0.3
>            Reporter: sepuri sai krishna
>            Priority: Major
>              Labels: pull-request-available
>
> A partitioned write fails when a FLOAT or DOUBLE partition column holds both 
> 0.0 and -0.0 in the same task, and nothing is written. With the default 
> configuration:
> {code:sql}
> CREATE TABLE t (id INT, d DOUBLE) USING parquet PARTITIONED BY (d);
> INSERT INTO t SELECT /*+ COALESCE(1) */ * FROM VALUES
>   (1, 0.0D), (2, -0.0D), (3, 0.0D), (4, 1.5D) AS v(id, d);
> -- [TASK_WRITE_FAILED] Task failed while writing rows to file:/.../t.
> -- Caused by: org.apache.hadoop.fs.FileAlreadyExistsException: File already 
> exists:
> --   
> file:/.../t/_temporary/0/_temporary/attempt_.../d=0.0/part-00000-<uuid>.c000.snappy.parquet
> SELECT count(*) FROM t;   -- 0
> {code}
> Same on 3.5.3, 4.0.3 and 4.2.0 (official binaries) and on master, for 
> Parquet, ORC, CSV and JSON, {{INSERT INTO}}, {{INSERT OVERWRITE}}, CTAS and 
> {{df.write.partitionBy}}, FLOAT and DOUBLE, with other partition columns 
> before it, and Hive tables. NaNs with different bits, e.g. {{NaN}} and 
> {{-NaN}}, fail the same way, on {{d=NaN}}.
> Cause: the write sorts the rows of a task by the dynamic partition columns, 
> where -0.0 = 0.0 and all NaNs are equal, so the sort can leave them 
> interleaved: 0.0, -0.0, 0.0. {{DynamicPartitionDataSingleWriter}} starts a 
> new partition directory whenever the bytes of the partition values change, so 
> it writes d=0.0, then d=-0.0, then d=0.0 again, and the second file of d=0.0 
> has the same name as the first ({{c000}}), which exists. With concurrent 
> writers ({{spark.sql.maxConcurrentOutputFileWriters}}) the writers are keyed 
> by those bytes, so NaNs with different bits open the same {{d=NaN}} file, and 
> when the writers fall back to sorting, the zeros fail as above.
> When the zeros are in different tasks the write succeeds, but creates both 
> d=0.0 and d=-0.0, so where a row ends up depends on how the rows are split 
> into tasks. The file stream sink names every file with a random UUID, so it 
> does not fail, but it writes both d=0.0 and d=-0.0 even within one task.
> Spark already normalizes -0.0 to 0.0 and NaNs to one NaN for grouping, join 
> and window partition keys (SPARK-26021, NormalizeFloatingNumbers), and for 
> array set operations (SPARK-54918). Dynamic partition values are grouping 
> keys as well. SPARK-26012 fixed the same failure for null and empty strings, 
> which both go to the default partition, by converting empty strings to null 
> before the write.
> Workaround for the zeros: write {{d + 0.0D}} instead of {{d}}, which turns 
> -0.0 into 0.0.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to