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

   Part of #6615.
   
   ## What / Why
   
   This issue moves map and struct expression coverage to Comet SQL tests under 
`sql-tests/expressions/map/` and `sql-tests/expressions/struct/`. The sources 
are `CometMapExpressionSuite` and the struct tests in `CometExpressionSuite` 
(`named_struct`, `get_struct_field`, `to_json`). Static analysis on `main` at 
3bc2faa934 found the following:
   
   | Suite | Covered | Convert | Blocked | Split | Keep | Total |
   |---|---|---|---|---|---|---|
   | `CometMapExpressionSuite` | 0 | 14 | 15 | 0 | 0 | 29 |
   | `CometExpressionSuite` | 1 | 10 | 2 | 2 | 1 | 16 |
   | **Total** | **1** | **24** | **17** | **2** | **1** | **45** |
   
   Most of the blocked tests are folded-literal tests. The suite's section 
header (L366-L373) says they need ConstantFolding on, so that the map or array 
literal reaches `CometLiteral`'s folded-literal expansion and the key-type 
guards on the lookup. The SQL suite always excludes ConstantFolding, so these 
wait on #6618. As in the array issue, most map fixtures insert 3-6 rows with 
`INSERT ... VALUES` (one file per row), so conversions that care about batches 
need one-file inserts.
   
   ## Work
   
   Line numbers refer to `CometMapExpressionSuite` unless marked.
   
   **Maps: existing fixtures to extend**
   
   - `map_keys.sql`, `map_values.sql` (L36)
     - Add `map<bigint,bigint>` with NULL maps and NULL values.
     - Change the `spark_answer_only` queries to `query` if the plan is native, 
which looks likely.
   - `map_from_arrays.sql` (L106): add `array(s)` / `array(i)` columns, and 
change the `spark_answer_only` queries to `query`.
   - `array/size.sql` (L219, L232): the map shapes.
   - `map_from_entries.sql` (L340): an `array<binary>` key/value with 
`expect_dispatch(map_from_entries)`.
   
   **Maps: new fixtures**
   
   - `map_struct_keys.sql` (L67): struct-keyed maps with NULLs, including 
