1717#include " paimon/common/file_index/bsi/bit_slice_index_bitmap_file_index.h"
1818
1919#include < cassert>
20+ #include < climits>
2021#include < cstddef>
22+ #include < cstdint>
2123
2224#include " fmt/format.h"
2325#include " paimon/common/file_index/bsi/bit_slice_index_roaring_bitmap.h"
3133#include " paimon/io/data_input_stream.h"
3234#include " paimon/memory/bytes.h"
3335#include " paimon/utils/roaring_bitmap32.h"
36+ namespace {
37+ // Safe absolute value for int64_t that avoids undefined behavior when value == INT64_MIN.
38+ // This mirrors Java's Math.abs() wrapping semantics.
39+ inline int64_t SafeAbs (int64_t value) {
40+ if (value == INT64_MIN ) {
41+ return INT64_MIN ;
42+ }
43+ return value < 0 ? -value : value;
44+ }
3445
46+ } // namespace
3547namespace paimon {
3648class MemoryPool ;
3749
@@ -153,10 +165,14 @@ Result<std::shared_ptr<FileIndexResult>> BitSliceIndexBitmapFileIndexReader::Vis
153165 BitmapIndexResult::BitmapSupplier bitmap_supplier =
154166 [literal = literal, reader = shared_from_this ()]() -> Result<RoaringBitmap32> {
155167 PAIMON_ASSIGN_OR_RAISE (int64_t value, reader->value_mapper_ (literal));
156- if (value >= 0 ) {
168+ if (value == INT64_MIN ) {
169+ // Everything is greater than INT64_MIN (writer cannot store it)
170+ return RoaringBitmap32::Or (reader->positive_ ->IsNotNull (),
171+ reader->negative_ ->IsNotNull ());
172+ } else if (value >= 0 ) {
157173 return reader->positive_ ->GreaterThan (value);
158174 } else {
159- PAIMON_ASSIGN_OR_RAISE (RoaringBitmap32 b1, reader->negative_ ->LessThan (- value));
175+ PAIMON_ASSIGN_OR_RAISE (RoaringBitmap32 b1, reader->negative_ ->LessThan (SafeAbs ( value) ));
160176 RoaringBitmap32 b2 = reader->positive_ ->IsNotNull ();
161177 b1 |= b2;
162178 return b1;
@@ -170,10 +186,15 @@ Result<std::shared_ptr<FileIndexResult>> BitSliceIndexBitmapFileIndexReader::Vis
170186 BitmapIndexResult::BitmapSupplier bitmap_supplier =
171187 [literal = literal, reader = shared_from_this ()]() -> Result<RoaringBitmap32> {
172188 PAIMON_ASSIGN_OR_RAISE (int64_t value, reader->value_mapper_ (literal));
173- if (value >= 0 ) {
189+ if (value == INT64_MIN ) {
190+ // All non-null rows satisfy x >= INT64_MIN
191+ return RoaringBitmap32::Or (reader->positive_ ->IsNotNull (),
192+ reader->negative_ ->IsNotNull ());
193+ } else if (value >= 0 ) {
174194 return reader->positive_ ->GreaterOrEqual (value);
175195 } else {
176- PAIMON_ASSIGN_OR_RAISE (RoaringBitmap32 b1, reader->negative_ ->LessOrEqual (-value));
196+ PAIMON_ASSIGN_OR_RAISE (RoaringBitmap32 b1,
197+ reader->negative_ ->LessOrEqual (SafeAbs (value)));
177198 RoaringBitmap32 b2 = reader->positive_ ->IsNotNull ();
178199 b1 |= b2;
179200 return b1;
@@ -187,8 +208,11 @@ Result<std::shared_ptr<FileIndexResult>> BitSliceIndexBitmapFileIndexReader::Vis
187208 BitmapIndexResult::BitmapSupplier bitmap_supplier =
188209 [literal = literal, reader = shared_from_this ()]() -> Result<RoaringBitmap32> {
189210 PAIMON_ASSIGN_OR_RAISE (int64_t value, reader->value_mapper_ (literal));
190- if (value < 0 ) {
191- return reader->negative_ ->GreaterThan (-value);
211+ if (value == INT64_MIN ) {
212+ // Nothing is less than INT64_MIN
213+ return RoaringBitmap32 ();
214+ } else if (value < 0 ) {
215+ return reader->negative_ ->GreaterThan (SafeAbs (value));
192216 } else {
193217 PAIMON_ASSIGN_OR_RAISE (RoaringBitmap32 b1, reader->positive_ ->LessThan (value));
194218 RoaringBitmap32 b2 = reader->negative_ ->IsNotNull ();
@@ -203,8 +227,11 @@ Result<std::shared_ptr<FileIndexResult>> BitSliceIndexBitmapFileIndexReader::Vis
203227 BitmapIndexResult::BitmapSupplier bitmap_supplier =
204228 [literal = literal, reader = shared_from_this ()]() -> Result<RoaringBitmap32> {
205229 PAIMON_ASSIGN_OR_RAISE (int64_t value, reader->value_mapper_ (literal));
206- if (value < 0 ) {
207- return reader->negative_ ->GreaterOrEqual (-value);
230+ if (value == INT64_MIN ) {
231+ // Writer cannot store INT64_MIN, so no row can match
232+ return RoaringBitmap32 ();
233+ } else if (value < 0 ) {
234+ return reader->negative_ ->GreaterOrEqual (SafeAbs (value));
208235 } else {
209236 PAIMON_ASSIGN_OR_RAISE (RoaringBitmap32 b1, reader->positive_ ->LessOrEqual (value));
210237 RoaringBitmap32 b2 = reader->negative_ ->IsNotNull ();
@@ -232,13 +259,17 @@ Result<std::shared_ptr<FileIndexResult>> BitSliceIndexBitmapFileIndexReader::Vis
232259 result_bitmaps.reserve (literals.size ());
233260 for (const auto & literal : literals) {
234261 PAIMON_ASSIGN_OR_RAISE (int64_t value, reader->value_mapper_ (literal));
235- RoaringBitmap32 equal;
236- if (value < 0 ) {
237- PAIMON_ASSIGN_OR_RAISE (equal, reader->negative_ ->Equal (-value));
262+ if (value == INT64_MIN ) {
263+ // Writer cannot store INT64_MIN, so no row can match it
264+ result_bitmaps.emplace_back ();
265+ } else if (value < 0 ) {
266+ PAIMON_ASSIGN_OR_RAISE (RoaringBitmap32 equal,
267+ reader->negative_ ->Equal (SafeAbs (value)));
268+ result_bitmaps.emplace_back (std::move (equal));
238269 } else {
239- PAIMON_ASSIGN_OR_RAISE (equal, reader->positive_ ->Equal (value));
270+ PAIMON_ASSIGN_OR_RAISE (RoaringBitmap32 equal, reader->positive_ ->Equal (value));
271+ result_bitmaps.emplace_back (std::move (equal));
240272 }
241- result_bitmaps.emplace_back (std::move (equal));
242273 }
243274 return RoaringBitmap32::FastUnion (result_bitmaps);
244275 };
@@ -255,13 +286,17 @@ Result<std::shared_ptr<FileIndexResult>> BitSliceIndexBitmapFileIndexReader::Vis
255286 result_bitmaps.reserve (literals.size ());
256287 for (const auto & literal : literals) {
257288 PAIMON_ASSIGN_OR_RAISE (int64_t value, reader->value_mapper_ (literal));
258- RoaringBitmap32 equal;
259- if (value < 0 ) {
260- PAIMON_ASSIGN_OR_RAISE (equal, reader->negative_ ->Equal (-value));
289+ if (value == INT64_MIN ) {
290+ // Writer cannot store INT64_MIN, so no row can match it
291+ result_bitmaps.emplace_back ();
292+ } else if (value < 0 ) {
293+ PAIMON_ASSIGN_OR_RAISE (RoaringBitmap32 equal,
294+ reader->negative_ ->Equal (SafeAbs (value)));
295+ result_bitmaps.emplace_back (std::move (equal));
261296 } else {
262- PAIMON_ASSIGN_OR_RAISE (equal, reader->positive_ ->Equal (value));
297+ PAIMON_ASSIGN_OR_RAISE (RoaringBitmap32 equal, reader->positive_ ->Equal (value));
298+ result_bitmaps.emplace_back (std::move (equal));
263299 }
264- result_bitmaps.emplace_back (std::move (equal));
265300 }
266301 auto in = RoaringBitmap32::FastUnion (result_bitmaps);
267302 ebm -= in;
0 commit comments