Skip to content

[test](nereids) Replace flaky null stats case with unit test - #65445

Merged
morrySnow merged 3 commits into
apache:masterfrom
shuke987:fix-scale-num-nulls-ut
Jul 13, 2026
Merged

[test](nereids) Replace flaky null stats case with unit test#65445
morrySnow merged 3 commits into
apache:masterfrom
shuke987:fix-scale-num-nulls-ut

Conversation

@shuke987

@shuke987 shuke987 commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: N/A

Related PR: #62265

Problem Summary:

test_scale_num_nulls checks that table-level numNulls=3 is scaled to 1 when partition pruning selects 4 of 12 rows. The regression case executes EXPLAIN MEMO PLAN immediately after insert and analyze, but Cloud P0 reports the physical partition row count asynchronously. The planner can therefore observe a transient selected-partition row count of zero, while waiting for the real row count can take up to two minutes.

This change:

  • adds deterministic FE unit coverage that invokes StatsCalculator.computeOlapScan() with a three-partition OLAP scan;
  • fixes the table row count at 12, selected-partition row count at 4, and cached table-level column statistics at ndv=1, min=max=2, and numNulls=3;
  • verifies the final scan statistics have ndv=1, min=max=2, count=4, and scaled numNulls=1;
  • removes the timing-dependent Groovy regression case.

The unit test exercises the production partition-pruning statistics path using fixed in-memory inputs. It has no cluster, physical row-count reporting, polling, sleep, network, or storage dependency. Production behavior is unchanged.

Release note

None

Check List (For Author)

  • Test

    • Regression test
    • Unit Test
      • StatsCalculatorTest#testComputeOlapScanScalesNumNullsForSelectedPartitions: passed 3 consecutive runs
      • StatsCalculatorTest: 17 tests passed
    • Manual test
    • No need to test or manual test
  • 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

### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#62265

Problem Summary: The test_scale_num_nulls regression case checks selected-partition null-count scaling immediately after insert and analyze. In Cloud P0, the physical partition row count is reported asynchronously and can still be zero, while waiting for it can take up to two minutes. Extract the existing scaling formula into a package-private helper, cover the exact 12/4/3 to 1 calculation with a deterministic FE unit test, and remove the timing-dependent Groovy case. Planner behavior is unchanged.

### Release note

None

### Check List (For Author)

- Test: Unit Test
    - `StatsCalculatorTest#testScaleNumNullsForSelectedPartitions` passed three consecutive runs
    - Full `StatsCalculatorTest` passed 17 tests
- Behavior changed: No
- 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?

@shuke987

Copy link
Copy Markdown
Contributor Author

run buildall

@shuke987

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.

Reviewed PR 65445. I did not find a substantiated issue that needs an inline review comment.

Critical checkpoints:

  • Goal and test: the PR replaces a timing-dependent regression case for partition-pruned null-count scaling with deterministic FE unit coverage. The production formula is unchanged, and the new test verifies table count 12, selected count 4, and numNulls 3 scaling to 1.
  • Scope: the change is small and focused: helper extraction, one unit test, and removal of the flaky Groovy case.
  • Concurrency/lifecycle/config/persistence/data writes: not applicable; this PR does not add concurrent state, lifecycle ownership, config items, persisted formats, transaction paths, or write paths.
  • Compatibility and FE/BE protocol: not applicable; no serialized format, thrift field, or FE/BE interface changes.
  • Parallel paths: the helper remains called from the same partition-pruned OlapScan stats path as the previous inline code. Non-pruned table stats and MV fallback paths are not changed.
  • Conditional checks: the tableRowCount == 0 ? 1 : ... branch is preserved from the original code; no new special condition was introduced.
  • Tests and expected results: the deleted regression case had no .out file and depended on asynchronous physical row-count reporting; the replacement unit test directly exercises the extracted scaling logic. I did not see an expected-output issue.
  • Observability/performance: no new logging or metrics are needed for this test-only/helper extraction; the production hot path keeps the same arithmetic and allocation behavior.
  • Other issues: no additional correctness, style, or duplicate-review issue found.

User focus: no additional user-provided focus points were supplied.

Subagent conclusions:

  • optimizer-rewrite found no valuable optimizer/rewrite candidate and did not append findings.
  • tests-session-config found no valuable test/session/config candidate and did not append findings.
  • Final convergence round 1 ended with both live subagents replying NO_NEW_VALUABLE_FINDINGS for the same ledger and proposed final comment set with no inline comments.

