Skip to content

[fix](fe) Reject LARGEINT bucket of NTILE - #68030

Merged
jacktengg merged 1 commit into
apache:masterfrom
jacktengg:DORIS-28769
Sep 16, 2026
Merged

jacktengg merged 1 commit into
apache:masterfrom
jacktengg:DORIS-28769

Conversation

@jacktengg

@jacktengg jacktengg commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Problem Summary:
Frontend declared NTILE(LARGEINT) -> LARGEINT, but WindowFunctionNTile in backend always returns BIGINT, since the bucket index is computed with an int64 value. As a result, a legal-looking window query

select ntile(170141183460469231731687303715884105727) over (order by k) from t;

failed in the prepare phase with an internal error instead of a clear user error:

[INTERNAL_ERROR]Result type of ntile is not matched, planner expect LARGEINT, but get BIGINT

Fix:

  1. remove the LARGEINT signature of NTILE, so that every declared signature returns BIGINT and keeps consistent with backend;
  2. reject a LARGEINT bucket in checkLegalityBeforeTypeCoercion with an explicit AnalysisException, because backend computes the bucket index with an int64 value and can not handle a LARGEINT bucket;
  3. drop the redundant buckets field, which duplicated the first child and was not initialized when the expression is rebuilt by withChildren, and read the first argument through getArgument(0).

After the fix, the query above is rejected during analysis with The bucket of NTILE must be an integer within the range of BIGINT, but got LARGEINT, while an integer bucket (TINYINT/SMALLINT/INT/BIGINT) keeps working as before.

None

  • Test: Regression test / Unit Test
    • ./run-regression-test.sh --run -f regression-test/suites/query_p0/sql_functions/window_functions/test_ntile_function.groovy
  • Behavior changed: Yes. A LARGEINT bucket of NTILE is rejected during analysis with an explicit error message, instead of failing in the prepare phase with an internal type mismatch error.
  • Does this need documentation: No

What problem does this PR solve?

Issue Number: close #xxx

Related PR: #xxx

Problem Summary:

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

Problem Summary:
Frontend declared `NTILE(LARGEINT) -> LARGEINT`, but `WindowFunctionNTile` in backend always
returns BIGINT, since the bucket index is computed with an int64 value. As a result, a
legal-looking window query

    select ntile(170141183460469231731687303715884105727) over (order by k) from t;

failed in the prepare phase with an internal error instead of a clear user error:

    [INTERNAL_ERROR]Result type of ntile is not matched, planner expect LARGEINT, but get BIGINT

Fix:
1. remove the LARGEINT signature of NTILE, so that every declared signature returns BIGINT and
   keeps consistent with backend;
2. reject a LARGEINT bucket in `checkLegalityBeforeTypeCoercion` with an explicit
   AnalysisException, because backend computes the bucket index with an int64 value and can
   not handle a LARGEINT bucket;
3. drop the redundant `buckets` field, which duplicated the first child and was not initialized
   when the expression is rebuilt by `withChildren`, and read the first argument through
   `getArgument(0)`.

After the fix, the query above is rejected during analysis with
`The bucket of NTILE must be an integer within the range of BIGINT, but got LARGEINT`, while an
integer bucket (TINYINT/SMALLINT/INT/BIGINT) keeps working as before.

None

- Test: Regression test / Unit Test
    - `./run-regression-test.sh --run -f regression-test/suites/query_p0/sql_functions/window_functions/test_ntile_function.groovy`
    - `./run-fe-ut.sh --run org.apache.doris.nereids.trees.expressions.functions.window.NtileBucketTest`
- Behavior changed: Yes. A LARGEINT bucket of NTILE is rejected during analysis with an explicit
  error message, instead of failing in the prepare phase with an internal type mismatch error.
- 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?

@jacktengg

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 result: no blocking issues found at head cbfe7060eab84c0868c9476a0c661a70e91f46b4. This change looks good to merge based on static review.

