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

   ## Summary
   
   The batch murmur3 hash reads (`read32BitsMurmur3HashValues` / 
`read64BitsMurmur3HashValues` / `read128BitsMurmur3HashValues`) on immutable 
`BytesDictionary` and `BigDecimalDictionary` hash truncated values when the 
dictionary uses the fixed-byte layout.
   
   The reads went through the `ValueReader` hash defaults, which hash 
`readUnpaddedBytes`. `FixedByteValueReaderWriter.readUnpaddedBytes` stops at 
the first `0x00` byte because the fixed-byte layout pads STRING values with 
`\0`. For BYTES and BIG_DECIMAL, 
`DictionaryIndexType.shouldUseVarLengthDictionary` picks the fixed-byte layout 
only when all values have the same length, so there is no padding and `0x00` is 
real data:
   - A BIG_DECIMAL with scale 0 serializes with leading `0x00` scale bytes, so 
every such value hashed as the empty array.
   - A BYTES value hashed only its bytes before the first `0x00`, so e.g. `{1, 
0, 0, 0}` and `{1, 0, 0, 1}` collided.
   - The batch hash disagreed with the single-value 
`Dictionary#get*BitsMurmur3HashValue`, which hashes the full `getBytesValue`.
   
   Changes:
   - Add `ValueReader#readBytes`, which reads the full value (the whole slot 
for fixed-byte, the exact length for var-length), next to `readUnpaddedBytes`, 
which is now documented as STRING-only.
   - Hash in the dictionaries from the read that matches the type: `readBytes` 
for BYTES / BIG_DECIMAL, `readUnpaddedBytes` for STRING. STRING hashes are 
unchanged. The per-row loops reuse one scratch buffer and stay branch-free, and 
the fixed-byte read is now a single bulk copy instead of a word-by-word zero 
scan.
   - Remove the padding-aware hash defaults from `ValueReader` and the matching 
public helpers from `BaseImmutableDictionary`, so the STRING padding semantics 
can no longer be applied to other types by accident.
   - `ImmutableDictionaryTest` adds fixed-byte BYTES (leading, interior and 
trailing `0x00`) and scale-0 BIG_DECIMAL dictionaries, asserting the batch 
hashes match the single-value hashes and are distinct, and checks batch against 
single-value hashes for the existing STRING, BIG_DECIMAL and BYTES dictionaries.
   
   ## Reachability
   
   No query returns wrong results today, so this fixes a latent inconsistency:
   - The only production consumer of `BlockValSet#get*BitsMurmur3HashValuesSV` 
is `DistinctCountOffHeapAggregationFunction`, which takes the hash path only 
when `blockValSet.isDictionaryEncoded()` is false. For dictionary-encoded input 
it collects dict ids and later hashes through the single-value 
`Dictionary#get*BitsMurmur3HashValue`, which is correct.
   - `ProjectionBlockValSet#isDictionaryEncoded` and 
`DataFetcher#addDataSource` use the same condition (a dictionary plus a 
dict-encoded forward index), so when the hash path runs, `DataFetcher` has no 
dictionary and reads hashes from the forward index. The dictionary branch in 
`DataFetcher.ColumnValueReader#read*BitsMurmur3HashValues` is not reached.
   - `StarTreePreAggregatedBlockValSet` delegates `isDictionaryEncoded`, and 
`TransformBlockValSet` hashes `getBytesValuesSV`, which reads the full value.
   
   ## Compatibility
   
   No on-disk or wire format changes. `ValueReader` (in `pinot-segment-local`, 
not an SPI) gains the abstract `readBytes` and loses the three hash defaults, 
and `BaseImmutableDictionary` loses its public `get32BitsMurmur3Hash(int, 
byte[])` / `get64BitsMurmur3Hash(int, byte[])` / 
`get128BitsMurmur3HashValue(int, byte[])` helpers. `FixedByteValueReaderWriter` 
and `VarLengthValueReader` are the only `ValueReader` implementations.
   
   🤖 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