fix(core): fix crash on LATEST BY ALL queries over large tables#6832
fix(core): fix crash on LATEST BY ALL queries over large tables#6832bluestreak01 merged 2 commits intomasterfrom
Conversation
Numbers.MAX_SAFE_INT_POW_2 was 1L << 31 (2,147,483,648), which does not fit in a signed 32-bit int. The rehash overflow guard compared newKeyCapacity > MAX_SAFE_INT_POW_2, so when newKeyCapacity was exactly 2^31 the check passed. The subsequent (int) cast produced Integer.MIN_VALUE, and clear() fed a negative byte count to native memset, causing a SIGSEGV. Change the constant to 1L << 30 so the guard rejects 2^31 and throws a clean CairoException instead of crashing the JVM. Deduplicate the constant from Unordered4Map, Unordered8Map, and UnorderedVarcharMap — they each had a private copy with the same bug. Co-Authored-By: Claude Opus 4.6 <[email protected]>
WalkthroughConsolidates the Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Suggested reviewers
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ast-grep (0.41.0)core/src/main/java/io/questdb/std/Numbers.javacore/src/test/java/io/questdb/test/cairo/map/OrderedMapTest.javaThanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitia review |
|
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@core/src/test/java/io/questdb/test/cairo/map/OrderedMapTest.java`:
- Around line 1384-1387: The test constructs OrderedMap with a 0.5 load factor
but the comment and intended behavior match the 0.75 case; update the OrderedMap
instantiation in OrderedMapTest (the constructor call that currently passes 0.5)
to pass 0.75 so the subsequent map.setKeyCapacity(Integer.MAX_VALUE / 4 * 3 + 1)
check aligns with the comment and mirrors MapTest.testSetKeyCapacityOverflow
behavior.
ℹ️ Review info
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
core/src/main/java/io/questdb/cairo/map/Unordered4Map.javacore/src/main/java/io/questdb/cairo/map/Unordered8Map.javacore/src/main/java/io/questdb/cairo/map/UnorderedVarcharMap.javacore/src/main/java/io/questdb/std/Numbers.javacore/src/test/java/io/questdb/test/cairo/map/MapTest.javacore/src/test/java/io/questdb/test/cairo/map/OrderedMapTest.java
[PR Coverage check]😍 pass : 0 / 0 (0%) |
Summary
Numbers.MAX_SAFE_INT_POW_2from1L << 31to1L << 30. The old value (2^31) does not fit in a signed 32-bit int, so the rehash overflow guardnewKeyCapacity > MAX_SAFE_INT_POW_2let exactly 2^31 through. The subsequent(int)cast producedInteger.MIN_VALUE, andclear()fed ~18 EB to nativememset, causing a SIGSEGV.Unordered4Map,Unordered8Map, andUnorderedVarcharMap— each had a private copy with the same bug.MapTestandOrderedMapTest.Crash chain
LATEST BY ALLquery on a large table fills anOrderedMapuntilkeyCapacityreaches 2^30.rehash()doubles tonewKeyCapacity = 1L << 31. The guard (> 1L << 31) is false at the boundary — allocation of 16 GB succeeds.keyCapacity = (int)(1L << 31)truncates toInteger.MIN_VALUE(−2,147,483,648).map.clear()computes(long)keyCapacity << 3=0xFFFFFFFC00000000(~18.4 EB) and passes it to nativememset→SIGSEGV.Fix
MAX_SAFE_INT_POW_2 = 1L << 30makes the guard rejectnewKeyCapacity = 2^31, throwing a cleanCairoException("map capacity overflow")instead of crashing the JVM.