Skip to content

[fix](be) fix BE core due to explode_bitmap size exceeding INT_MAX#66034

Open
Baymine wants to merge 1 commit into
apache:masterfrom
Baymine:fix/explode-bitmap-int-max
Open

[fix](be) fix BE core due to explode_bitmap size exceeding INT_MAX#66034
Baymine wants to merge 1 commit into
apache:masterfrom
Baymine:fix/explode-bitmap-int-max

Conversation

@Baymine

@Baymine Baymine commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: close #66033

Problem Summary:

VExplodeBitmapTableFunction::get_value computed the number of rows to emit with max_step = std::min(max_step, (int)(_cur_size - _cur_offset));. Both _cur_size (the bitmap cardinality) and _cur_offset are int64_t. When a bitmap holds more than INT_MAX (~2.1 billion) elements, the subtraction _cur_size - _cur_offset exceeds the range of int, so the C-style (int) cast overflows and yields a negative max_step. That negative value is later used in target->resize(origin_size + max_step), which underflows the size computation and crashes the BE (core dump).

The fix performs the std::min in int64_t space so the comparison is done without truncation, then casts the result — now provably within [0, max_step] and therefore in int range — back to int. A DCHECK_GE(max_step, 0) guard documents and asserts the post-condition, matching the glog DCHECK idiom already used by the sibling table_function sources.

Release note

Fix BE crash when exploding a bitmap whose cardinality exceeds INT_MAX.

Check List (For Author)

  • Test

    • Unit Test: added be/test/exprs/function/table_function_test.cpp: vexplode_bitmap_cardinality_exceeds_int_max. It cheaply builds a bitmap whose cardinality exceeds INT_MAX from a Roaring range (a few KB — the overflow occurs on the first get_value call, before any element is materialized, so no large allocation is needed) and asserts get_value returns a positive batch. On the pre-fix code the (int) cast overflows to a negative max_step and crashes; the test reproduces this and passes on the fix (verified under ASAN).
  • Behavior changed:

    • No (crash avoidance only; correct results are unchanged).
  • Does this need documentation?

    • No.

@hello-stephen

Copy link
Copy Markdown
Contributor

Thank you for your contribution to Apache Doris.
Don't know what should be done next? See How to process your PR.

