Skip to content

[opt](function) speed up zero-scale decimal casts#65410

Open
Mryange wants to merge 1 commit into
apache:masterfrom
Mryange:optimize-decimal-zero-scale-cast
Open

[opt](function) speed up zero-scale decimal casts#65410
Mryange wants to merge 1 commit into
apache:masterfrom
Mryange:optimize-decimal-zero-scale-cast

Conversation

@Mryange

@Mryange Mryange commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Integer-to-DecimalV3 casts with zero scale previously went through the generic decimal cast path even when the target decimal precision can represent the full integer input range. For example, casting an INT column to DECIMALV3(10, 0) still used the common _from_int helper, which computes decimal scaling and range-related values that are unnecessary when the scale is zero and the cast cannot narrow the integer range.

Root cause: the DecimalV3 cast implementation did not have a direct fast path for non-narrowing integer casts to zero-scale decimal types.

This change adds a direct zero-scale DecimalV3 path for integer and boolean inputs when the target decimal range is not narrower than the input range. The fast path writes the input value directly into the decimal native value and preserves the existing generic path for narrowing casts, non-zero-scale casts, and overflow-sensitive cases.

Local optest profiling for:

select sum(cast(quantity as decimalv3(10,0))) from q14_avg_expr_100m;

showed the cast expression time improving from about 119.0 ms to about 109.7 ms on 100M rows, roughly an 8% reduction in this expression counter.

Release note

None

Check List (For Author)

  • Test

    • Regression test
    • Unit Test
    • Manual test (add detailed scripts or steps below)
    • No need to test or manual test. Explain why:
      • This is a refactor/code format and no logic has been changed.
      • Previous test can cover this change.
      • No code files have been changed.
      • Other reason
  • Behavior changed:

    • No.
    • Yes.
  • Does this need documentation?

    • No.
    • Yes.

Check List (For Reviewer who merge this PR)

  • Confirm the release note
  • Confirm test cases
  • Confirm document
  • Add branch pick label

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

@Mryange

Mryange commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

/review

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

Automated review summary for PR 65410.

I did not find a blocking correctness issue in this patch, so I am leaving a comment-only review with no inline comments.

Critical checkpoint conclusions:

  • Goal and coverage: the PR adds a fast path for integer/bool to DecimalV3 casts when target scale is zero and the target integral range is not narrower. Existing BE cast unit templates cover scale-zero integer-to-DecimalV3 cases, including non-narrowing combinations that now enter this branch, plus existing bool coverage.
  • Scope: the change is small and localized to be/src/exprs/function/cast/cast_to_decimal.h.
  • Error/null semantics: the fast path matches the old generic path for to_scale == 0 && !narrow_integral; the old path used multiplier 1, skipped range checks, assigned the native decimal value, and returned success. Nullable wrapping stays outside this branch for the same non-narrowing condition.
  • Concurrency/lifecycle: no new shared state, threads, locks, static initialization, or lifecycle behavior.
  • Configuration/compatibility/persistence: no new configs, no FE-BE protocol or storage-format change, and no edit-log or transaction persistence impact.
  • Parallel paths: narrowing casts, non-zero-scale casts, DecimalV2, float, string, and decimal-source casts remain on the existing generic paths.
  • Performance/observability: the optimization removes generic dispatch and scale work only for the proven direct-write case; no new observability appears necessary for this pure expression cast path.

Subagent conclusions:

  • optimizer-rewrite reported no candidates in its initial pass and returned NO_NEW_VALUABLE_FINDINGS in convergence round 1.
  • tests-session-config reported no candidates in its initial pass and returned NO_NEW_VALUABLE_FINDINGS in convergence round 1.
  • Main review dismissed the overflow/strict-mode, nullable early-return, and coverage concerns with code evidence in the shared ledger. No candidate became an inline comment.

Validation note: this checkout is not worktree-initialized and thirdparty/installed / thirdparty/installed/bin/protoc are absent, so I performed static review plus GitHub PR metadata/patch verification only; I did not run BE unit tests or a build.

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

@Mryange

Mryange commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

run buildall

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	18042	4203	4058	4058
q2	2045	315	200	200
q3	10298	1438	828	828
q4	4677	476	342	342
q5	7485	847	577	577
q6	183	164	136	136
q7	751	837	622	622
q8	10000	1643	1613	1613
q9	5819	4446	4447	4446
q10	6814	1812	1541	1541
q11	497	359	313	313
q12	716	553	442	442
q13	18126	3342	2748	2748
q14	259	260	241	241
q15	q16	788	772	702	702
q17	1029	907	925	907
q18	7031	5748	5508	5508
q19	1160	1298	1049	1049
q20	738	645	524	524
q21	5647	2505	2491	2491
q22	430	357	301	301
Total cold run time: 102535 ms
Total hot run time: 29589 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4340	4275	4291	4275
q2	280	315	213	213
q3	4557	4991	4416	4416
q4	2032	2154	1363	1363
q5	4456	4335	4335	4335
q6	226	179	127	127
q7	1728	2041	1760	1760
q8	2610	2196	2137	2137
q9	7848	8001	7801	7801
q10	4687	4698	4252	4252
q11	578	441	379	379
q12	731	887	642	642
q13	3283	3553	2987	2987
q14	307	314	285	285
q15	q16	765	737	658	658
q17	1354	1328	1323	1323
q18	7942	7485	6953	6953
q19	1104	1062	1049	1049
q20	2227	2216	1941	1941
q21	5232	4604	4445	4445
q22	507	463	403	403
Total cold run time: 56794 ms
Total hot run time: 51744 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 180180 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 6415014561e7c4671d5249930ce92414da6523fc, data reload: false

