Skip to content

[Opt](bitmap) Optimize bitmap op count rewrites#65483

Draft
linrrzqqq wants to merge 1 commit into
apache:masterfrom
linrrzqqq:bitmap-op-count-v2
Draft

[Opt](bitmap) Optimize bitmap op count rewrites#65483
linrrzqqq wants to merge 1 commit into
apache:masterfrom
linrrzqqq:bitmap-op-count-v2

Conversation

@linrrzqqq

Copy link
Copy Markdown
Collaborator

Problem Summary:

Background

bitmap_count(bitmap_op(...)) currently materializes an intermediate bitmap before counting. For patterns such as bitmap_count(bitmap_and(...)), bitmap_count(bitmap_or(...)), bitmap_count(bitmap_xor(...)), and bitmap_count(bitmap_and_not(...)), Doris already has corresponding bitmap_*_count functions that can compute the cardinality directly.

Also, bitmap_and_count, bitmap_or_count, bitmap_xor_count, and bitmap_and_not_count are semantically always not null, but their previous metadata could be marked nullable when bitmap arguments were nullable.

Changes

  • Add Nereids expression rewrite:

    • bitmap_count(bitmap_and(...)) -> bitmap_and_count(...)
    • bitmap_count(bitmap_or(...)) -> bitmap_or_count(...)
    • bitmap_count(bitmap_xor(...)) -> bitmap_xor_count(...)
    • bitmap_count(bitmap_not(...)) / bitmap_and_not(...) -> bitmap_and_not_count(...)
  • Mark bitmap op count scalar functions as always not nullable in Nereids.

  • Add BE v2 implementations for bitmap op count return type inference:

    • bitmap_and_count_v2
    • bitmap_or_count_v2
    • bitmap_xor_count_v2
    • bitmap_and_not_count_v2
  • Add new_version_bitmap_op_count query option to select the v2 BE implementations.

  • Optimize binary bitmap count execution paths to avoid intermediate bitmap materialization.

  • Fix BitmapValue::or_cardinality for SET/SET input.

  • Merge bitmap_and_not / bitmap_andnot aliases into bitmap_not.

@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?

@linrrzqqq

Copy link
Copy Markdown
Collaborator Author

/review

@linrrzqqq

Copy link
Copy Markdown
Collaborator Author

run buildall

@linrrzqqq linrrzqqq marked this pull request as draft July 11, 2026 19:26

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found one compatibility issue that should be fixed before merge.

Critical checkpoints: the PR's goal is clear and the bitmap-count rewrite/fast paths are covered by focused unit and regression additions, but the FE/BE compatibility checkpoint is not satisfied for rolling upgrades. The change is otherwise focused; I did not find concurrency, lifecycle, persistence, observability, or transaction risks in the changed paths. Parallel execution paths for query, load, insert, stream load, and BE constant folding were checked for query-option propagation. Tests were reviewed statically but not run because this checkout is missing .worktree_initialized and thirdparty/installed/bin/protoc.

Subagent conclusions: optimizer-rewrite reported no additional candidates. tests-session-config reported the same rolling-upgrade nullability issue as TSC-1, merged as duplicate of MRG-001. Convergence round 1 ended with both live subagents replying NO_NEW_VALUABLE_FINDINGS for the final ledger/comment set.

User focus: no additional user-provided review focus was supplied.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anchor repair for the same compatibility issue: the previous review summary remains applicable, and the misplaced left-side inline comment was deleted. This review resubmits the inline comment on the added right-side line.

Critical checkpoints: the PR's goal is clear and the bitmap-count rewrite/fast paths are covered by focused unit and regression additions, but the FE/BE compatibility checkpoint is not satisfied for rolling upgrades. The change is otherwise focused; I did not find concurrency, lifecycle, persistence, observability, or transaction risks in the changed paths. Parallel execution paths for query, load, insert, stream load, and BE constant folding were checked for query-option propagation. Tests were reviewed statically but not run because this checkout is missing .worktree_initialized and thirdparty/installed/bin/protoc.

