englefly opened a new pull request, #69340:
URL: https://github.com/apache/doris/pull/69340

   ### What problem does this PR solve?
   
   Issue Number: None
   
   Related PR: None
   
   Problem Summary:
   
   With nested column pruning enabled, `CARDINALITY(ARRAY_MAP(x -> x, a))` over 
an
   `ARRAY<STRUCT<...>>` column fails at execution with
   
   ```
   [E-3110][INTERNAL_ERROR]Invalid META access path for column 'item': OFFSET 
metadata is not supported at this level
   ```
   
   `EXPLAIN VERBOSE` shows the access path `a.*.OFFSET`: the OFFSET metadata 
that `cardinality()` needs has been
   pushed down to the struct element layer. Disabling the pruning makes the 
same query succeed.
   
   Root cause: `visitCardinality` creates a META/OFFSET context for the 
ARRAY_MAP result, and `visitArrayMap`
   forwarded that context unchanged into `collectArrayPathInLambda`. The lambda 
body reaches the input array
   through an array item, and `visitArrayItemSlot` adds the element-level `*`, 
so the OFFSET suffix ends up on
   the element (struct) layer. The BE only supports OFFSET metadata at 
array/map/string level.
   
   ARRAY_MAP keeps the container shape of its inputs: the result offsets come 
from the first input array and the
   result null map is the union of all inputs' null maps. A metadata 
requirement on the ARRAY_MAP result is
   therefore a requirement on the input arrays' containers, not on the elements.
   
   Fix: when ARRAY_MAP is collected with a META context, route the NULL/OFFSET 
requirement to the input array
   containers (`a.OFFSET`, `s.arr.OFFSET`, `m.VALUES.OFFSET`, `a.NULL`) and 
collect the lambda body with a fresh
   DATA context, so the element paths the lambda actually reads are still kept. 
Every input array gets the
   container metadata, because the result offsets come from the first input 
while the result null map is the
   union of all inputs' null maps (equal lengths do not imply equal nullness: 
`cardinality(array_map((x, y) ->
   x + y, [1, 2], NULL))` is NULL).
   
   Before: the plan shows `[a.*.OFFSET]` and the query fails with E-3110.
   After: the plan shows `[a.*, a.OFFSET]` and the query returns `2 / 0 / NULL 
/ 2` for a two-element array, an
   empty array, a NULL array and an array holding a NULL element.
   
   Nested variants are fixed the same way:
   
   | expression | before | after |
   | --- | --- | --- |
   | `cardinality(array_map(x -> x, a))` | `a.*.OFFSET` (fails) | `a.*, 
a.OFFSET` |
   | struct field `s.arr` | `s.arr.*.OFFSET` (fails) | `s.arr.*, s.arr.OFFSET` |
   | map value `m['k']` | `m.*.*.OFFSET` (fails) | `m.KEYS, m.VALUES.*, 
m.VALUES.OFFSET` |
   | `array_map(x -> x, a) IS NULL` | element-level `a.*.NULL` | `a.*, a.NULL` |
   | multi-array `array_map((x, y) -> ..., a, b)` | `a.*.OFFSET, b.*.OFFSET` 
(fails) | `a.*, a.OFFSET, b.*, b.OFFSET` |
   
   ### Release note
   
   Fix `[E-3110] Invalid META access path ... OFFSET metadata is not supported 
at this level` for
   `CARDINALITY(ARRAY_MAP(...))` when nested column pruning is enabled on 
array-of-struct columns.
   
   ### Check List (For Author)
   
   - Test
       - [x] Regression test: new suite 
`nereids_rules_p0/column_pruning/array_map_container_metadata_pruning`
         (with `notContains "a.*.OFFSET"` guards); the whole 
`nereids_rules_p0/column_pruning` directory
         (16 suites) passes.
       - [x] Unit Test: `PruneNestedColumnTest`, 5 new cases; 78/78 tests pass.
       - [x] Manual test: the reproduction SQL fails with E-3110 before the fix 
and returns the expected
         `2 / 0 / NULL / 2` after it on a local FE + BE cluster.
       - [ ] No need to test.
   - Behavior changed:
       - [ ] No.
       - [x] Yes. `CARDINALITY(ARRAY_MAP(...))` and `ARRAY_MAP(...) IS NULL` 
now collect the input array's
         OFFSET/NULL metadata instead of an element-level metadata path, and 
keep the element data that the
         lambda reads.
   - Does this need documentation?
       - [x] No.
   


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