Please clearly describe your PR:

  1. What problem was fixed (it's best to include specific error reporting information). How it was fixed.
  2. Which behaviors were modified. What was the previous behavior, what is it now, why was it modified, and what possible impacts might there be.
  3. What features were added. Why was this function added?
  4. Which code was refactored and why was this part of the code refactored?
  5. Which functions were optimized and what is the difference before and after the optimization?

## Proposed changes

Issue Number: close apache#66033

Problem Summary:

`VExplodeBitmapTableFunction::get_value` computed the number of rows to emit
with `max_step = std::min(max_step, (int)(_cur_size - _cur_offset));`. Both
`_cur_size` (the bitmap cardinality) and `_cur_offset` are `int64_t`. When a
bitmap holds more than `INT_MAX` (~2.1 billion) elements, the subtraction
`_cur_size - _cur_offset` exceeds the range of `int`, so the C-style `(int)`
cast overflows and yields a negative `max_step`. That negative value is later
used in `target->resize(origin_size + max_step)`, which underflows the size
computation and crashes the BE (core dump).

The fix performs the `std::min` in `int64_t` space so the comparison is done
without truncation, then casts the result — which is now provably within
`[0, max_step]` and therefore in `int` range — back to `int`. A
`DCHECK_GE(max_step, 0)` guard documents and asserts the post-condition in
debug builds, matching the glog `DCHECK` idiom already used by the sibling
table_function sources.

### Release note

Fix BE crash when exploding a bitmap whose cardinality exceeds INT_MAX.

### Check List (For Author)

- Test: Unit Test — added be/test/exprs/function/table_function_test.cpp:vexplode_bitmap_cardinality_exceeds_int_max,
  which builds a bitmap with cardinality > INT_MAX (via a Roaring range, ~KB) and asserts get_value returns a positive batch; this reproduces the pre-fix negative-overflow crash.
- Behavior changed: No (crash avoidance only; correct results are unchanged).
- Does this need documentation: No
@Baymine
Baymine force-pushed the fix/explode-bitmap-int-max branch from e6a1861 to d3a872e Compare July 25, 2026 04:52
@Baymine

Baymine commented Jul 25, 2026

Copy link
Copy Markdown
Contributor Author

/review

@Baymine

Baymine commented Jul 25, 2026

Copy link
Copy Markdown
Contributor Author

run buildall

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-H: Total hot run time: 29358 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpch-tools
Tpch sf100 test result on commit d3a872e46c419a4bb08273fd644fe834833b3fa6, data reload: false

------ Round 1 ----------------------------------
============================================
q1	17771	4145	4103	4103
q2	2027	320	196	196
q3	10334	1373	798	798
q4	4671	479	344	344
q5	7567	837	570	570
q6	174	171	136	136
q7	735	804	606	606
q8	9825	1540	1642	1540
q9	5999	4304	4330	4304
q10	6795	1725	1483	1483
q11	530	343	317	317
q12	728	562	459	459
q13	18110	3352	2753	2753
q14	270	255	246	246
q15	q16	780	772	695	695
q17	1215	1056	943	943
q18	6963	5659	5415	5415
q19	1284	1248	1094	1094
q20	808	662	626	626
q21	5672	2681	2437	2437
q22	427	344	293	293
Total cold run time: 102685 ms
Total hot run time: 29358 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4430	4318	4396	4318
q2	286	329	214	214
q3	4639	4947	4415	4415
q4	2036	2152	1363	1363
q5	4412	4223	4227	4223
q6	230	173	124	124
q7	1710	2052	1705	1705
q8	2521	2133	2066	2066
q9	7836	7821	7724	7724
q10	4665	4628	4240	4240
q11	588	414	397	397
q12	730	758	542	542
q13	3512	3572	2994	2994
q14	333	320	275	275
q15	q16	745	760	752	752
q17	1351	1330	1341	1330
q18	8004	7302	6881	6881
q19	1095	1071	1109	1071
q20	2206	2189	1939	1939
q21	5228	4562	4305	4305
q22	502	479	409	409
Total cold run time: 57059 ms
Total hot run time: 51287 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 176812 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpcds-tools
TPC-DS sf100 test result on commit d3a872e46c419a4bb08273fd644fe834833b3fa6, data reload: false

query5	4367	607	484	484
query6	459	217	208	208
query7	4872	620	345	345
query8	329	197	170	170
query9	8791	4065	4038	4038
query10	502	368	295	295
query11	5893	2334	2120	2120
query12	159	102	97	97
query13	1274	574	425	425
query14	6280	5191	4828	4828
query14_1	4239	4230	4218	4218
query15	216	208	181	181
query16	1038	474	419	419
query17	1136	724	592	592
query18	2679	477	362	362
query19	212	190	150	150
query20	113	109	108	108
query21	235	160	137	137
query22	13647	13537	13330	13330
query23	17309	16466	16066	16066
query23_1	16212	16159	16326	16159
query24	7521	1769	1278	1278
query24_1	1323	1278	1297	1278
query25	584	489	352	352
query26	1331	340	219	219
query27	2614	575	372	372
query28	4440	1978	1986	1978
query29	1059	602	464	464
query30	341	270	231	231
query31	1124	1077	986	986
query32	110	63	60	60
query33	521	313	252	252
query34	1179	1128	662	662
query35	759	778	652	652
query36	1170	1181	1052	1052
query37	152	109	89	89
query38	1887	1694	1658	1658
query39	900	871	846	846
query39_1	838	844	824	824
query40	246	161	151	151
query41	80	75	77	75
query42	88	90	89	89
query43	316	320	276	276
query44	1433	779	761	761
query45	191	180	174	174
query46	1087	1170	707	707
query47	2164	2135	1974	1974
query48	423	437	309	309
query49	574	406	302	302
query50	1062	415	326	326
query51	10855	10404	10423	10404
query52	92	86	71	71
query53	255	285	203	203
query54	295	241	220	220
query55	76	71	88	71
query56	303	288	303	288
query57	1329	1316	1222	1222
query58	290	260	259	259
query59	1588	1756	1412	1412
query60	302	275	251	251
query61	157	150	143	143
query62	542	494	420	420
query63	241	197	202	197
query64	2740	1032	876	876
query65	4717	4635	4613	4613
query66	1775	501	382	382
query67	29215	29180	29048	29048
query68	3070	1597	1040	1040
query69	401	295	265	265
query70	1065	943	930	930
query71	375	326	312	312
query72	3137	2697	2348	2348
query73	825	784	435	435
query74	5076	4888	4733	4733
query75	2553	2502	2112	2112
query76	2328	1167	751	751
query77	346	386	279	279
query78	11857	11923	11199	11199
query79	1387	1132	725	725
query80	1293	558	474	474
query81	567	334	284	284
query82	634	155	119	119
query83	402	322	302	302
query84	281	151	127	127
query85	994	629	554	554
query86	444	292	279	279
query87	1813	1828	1779	1779
query88	3735	2822	2831	2822
query89	453	370	328	328
query90	1914	193	189	189
query91	202	194	165	165
query92	63	61	55	55
query93	1701	1560	924	924
query94	724	363	321	321
query95	799	597	473	473
query96	1043	771	333	333
query97	2626	2644	2489	2489
query98	222	205	202	202
query99	1088	1106	976	976
Total cold run time: 263935 ms
Total hot run time: 176812 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
ClickBench: Total hot run time: 25.1 s
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/clickbench-tools
ClickBench test result on commit d3a872e46c419a4bb08273fd644fe834833b3fa6, data reload: false

query1	0.00	0.00	0.00
query2	0.10	0.05	0.05
query3	0.25	0.14	0.14
query4	1.61	0.15	0.15
query5	0.24	0.23	0.23
query6	1.25	1.11	1.07
query7	0.04	0.01	0.01
query8	0.05	0.03	0.03
query9	0.38	0.31	0.31
query10	0.55	0.60	0.60
query11	0.19	0.15	0.13
query12	0.18	0.14	0.15
query13	0.46	0.47	0.48
query14	1.01	1.01	1.01
query15	0.62	0.59	0.60
query16	0.34	0.30	0.33
query17	1.09	1.12	1.08
query18	0.24	0.21	0.21
query19	2.01	1.96	1.96
query20	0.02	0.01	0.01
query21	15.44	0.21	0.15
query22	4.96	0.05	0.05
query23	16.09	0.31	0.12
query24	2.98	0.40	0.31
query25	0.11	0.05	0.04
query26	0.73	0.20	0.14
query27	0.04	0.04	0.04
query28	3.53	0.92	0.53
query29	12.55	4.10	3.31
query30	0.28	0.16	0.15
query31	2.76	0.58	0.31
query32	3.22	0.58	0.49
query33	3.24	3.17	3.18
query34	15.50	4.26	3.50
query35	3.53	3.51	3.53
query36	0.54	0.42	0.42
query37	0.09	0.06	0.07
query38	0.05	0.04	0.04
query39	0.04	0.03	0.03
query40	0.18	0.16	0.15
query41	0.09	0.03	0.03
query42	0.04	0.03	0.03
query43	0.04	0.04	0.03
Total cold run time: 96.66 s
Total hot run time: 25.1 s

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 100.00% (3/3) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 75.33% (31089/41269)
Line Coverage 59.91% (346564/578505)
Region Coverage 56.71% (291582/514186)
Branch Coverage 58.05% (130245/224373)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] BE crashes (core dump) when explode_bitmap is called on a bitmap with cardinality exceeding INT_MAX

2 participants