Subagent conclusions: optimizer-rewrite reported no additional candidates. tests-session-config reported the same rolling-upgrade nullability issue as TSC-1, merged as duplicate of MRG-001. Convergence round 1 ended with both live subagents replying NO_NEW_VALUABLE_FINDINGS for the final ledger/comment set.

User focus: no additional user-provided review focus was supplied.

*/
public class BitmapAndCount extends ScalarFunction
implements ExplicitlyCastableSignature {
implements ExplicitlyCastableSignature, AlwaysNotNullable {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The FE now advertises these bitmap op-count functions as always non-nullable, but that is only true on BEs that understand new_version_bitmap_op_count and select the new _v2 functions. In a rolling upgrade, an older BE ignores the new optional thrift field and still binds the old bitmap_and_count implementation; with nullable bitmap arguments that old implementation derives Nullable(BIGINT) while the new FE plan sends BIGINT, and FunctionBuilderImpl::build rejects the mismatch during function preparation. Please keep the FE nullability compatible until all target BEs can execute the _v2 path, or gate the not-null metadata/rewrite on a BE capability/version check.

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17580	4078	3995	3995
q2	2005	330	205	205
q3	10937	1423	836	836
q4	4734	465	333	333
q5	8408	852	590	590
q6	346	169	137	137
q7	820	830	613	613
q8	10558	1652	1526	1526
q9	5873	4451	4419	4419
q10	6802	1756	1515	1515
q11	504	344	307	307
q12	698	562	434	434
q13	18476	3293	2785	2785
q14	267	258	244	244
q15	q16	775	777	700	700
q17	1051	991	939	939
q18	6808	5650	5465	5465
q19	1250	1289	1081	1081
q20	773	675	523	523
q21	5667	2669	2325	2325
q22	431	356	294	294
Total cold run time: 104763 ms
Total hot run time: 29266 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4299	4243	4269	4243
q2	289	314	208	208
q3	4562	4961	4342	4342
q4	2031	2132	1349	1349
q5	4404	4330	4326	4326
q6	224	174	125	125
q7	2211	1826	1578	1578
q8	2466	2073	2097	2073
q9	7847	7803	7925	7803
q10	4723	4732	4274	4274
q11	733	411	378	378
q12	741	796	543	543
q13	3260	3583	2977	2977
q14	313	306	279	279
q15	q16	714	735	641	641
q17	1340	1306	1317	1306
q18	7979	7317	6718	6718
q19	1115	1091	1111	1091
q20	2208	2234	1935	1935
q21	5200	4510	4457	4457
q22	537	455	393	393
Total cold run time: 57196 ms
Total hot run time: 51039 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 179900 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 90a0650c39eb41db6bf627a05bf32abf536c34a7, data reload: false

query5	4333	639	503	503
query6	445	221	211	211
query7	4837	606	344	344
query8	336	212	173	173
query9	8789	4013	4045	4013
query10	500	363	307	307
query11	5931	2356	2132	2132
query12	160	106	101	101
query13	1275	630	462	462
query14	6522	5307	4952	4952
query14_1	4304	4254	4260	4254
query15	216	214	187	187
query16	1009	459	425	425
query17	1112	721	565	565
query18	2692	471	337	337
query19	203	183	152	152
query20	108	107	100	100
query21	233	151	126	126
query22	13613	13634	13504	13504
query23	17364	16451	16124	16124
query23_1	16141	16199	16159	16159
query24	7559	1741	1282	1282
query24_1	1310	1306	1315	1306
query25	549	439	368	368
query26	1331	352	206	206
query27	2592	586	381	381
query28	4397	2012	1996	1996
query29	1094	627	490	490
query30	340	265	224	224
query31	1141	1097	978	978
query32	116	65	62	62
query33	529	318	256	256
query34	1171	1165	658	658
query35	783	784	681	681
query36	1406	1361	1247	1247
query37	156	110	93	93
query38	1894	1706	1671	1671
query39	918	910	889	889
query39_1	865	871	891	871
query40	246	165	145	145
query41	75	89	84	84
query42	96	94	94	94
query43	317	321	281	281
query44	1419	812	774	774
query45	204	192	182	182
query46	1058	1199	760	760
query47	2362	2350	2243	2243
query48	403	435	296	296
query49	581	433	319	319
query50	1112	430	343	343
query51	10823	10506	10709	10506
query52	86	88	77	77
query53	265	283	212	212
query54	297	250	234	234
query55	75	73	72	72
query56	288	321	291	291
query57	1448	1435	1301	1301
query58	288	275	261	261
query59	1546	1581	1433	1433
query60	304	275	254	254
query61	182	173	173	173
query62	701	660	589	589
query63	245	208	211	208
query64	2930	1072	875	875
query65	4805	4766	4761	4761
query66	1772	498	397	397
query67	29571	29552	29430	29430
query68	3185	1650	1001	1001
query69	415	321	270	270
query70	1111	948	989	948
query71	373	338	317	317
query72	3026	2776	2387	2387
query73	835	784	449	449
query74	5100	4917	4759	4759
query75	2605	2612	2206	2206
query76	2323	1174	810	810
query77	349	378	281	281
query78	12331	12481	11908	11908
query79	1424	1122	745	745
query80	1334	553	461	461
query81	525	320	280	280
query82	616	159	119	119
query83	357	321	287	287
query84	287	162	128	128
query85	953	599	507	507
query86	425	306	291	291
query87	1827	1824	1740	1740
query88	3685	2810	2746	2746
query89	473	420	355	355
query90	1943	200	196	196
query91	197	187	159	159
query92	61	58	52	52
query93	1726	1591	911	911
query94	719	361	307	307
query95	778	508	474	474
query96	1078	833	360	360
query97	2699	2657	2546	2546
query98	216	215	201	201
query99	1149	1172	1042	1042
Total cold run time: 266151 ms
Total hot run time: 179900 ms

@hello-stephen

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

query1	0.01	0.01	0.00
query2	0.14	0.09	0.08
query3	0.37	0.24	0.24
query4	1.61	0.25	0.25
query5	0.33	0.31	0.31
query6	1.16	0.66	0.67
query7	0.04	0.01	0.01
query8	0.09	0.08	0.07
query9	0.50	0.37	0.37
query10	0.58	0.58	0.57
query11	0.31	0.19	0.18
query12	0.32	0.19	0.19
query13	0.52	0.53	0.53
query14	0.93	0.94	0.91
query15	0.67	0.60	0.60
query16	0.39	0.38	0.39
query17	1.05	1.00	1.03
query18	0.31	0.29	0.28
query19	1.91	1.84	1.79
query20	0.02	0.01	0.01
query21	15.40	0.37	0.32
query22	4.89	0.14	0.13
query23	15.81	0.50	0.30
query24	2.30	0.60	0.45
query25	0.15	0.10	0.10
query26	0.72	0.26	0.21
query27	0.10	0.09	0.09
query28	3.47	0.90	0.52
query29	12.44	4.19	3.24
query30	0.38	0.26	0.26
query31	2.76	0.62	0.33
query32	3.24	0.59	0.48
query33	2.97	2.97	2.92
query34	15.74	4.10	3.37
query35	3.27	3.25	3.25
query36	0.62	0.52	0.50
query37	0.12	0.10	0.10
query38	0.08	0.07	0.08
query39	0.08	0.06	0.06
query40	0.20	0.18	0.17
query41	0.13	0.09	0.08
query42	0.09	0.06	0.06
query43	0.07	0.06	0.07
Total cold run time: 96.29 s
Total hot run time: 25.5 s

@hello-stephen

Copy link
Copy Markdown
Contributor

BE UT Coverage Report

Increment line coverage 97.79% (133/136) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 56.91% (23547/41374)
Line Coverage 40.58% (230303/567514)
Region Coverage 36.47% (181884/498786)
Branch Coverage 37.55% (81229/216324)

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 97.79% (133/136) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 74.87% (30226/40372)
Line Coverage 58.84% (331899/564087)
Region Coverage 55.58% (278305/500751)
Branch Coverage 56.91% (123225/216518)

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 100.00% (25/25) 🎉
Increment coverage report
Complete coverage report

@linrrzqqq linrrzqqq force-pushed the bitmap-op-count-v2 branch from 90a0650 to 2848f59 Compare July 12, 2026 02:53
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.

2 participants