Validation performed:

  • Read the required review prompt, repo code-review skill, required AGENTS files, existing review context, changed-file list, focus file, and shared ledger before diff review.
  • Used GitHub PR metadata/patch as authoritative because the local checkout lacks the base commit.
  • Reconfirmed current head 509ca74e437846fa0341a7e1d8be7c85b33bcac3, file list, and absence of existing inline comments before submission.
  • Verified the GitHub patch reverse-applies to the local PR head.
  • Ran git diff --check HEAD -- on the touched files successfully.

I did not run FE tests/build in this runner because .worktree_initialized, thirdparty/installed, and thirdparty/installed/bin/protoc are missing; per fe/AGENTS.md, FE build/test should stop until thirdparty dependencies are present.

@shuke987

Copy link
Copy Markdown
Contributor Author

/review

@shuke987

Copy link
Copy Markdown
Contributor Author

run buildall

@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 coverage regression in the replacement test. The new unit test is useful and deterministic, but it no longer proves the deleted SQL regression's full optimizer path from a partition predicate to pruned scan statistics.

Critical checkpoints:

  • Goal and test: the PR aims to replace a flaky regression case for selected-partition null-count scaling. The current test proves the already-pruned computeOlapScan branch scales 12/4/3 to 1, but it does not prove that where d = '2017-01-01' still reaches that branch with a pruned LogicalOlapScan.
  • Scope: the code change is small and focused, but deleting the regression removes planner-level coverage that should be replaced in a non-flaky way.
  • Concurrency/lifecycle/config/persistence/data writes: not applicable; no concurrent state, lifecycle ownership, config, persistence, transaction, or write path is changed.
  • Compatibility and FE/BE protocol: not applicable; no serialized format, thrift field, or FE/BE interface is changed.
  • Parallel paths: the production stats formula is unchanged. The issue is that the replacement test covers only the direct stats path, not the parallel planner/pruning path formerly covered by the regression.
  • Conditional checks: no new special condition is introduced; the preserved tableRowCount == 0 ? 1 : ... branch was not a concern.
  • Tests and expected results: the deleted Groovy case had no .out file and was timing-sensitive, but it did exercise predicate planning, partition pruning, and memo stats together. The replacement should keep deterministic unit coverage and add a non-flaky planner-level check for that integration.
  • Observability/performance: no observability or performance issue found.
  • Other issues: targeted checkstyle for StatsCalculatorTest.java passed; no duplicate inline comments existed.

User focus: no additional user-provided focus points were supplied.

Subagent conclusions:

  • optimizer-rewrite proposed OR-1; after main-agent verification it became the inline comment M-1.
  • tests-session-config reported no TS candidates; its no-finding note included a successful targeted Maven checkstyle pass.
  • Final convergence round 1 ended with both live subagents replying NO_NEW_VALUABLE_FINDINGS for the same ledger and one-comment proposed final set after M-1 was accepted.

Validation performed:

  • Read the required review prompt, repo code-review skill, required AGENTS files, existing review context, changed-file list, focus file, and shared ledger before diff review.
  • Used GitHub PR metadata/patch as authoritative because the local checkout lacks the base commit.
  • Reconfirmed current head 74b125ed09ed2018c699737c00b580dce619d72e, file list, and absence of existing inline comments before submission.
  • Ran targeted Maven checkstyle for src/test/java/org/apache/doris/nereids/stats/StatsCalculatorTest.java successfully.
  • Ran git diff --check HEAD -- on the touched files successfully.

I did not run FE unit tests/build in this runner because .worktree_initialized, thirdparty/installed, and thirdparty/installed/bin/protoc are missing; per fe/AGENTS.md, FE build/test should stop until thirdparty dependencies are present.

@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 correction for the review above: re-submitting the same accepted inline finding on the exact mocked getSelectedPartitionIds() line.

@shuke987

Copy link
Copy Markdown
Contributor Author

/review

@shuke987

Copy link
Copy Markdown
Contributor Author

run buildall

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

Review completed for PR 65445 at head ea04ab6.

I did not find any new non-duplicative inline issue to submit. The only meaningful concern I found is the planner-level coverage gap already raised in discussion_r3556961223: the deleted Groovy regression exercised SQL predicate planning, partition pruning, analyze-backed stats, and memo stats together, while the new unit test pre-stubs selected partitions and directly calls computeOlapScan. I am not duplicating that existing inline thread.

Checkpoint conclusions:

  • Goal and test proof: the new JUnit test does prove the direct computeOlapScan selected-partition null-scaling arithmetic: table row count 12, selected partition row count 4, table-level numNulls 3, resulting row count/count 4 and numNulls 1.
  • Scope: the PR is focused and test-only, adding one FE unit test and deleting one regression suite.
  • Concurrency, lifecycle, persistence, compatibility, configuration, and observability: no production code or runtime behavior is changed. The test scopes Env static mocking and restores/removes the ConnectContext thread-local in finally.
  • Parallel paths and coverage: the only coverage loss is the already-open planner-level regression coverage thread, so no new duplicate comment is submitted.
  • User focus: no additional user-provided focus was present.

