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

Mihailo Aleksic updated SPARK-60038:
------------------------------------
    Summary: Merge nested nullability of all values in UNPIVOT value columns  
(was: Merge nested nullability of all values in UNPIVOT value columns- #59271)

> Merge nested nullability of all values in UNPIVOT value columns
> ---------------------------------------------------------------
>
>                 Key: SPARK-60038
>                 URL: https://issues.apache.org/jira/browse/SPARK-60038
>             Project: Spark
>          Issue Type: Improvement
>          Components: SQL
>    Affects Versions: 4.1.0
>            Reporter: Mihailo Aleksic
>            Priority: Major
>
> UNPIVOT (and {{Dataset.unpivot}} / {{melt}}) types each value column with the 
> data type of the first listed value. Only top-level nullability is merged 
> across the values; nested nullability (array {{containsNull}}, map 
> {{valueContainsNull}}, struct field
>   {{nullable}}) is taken from the first value. When the first value has NOT 
> NULL nested elements or fields and a later value has NULLs in them, the value 
> column claims those NULLs cannot exist: they are read as non-NULL values 
> (e.g. {{0}}), and {{IS NULL}} on them is
>   optimized to {{false}}. The result depends on the order of the values, and 
> INSERT / CTAS write the wrong values.
>   Repro:
>   {code:sql}
>   -- jan and feb are NOT NULL, mar and apr are nullable
>   CREATE TEMPORARY VIEW monthlySales AS SELECT * FROM VALUES
>     ('north', 10, 20, 30, CAST(NULL AS INT)),
>     ('south', 5, 6, NULL, NULL)
>     AS monthlySales(store, jan, feb, mar, apr);
>   SELECT store, half, b.lo, b.hi, b.hi IS NULL AS hi_is_null
>   FROM (
>     SELECT store, named_struct('lo', jan, 'hi', feb) AS h1, 
> named_struct('lo', mar, 'hi', apr) AS h2
>     FROM monthlySales
>   )
>   UNPIVOT (b FOR half IN (h1, h2))
>   ORDER BY store, half;
>   {code}
>   Actual ({{b}} is typed {{struct<lo: int NOT NULL, hi: int NOT NULL>}}, 
> taken from {{h1}}):
>   {noformat}
>   north  h1  10  20  false
>   north  h2  30  0   false
>   south  h1  5   6   false
>   south  h2  0   0   false
>   {noformat}
>   Expected:
>   {noformat}
>   north  h1  10    20    false
>   north  h2  30    NULL  true
>   south  h1  5     6     false
>   south  h2  NULL  NULL  true
>   {noformat}
>   Listing the nullable value first, {{IN (h2, h1)}}, returns the expected 
> result. Array values ({{array(jan, feb)}} vs {{array(mar, apr)}}), map 
> values, multi-value UNPIVOT and {{Dataset.unpivot}} are affected in the same 
> way.
>   Cause: {{Unpivot.valuesTypeCoercioned}} compares the value types with 
> {{DataTypeUtils.sameType}}, which ignores nullability. {{UnpivotCoercion}}, 
> which would widen the types and merge their nested nullability, therefore 
> does not run when the values differ only in
>   nested nullability, and {{UnpivotTransformer}} types the value column with 
> {{values.head(index).dataType}}. The single-pass resolver's 
> {{UnpivotResolver}} already applies {{UnpivotTypeCoercion}} unconditionally.
>   This affects all versions since UNPIVOT was added in 3.4.0 (SPARK-38864, 
> SPARK-39876).



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