raghavyadav01 opened a new pull request, #19608:
URL: https://github.com/apache/pinot/pull/19608

   Stacked on #19607 (the declared-child-spec fix), which this needs for the 
child's single/multi-value flag. Review that one first; the second commit here 
is the multi-value work.
   
   ### The problem
   
   A key whose values are collections has nowhere to go. 
`OpenStructTypeInference` does not map a collection, so the key falls back to 
STRING and the column stores the list's `toString`:
   
   ```
   {"tags": [1, 2, 3]}   →   props$tags = "[1, 2, 3]"      // not even JSON
   ```
   
   Nothing inside it can be filtered, counted or grouped, and the elements' own 
types are gone.
   
   ### Change
   
   Materialize such a key as a **multi-value column of its element type**, 
written by the standard MV creators. `writeColumnIndexes` was already generic 
over `IndexCreator`, which has a multi-value `add`, so this needed the shape 
and the per-element dictIds rather than a new creator.
   
   Shape follows the same rule the type already does, and for the same reason — 
a column cannot be reshaped underneath documents that already wrote to it:
   
   - **A declaration decides it, both ways.** A key declared single-value stays 
single-value even when its values are collections, because that is what the 
user asked for.
   - **Otherwise the first value decides, and sticks.** A collection arriving 
later on a scalar-shaped key is handled like any other value the column cannot 
represent — stringified on a STRING key, a coercion failure on a typed one.
   - **Elements that disagree resolve to STRING**, the same answer a key whose 
values drift across rows gets, so a mixed array keeps every element rather than 
losing the odd ones.
   
   Edge cases, all covered by tests:
   
   | case | result |
   |---|---|
   | scalar on a multi-value key | one element |
   | absent document | one default element, as the standard creator writes for 
an absent MV field |
   | empty list | not a value — no elements, no type to infer, no empty state 
on disk — so the key is absent for that document, exactly as a null value is |
   | list longer than the mutable column's maximum | dropped and metered as a 
coercion failure, rather than failing the segment |
   
   ### Both tiers
   
   `MutableKeyColumn` gains a multi-value mode over 
`FixedByteMVMutableForwardIndex`, so the consuming tier resolves the same 
values by its own route. `OpenStructConsumingSealedParityTest` covers a 
multi-value key element for element either side of `seal()`, pinning the values 
themselves rather than only cross-tier equality.
   
   ### Tests
   
   - `OpenStructMultiValueKeyTest` — element type, numeric elements, 
disagreeing elements, declared SV with list values, declared MV with scalar 
values, scalar on an MV key, shape stickiness, absent docs, empty lists.
   - `OpenStructConsumingSealedParityTest` — new multi-value parity case.
   
   78 OPEN_STRUCT tests across `pinot-spi` and `pinot-segment-local` pass.
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)


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