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

Max Gekk reassigned SPARK-48275:
--------------------------------

    Assignee: Mao Li

> array_sort: Improve documentation for default comparator's behavior for 
> different types
> ---------------------------------------------------------------------------------------
>
>                 Key: SPARK-48275
>                 URL: https://issues.apache.org/jira/browse/SPARK-48275
>             Project: Spark
>          Issue Type: Documentation
>          Components: SQL
>    Affects Versions: 3.5.0
>         Environment: Running in Databricks on [Databricks Runtime 
> 15.1|https://docs.databricks.com/en/release-notes/runtime/15.1.html].
>            Reporter: Matt Braymer-Hayes
>            Assignee: Mao Li
>            Priority: Trivial
>              Labels: pull-request-available
>
> h1. tl;dr
> It would be helpful for the documentation for array_sort() to include the 
> default comparator behavior for different array element types, especially 
> structs. It would also be helpful for the 
> {{{\{DATATYPE_MISMATCH.INVALID_ORDERING_TYPE }}}} error to recommend using a 
> custom comparator instead of the default comparator, especially when sorting 
> on a complex type (e.g., a struct containing an unorderable field, like a 
> map).
>  
> ----
> h1. Background
> The default comparator for {{array_sort()}} for struct elements is to sort by 
> every field in the struct in schema order (i.e., ORDER BY field1, field2, 
> ..., fieldN). This requires every field to be orderable: if they aren't an 
> error occurs.
>  
> Here's a small example:
> {code:java}
> import pyspark.sql.functions as F
> import pyspark.sql.types as T
> schema = T.StructType([
>     T.StructField(
>         'value',
>         T.ArrayType(
>             T.StructType([
>                 T.StructField('orderable', T.IntegerType(), True),
>                 T.StructField('unorderable', T.MapType(T.StringType(), 
> T.StringType(), True), True), # remove this field and both commands below 
> succeed
>             ]),
>             False
>         ),
>         False
>     )
> ])
> df = spark.createDataFrame([], schema=schema)
> df.select(F.array_sort(df['value'])).collect(){code}
> Output:
> {code:java}
> [DATATYPE_MISMATCH.INVALID_ORDERING_TYPE] Cannot resolve 
> "(namedlambdavariable() < namedlambdavariable())" due to data type mismatch: 
> The `<` does not support ordering on type "STRUCT<orderable: INT, 
> unorderable: MAP<STRING, STRING>>". SQLSTATE: 42K09 {code}
>  
> If the default comparator doesn't work for a user (e.g., they have an 
> unorderable field like a map in their struct), array_sort() accepts a custom 
> comparator, where users can order array elements however they like.
>  
> Building on the previous example:
>  
> {code:java}
> import pyspark.sql as psql
> def comparator(l: psql.Column, r: psql.Column) -> psql.Column:
>     """Order structs l and r by order field.
>     Rules:
>         * Nulls are last
>         * In ascending order
>     """
>     return (
>         F.when(l['order'].isNull() & r['order'].isNull(), 0)
>         .when(l['order'].isNull(), 1)
>         .when(r['order'].isNull(), -1)
>         .when(l['order'] < r['order'], -1)
>         .when(l['order'] == r['order'], 0)
>         .otherwise(1)
>     )
> df.select(F.array_sort(df['value'], comparator)).collect(){code}
> This works as intended.
>  
> ----
> h1. Ask
> The documentation for {{array_sort()}} should include information on the 
> behavior of the default comparator for various datatypes. For the 
> array-of-unorderable-structs example, it would be helpful to know that the 
> default comparator for structs compares all fields in schema order (i.e., 
> {{{}ORDER BY field1, field2, ..., fieldN{}}}).
>  
> Additionally, when users passes an unorderable type to array_sort() and uses 
> the default comparator, the returned error should recommend the user use a 
> custom comparator instead.



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