query5	4319	633	484	484
query6	464	219	228	219
query7	4965	603	330	330
query8	337	185	176	176
query9	8794	4145	4114	4114
query10	486	345	291	291
query11	5933	2339	2117	2117
query12	159	114	104	104
query13	1253	609	455	455
query14	6289	5304	4952	4952
query14_1	4304	4311	4272	4272
query15	222	206	183	183
query16	1053	478	448	448
query17	1121	733	595	595
query18	2728	491	359	359
query19	213	194	153	153
query20	113	113	108	108
query21	231	159	136	136
query22	13603	13611	13403	13403
query23	17555	16703	16222	16222
query23_1	16262	16308	16279	16279
query24	7517	1741	1291	1291
query24_1	1320	1321	1313	1313
query25	568	452	373	373
query26	1330	365	211	211
query27	2568	587	366	366
query28	4405	2035	2017	2017
query29	1051	618	481	481
query30	336	262	227	227
query31	1108	1096	991	991
query32	100	62	60	60
query33	527	320	248	248
query34	1159	1130	628	628
query35	773	782	674	674
query36	1387	1365	1189	1189
query37	157	104	97	97
query38	1870	1709	1609	1609
query39	921	927	905	905
query39_1	898	873	882	873
query40	245	159	143	143
query41	65	64	62	62
query42	92	92	93	92
query43	326	318	277	277
query44	1412	773	781	773
query45	205	184	181	181
query46	1086	1231	755	755
query47	2325	2411	2264	2264
query48	396	423	306	306
query49	606	427	316	316
query50	1076	426	322	322
query51	10824	10916	10804	10804
query52	91	88	76	76
query53	250	287	212	212
query54	278	244	225	225
query55	74	71	69	69
query56	310	289	287	287
query57	1439	1403	1320	1320
query58	289	251	257	251
query59	1591	1650	1421	1421
query60	299	270	258	258
query61	154	151	154	151
query62	700	660	576	576
query63	241	206	204	204
query64	2590	1028	900	900
query65	4844	4773	4769	4769
query66	1723	512	387	387
query67	29529	29438	29261	29261
query68	3043	1489	985	985
query69	419	309	279	279
query70	1044	963	984	963
query71	359	342	296	296
query72	3149	2797	2392	2392
query73	780	838	428	428
query74	5116	4956	4764	4764
query75	2742	2578	2255	2255
query76	2353	1203	812	812
query77	361	387	291	291
query78	12286	12333	11786	11786
query79	1381	1160	733	733
query80	1142	546	497	497
query81	506	315	277	277
query82	562	160	120	120
query83	390	320	289	289
query84	273	157	129	129
query85	958	600	513	513
query86	407	292	287	287
query87	1818	1830	1751	1751
query88	3775	2798	2796	2796
query89	464	422	369	369
query90	1775	209	209	209
query91	221	204	173	173
query92	65	68	63	63
query93	1654	1451	986	986
query94	657	375	323	323
query95	795	596	476	476
query96	1102	826	361	361
query97	2696	2710	2549	2549
query98	219	211	208	208
query99	1145	1185	1064	1064
Total cold run time: 265470 ms
Total hot run time: 180180 ms

@hello-stephen

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

query1	0.01	0.01	0.01
query2	0.09	0.06	0.06
query3	0.25	0.13	0.13
query4	1.61	0.14	0.14
query5	0.29	0.22	0.22
query6	1.25	1.07	1.06
query7	0.03	0.01	0.01
query8	0.06	0.04	0.04
query9	0.37	0.30	0.32
query10	0.55	0.59	0.54
query11	0.19	0.14	0.14
query12	0.18	0.14	0.15
query13	0.46	0.47	0.48
query14	1.01	1.01	1.00
query15	0.61	0.60	0.59
query16	0.31	0.31	0.33
query17	1.09	1.06	1.10
query18	0.22	0.21	0.21
query19	2.02	1.91	1.96
query20	0.02	0.01	0.01
query21	15.42	0.19	0.13
query22	4.97	0.06	0.06
query23	16.05	0.31	0.12
query24	2.99	0.43	0.33
query25	0.11	0.05	0.04
query26	0.73	0.20	0.14
query27	0.05	0.03	0.04
query28	3.54	0.94	0.53
query29	12.52	4.12	3.31
query30	0.28	0.15	0.15
query31	2.77	0.59	0.30
query32	3.22	0.60	0.48
query33	3.09	3.28	3.13
query34	15.66	4.24	3.56
query35	3.52	3.50	3.54
query36	0.55	0.43	0.43
query37	0.09	0.07	0.06
query38	0.05	0.04	0.04
query39	0.03	0.04	0.03
query40	0.18	0.16	0.14
query41	0.09	0.03	0.04
query42	0.04	0.03	0.03
query43	0.04	0.04	0.04
Total cold run time: 96.61 s
Total hot run time: 24.96 s

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 100.00% (10/10) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 73.03% (29263/40072)
Line Coverage 56.62% (316250/558521)
Region Coverage 53.10% (263257/495799)
Branch Coverage 54.09% (115398/213352)

@HappenLee HappenLee 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.

LGTM

@github-actions github-actions Bot added the approved Indicates a PR has been approved by one committer. label Jul 10, 2026
@github-actions

Copy link
Copy Markdown
Contributor

PR approved by at least one committer and no changes requested.

@github-actions

Copy link
Copy Markdown
Contributor

PR approved by anyone and no changes requested.

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

Labels

approved Indicates a PR has been approved by one committer. reviewed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants