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

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

> Preserve TIME precision in the PySpark Arrow/pandas type mapping
> ----------------------------------------------------------------
>
>                 Key: SPARK-57696
>                 URL: https://issues.apache.org/jira/browse/SPARK-57696
>             Project: Spark
>          Issue Type: Sub-task
>          Components: Pandas API on Spark
>    Affects Versions: 4.3.0
>            Reporter: Max Gekk
>            Priority: Major
>              Labels: pull-request-available
>
> h2. What
> Carry the {{TimeType(p)}} fractional-second precision {{p}} (in [0, 9]) 
> across the
> PySpark Arrow/pandas type mapping in {{python/pyspark/sql/pandas/types.py}} 
> so that a
> {{TIME(p)}} column round-trips back to the same {{TIME(p)}}, instead of 
> collapsing to the
> default {{TimeType()}} (precision 6).
> This is the PySpark counterpart of SPARK-57661, which fixes the same gap in 
> the JVM
> {{ArrowUtils}} (Spark <-> Arrow) mapping.
> h2. Why
> {{to_arrow_type}} maps {{TimeType}} to {{pa.time64("ns")}}, which carries 
> only a time unit
> and no fractional-second precision field. {{from_arrow_type}} maps any 
> {{is_time64(at)}}
> back to {{TimeType()}}, whose constructor defaults to {{precision = 6}}. As a 
> result the
> declared precision is lost on any Arrow/pandas round-trip ({{TIME(0)}}, 
> {{TIME(3)}},
> {{TIME(9)}}, ... all read back as {{TIME(6)}}), so PySpark Arrow-based 
> transfer
> (createDataFrame from Arrow/pandas, {{mapInArrow}}, {{toPandas}} schema, 
> etc.) silently
> widens or narrows the type label. The stored values are unaffected; this is 
> purely a
> type-fidelity gap.
> PyArrow's {{time64}} logical type only encodes the unit (us/ns) and cannot 
> represent
> precision [0, 9], so the precision must be carried in the Arrow field 
> metadata, mirroring
> the {{SPARK::time::precision}} key the JVM {{ArrowUtils}} uses in SPARK-57661.
> h2. Scope
> * {{python/pyspark/sql/pandas/types.py}}: when building the Arrow field for a 
> {{TimeType(p)}},
> tag it with the precision metadata key {{SPARK::time::precision}}; when 
> reading an Arrow
> {{time64}} field back, read that key to reconstruct {{TimeType(p)}}.
> * Reuse the same metadata key and fallback semantics as the JVM side 
> (SPARK-57661) for
> consistency.
> h2. Behavior on read-back
> * Metadata present and in [0, 9]: reconstruct the exact {{TimeType(p)}}.
> * Metadata absent (foreign Arrow data) or out of [0, 9]: fall back to the 
> default
> {{TimeType()}} (precision 6), preserving today's behavior for non-Spark 
> producers.
> h2. Out of scope
> * Value semantics / rounding: values are carried verbatim; no change to how 
> {{TIME(p)}}
> values are truncated.
> * The JVM {{ArrowUtils}} mapping (handled in SPARK-57661) and the Spark 
> Connect
> proto/converters (separate sub-tasks).
> h2. How tested
> PySpark Arrow conversion tests: round-trip {{TIME(p)}} for {{p}} in {0, 3, 6, 
> 9} preserves
> {{p}}; a {{time64}} field with no precision metadata falls back to 
> {{TIME(6)}}; the
> precision key does not leak into reconstructed field metadata.
> h2. Does this introduce any user-facing change
> No. The TIME data type is gated behind the internal flag 
> {{spark.sql.timeType.enabled}},
> which is off by default in production. With the flag enabled, a {{TIME(p)}} 
> column
> transferred over Arrow/pandas in PySpark retains its declared precision 
> instead of always
> reading back as {{TIME(6)}}. No change to stored values.



--
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