`map_keys(map1).id2` (#1754).
   - `map_from_arrays_ansi.sql` (L130): ANSI on, a codegen matrix, one-file 
inserts, and `expect_native(map_from_arrays)`.
   - `map_from_arrays_scalar_operands.sql` (L189): a codegen matrix and 
`expect_native(map_from_arrays)`.
   - `map_from_entries_types.sql` (L264, L299)
     - `-- ConfigMatrix: spark.comet.scan.enabled=true,false` plus the convert 
config.
     - 13 typed columns.
   - `map_sort.sql` (L328, L618, `MinSparkVersion: 4.0`): GROUP BY a map, and 
GROUP BY a sliced map.
   - `map_lookup_sliced.sql` (L593): lookups below `LIMIT 15 OFFSET 5`, with an 
ANSI matrix.
   - `element_at_map_column_key.sql` (L608): a per-row column key, with an ANSI 
matrix.
   
   **Structs** (all lines in `CometExpressionSuite`)
   
   - `struct/get_struct_field.sql`
     - Covers L3098, L3115, L3142, and the V1 halves of L3181, L3204 and L3236.
     - Use one nested table, `nested1 struct<id, nested2 struct<id>>`, holding 
a NULL struct, a NULL inner field and a NULL inner struct.
     - Project `nested1.id`, `nested1.nested2`, `nested1.nested2.id`, both 
fields together, and `nested1`.
   - `struct/get_struct_field_spark_scan.sql` (new, L3069): 
`spark.comet.scan.enabled=false` and `spark.comet.convert.parquet.enabled=true` 
over the same nested table.
   - `struct/create_named_struct.sql`
     - L2939: nested `named_struct`, and boolean and tinyint fields.
     - L2954: `expect_fallback(with duplicate field names is not supported)`.
   - `struct/structs_to_json.sql`
     - L2974: non-exact float and double values.
     - L2999: CR, LF, form feed, backspace and single-quote characters in 
values, and double quotes in field names.
     - L3028: supplementary-plane characters, e.g. U+1F911.
   
   **Blocked**
   
   - **#6618, keep ConstantFolding:**
     - L383 and L437 into `map_entries.sql`.
     - L397, L490, L515, L530 and L545 into `element_at_map.sql`.
     - L409, L475 and L501 into `element_at_map_collation.sql`.
     - L424 into `create_map.sql`.
     - L456 into `map_contains_key.sql`.
     - L560 into `conditional/if_nested_nullability.sql`.
   - **#6618, exclude `ConvertToLocalRelation`:** L352, the non-null-value 
LocalTableScan source from #4789.
   - **#6617:** L158, `map_from_arrays` with unequal lengths. It pins native 
execution plus error-class, exception-class and SQLSTATE parity.
   - **DSv2 halves:** the V2 rows of `CometExpressionSuite` L3069, L3181, L3204 
and L3236.
     - SQL fixtures over catalog tables always read through the V1 file source.
     - The analysis found the V2 halves of L36, L67 and L232 compare Spark with 
Spark anyway, because Comet has no native DSv2 Parquet scan and 
`convert.parquet` is off.
     - The two ignored V2 tests have no issue link. Consider dropping these 
halves rather than keeping them.
   
   ## Stays in Scala
   
   - **`CometExpressionSuite` L339.** It needs a nullable struct whose inner 
field is declared non-nullable, built with `createDataFrame` and an explicit 
schema, then pushed through a Comet shuffle. A Parquet table always reads back 
nullable fields.
   
   ## Fixture problems to fix along the way
   
   - **Lookups that don't use -0.0.** `element_at_map.sql:62-70` and 
`get_map_value.sql:48` write `CAST(-0.0 AS DOUBLE)`, which is `+0.0`, so they 
never look up a negative zero. They still pass because the fallback is decided 
by key type. Use `double('-0.0')`.
   - **Duplicates of fixture queries.** L437, L530 and L560 are the same 
queries as `map_entries.sql:50-54`, `element_at_map.sql:150-152` and 
`if_nested_nullability.sql:77-81`, minus constant folding.
   - **Dead branch.** In L219 the `map(_8, _9)` branch never runs, because `_2 
= i % 4` is never negative.
   
   ## Done when
   
   - Every test in the table below is accounted for. Either a fixture covers it 
(the same inputs, configs and assertion strength, or stronger), the fixture 
that already covers it is cited, or it stays in Scala for the reason given 
above.
   - Each converted Scala test is deleted in the PR that adds its coverage. A 
suite left empty is deleted and removed from the suite lists in 
`.github/workflows/pr_build_linux.yml` and `pr_build_macos.yml`.
   - The new and changed fixtures pass on every Spark profile. Apply 
`run-all-spark-profiles`, because pull requests run only the default profile.
   
   <details><summary>Every Scala test in scope, with its verdict and target 
fixture</summary>
   
   | Suite | Line | Test | Verdict | Target |
   |---|---|---|---|---|
   | `CometExpressionSuite` | 339 | GetStructField: non-nullable field of a 
nullable struct (Delta action-frame shape) | keep |  |
   | `CometExpressionSuite` | 2939 | named_struct | convert | 
struct/create_named_struct.sql |
   | `CometExpressionSuite` | 2954 | named_struct with duplicate field names | 
convert | struct/create_named_struct.sql |
   | `CometExpressionSuite` | 2974 | to_json | convert | 
struct/structs_to_json.sql |
   | `CometExpressionSuite` | 2999 | to_json escaping of field names and string 
values | convert | struct/structs_to_json.sql |
   | `CometExpressionSuite` | 3028 | to_json unicode | convert | 
struct/structs_to_json.sql |
   | `CometExpressionSuite` | 3053 | struct and named_struct with dictionary | 
covered | struct/create_named_struct.sql |
   | `CometExpressionSuite` | 3069 | get_struct_field | split (rest: other) | 
struct/get_struct_field_spark_scan.sql (new) |
   | `CometExpressionSuite` | 3098 | get_struct_field - select primitive fields 
| convert | struct/get_struct_field.sql |
   | `CometExpressionSuite` | 3115 | get_struct_field - select subset of struct 
| convert | struct/get_struct_field.sql |
   | `CometExpressionSuite` | 3142 | get_struct_field - read entire struct | 
convert | struct/get_struct_field.sql |
   | `CometExpressionSuite` | 3181 | get_struct_field with DataFusion 
ParquetExec - simple case - V1 (testV1AndV2; test( at line 3167) | convert | 
struct/get_struct_field.sql |
   | `CometExpressionSuite` | 3181 | get_struct_field with DataFusion 
ParquetExec - simple case - V2 (ignored; ignore( at line 3176) | blocked: other 
| struct/get_struct_field.sql |
   | `CometExpressionSuite` | 3204 | get_struct_field with DataFusion 
ParquetExec - select subset of struct - V1 (testV1AndV2; test( at line 3167) | 
convert | struct/get_struct_field.sql |
   | `CometExpressionSuite` | 3204 | get_struct_field with DataFusion 
ParquetExec - select subset of struct - V2 (ignored; ignore( at line 3176) | 
blocked: other | struct/get_struct_field.sql |
   | `CometExpressionSuite` | 3236 | get_struct_field with DataFusion 
ParquetExec - read entire struct | split (rest: other) | 
struct/get_struct_field.sql |
   | `CometMapExpressionSuite` | 36 | read map[int, int] from parquet | convert 
| map/map_keys.sql; map/map_values.sql |
   | `CometMapExpressionSuite` | 67 | read map[struct, struct] from parquet | 
convert | map/map_struct_keys.sql (new) |
   | `CometMapExpressionSuite` | 106 | map_from_arrays | convert | 
map/map_from_arrays.sql |
   | `CometMapExpressionSuite` | 130 | map_from_arrays short-circuits null keys 
(codegen=$codegenEnabled) [instances: false, true] | convert | 
map/map_from_arrays_ansi.sql (new) |
   | `CometMapExpressionSuite` | 158 | map_from_arrays rejects unequal batched 
row lengths (codegen=$codegenEnabled) [instances: false, true] | blocked: #6617 
| map/map_from_arrays_unequal_lengths.sql (new) |
   | `CometMapExpressionSuite` | 189 | map_from_arrays broadcasts scalar 
operands (codegen=$codegenEnabled) [instances: false, true] | convert | 
map/map_from_arrays_scalar_operands.sql (new) |
   | `CometMapExpressionSuite` | 219 | size with map input | convert | 
array/size.sql |
   | `CometMapExpressionSuite` | 232 | size with map input - v2 reader | 
convert | array/size.sql |
   | `CometMapExpressionSuite` | 264 | map_from_entries - convert from Parquet 
| convert | map/map_from_entries_types.sql (new) |
   | `CometMapExpressionSuite` | 299 | map_from_entries - native Parquet reader 
| convert | map/map_from_entries_types.sql (new) |
   | `CometMapExpressionSuite` | 328 | group by map column with string values | 
convert | map/map_sort.sql (new) |
   | `CometMapExpressionSuite` | 340 | map_from_entries - binary type routes 
through codegen dispatcher | convert | map/map_from_entries.sql |
   | `CometMapExpressionSuite` | 352 | map_entries on non-null value map from 
local table scan (#4789) | blocked: #6618 | map/map_entries.sql |
   | `CometMapExpressionSuite` | 383 | map_entries on a folded 
non-nullable-value map (multirow) | blocked: #6618 | map/map_entries.sql |
   | `CometMapExpressionSuite` | 397 | nested map lookup with floating-point 
keys falls back | blocked: #6618 | map/element_at_map.sql |
   | `CometMapExpressionSuite` | 409 | nested map lookup with collated string 
keys falls back | blocked: #6618 | map/element_at_map_collation.sql |
   | `CometMapExpressionSuite` | 424 | folded map literal with 
calendar-interval keys falls back (multirow) | blocked: #6618 | 
map/create_map.sql |
   | `CometMapExpressionSuite` | 437 | map_entries widening keeps nested map 
value nullability (multirow) | blocked: #6618 | map/map_entries.sql |
   | `CometMapExpressionSuite` | 456 | map_contains_key over nested 
floating-point map keys falls back (multirow) | blocked: #6618 | 
map/map_contains_key.sql |
   | `CometMapExpressionSuite` | 475 | map_contains_key over nested collated 
map keys falls back (multirow) | blocked: #6618 | 
map/element_at_map_collation.sql |
   | `CometMapExpressionSuite` | 490 | folded map literal with floating-point 
keys in element_at falls back (multirow) | blocked: #6618 | 
map/element_at_map.sql |
   | `CometMapExpressionSuite` | 501 | folded map literal with collated string 
keys in element_at falls back (multirow) | blocked: #6618 | 
map/element_at_map_collation.sql |
   | `CometMapExpressionSuite` | 515 | folded map literal with complex array 
key in element_at falls back (multirow) | blocked: #6618 | 
map/element_at_map.sql |
   | `CometMapExpressionSuite` | 530 | folded nested map lookup with per-row 
key evaluation (multirow, non-ansi) | blocked: #6618 | map/element_at_map.sql |
   | `CometMapExpressionSuite` | 545 | large folded map literal in element_at 
runs natively (multirow) | blocked: #6618 | map/element_at_map.sql |
   | `CometMapExpressionSuite` | 560 | IF with a folded map literal branch and 
a map column (multirow) | blocked: #6618 | 
conditional/if_nested_nullability.sql |
   | `CometMapExpressionSuite` | 593 | map lookup on a sliced map reads the 
visible entries | convert | map/map_lookup_sliced.sql (new) |
   | `CometMapExpressionSuite` | 608 | element_at on a map column with a 
per-row lookup key | convert | map/element_at_map_column_key.sql (new) |
   | `CometMapExpressionSuite` | 618 | mapsort on a sliced map does not overrun 
the sorted entries | convert | map/map_sort.sql (new) |
   
   </details>
   


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