Critical checkpoint conclusions:

  • Goal and proof: the patch rejects LARGEINT buckets during Nereids analysis before explicitly-castable signature resolution, removes the invalid LARGEINT return signature, and leaves every accepted signature returning BIGINT. The generic window translator therefore sends a BIGINT result/intermediate type, matching BE WindowFunctionNTile's fixed INT64 result. The two new regression cases cover both a parser-inferred LARGEINT and an in-range value explicitly typed LARGEINT; existing ordered positive cases continue to cover NTILE execution.
  • Scope and lifecycle: the two-file change is small and focused. Removing the duplicate buckets field and reading getArgument(0) aligns legality checks with the canonical child used by reconstruction, equality/hash, signature search, and translation. No stale-child or signature-cache path was found.
  • Concurrency, configuration, compatibility, and parallel paths: no concurrency/locking, configuration, persistence, transaction, data-write, observability, or memory-management behavior changes. There is one FE NTILE registry/translation chain and one BE registration. New-FE plans remain compatible with old and new BEs; no protocol or storage-format change is involved.
  • Runtime correctness and performance: positive BIGINT buckets, including the maximum value, cannot cause a bucket-driven divide by zero or overflow in the reachable BE arithmetic. The new FE checks are constant-time analysis work and introduce no hot-path regression.
  • Tests and results: the added cases use the required test { sql; exception } form and require no .out rows; existing positive output is deterministically ordered. Per the automated-review runner contract, I did not run builds or tests, so this conclusion is static and does not independently verify the author's reported test execution.
  • User focus: no additional review focus was provided; the full PR was reviewed.

@jacktengg

Copy link
Copy Markdown
Contributor Author

run buildall

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 0.00% (0/9) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17560	3056	3055	3055
q2	2089	253	230	230
q3	10244	905	541	541
q4	4673	255	212	212
q5	7665	594	393	393
q6	137	118	95	95
q7	517	507	395	395
q8	9263	940	939	939
q9	3548	2420	2453	2420
q10	6518	872	738	738
q11	396	209	186	186
q12	614	264	209	209
q13	18123	1539	1157	1157
q14	163	162	139	139
q15	q16	441	400	383	383
q17	1329	880	838	838
q18	3174	2324	2301	2301
q19	1247	940	834	834
q20	385	287	199	199
q21	5671	1819	1887	1819
q22	332	266	232	232
Total cold run time: 94089 ms
Total hot run time: 17315 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	3381	3326	3321	3321
q2	521	396	386	386
q3	2352	2356	2197	2197
q4	1220	1200	903	903
q5	2253	2188	2157	2157
q6	167	117	86	86
q7	1060	937	862	862
q8	1601	1412	1422	1412
q9	3232	3227	3201	3201
q10	1918	1881	1652	1652
q11	374	275	254	254
q12	462	446	351	351
q13	1485	1564	1162	1162
q14	179	169	158	158
q15	q16	398	402	364	364
q17	3709	3398	3324	3324
q18	4942	4525	5143	4525
q19	960	865	889	865
q20	1026	1006	839	839
q21	3876	3219	3270	3219
q22	391	360	309	309
Total cold run time: 35507 ms
Total hot run time: 31547 ms

@hello-stephen

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

