viirya opened a new issue, #5566:
URL: https://github.com/apache/datafusion-comet/issues/5566

   ## Is your feature request related to a problem or challenge?
   
   `CometShuffleExchangeExec.supportedHashPartitioningDataType` rejects nested 
types
   as hash partitioning keys, so a query that repartitions on a struct, array 
or map
   column falls back to Spark for the entire shuffle:
   
   ```scala
   def supportedHashPartitioningDataType(dt: DataType): Boolean = dt match {
     case st: StringType if isStringCollationType(st) => false
     case _: BooleanType | ... | _: DateType => true
     case _: DecimalType => true
     case dt if isTimeType(dt) => true
     case _ => false     // struct / array / map land here
   }
   ```
   
   The comment above it explains the restriction as:
   
   > Native code does not support hashing complex types, see hash_funcs/utils.rs
   
   That is no longer accurate. `native/spark-expr/src/hash_funcs/utils.rs` 
hashes
   nested types recursively -- struct fields, `List`/`LargeList`/`FixedSizeList`
   elements, and map keys and values -- and shuffle partitioning calls the same
   `create_murmur3_hashes` entry point, with the same seed, that the `hash`
   expression uses. Nested hashing is exercised today through `hash()` / 
`xxhash64()`,
   whose gate (`HashUtils.unsupportedReasonFor` in `serde/hash.scala`) recurses
   through struct/array/map, with coverage in `CometHashExpressionSuite`.
   
   So a shuffle on a nested key falls back even though the machinery to run it
   natively is present and in use elsewhere.
   
   ## Describe the solution you'd like
   
   Allow struct/array/map as hash partitioning keys for native shuffle, checked
   recursively so that a leaf type which cannot be hashed natively disqualifies 
the
   whole key and the shuffle still falls back to Spark. Two such leaves exist 
today:
   
   - **collated strings** -- Comet hashes raw bytes. This is a correctness 
matter,
     not just a difference: in #1947 / #4035, rows equal under the collation 
reached
     different partitions and a downstream collation-aware `DISTINCT` in Spark 
then
     produced `aabb` instead of `ab`.
   - **CalendarInterval** -- allowed as a shuffle *data* column, but the native
     hasher has no `Interval` branch and fails with "Unsupported data type in
     hasher" (#5059).
   
   Map keys need one extra restriction. Map entry order is not semantically
   meaningful, so two equal maps must hash alike. Spark 4.0+ normalizes a map
   shuffle key by wrapping it in `mapsort(...)` (#1941); earlier versions 
insert no
   such normalization, so Comet would hash physical entry order and could route
   equal maps to different partitions. Map keys should therefore be admitted 
only on
   Spark 4.0+, and only when the `mapsort` is itself convertible -- 
`CometMapSort`
   supports scalar map keys only, and otherwise the existing 
partitioning-expression
   check already forces a fallback.
   
   Worth putting behind a config so the previous behavior remains available.
   
   ## Describe alternatives you've considered
   
   Leaving the gate as it is and only correcting the stale comment. That keeps a
   supported, tested native capability unreachable from shuffle for no technical
   reason.
   
   ## Additional context
   
   Notably, Spark rewrites a deeply nested partitioning key into a 
`transform(...)`
   containing a nested `mapsort(...)`, e.g. for
   `struct<a: array<struct<m: map<string, array<int>>, s: string>>, i: int>`:
   
   ```
   hashpartitioning(if (isnull(k)) null else named_struct(
     a, transform(k.a, lambdafunction(
          if (isnull(x)) null else named_struct(m, mapsort(x.m), s, x.s), x, 
false)),
     i, k.i), 10)
   ```
   
   so the normalization applies at any depth, not only to a top-level map key.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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

Reply via email to