Jackie-Jiang opened a new pull request, #19390:
URL: https://github.com/apache/pinot/pull/19390

   ## Summary
   
   With null handling enabled, a group-by query was routed to the no-dictionary 
group key generators regardless of how its columns are encoded, and the 
multi-value key path ignored nulls entirely. This PR makes every group key 
generator null-aware, so the routing can go back to being decided by column 
encoding alone.
   
   ### Dictionary-based group key generation
   
   With null handling enabled, a column whose segment tracks nulls reserves one 
further dictionary id, one past its last real id, to stand for a null value; 
its cardinality counts one more than the dictionary holds. A block's null rows 
are moved onto the reserved id before key composition (copying the block's id 
array, which is shared with other readers of the column), so the per-row 
kernels and the raw key arithmetic are untouched. The reserved id composes into 
the raw key like any other value and is read back out as SQL `NULL`.
   
   A column that tracks no nulls reserves nothing, and neither does any column 
when null handling is disabled, which leaves the cardinalities, the holder 
selection and the block reads exactly as they are today. Dictionary-encoded 
group-by columns therefore keep the dictionary-based generator in both modes, 
instead of paying for per-row hash lookups on the no-dictionary path.
   
   ### Multi-value key path of the no-dictionary generators
   
   The `int[][]` overloads of both no-dictionary generators read every column 
without consulting its null bitmap, so a null row was grouped under the 
column's default null value instead of under a group of its own — for every 
column on that path, single-value columns included. Both overloads now 
recognize nulls: a null row contributes one `NULL` group, mirroring the 
single-value behavior and the row's physical storage as a one-element default 
value.
   
   With that closed, the null-enabled and null-disabled twin loops in both 
generators are merged: every iteration on these paths pays for a hash-map 
operation, which dwarfs the predicted per-row null check the merge adds, and 
both files end up smaller than before while doing more.
   
   ### Bugfix: rows misattributed once the group limit is reached
   
   The null-enabled at-limit path of `NoDictionaryMultiColumnGroupKeyGenerator` 
resolved each column's key value but never stored it, composing whatever the 
key buffer held from the previous row — which, after a new group's buffer swap, 
is `{0, 0, ...}`: exactly the first group's key. With null handling enabled and 
`numGroupsLimit` reached, rows belonging to existing groups could be counted 
into the first group or dropped. The resolved value is now stored, same as the 
null-disabled twin always did.
   
   ### Behavior changes
   
   All confined to queries that enable null handling:
   - Grouping by a multi-value column with null rows now returns a `NULL` 
group; previously those rows were grouped under the column's default null value.
   - Rows past the group limit are attributed to their correct existing groups 
(the bugfix above).
   - The group id upper bound for dictionary-encoded columns is now derived 
from cardinalities rather than defaulting to `numGroupsLimit`, matching the 
null-handling-disabled behavior.
   
   With null handling disabled nothing changes: no id is reserved, the routing 
condition is the encoding check it used to be, and the per-row loops of the 
dictionary-based generator are byte-identical.
   
   ### Tests
   
   `NullHandlingEnabledQueriesTest` gains nine query-level tests covering every 
generator and key path with nulls: dictionary-encoded SV (including a row 
holding the column's default null value, which must not join the `NULL` group), 
two dictionary columns, dictionary MV, raw SV (INT and STRING, which exercise 
the primitive-map and object-map null keys respectively), raw MV, mixed 
raw/dictionary SV and MV, and a regression test for the group-limit 
misattribution that fails on the previous code by construction. 
`DictionaryBasedGroupKeyGeneratorTest` additionally covers 
`IntGroupIdMap.clearAndTrim` past the caching threshold.
   


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