query5	4258	419	360	360
query6	384	132	120	120
query7	4942	420	230	230
query8	300	125	130	125
query9	8703	2891	2928	2891
query10	381	214	174	174
query11	5386	1053	935	935
query12	120	70	70	70
query13	1188	409	304	304
query14	6011	2235	2144	2144
query14_1	2035	2029	2018	2018
query15	171	126	119	119
query16	918	382	350	350
query17	782	469	376	376
query18	2335	328	234	234
query19	168	132	112	112
query20	73	73	72	72
query21	204	105	89	89
query22	5495	5456	5450	5450
query23	6912	6425	6264	6264
query23_1	6179	6170	6133	6133
query24	7256	1140	773	773
query24_1	779	805	779	779
query25	399	275	219	219
query26	1217	230	126	126
query27	2795	427	241	241
query28	4667	1498	1479	1479
query29	903	399	342	342
query30	250	156	127	127
query31	816	402	333	333
query32	128	69	75	69
query33	445	218	180	180
query34	991	837	476	476
query35	409	413	345	345
query36	553	594	534	534
query37	118	86	73	73
query38	1021	863	830	830
query39	507	488	467	467
query39_1	486	484	472	472
query40	202	87	76	76
query41	54	51	50	50
query42	74	75	72	72
query43	240	244	218	218
query44	991	537	543	537
query45	115	105	97	97
query46	802	858	505	505
query47	758	778	714	714
query48	298	301	225	225
query49	531	244	194	194
query50	730	270	191	191
query51	8063	7999	7981	7981
query52	67	66	60	60
query53	190	191	147	147
query54	209	171	197	171
query55	80	57	67	57
query56	186	154	152	152
query57	681	647	683	647
query58	199	178	163	163
query59	1246	1259	1141	1141
query60	234	187	169	169
query61	116	115	108	108
query62	348	212	174	174
query63	177	142	139	139
query64	2748	631	554	554
query65	1686	1686	1655	1655
query66	1843	248	197	197
query67	9898	10020	9891	9891
query68	2794	1243	772	772
query69	339	222	200	200
query70	680	576	607	576
query71	235	184	178	178
query72	2239	1707	1494	1494
query73	653	594	341	341
query74	1572	1235	1156	1156
query75	1193	1122	965	965
query76	2278	720	499	499
query77	251	265	211	211
query78	3902	3725	3317	3317
query79	1205	799	577	577
query80	471	321	271	271
query81	414	154	135	135
query82	584	121	97	97
query83	303	206	197	197
query84	290	110	87	87
query85	747	328	296	296
query86	302	169	167	167
query87	1054	996	921	921
query88	2734	2096	2097	2096
query89	286	197	175	175
query90	1970	133	133	133
query91	128	114	96	96
query92	83	72	85	72
query93	1164	1062	695	695
query94	431	257	244	244
query95	513	321	227	227
query96	769	610	278	278
query97	1090	1061	1042	1042
query98	145	134	138	134
query99	418	358	312	312
Total cold run time: 174082 ms
Total hot run time: 82866 ms

@hello-stephen

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

query1	0.01	0.00	0.01
query2	0.07	0.04	0.03
query3	0.25	0.09	0.11
query4	1.60	0.09	0.11
query5	0.17	0.16	0.16
query6	1.26	0.68	0.68
query7	0.04	0.01	0.01
query8	0.05	0.03	0.03
query9	0.29	0.21	0.24
query10	0.37	0.35	0.36
query11	0.16	0.12	0.11
query12	0.15	0.12	0.12
query13	0.30	0.31	0.32
query14	0.47	0.47	0.47
query15	0.36	0.34	0.36
query16	0.22	0.26	0.22
query17	0.71	0.71	0.72
query18	0.19	0.17	0.17
query19	1.23	1.23	1.20
query20	0.02	0.01	0.01
query21	15.47	0.17	0.11
query22	5.06	0.05	0.04
query23	16.18	0.26	0.09
query24	3.02	0.31	0.25
query25	0.11	0.04	0.04
query26	0.79	0.17	0.12
query27	0.04	0.02	0.02
query28	3.64	0.57	0.26
query29	12.43	3.20	2.56
query30	0.27	0.11	0.12
query31	2.75	0.39	0.18
query32	3.50	0.34	0.23
query33	1.50	1.53	1.44
query34	15.37	2.24	1.79
query35	1.79	1.80	1.80
query36	0.46	0.29	0.30
query37	0.06	0.04	0.03
query38	0.05	0.03	0.03
query39	0.03	0.02	0.03
query40	0.12	0.07	0.07
query41	0.08	0.02	0.02
query42	0.04	0.02	0.02
query43	0.04	0.02	0.03
Total cold run time: 90.72 s
Total hot run time: 14.85 s

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 4.85% (8/165) 🎉
Increment coverage report
Complete coverage report

@jacktengg
jacktengg merged commit 093d6d1 into apache:master Sep 16, 2026
44 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

PR approved by anyone and no changes requested.

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

Copy link
Copy Markdown
Contributor

PR approved by at least one committer 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