fix: NULL bitmap corruption in InplaceSort and roaring filter#24057
Conversation
Review Summary by QodoFix NULL bitmap corruption in InplaceSort and roaring filter
WalkthroughsDescription• Fix NULL bitmap corruption in InplaceSort for runtime filters - Reset null bitmap before InplaceSort in hashbuild and fuzzyfilter - InplaceSort reorders data but not null bitmap, causing corruption • Skip NULL values in roaring filter duplicate detection - Add null bitmap checks in addFunc, testFunc, testAndAddFunc - Prevents false "Duplicate entry" errors with nullable UNIQUE INDEX • Add comprehensive test coverage for NULL handling - 30+ test cases for roaring filter NULL scenarios - 2 new tests for hashbuild runtime filter with NULLs Diagramflowchart LR
A["InplaceSort<br/>reorders data"] -->|"corrupts bitmap"| B["NULL bitmap<br/>misaligned"]
B -->|"fix: Reset()"| C["Cleared bitmap<br/>before sort"]
C -->|"correct"| D["Valid serialized<br/>filter"]
E["Roaring filter<br/>processes values"] -->|"includes NULLs"| F["False duplicates<br/>detected"]
F -->|"fix: nsp.Contains check"| G["NULLs skipped<br/>per SQL standard"]
G -->|"correct"| H["Accurate duplicate<br/>detection"]
File Changes1. pkg/sql/colexec/fuzzyfilter/filter.go
|
Code Review by Qodo
1. NULLs become IN values
|
ed7bea7 to
b0b6a51
Compare
Fix four related NULL-handling bugs: 1. hashbuild/build.go: Reset null bitmap before InplaceSort in handleRuntimeFilter. InplaceSort reorders data but NOT the null bitmap, causing bitmap corruption in serialized runtime filters for JOIN queries with nullable join keys. (Fixes matrixorigin#24055) 2. fuzzyfilter/roaring_filter.go: Skip NULL values in addFunc, testFunc, and testAndAddFunc. SQL standard: NULL != NULL, so NULLs must not participate in duplicate detection. Without this fix, multiple NULL values in a UNIQUE INDEX column could false- trigger 'Duplicate entry' errors. (Fixes matrixorigin#24056) 3. fuzzyfilter/filter.go: Defensive null bitmap reset before InplaceSort in pass2RuntimeFilter path. 4. indexbuild/build.go: Same InplaceSort null bitmap corruption as hashbuild — reset bitmap before sort in handleRuntimeFilter. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
@mergify refresh |
- Rename newroaringFilter to newRoaringFilter (Go naming convention) - Simplify constructor by assigning directly to struct fields - Add default panic for unsupported types - Use MustFixedColNoTypeCheck in testAndAddFunc for consistency
✅ Pull request refreshed |
Merge Queue Status
This pull request spent 13 minutes 41 seconds in the queue, including 9 seconds running CI. Required conditions to merge
|
What type of PR is this?
Which issue(s) this PR fixes:
Fixes #24055 — hashbuild InplaceSort NULL bitmap corruption in runtime filter
Fixes #24056 — FuzzyFilter roaring_filter NULL handling for UNIQUE INDEX
What this PR does / why we need it:
Fixes three related NULL-handling bugs discovered during the investigation of PR #24054:
1. hashbuild runtime filter InplaceSort (build.go)
handleRuntimeFilter()callsInplaceSort()onUniqueJoinKeysvectors before serializing them as runtime IN-filters. However,InplaceSort()reorders the data array but never updates the null bitmap (nsp). After sorting, null positions in the bitmap no longer correspond to actual null values, producing corrupted serialized filter data.Fix: Call
GetNulls().Reset()beforeInplaceSort(). NULLs are irrelevant for IN-filter matching (probe side should never match NULLs), so clearing the bitmap is the correct and cheapest fix.2. fuzzyfilter roaring bitmap NULL handling (roaring_filter.go)
addFunc,testFunc, andtestAndAddFunciterate all vector values without checking the null bitmap. NULL values (which appear as zero in the raw data) get added to the roaring bitmap as if they were real values.Fix: Add
nsp.Contains(uint64(i))check to skip NULL rows in all three functions. Per SQL standard, NULL != NULL.3. fuzzyfilter pass2RuntimeFilter InplaceSort (filter.go)
Defensive fix: Reset null bitmap before
InplaceSort()onpass2RuntimeFilter, same pattern as fix #1.4. indexbuild InplaceSort (indexbuild/build.go)
Same InplaceSort null bitmap corruption pattern as hashbuild.
indexBuild.handleRuntimeFilter()sorts vectors without resetting the null bitmap.Test coverage
roaring_filter_test.go (new, 30 sub-tests)
TestRoaringAddFuncSkipsNulls/TestRoaringTestFuncSkipsNulls/TestRoaringTestAndAddFuncSkipsNullsTestRoaringMultipleTypes/TestRoaringTestAndAddMultipleBatchesTestValueToString/TestIfCanUseRoaringFilter/TestNewRoaringFilterAllTypesbuild_test.go (2 new tests)
TestHashBuildRuntimeFilterWithNulls/TestHashBuildRuntimeFilterWithNullsHashOnPK