Validation: static review only. I did not run builds or tests because the review prompt explicitly says this environment is only for review operations and not to attempt builds or code modifications.

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage `` 🎉
Increment coverage report
Complete coverage report

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17645	4073	4056	4056
q2	2033	324	200	200
q3	10297	1413	828	828
q4	4680	485	338	338
q5	7506	846	579	579
q6	183	168	134	134
q7	771	830	621	621
q8	9319	1617	1572	1572
q9	5550	4424	4365	4365
q10	6758	1811	1522	1522
q11	485	340	312	312
q12	699	553	421	421
q13	18108	3338	2720	2720
q14	272	261	243	243
q15	q16	793	777	705	705
q17	1019	1013	1004	1004
q18	7039	5678	5566	5566
q19	1321	1276	1084	1084
q20	779	662	524	524
q21	6128	2775	2641	2641
q22	454	382	316	316
Total cold run time: 101839 ms
Total hot run time: 29751 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	5105	4737	4786	4737
q2	287	327	215	215
q3	4991	5343	4654	4654
q4	2067	2158	1354	1354
q5	4915	4728	4652	4652
q6	240	193	133	133
q7	1932	1702	1507	1507
q8	2418	2085	2054	2054
q9	7756	7202	7167	7167
q10	4658	4598	4142	4142
q11	516	382	351	351
q12	734	747	524	524
q13	3023	3364	2749	2749
q14	270	280	252	252
q15	q16	679	694	611	611
q17	1282	1247	1267	1247
q18	7295	6852	6771	6771
q19	1107	1107	1075	1075
q20	2205	2191	1932	1932
q21	5232	4540	4365	4365
q22	541	438	408	408
Total cold run time: 57253 ms
Total hot run time: 50900 ms

@hello-stephen

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

query5	4332	666	509	509
query6	477	224	213	213
query7	4885	582	325	325
query8	340	197	174	174
query9	8786	4136	4089	4089
query10	474	334	302	302
query11	5950	2356	2177	2177
query12	158	104	104	104
query13	1285	609	439	439
query14	6271	5309	4932	4932
query14_1	4313	4293	4286	4286
query15	210	200	183	183
query16	1004	462	488	462
query17	949	772	596	596
query18	2444	483	358	358
query19	213	188	156	156
query20	117	113	108	108
query21	237	159	136	136
query22	13679	13582	13348	13348
query23	17523	16537	16192	16192
query23_1	16263	16373	16125	16125
query24	7510	1794	1297	1297
query24_1	1318	1317	1314	1314
query25	569	464	396	396
query26	1341	366	209	209
query27	2564	590	376	376
query28	4436	2038	2044	2038
query29	1114	631	513	513
query30	343	272	229	229
query31	1122	1090	998	998
query32	107	65	60	60
query33	549	332	261	261
query34	1187	1165	643	643
query35	768	785	690	690
query36	1418	1391	1181	1181
query37	153	116	96	96
query38	1878	1758	1638	1638
query39	936	912	880	880
query39_1	872	878	921	878
query40	239	155	137	137
query41	62	65	60	60
query42	91	93	99	93
query43	322	322	279	279
query44	1389	783	809	783
query45	201	185	176	176
query46	1072	1190	759	759
query47	2401	2336	2269	2269
query48	377	427	309	309
query49	592	427	311	311
query50	1101	409	315	315
query51	10925	10868	10942	10868
query52	91	86	76	76
query53	253	278	201	201
query54	284	258	234	234
query55	78	69	65	65
query56	298	287	282	282
query57	1438	1403	1293	1293
query58	307	258	253	253
query59	1568	1623	1415	1415
query60	300	267	263	263
query61	156	147	149	147
query62	688	660	582	582
query63	242	200	206	200
query64	2842	1001	860	860
query65	4828	4763	4780	4763
query66	1820	515	379	379
query67	29489	29463	29358	29358
query68	3153	1527	954	954
query69	403	310	268	268
query70	1066	937	960	937
query71	345	313	312	312
query72	3058	2698	2427	2427
query73	820	813	433	433
query74	5129	4945	4732	4732
query75	2614	2597	2233	2233
query76	2302	1175	782	782
query77	356	369	280	280
query78	12312	12332	11635	11635
query79	1454	1125	739	739
query80	1289	535	467	467
query81	552	318	283	283
query82	611	156	120	120
query83	377	320	299	299
query84	333	158	130	130
query85	952	583	529	529
query86	432	290	288	288
query87	1833	1812	1767	1767
query88	3695	2820	2801	2801
query89	455	411	355	355
query90	1935	206	192	192
query91	204	186	158	158
query92	58	59	53	53
query93	1755	1540	1045	1045
query94	697	365	279	279
query95	779	500	485	485
query96	1100	814	358	358
query97	2684	2703	2522	2522
query98	215	205	199	199
query99	1153	1179	1021	1021
Total cold run time: 266174 ms
Total hot run time: 180151 ms

@hello-stephen

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

query1	0.01	0.01	0.01
query2	0.10	0.05	0.05
query3	0.25	0.17	0.14
query4	1.61	0.14	0.14
query5	0.24	0.24	0.23
query6	1.25	1.08	1.04
query7	0.04	0.01	0.01
query8	0.06	0.04	0.04
query9	0.38	0.30	0.32
query10	0.60	0.55	0.53
query11	0.20	0.14	0.13
query12	0.18	0.15	0.15
query13	0.46	0.48	0.46
query14	1.02	1.02	0.99
query15	0.62	0.59	0.60
query16	0.31	0.32	0.32
query17	1.08	1.10	1.12
query18	0.23	0.21	0.20
query19	2.02	1.89	1.98
query20	0.01	0.01	0.01
query21	15.45	0.20	0.12
query22	4.94	0.05	0.06
query23	16.16	0.31	0.13
query24	3.00	0.39	0.32
query25	0.11	0.05	0.04
query26	0.71	0.20	0.16
query27	0.04	0.04	0.04
query28	3.56	0.91	0.54
query29	12.51	4.09	3.23
query30	0.28	0.16	0.16
query31	2.77	0.60	0.31
query32	3.22	0.59	0.48
query33	3.26	3.14	3.12
query34	15.57	4.27	3.52
query35	3.53	3.58	3.55
query36	0.56	0.43	0.45
query37	0.09	0.07	0.06
query38	0.05	0.04	0.04
query39	0.04	0.03	0.03
query40	0.19	0.17	0.16
query41	0.08	0.03	0.04
query42	0.04	0.02	0.02
query43	0.04	0.04	0.03
Total cold run time: 96.87 s
Total hot run time: 24.9 s

@morrySnow
morrySnow merged commit 8b52996 into apache:master Jul 13, 2026
32 of 33 checks passed
@github-actions github-actions Bot added the approved Indicates a PR has been approved by one committer. label Jul 13, 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.

yiguolei pushed a commit that referenced this pull request Jul 16, 2026
…est (#65656)

### What problem does this PR solve?

Related PR: #65445

Problem Summary:

Backport #65445 to branch-4.1.

The regression case `test_scale_num_nulls` depends on asynchronously
visible physical row counts. When the physical row count is still 0,
Nereids scales the selected-partition column statistics to 0 even though
the injected partition/table statistics are correct, making the case
flaky.

Replace the environment-dependent Groovy regression case with a
deterministic FE unit test that directly constructs the partition/table
statistics and verifies selected-partition scaling, including row count,
NDV, min/max, count, and numNulls.

### Coverage rationale

- This is a branch backport of merged PR #65445. The same planner-level
coverage concern was raised in [the upstream review
thread](#65445 (comment)),
then explicitly resolved by a maintainer before the PR was approved and
merged.
- The independent behavior introduced with #62265 is selected-partition
statistics scaling. The replacement test invokes the real
`StatsCalculator.computeOlapScan()` path and verifies row count, NDV,
min/max, count, and `numNulls`. SQL predicate-to-partition selection
remains covered by `PruneOlapScanPartitionTest` on this release branch.
- The removed cluster case sampled the strict physical partition row
count immediately after insert/analyze. In Cloud P0 that value can
remain 0 for up to two minutes even when table-level column statistics
are correct. Retaining the case or waiting for that report would
preserve the flake or add up to two minutes to the suite.
- `SHOW COLUMN STATS` was only failure diagnostics, and memo text
formatting was not an independent assertion target of this case.

### Release note

None

### Check List (For Author)

- Test
    - [ ] Regression test
    - [x] 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

  Local validation:
-
`StatsCalculatorTest#testComputeOlapScanScalesNumNullsForSelectedPartitions`:
passed (1 test)
  - `StatsCalculatorTest`: passed (17 tests)
  - `mvn -pl fe-core -am checkstyle:check`: passed (0 violations)

- Behavior changed:
    - [x] No.
    - [ ] Yes.

- Does this need documentation?
    - [x] No.
    - [ ] Yes.

### Check List (For Reviewer who merge this PR)

- [ ] Confirm the release note
- [ ] Confirm test cases
- [ ] Confirm document
- [ ] Add branch pick label
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. dev/4.0.x dev/4.1.4-merged reviewed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants