Skip to content

[fix](be) Restrict page index pruning to surviving scan rows - #68279

Draft
mrhhsg wants to merge 9 commits into
apache:masterfrom
mrhhsg:fix/scan-stats-counted-after-key-range
Draft

mrhhsg wants to merge 9 commits into
apache:masterfrom
mrhhsg:fix/scan-stats-counted-after-key-range

Conversation

@mrhhsg

@mrhhsg mrhhsg commented Sep 20, 2026 •

Copy link
Copy Markdown
Member

What problem does this PR solve?

Issue Number: None

Problem Summary:

After key-range or index pruning leaves only a few rows, page-index pruning still used whole-segment ranges. Fixing RowsStatsFiltered accounting alone did not avoid parsing and evaluating unrelated page ZoneMaps or reading unrelated Bloom filters.

This PR retains the exact surviving-row accounting and fixes the actual work:

  • Select sorted, unique candidate pages by intersecting the surviving Roaring bitmap with the current row ranges, using each column's own ordinal index. Dense candidates advance sequentially; sparse candidates seek past bitmap gaps without enumerating every surviving row.
  • Share candidate-page selection across ordinary ZoneMap, expression ZoneMap and Bloom-filter filtering. Carry each column's narrowed ranges into the next column/stage, and keep the final bitmap intersection.
  • Preserve unsupported/disabled expression behavior and synthetic constant readers without physical page indexes. Reject inconsistent ZoneMap/ordinal page counts with Corruption.
  • Expose ZoneMapIndexPagesEvaluated and BloomFilterIndexPagesEvaluated so the work can be distinguished from filtered-row accounting. ZoneMap evaluations count column-pages, including expression evaluation, rather than unique physical pages.
  • Retain removal of the unused, always-zero RowsZoneMapRuntimePredicateFiltered counter from the original accounting fix.

Evidence: On master 3750a819a2af157ad539d947bc301ff0f806b928 plus the original counter-only changes, an instrumented predicate was evaluated on all 8 pages for both a one-row point lookup and two disjoint keys. The same assertions pass after this fix with exactly 1 and 2 evaluations. SQL regression on 200,000 rows observes 1 ZoneMap evaluation for the point lookup versus 13 for the no-key-range control, 2 for disjoint keys, and 1 Bloom-filter evaluation for the point lookup. A rejecting expression evaluates and rejects only the candidate page.

Whole-index ZoneMap metadata loading is unchanged. The RELEASE microbenchmark below measures actual page-index pruning, not end-to-end query latency or disk-cold I/O.

RELEASE benchmark

Added be/benchmark/page_index_pruning/README.md, a real ColumnWriter/ColumnReader benchmark and reproducible run/comparison scripts. The identical source selects the real old/new reader API at compile time. Compare counter-only baseline 7f9400797d5 against fix 27896b5cbe6, with identical benchmark changes, Clang 20 -O3, pinned CPUs, and the same third-party dependencies.

The 144-case matrix covers ZoneMap/Bloom Filter, 8/128/4096 pages, six candidate shapes, half/all page matches, and warm/fresh readers. Before timing, it checks the complete surviving bitmap, ordinal boundaries, and actual predicate calls. Counting predicates are not used inside the timed loop. A/B/B/A, five repetitions per run, 0.1 seconds minimum, yields 10 samples per implementation/case (2,880 total).

Example: 4096 pages, one surviving candidate row, every page matches v = 0; median CPU microseconds:

Index Reader Counter-only Candidate pages Ratio
ZoneMap Warm 487.642 0.363 ~1345x
Bloom Filter Warm 1382.526 0.946 ~1461x
ZoneMap FreshReader 1479.080 973.007 ~1.52x
Bloom Filter FreshReader 1444.951 63.543 ~22.74x

Actual page evaluations drop from 4096 to 1. FreshReader includes reader creation/index decoding but uses warm file/page caches: it is not a disk-cold benchmark. The deliberately controlled constant-per-page INT data is not a general SQL workload. Alternating matching pages additionally expose the old repeated RowRanges union cost, so large ratios must not be attributed only to predicate evaluation or presented as query speedups.

Full-candidate controls are retained. The shared host and CPU scaling caused substantial noise in a few short cases; eight suspicious 8-page warm cases were rerun A/B/B/A on another pinned CPU, seven repetitions and 0.5 seconds minimum (224 additional samples). The worst repeated median increase was ~4.2% (~53 ns) when all eight pages contain candidates and half match; full-row controls increased by up to ~2.5%. This is not a claim that every workload improves. Raw JSON, per-case ranges, environment/build records and exact binaries were retained locally.

Release note

Avoid redundant ZoneMap and Bloom-filter page evaluations after key-range/index pruning, while keeping filtered-row profile counters accurate for sparse candidate rows. Add page-index evaluation counters to query profiles.

Check List (For Author)

  • Test:
    • Unit Test: ./run-be-ut.sh --run --filter='SegmentIterator*:*ZoneMap*:*ColumnReader*:*OrdinalPageIndex*' -j32 — 269 ASAN tests passed. Includes actual predicate-call instrumentation, sparse/same-page/empty candidates, cross-column pruning, randomized candidate-page oracle checks, expression enabled/disabled paths, inconsistent index metadata, and synthetic constant readers.
    • Regression test: point_lookup_zone_map_profile — generated the golden file using -forceGenOut, then reran normally with an isolated cluster configuration; query results and profile assertions passed.
    • Regression test: test_expr_zonemap_pruning, test_zone_map_delete, test_bloom_filter_is_not_null passed on the isolated cluster.
    • Build: ./build.sh --be --fe -j24 (ASAN).
    • RELEASE benchmark: ./build.sh --benchmark -j32 on both revisions; 144-case preflight on both plus 2,880 matrix / 224 focused timing samples, no skip/error. Fresh benchmark-only packaging needs the documented local bin/conf staging. The shared benchmark entry point also needed three stale Variant API uses adapted; no product changes were needed for the benchmark.
    • Formatting, build-header hygiene, shell syntax, comparison-script positive/negative checks, and git diff --check.
    • New benchmark header clang-tidy passes with the same documented analysis-only overlay. Full shared-main analysis still reports an existing unused _ in Example1, outside changed lines.
    • Static analysis: the unmodified checker is blocked by an existing unmatched NOLINTEND in be/src/core/types.h:576 on the base revision. A local-only VFS overlay removes that lint directive for analysis, with a toolchain resource-directory wrapper; no product/header workaround is included in this PR. With this analysis-only overlay, the checker passed with zero changed-line diagnostics.
  • Behavior changed:
    • Yes. Query results and storage format are unchanged; page-index work is restricted to surviving candidates and profiles expose the actual evaluation counts.
  • Does this need documentation?
    • Yes. Benchmark setup, coverage, limits and reproducible commands are included in be/benchmark/page_index_pruning/README.md.

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

@mrhhsg

mrhhsg commented Sep 20, 2026

Copy link
Copy Markdown
Member 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.

Review conclusion: request changes.

The PR correctly fixes the contiguous point-lookup accounting case and safely removes the dead runtime-predicate counter, but the new min/max seed is only a dense envelope. With disjoint key ranges or sparse cache/index survivors, RowsStatsFiltered and RowsBloomFilterFiltered still charge rows already removed by the earlier bitmap. The final row bitmap/output remains correct, so this is a profile-accounting correctness issue rather than a row-result issue.

Critical checkpoints:

  • Goal: partially achieved; contiguous point lookup is fixed, but sparse/disjoint candidates are not accounted exactly.
  • Scope/focus: the change is focused; no additional user focus was supplied.
  • Concurrency/lifecycle: no new threads, shared mutable state, lock ordering, or special lifecycle were introduced.
  • Configuration/compatibility: no config, FE-BE protocol, storage-format, transaction, or rolling-upgrade change. The removed profile counter had no live repository consumers and was always zero from the duplicated intersection.
  • Parallel paths: segment-level and expression zone-map counters remain wired; the remaining issue is the per-segment condition-range path.
  • Error/memory/data correctness: no new unchecked Status, allocation, delete-bitmap, version, or output-row defect was found.
  • Tests: the added BE and regression tests cover a contiguous point lookup and full-scan zone-map pruning, but not disjoint key/cache/index survivor sets; the regression test also has a trailing DROP TABLE contrary to the repository debugging convention.
  • Validation: static review only; builds and tests were not run per the review prompt.

Please address the inline sparse-accounting and regression-test cleanup comments, then add a disjoint-range counter test before re-review.

@mrhhsg

mrhhsg commented Sep 22, 2026

Copy link
Copy Markdown
Member Author

/review

@github-actions

Copy link
Copy Markdown
Contributor

Codex automated review failed and did not complete.

Error: Codex completed, but no new pull request review was submitted for the current head SHA.
Workflow run: https://github.com/apache/doris/actions/runs/35673575962

Please inspect the workflow logs and rerun the review after the underlying issue is resolved.

@mrhhsg mrhhsg changed the title [fix](scan) Stop counting rows the key range already pruned as zone-map filtered [fix](be) Restrict page index pruning to surviving scan rows Sep 22, 2026
@mrhhsg
mrhhsg force-pushed the fix/scan-stats-counted-after-key-range branch from 6025c81 to 27896b5 Compare September 22, 2026 02:12
mrhhsg added a commit to mrhhsg/doris that referenced this pull request Sep 22, 2026
### What problem does this PR solve?

Issue Number: None

Related PR: apache#68279

Problem Summary: Correct filtered-row counters alone do not avoid page-index
work on rows already removed by key ranges or other indexes. On an eight-page
segment, an instrumented point lookup still evaluated all eight ZoneMaps.
Select candidate pages from the surviving bitmap and current row ranges using
each column's ordinal index, and share that selection across ordinary ZoneMap,
expression ZoneMap and Bloom-filter pruning. Carry reduced ranges across columns,
preserve synthetic readers without physical pages, and retain exact sparse-row
accounting. The point/disjoint-key tests now evaluate one/two pages respectively.

### Release note

Skip redundant ZoneMap and Bloom-filter page evaluations after key-range/index
pruning and expose the actual page-index evaluation counts in query profiles.

### Check List (For Author)

- Test:
    - Unit Test: 269 focused ASAN BE tests passed, including candidate-page oracle,
      sparse/empty rows, expression flags, corrupt metadata and synthetic readers.
    - Regression test: point_lookup_zone_map_profile (generated output and normal
      rerun), test_expr_zonemap_pruning, test_zone_map_delete,
      test_bloom_filter_is_not_null passed on an isolated local cluster.
    - Build: ./build.sh --be --fe -j24 (ASAN).
    - Formatting, build hygiene and git diff --check passed.
    - Static analysis: see PR body for existing base-header/toolchain blockers
      and the local-only validation overlay (zero changed-line diagnostics).
      No RELEASE timing benchmark.
- Behavior changed: Yes (same query results and storage format; less page-index
  work and new profile counters).
- Does this need documentation: No
@mrhhsg

mrhhsg commented Sep 22, 2026

Copy link
Copy Markdown
Member Author

/review

@github-actions

Copy link
Copy Markdown
Contributor

Codex automated review failed and did not complete.

Error: Codex completed, but no new pull request review was submitted for the current head SHA.
Workflow run: https://github.com/apache/doris/actions/runs/35678741654

Please inspect the workflow logs and rerun the review after the underlying issue is resolved.

@mrhhsg

mrhhsg commented Sep 22, 2026

Copy link
Copy Markdown
Member Author

Local pipeline review — ✅ PASS

schema: doris-repo-review/v1
status: PASS
pr: apache/doris#68279
commit: c92b9b836e07a2691de61575d93a50be3c7eb20c
base: 14c957e048bfb3617f8cb23bc39db712089fb98f
reviewed_at: 2026-09-22T12:07+08:00
reviewer: mrhhsg
model: gpt-6-astra
effort: xhigh
findings: {blocker: 0, major: 0, minor: 0, nit: 0}
rounds: 1
converged: true

Notes for maintainers

  • Static review only: builds, unit/regression tests, benchmark timings, and merged-tree CI were not independently validated in this run.

Reviewed locally with the doris-repo-review pipeline. Repository policy may accept this receipt for the matching commit; it is not a human Apache approval.

mrhhsg added a commit to mrhhsg/doris that referenced this pull request Sep 24, 2026
### What problem does this PR solve?

Issue Number: None

Related PR: apache#68279

Problem Summary: Correct filtered-row counters alone do not avoid page-index
work on rows already removed by key ranges or other indexes. On an eight-page
segment, an instrumented point lookup still evaluated all eight ZoneMaps.
Select candidate pages from the surviving bitmap and current row ranges using
each column's ordinal index, and share that selection across ordinary ZoneMap,
expression ZoneMap and Bloom-filter pruning. Carry reduced ranges across columns,
preserve synthetic readers without physical pages, and retain exact sparse-row
accounting. The point/disjoint-key tests now evaluate one/two pages respectively.

### Release note

Skip redundant ZoneMap and Bloom-filter page evaluations after key-range/index
pruning and expose the actual page-index evaluation counts in query profiles.

### Check List (For Author)

- Test:
    - Unit Test: 269 focused ASAN BE tests passed, including candidate-page oracle,
      sparse/empty rows, expression flags, corrupt metadata and synthetic readers.
    - Regression test: point_lookup_zone_map_profile (generated output and normal
      rerun), test_expr_zonemap_pruning, test_zone_map_delete,
      test_bloom_filter_is_not_null passed on an isolated local cluster.
    - Build: ./build.sh --be --fe -j24 (ASAN).
    - Formatting, build hygiene and git diff --check passed.
    - Static analysis: see PR body for existing base-header/toolchain blockers
      and the local-only validation overlay (zero changed-line diagnostics).
      No RELEASE timing benchmark.
- Behavior changed: Yes (same query results and storage format; less page-index
  work and new profile counters).
- Does this need documentation: No

Claude-Session: https://claude.ai/code/session_018ZrdaZUYBhBJtmsmJwzxkQ
@mrhhsg
mrhhsg force-pushed the fix/scan-stats-counted-after-key-range branch from c92b9b8 to 3000ffc Compare September 24, 2026 05:20
@mrhhsg

mrhhsg commented Oct 9, 2026

Copy link
Copy Markdown
Member Author

run buildall

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17593	5611	5516	5516
q2	2075	306	249	249
q3	10292	1409	835	835
q4	4679	476	346	346
q5	7452	804	533	533
q6	190	184	157	157
q7	776	807	604	604
q8	9267	1372	1149	1149
q9	5722	4443	4424	4424
q10	6839	1300	1028	1028
q11	454	257	240	240
q12	638	399	284	284
q13	18067	3063	2371	2371
q14	274	263	244	244
q15	q16	750	730	659	659
q17	1178	743	576	576
q18	7097	6238	6184	6184
q19	1232	956	612	612
q20	391	334	235	235
q21	6070	2580	2623	2580
q22	382	343	289	289
Total cold run time: 101418 ms
Total hot run time: 29115 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	6718	6678	6779	6678
q2	746	616	537	537
q3	5526	5691	5258	5258
q4	2049	2198	1595	1595
q5	5856	5691	5863	5691
q6	271	190	149	149
q7	2233	1975	1909	1909
q8	3138	2758	2624	2624
q9	8210	8155	7893	7893
q10	3666	3599	3266	3266
q11	579	410	373	373
q12	661	698	489	489
q13	2729	3071	2391	2391
q14	278	291	256	256
q15	q16	659	687	616	616
q17	7742	6940	6858	6858
q18	13063	12261	12995	12261
q19	916	791	789	789
q20	2166	2190	1927	1927
q21	5771	4697	4777	4697
q22	518	465	401	401
Total cold run time: 73495 ms
Total hot run time: 66658 ms

@hello-stephen

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

query5	4307	570	452	452
query6	427	202	193	193
query7	4808	441	221	221
query8	325	187	166	166
query9	8793	4005	3954	3954
query10	480	311	260	260
query11	6030	3395	3167	3167
query12	143	101	80	80
query13	1244	427	307	307
query14	6543	4683	4482	4482
query14_1	4226	4242	4202	4202
query15	201	201	182	182
query16	948	437	453	437
query17	862	683	542	542
query18	2418	420	306	306
query19	199	160	135	135
query20	80	79	79	79
query21	207	133	108	108
query22	12995	12959	12827	12827
query23	13303	12580	12139	12139
query23_1	12254	12199	12245	12199
query24	7120	832	477	477
query24_1	479	472	463	463
query25	536	416	366	366
query26	1310	257	144	144
query27	2755	446	272	272
query28	4613	1963	1954	1954
query29	1558	601	455	455
query30	298	215	183	183
query31	894	753	646	646
query32	140	88	93	88
query33	535	296	245	245
query34	951	842	502	502
query35	785	745	643	643
query36	816	809	730	730
query37	121	98	89	89
query38	1803	1755	1671	1671
query39	690	705	671	671
query39_1	646	654	660	654
query40	210	113	92	92
query41	62	64	61	61
query42	88	80	82	80
query43	365	379	318	318
query44	1293	686	697	686
query45	186	181	165	165
query46	844	953	565	565
query47	2982	3066	2945	2945
query48	296	308	212	212
query49	564	403	293	293
query50	676	272	211	211
query51	10246	10482	10072	10072
query52	82	76	68	68
query53	189	212	151	151
query54	229	186	179	179
query55	70	68	68	68
query56	222	207	218	207
query57	1590	1595	1567	1567
query58	260	271	273	271
query59	2342	2347	2119	2119
query60	279	213	224	213
query61	150	148	144	144
query62	394	348	285	285
query63	200	159	164	159
query64	2740	908	790	790
query65	3448	3367	3336	3336
query66	1798	418	344	344
query67	20135	20024	19980	19980
query68	2985	990	602	602
query69	373	278	246	246
query70	910	861	833	833
query71	296	231	202	202
query72	2759	2630	2235	2235
query73	505	526	296	296
query74	4570	4459	4284	4284
query75	2336	2267	1974	1974
query76	2302	1013	588	588
query77	354	387	301	301
query78	8951	9086	8531	8531
query79	887	908	528	528
query80	534	424	339	339
query81	547	328	276	276
query82	577	134	113	113
query83	296	194	180	180
query84	311	123	103	103
query85	818	410	359	359
query86	316	242	282	242
query87	2026	1937	1807	1807
query88	3638	2726	2697	2697
query89	333	291	253	253
query90	1919	183	183	183
query91	161	147	125	125
query92	87	88	91	88
query93	988	986	556	556
query94	446	312	274	274
query95	586	407	326	326
query96	681	531	237	237
query97	2475	2431	2322	2322
query98	160	148	144	144
query99	777	757	651	651
Total cold run time: 233402 ms
Total hot run time: 151489 ms

@hello-stephen

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

query1	0.01	0.01	0.01
query2	0.10	0.05	0.05
query3	0.26	0.11	0.11
query4	1.61	0.12	0.13
query5	0.28	0.24	0.26
query6	1.17	0.69	0.67
query7	0.04	0.01	0.01
query8	0.05	0.03	0.04
query9	0.42	0.36	0.35
query10	0.57	0.62	0.60
query11	0.20	0.14	0.15
query12	0.20	0.15	0.14
query13	0.48	0.50	0.49
query14	0.97	0.98	0.97
query15	0.62	0.61	0.59
query16	0.36	0.37	0.36
query17	1.16	1.12	1.14
query18	0.22	0.21	0.21
query19	2.16	1.98	1.98
query20	0.02	0.01	0.01
query21	15.51	0.27	0.13
query22	4.39	0.04	0.05
query23	16.30	0.31	0.11
query24	3.23	0.53	0.39
query25	0.11	0.06	0.04
query26	1.04	0.26	0.15
query27	0.04	0.03	0.04
query28	1.86	0.60	0.41
query29	12.55	4.14	3.27
query30	0.29	0.14	0.14
query31	2.79	0.58	0.34
query32	3.23	0.61	0.53
query33	3.11	3.31	3.29
query34	15.43	3.94	3.40
query35	3.37	3.34	3.34
query36	0.56	0.44	0.46
query37	0.10	0.07	0.06
query38	0.05	0.04	0.03
query39	0.04	0.03	0.03
query40	0.16	0.15	0.14
query41	0.08	0.03	0.03
query42	0.03	0.02	0.02
query43	0.04	0.03	0.03
Total cold run time: 95.21 s
Total hot run time: 24.59 s

@mrhhsg
mrhhsg force-pushed the fix/scan-stats-counted-after-key-range branch from 3000ffc to 725f2f6 Compare October 18, 2026 14:54
mrhhsg added a commit to mrhhsg/doris that referenced this pull request Oct 18, 2026
Issue Number: None

Related PR: apache#68279

Problem Summary: Correct filtered-row counters alone do not avoid page-index
work on rows already removed by key ranges or other indexes. On an eight-page
segment, an instrumented point lookup still evaluated all eight ZoneMaps.
Select candidate pages from the surviving bitmap and current row ranges using
each column's ordinal index, and share that selection across ordinary ZoneMap,
expression ZoneMap and Bloom-filter pruning. Carry reduced ranges across columns,
preserve synthetic readers without physical pages, and retain exact sparse-row
accounting. The point/disjoint-key tests now evaluate one/two pages respectively.

Skip redundant ZoneMap and Bloom-filter page evaluations after key-range/index
pruning and expose the actual page-index evaluation counts in query profiles.

- Test:
    - Unit Test: 269 focused ASAN BE tests passed, including candidate-page oracle,
      sparse/empty rows, expression flags, corrupt metadata and synthetic readers.
    - Regression test: point_lookup_zone_map_profile (generated output and normal
      rerun), test_expr_zonemap_pruning, test_zone_map_delete,
      test_bloom_filter_is_not_null passed on an isolated local cluster.
    - Build: ./build.sh --be --fe -j24 (ASAN).
    - Formatting, build hygiene and git diff --check passed.
    - Static analysis: see PR body for existing base-header/toolchain blockers
      and the local-only validation overlay (zero changed-line diagnostics).
      No RELEASE timing benchmark.
- Behavior changed: Yes (same query results and storage format; less page-index
  work and new profile counters).
- Does this need documentation: No

Claude-Session: https://claude.ai/code/session_018ZrdaZUYBhBJtmsmJwzxkQ
mrhhsg added a commit to mrhhsg/doris that referenced this pull request Oct 18, 2026
### What problem does this PR solve?

Issue Number: None

Related PR: apache#68279

Problem Summary: Rebasing the page-index pruning change onto the current master
required two test adaptations. `StorageReadOptions` now requires the statistics
reference in its constructor instead of a default-constructed object, and
`Segment::get_column_reader` was replaced by `get_column_reader_for_pruning`.
The stub `ColumnIterator` in the candidate-pushdown test also follows the new
`get_row_ranges_by_zone_map` signature that receives the surviving row bitmap.

### Release note

None

### Check List (For Author)

- Test: Unit Test
- Behavior changed: No
- Does this need documentation: No
@mrhhsg

mrhhsg commented Oct 18, 2026

Copy link
Copy Markdown
Member 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 all 15 changed paths at 725f2f6f97363329234a734bbd06c50abe825315 using the supplied aggregate diff. No new substantiated findings; no previously reported blocking finding remains applicable. Review converged in 1 round: both complete-scope reviewers and the additional sparse-integration reviewer returned NO_NEW_VALUABLE_FINDINGS, and all candidate/risk checks have evidence-backed dispositions.

Critical checkpoint conclusions:

  • Goal and proof: candidate selection intersects the surviving bitmap with current ranges using each column's ordinal index. Ordinary ZoneMap, expression ZoneMap and Bloom filtering retain conservative page ranges and intersect them into the original bitmap. Alive-row cardinality prevents sparse gaps from inflating filtered-row counters. Unit tests instrument actual predicate calls and compare selection with an independent full-page oracle; SQL/profile tests cover the intended behavior. These tests were inspected, not executed here.
  • Scope and reuse: the shared selector covers all three index paths, and the changes stay focused on pruning, profile statistics, API forwarding and tests.
  • Concurrency and locking: traversal state is local; shared physical indexes retain existing call-once loading. Scanner statistics retain reader ownership and publish once through the existing close guard into atomic profile counters. No new lock order or blocking work under locks is introduced.
  • Lifecycle and memory: readers and temporary iterators/vectors retain existing ownership and Status-exit cleanup. Variant forwarding preserves its reader owner. No new global/static initialization dependency or persistent owner cycle was found.
  • Configuration: no configuration item is added. The existing expression-filter option still preserves input ranges when disabled.
  • Compatibility: these are internal C++ API updates, with all in-tree callers and overrides updated. No storage-format, wire-protocol, or shipped dependency change is introduced; query result semantics are preserved by the intersection invariant. The unused runtime-predicate profile counter is removed and two page-evaluation counters are added.
  • Thrift/protobuf: no generated schema or field/enum ID changes.
  • Parallel paths: ordinary, expression and Bloom paths are covered, including constant readers, sparse Variant fallback and complex-column no-op paths. Shared cloud/local scanning uses the same implementation. Synthetic readers skip physical index access; this checkout's nested-group provider cannot populate flattened child readers.
  • Conditional/error paths: empty candidates skip work; unsupported/disabled expression cases preserve their fallback. ZoneMap/ordinal count mismatch fails with Corruption before indexing. Changed load/parse calls propagate Status failures.
  • Test coverage: point, disjoint, same-page and empty candidates, rejection, cross-column narrowing, expression enable/disable, synthetic fallback, corrupted metadata and randomized selection are covered in source. Additional cases for disjoint/rejecting Bloom filters and deliberately different column page layouts would strengthen regression coverage; the shared selector and subset-intersection logic were independently traced for those mechanisms.
  • Expected results: all nine SQL golden sections agree with the deterministic queries, including the ordered disjoint-key projection. ProfileAction waits for complete profiles and requested counter names. Both tables are dropped before creation and preserved afterward. Golden-file generation provenance was not reproduced.
  • Observability: new ZoneMap/Bloom page counters are initialized, incremented on the relevant candidate-page work and collected into the scan profile. Existing expression rejection counters remain available; no heavy INFO logging is added.
  • Transactions and persistence: read pruning does not add writes, metadata mutations or EditLog changes. Existing version/delete restrictions remain ahead of candidate filtering.
  • Data modification/atomicity: no write or commit path changes; no new crash-recovery operation or atomicity requirement.
  • FE-BE variables: none added.
  • Performance: sparse selection skips bitmap gaps instead of enumerating surviving rows or visiting every page; ascending page IDs avoid repeated range unions. Whole-index ZoneMap metadata loading remains. Author-reported build, test and benchmark results were not independently reproduced, and pruning microbenchmarks are not treated as end-to-end query speedups.
  • Other issues: final checks of forward/reverse scans, count-shaped index bitmaps, delete predicates, synthetic readers, index alignment, removed counter references and updated virtual APIs found no additional substantiated issue.

Existing review context: discussion_r4057083753's sparse counter overcount is fixed by exact alive-row deltas and covered by DisjointKeyRangesOnlyCountAliveRows; discussion_r4057083754's trailing DROP is removed. Neither is reposted. The user focus file contains no additional requested focus.

Validation limits: static review only, as required by the review contract. No builds, tests, benchmarks, release-binary ABI audit or source edits were performed. External implementations absent from this checkout were not assessed. No unresolved review candidate or uncovered changed path remains.

Review converged after 1 round(s).

@mrhhsg

mrhhsg commented Oct 18, 2026

Copy link
Copy Markdown
Member Author

run buildall

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17597	5638	5547	5547
q2	2103	320	285	285
q3	10232	1429	856	856
q4	4687	477	336	336
q5	7435	802	543	543
q6	186	186	153	153
q7	757	798	616	616
q8	9256	1350	1103	1103
q9	5596	4281	4303	4281
q10	6796	1288	1010	1010
q11	419	258	238	238
q12	634	400	280	280
q13	18083	3582	3021	3021
q14	271	277	248	248
q15	q16	737	715	676	676
q17	1181	754	583	583
q18	7066	6241	6166	6166
q19	1111	969	615	615
q20	394	330	222	222
q21	5204	2331	2412	2331
q22	362	315	270	270
Total cold run time: 100107 ms
Total hot run time: 29380 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	6141	6124	6103	6103
q2	682	580	557	557
q3	5218	5415	4967	4967
q4	1978	2099	1581	1581
q5	5273	5376	5737	5376
q6	265	200	155	155
q7	2326	2028	1863	1863
q8	3247	2789	2715	2715
q9	8065	8082	8208	8082
q10	3781	3709	3384	3384
q11	689	474	425	425
q12	677	773	525	525
q13	3626	3913	3312	3312
q14	331	318	300	300
q15	q16	695	736	635	635
q17	8103	6994	6840	6840
q18	13218	12286	13125	12286
q19	951	814	829	814
q20	2201	2171	1949	1949
q21	5973	4900	4982	4900
q22	512	456	421	421
Total cold run time: 73952 ms
Total hot run time: 67190 ms

@mrhhsg

mrhhsg commented Oct 18, 2026

Copy link
Copy Markdown
Member Author

Re-checked the full review history at HEAD 725f2f6f97363329234a734bbd06c50abe825315. No code change was required in this round.

Previous inline findings — fixed and resolved:

  • Sparse-accounting overcount in segment_iterator.cpp: condition ranges are again built for the whole segment, and the Bloom filter / zone map / expression zone map stages charge only rows still set in _row_bitmap (_count_alive_rows). DisjointKeyRangesOnlyCountAliveRows covers disjoint key ranges ({1}, {5000}) with RowsStatsFiltered == 1.
  • Trailing DROP TABLE in point_lookup_zone_map_profile.groovy: removed; the table is only dropped before creation.

Other top-level comments: the hello-stephen entries are TPC-H / TPC-DS / ClickBench benchmark payloads, and the remaining entries are /review / run buildall commands and CI failure notices. None contains a code finding.

The current CHANGES_REQUESTED decision comes from the github-actions review of 2026-09-20; that reviewer's own review at this HEAD states that no previously reported blocking finding remains applicable.

Validation at this HEAD (local): SegmentIteratorKeyRangeStatsTest.* (10 tests) and SegmentIteratorExprZonemapTest.* (21 tests) pass.

Could a maintainer take another look and clear the change request if the remaining concerns are satisfied?

@hello-stephen

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

query5	4317	585	489	489
query6	462	209	197	197
query7	4833	444	228	228
query8	314	179	151	151
query9	8778	4008	4026	4008
query10	493	303	261	261
query11	5999	3789	3518	3518
query12	140	90	87	87
query13	1242	440	334	334
query14	6163	4075	3754	3754
query14_1	3546	3506	3548	3506
query15	209	214	186	186
query16	944	446	410	410
query17	864	665	538	538
query18	2420	424	312	312
query19	214	166	138	138
query20	89	97	82	82
query21	217	135	112	112
query22	13070	13141	12861	12861
query23	13768	12735	12454	12454
query23_1	12580	12484	12595	12484
query24	7098	846	466	466
query24_1	469	489	479	479
query25	549	417	365	365
query26	1341	262	143	143
query27	2725	439	278	278
query28	4593	1964	1960	1960
query29	1590	598	463	463
query30	310	219	190	190
query31	1008	930	811	811
query32	148	100	97	97
query33	529	306	250	250
query34	900	837	502	502
query35	762	754	666	666
query36	847	827	740	740
query37	133	107	94	94
query38	1789	1749	1692	1692
query39	794	802	752	752
query39_1	738	742	751	742
query40	221	122	107	107
query41	75	69	69	69
query42	92	88	86	86
query43	368	383	328	328
query44	1293	698	706	698
query45	188	179	171	171
query46	844	960	585	585
query47	2964	2736	2922	2736
query48	300	329	222	222
query49	615	400	292	292
query50	669	301	219	219
query51	10227	10158	10380	10158
query52	80	79	72	72
query53	196	202	152	152
query54	252	198	217	198
query55	68	68	70	68
query56	220	214	210	210
query57	1618	1563	1547	1547
query58	289	261	258	258
query59	2100	2156	1945	1945
query60	278	238	229	229
query61	146	143	145	143
query62	400	340	288	288
query63	200	171	161	161
query64	2755	983	778	778
query65	3297	3301	3259	3259
query66	1788	421	301	301
query67	19947	20123	19959	19959
query68	2912	995	608	608
query69	405	319	257	257
query70	872	801	793	793
query71	296	236	204	204
query72	2692	2623	2189	2189
query73	519	520	295	295
query74	4598	4466	4313	4313
query75	2316	2308	1940	1940
query76	2335	1020	626	626
query77	333	376	301	301
query78	9763	9738	9211	9211
query79	997	872	516	516
query80	819	452	357	357
query81	585	318	271	271
query82	586	139	108	108
query83	270	223	180	180
query84	314	116	100	100
query85	1008	415	367	367
query86	348	240	231	231
query87	2012	1964	1822	1822
query88	3629	2699	2681	2681
query89	367	302	256	256
query90	1717	186	183	183
query91	160	154	127	127
query92	100	90	89	89
query93	1024	1011	584	584
query94	521	296	287	287
query95	594	408	325	325
query96	656	537	238	238
query97	2436	2401	2317	2317
query98	164	152	149	149
query99	777	759	643	643
Total cold run time: 234395 ms
Total hot run time: 151961 ms

@hello-stephen

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

query1	0.00	0.00	0.00
query2	0.10	0.05	0.05
query3	0.26	0.12	0.12
query4	1.61	0.12	0.13
query5	0.30	0.25	0.25
query6	1.17	0.70	0.69
query7	0.04	0.01	0.01
query8	0.06	0.04	0.04
query9	0.40	0.34	0.35
query10	0.58	0.58	0.58
query11	0.21	0.14	0.14
query12	0.18	0.15	0.15
query13	0.50	0.50	0.50
query14	1.02	1.01	1.02
query15	0.64	0.61	0.61
query16	0.36	0.36	0.33
query17	1.17	1.13	1.18
query18	0.22	0.21	0.22
query19	2.09	1.99	1.94
query20	0.02	0.02	0.01
query21	15.49	0.27	0.14
query22	4.44	0.05	0.04
query23	16.29	0.33	0.12
query24	3.26	0.60	0.39
query25	0.11	0.06	0.05
query26	1.10	0.27	0.15
query27	0.04	0.04	0.03
query28	1.41	0.66	0.39
query29	12.50	4.22	3.32
query30	0.29	0.15	0.13
query31	2.78	0.58	0.33
query32	3.22	0.62	0.52
query33	3.16	3.20	3.26
query34	15.41	4.03	3.39
query35	3.35	3.37	3.35
query36	0.58	0.43	0.43
query37	0.10	0.06	0.06
query38	0.05	0.03	0.04
query39	0.04	0.03	0.03
query40	0.18	0.15	0.14
query41	0.09	0.02	0.02
query42	0.04	0.03	0.03
query43	0.04	0.04	0.03
Total cold run time: 94.9 s
Total hot run time: 24.55 s

@mrhhsg

mrhhsg commented Oct 18, 2026

Copy link
Copy Markdown
Member Author

Re-checked the full review history at HEAD 725f2f6f97363329234a734bbd06c50abe825315. No code change was required in this round.

  • The latest github-actions review (2026-10-18, at this HEAD) reports no new substantiated findings and states that no previously reported blocking finding remains applicable. Its only coverage note (extra disjoint/rejecting Bloom-filter and differing page-layout cases) is a non-blocking suggestion; existing tests already cover candidate-page Bloom filtering, cross-column narrowing and randomized selection.
  • Both previous inline threads (sparse accounting in segment_iterator.cpp, trailing DROP TABLE in point_lookup_zone_map_profile.groovy) remain fixed and resolved.
  • The remaining top-level entries are review/build commands, CI failure notices, and TPC-H / TPC-DS / ClickBench benchmark payloads (including the new TPC-DS result on this HEAD); none contains a code finding.

Validation at this HEAD (local): SegmentIteratorKeyRangeStatsTest.* (10 tests) and SegmentIteratorExprZonemapTest.* (21 tests) pass.

Could a maintainer take another look and clear the change request if the remaining concerns are satisfied?

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 100.00% (1/1) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 77.28% (35804/46331)
Line Coverage 62.52% (404354/646768)
Region Coverage 59.03% (341817/579101)
Branch Coverage 59.94% (157867/263363)

…ap filtered

Issue Number: None

Problem Summary: `SegmentIterator::_get_row_ranges_by_column_conditions()` builds
the condition row ranges from the whole segment, although `_row_bitmap` at that
point already carries the key-range and index pruning. The zone map / bloom
filter counters are therefore computed against rows that were pruned long
before. A point lookup shows it clearly: on a 200k row table,
`SELECT COUNT(*) FROM t WHERE k = 12345 AND v = 12345` reports

```
RowsKeyRangeFiltered: 199.999K (199999)   -- one row left
RowsStatsFiltered:    183.616K (183616)   -- but the zone map "filtered" this many
RowsConditionsFiltered: 0
```

Start the condition ranges from the rows that are still alive, so the counters
only report what the index really pruned; the same query now reports
`RowsStatsFiltered: 0` while a query without a key range still reports the full
`RowsStatsFiltered: 183616`. The final row bitmap is unchanged, since it is
intersected with the condition ranges either way.

The same block also intersected the condition ranges with the zone map ranges
twice and reported the (always empty) difference of the second, idempotent
intersection as `RowsZoneMapRuntimePredicateFiltered`. That counter lost its
source when the top-n filter was turned into a regular pushed-down conjunct in
keeping a profile row that can only ever be 0.

None

- Test:
    - Unit Test: Yes, `SegmentIteratorKeyRangeStatsTest` covers a point lookup
      whose key range already selects a single row (no rows counted as zone-map
      filtered) and the same predicate without a key range (zone map still
      prunes pages).
    - Regression test: Yes, `point_lookup_zone_map_profile` asserts the counters
      of the profile of such a point lookup.
- Behavior changed: Yes, profile only. `RowsStatsFiltered` / `RowsBloomFilterFiltered`
  no longer count rows that the key range or an index already removed, and the
  `RowsZoneMapRuntimePredicateFiltered` counter is removed.
- Does this need documentation: No

Claude-Session: https://claude.ai/code/session_01RZ36Pij3o8fGnYYg33PKnq
The min/max envelope of `_row_bitmap` is not the set of surviving rows: disjoint
key ranges or sparse index results (e.g. `k IN (1, 5000)`) still charged the rows
between them as zone-map / bloom filter filtered.

Keep building the condition ranges from the whole segment, and instead count
for each step only the removed rows that are still set in `_row_bitmap`. Add a
disjoint key range test, and keep the regression table after the run.

Claude-Session: https://claude.ai/code/session_01TcCqRsfwhu58PN1zNar5rD
Issue Number: None

Related PR: apache#68279

Problem Summary: Correct filtered-row counters alone do not avoid page-index
work on rows already removed by key ranges or other indexes. On an eight-page
segment, an instrumented point lookup still evaluated all eight ZoneMaps.
Select candidate pages from the surviving bitmap and current row ranges using
each column's ordinal index, and share that selection across ordinary ZoneMap,
expression ZoneMap and Bloom-filter pruning. Carry reduced ranges across columns,
preserve synthetic readers without physical pages, and retain exact sparse-row
accounting. The point/disjoint-key tests now evaluate one/two pages respectively.

Skip redundant ZoneMap and Bloom-filter page evaluations after key-range/index
pruning and expose the actual page-index evaluation counts in query profiles.

- Test:
    - Unit Test: 269 focused ASAN BE tests passed, including candidate-page oracle,
      sparse/empty rows, expression flags, corrupt metadata and synthetic readers.
    - Regression test: point_lookup_zone_map_profile (generated output and normal
      rerun), test_expr_zonemap_pruning, test_zone_map_delete,
      test_bloom_filter_is_not_null passed on an isolated local cluster.
    - Build: ./build.sh --be --fe -j24 (ASAN).
    - Formatting, build hygiene and git diff --check passed.
    - Static analysis: see PR body for existing base-header/toolchain blockers
      and the local-only validation overlay (zero changed-line diagnostics).
      No RELEASE timing benchmark.
- Behavior changed: Yes (same query results and storage format; less page-index
  work and new profile counters).
- Does this need documentation: No

Claude-Session: https://claude.ai/code/session_018ZrdaZUYBhBJtmsmJwzxkQ
### What problem does this PR solve?

Issue Number: None

Related PR: apache#68279

Problem Summary: Rebasing the page-index pruning change onto the current master
required two test adaptations. `StorageReadOptions` now requires the statistics
reference in its constructor instead of a default-constructed object, and
`Segment::get_column_reader` was replaced by `get_column_reader_for_pruning`.
The stub `ColumnIterator` in the candidate-pushdown test also follows the new
`get_row_ranges_by_zone_map` signature that receives the surviving row bitmap.

### Release note

None

### Check List (For Author)

- Test: Unit Test
- Behavior changed: No
- Does this need documentation: No
…ndex pruning

### What problem does this PR solve?

Issue Number: None

Related PR: apache#68279

Problem Summary: The Bloom filter and zone map counters now charge only the rows
that are still alive when each pruning step runs. In
test_variant_predefine_types_with_indexes_profile the inverted indexes consume
the probe predicates first, so by the time the Bloom filter runs there is no
surviving row left for it to reject. The `bloom_filter_must_filter_data` debug
point therefore fails with "Bloom filter did not filter the data", as seen in
the non-concurrent regression pipeline.

Disable the inverted index inside the Bloom filter probes so the filter is
exercised on the whole segment. When the index is not applied the predicate
stays in col_id_to_predicates and the Bloom filter still evaluates it; query
results and all .out baselines are unchanged.

### Release note

None

### Check List (For Author)

- Test: Regression test
    - variant_p0.predefine.test_types_with_indexes_profile passed on a local
      cluster; without the change it reproduces the pipeline failure with
      "Bloom filter did not filter the data"
    - fault_injection_p0.test_variant_bloom_filter,
      fault_injection_p0.test_variant_typed_path_bloom_filter and
      query_profile.point_lookup_zone_map_profile passed on the same cluster
- Behavior changed: No
- Does this need documentation: No
…serting

### What problem does this PR solve?

Issue Number: None

Related PR: apache#68279

Problem Summary: point_lookup_zone_map_profile assumes the whole fixture is one
segment, so the key range is applied before the zone map can prune anything.
An INSERT ... SELECT may create several segments depending on sink parallelism:
the non-concurrent pipeline produced 24 segments, the segment-level zone map in
Segment::new_iterator pruned 23 of them and charged their rows to
RowsStatsFiltered before the per-segment key range ran. The assertion that a
point lookup must report RowsStatsFiltered == 0 therefore failed
(RowsKeyRangeFiltered=36575, RowsStatsFiltered=163424).

Run a full compaction after the insert so the fixture deterministically has one
segment. The key range then narrows the scan to one row and the zone map has no
surviving row to charge. Verified locally: a 24-segment fixture reproduces the
pipeline failure (RowsStatsFiltered=191666), and the same fixture passes after
the compaction; the plain fixture still passes as before.

### Release note

None

### Check List (For Author)

- Test: Regression test
    - query_profile.point_lookup_zone_map_profile passed on a local cluster with
      the compacted fixture
    - a 24-segment fixture reproduces the non-concurrent pipeline assertion
      failure without the compaction and passes with it
- Behavior changed: No
- Does this need documentation: No
…lookup

### What problem does this PR solve?

Issue Number: None

Related PR: apache#68279

Problem Summary: point_lookup_zone_map_profile asserts RowsStatsFiltered == 0
after a point lookup, which only holds when the tablet holds a single segment:
with several segments the segment-level zone map charges whole segments before
the per-segment key range runs. The previous fixture relied on a full compaction
to establish that layout, but FullCompaction::pick_rowsets_to_compact skips the
initial empty [0-1] rowset plus a single data rowset regardless of how many
segments that rowset has. trigger_and_wait_compaction also treats a rejected
compaction's failure-time update as completion, so the fixture could silently
keep a multi-segment layout and fail in CI (24 segments,
RowsStatsFiltered=163424).

Split the data into two non-empty INSERT transactions so the compaction has more
than one data rowset and actually rewrites, then assert through the tablet
compaction status that the fixture holds exactly one segment instead of trusting
the helper's return value. Verified locally: a single transaction forced to
flush 9 segments fails the new invariant assertion and reproduces
RowsStatsFiltered=126560 without it, while the two-transaction fixture compacts
to one segment and reports RowsStatsFiltered=0 even when both transactions are
forced to flush multiple segments.

### Release note

None

### Check List (For Author)

- Test: Regression test
    - query_profile.point_lookup_zone_map_profile passed on a local cluster; the
      fixture reports NumSegmentTotal=1 and RowsStatsFiltered=0
    - variant_p0.predefine.test_variant_predefine_types_with_indexes_profile and
      the two fault_injection_p0 variant Bloom filter suites passed
- Behavior changed: No
- Does this need documentation: No
…probe

### What problem does this PR solve?

Issue Number: None

Related PR: apache#68279

Problem Summary: The new point_lookup_zone_map_profile suite probes the BE
compaction status to assert that the fixture holds a single segment. The probe
called the regression curl helper without credentials, while the compaction
helper used just before it forwards feHttpUser/feHttpPassword. When the
regression BE enables enable_all_http_auth, the probe would get 401 and the
suite would fail before any profile assertion. Forward the same configured
credentials to the probe.

### Release note

None

### Check List (For Author)

- Test: Regression test
    - query_profile.point_lookup_zone_map_profile passed on a local cluster; the
      log shows the probe now runs `curl -uroot: --max-time 10 -X GET ...`
- Behavior changed: No
- Does this need documentation: No
@mrhhsg
mrhhsg force-pushed the fix/scan-stats-counted-after-key-range branch from 725f2f6 to ac69ac7 Compare October 19, 2026 09:14
@mrhhsg

mrhhsg commented Oct 19, 2026

Copy link
Copy Markdown
Member 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 all 16 changed paths at ac69ac763059df4b8d8b0d41cf1878021546ad40. No new actionable finding was verified. Three independent reviewers returned NO_NEW_VALUABLE_FINDINGS against the same final empty finding set; all initial risks have evidence-backed dispositions.

Both existing concerns are addressed: exact bitmap intersections now prevent sparse/disjoint candidates from inflating filtered-row counts (thread 4057083753), and the regression preserves its tables after execution (thread 4057083754). No existing P0/P1 remains applicable. The focus file contains no additional user concern.

The production flow checked was:

Segment-level pruning -> bounded bitmap and key ranges
  -> index predicates and scan restrictions (existing ordering)
  -> Bloom -> ordinary ZoneMap -> expression ZoneMap
  -> exact bitmap intersection -> scanner-close profile collection

Critical checkpoint conclusions:

  1. Goal/correctness: all three page-index stages restrict evaluation to pages intersecting surviving rows and current ranges. Exact live-row deltas avoid charging earlier pruning again; final intersection retains exact candidates. Tests check output and actual evaluation work.
  2. Focus/abstraction: changes remain scoped to page pruning, statistics, wrapper signatures and their tests. The shared page selector removes duplicated selection logic.
  3. Concurrency/locks: candidate state and statistics remain iterator/scanner scoped. Existing once-only index loading and profile collection are preserved; no new thread, lock nesting or lock-order change.
  4. Lifecycle/memory/static initialization: temporary page lists and ranges have scoped ownership. Reader ownership remains intact, with no new asynchronous lifetime, ownership cycle, cache or cross-TU static dependency.
  5. Configuration: none added. The existing expression-filter gate retains disabled behavior.
  6. Compatibility: internal callers and overrides carry the new bitmap argument consistently. No persisted format or wire contract changes. Valid scalar writers already align ZoneMap/Bloom entries with ordinal data pages; inconsistent counts now return Corruption.
  7. Thrift/protobuf: no definitions changed; cross-branch field-ID checks are not applicable.
  8. Parallel paths: ordinary ZoneMap, Bloom, expressions, VARIANT forwarding, sparse paths, constant/default readers, unsafe casts and unsupported/multi-slot fallbacks were traced. Each column uses its own page boundaries.
  9. Conditions/errors: comments explain sparse seeks, repeated-page suppression, empty candidates, synthetic readers and metadata mismatch. New index/parsing Status values propagate; no new silent failure path found.
  10. Test coverage: instrumented unit tests cover point/disjoint/same-page/empty/rejecting candidates, Bloom work, successive columns, page boundaries, randomized independent page-selection oracles, index corruption and enabled/disabled/synthetic expressions. SQL profile assertions cover ordinary, expression and Bloom work.
  11. Changed results: the nine golden sections agree with the fixture and predicates; the multi-row query is ordered and other outputs are aggregates. Golden-file generation provenance was not independently reproduced.
  12. Observability: new evaluation counters distinguish actual page work from rows filtered, and are collected under the existing once-only scanner guard. Removed-counter references are updated. Profile level and completion handling support the regression parser.
  13. Transactions/persistence: version selection, delete-bitmap selection, edit logs and failover behavior are unchanged; no persistent-state mutation introduced.
  14. Writes/crash handling: no data-write or atomicity path changes. Temporary pruning state is released normally on checked error exits.
  15. FE/BE variables: none added or transmitted differently.
  16. Performance: bitmap seeks skip selected-page rows and sparse page gaps; sorted range append replaces repeated unions. Whole ZoneMap metadata loading remains unchanged. Full-candidate overhead and the author's benchmark figures were not measured in this review.
  17. Other risk sweep: iterator exhaustion, maximum ordinal bounds, aliasing intersections, pass-all metadata, dictionary rejection, candidate-pushdown ordering and special-reader reachability yielded no additional verified issue. The pinned CRoaring implementation supports the seek and half-open cardinality semantics used here.

Coverage is complete for the required static review. No builds, tests or benchmarks were run, and no product source was modified. Execution success, binary compatibility and performance measurements are not independently certified by this review.

Review converged after 1 round(s).

@mrhhsg

mrhhsg commented Oct 19, 2026

Copy link
Copy Markdown
Member Author

Re-checked the full review history at HEAD ac69ac763059df4b8d8b0d41cf1878021546ad40 (rebased onto e0bf4874070b).

Previous inline findings — fixed and resolved:

  • Sparse-accounting overcount in segment_iterator.cpp: condition ranges are again built for the whole segment, and the Bloom filter / zone map / expression zone map stages charge only rows still set in _row_bitmap (_count_alive_rows). DisjointKeyRangesOnlyCountAliveRows covers disjoint key ranges ({1}, {5000}) and asserts RowsStatsFiltered == 1.
  • Trailing DROP TABLE in point_lookup_zone_map_profile.groovy: removed; the tables are only dropped before creation.

Other top-level comments: the hello-stephen entries are the contribution template, TPC-H / TPC-DS / ClickBench benchmark payloads and a coverage report; the remaining entries are review/build commands and CI failure notices. None contains a code finding.

The current CHANGES_REQUESTED decision comes from the github-actions review of 2026-09-20; that reviewer's later review at an earlier head reported no remaining blocking finding. The only follow-up suggestion there (extra disjoint/rejecting Bloom-filter and differing page-layout cases) is non-blocking; the point-lookup fixture has since been rebuilt as a real single-segment table and the variant Bloom probes now run without inverted-index pruning.

Validation at this HEAD (fresh local runs):

  • query_profile.point_lookup_zone_map_profile — 1 suite, 0 failures
  • variant_p0/predefine.test_variant_predefine_types_with_indexes_profile — 1 suite, 0 failures

Could a maintainer take another look and clear the change request if the remaining concerns are satisfied?

@mrhhsg

mrhhsg commented Oct 19, 2026

Copy link
Copy Markdown
Member Author

run buildall

### What problem does this PR solve?

Problem Summary: The branch is based on a master revision that removed
JsonToVariantOptions::check_duplicate_json_path (upstream apache#68447), while four
BE unit test files still pass that field in designated initializers. The BE UT
pipeline builds the pull request head directly, so it fails to compile:

    core/data_type_serde/data_type_serde_arrow_test.cpp:960:36: error:
    no matching constructor for initialization of 'JsonStringToVariantEncoder'
    core/data_type_serde/data_type_variant_v2_serde_jsonb_test.cpp:115:32: error:
    no matching constructor for initialization of 'JsonStringToVariantEncoder'

Remove the deleted field from the six affected initializers in
data_type_serde_arrow_test.cpp, data_type_variant_v2_serde_jsonb_test.cpp,
variant_v2_execution_test.cpp and vparquet_writer_test.cpp. This matches the
upstream master fix (apache#69261) for the same fixtures.

### Release note

None

### Check List (For Author)

- Test: Unit Test
    - ./run-be-ut.sh: full doris_be_test compile and link passed
    - ./run-be-ut.sh --run --filter='DataTypeSerDeArrowTest.*:DataTypeVariantV2SerdeJsonbTest.*:VariantV2ExecutionTest.*:VParquetWriterTest.*': 53 tests passed
- Behavior changed: No
- Does this need documentation: No
@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17610	5174	5051	5051
q2	2078	304	247	247
q3	10298	1382	823	823
q4	4676	461	333	333
q5	7428	801	521	521
q6	178	186	151	151
q7	763	807	607	607
q8	9263	1354	1121	1121
q9	5546	4208	4202	4202
q10	6809	1297	1021	1021
q11	453	257	224	224
q12	633	407	275	275
q13	18091	3600	2988	2988
q14	268	265	245	245
q15	q16	722	715	690	690
q17	1219	764	582	582
q18	7053	6178	6099	6099
q19	1100	949	609	609
q20	392	344	222	222
q21	5228	2424	2448	2424
q22	392	316	274	274
Total cold run time: 100200 ms
Total hot run time: 28709 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	5877	5907	5974	5907
q2	720	624	570	570
q3	5590	5639	5186	5186
q4	2032	2134	1560	1560
q5	5920	5558	5739	5558
q6	243	187	144	144
q7	2336	2046	1771	1771
q8	3060	2699	2643	2643
q9	7950	7574	7511	7511
q10	3607	3586	3134	3134
q11	580	414	408	408
q12	657	660	506	506
q13	3297	3606	3008	3008
q14	288	285	277	277
q15	q16	668	689	618	618
q17	7753	7043	6863	6863
q18	13018	12236	12826	12236
q19	935	806	814	806
q20	2139	2125	1912	1912
q21	5587	4583	4698	4583
q22	489	448	428	428
Total cold run time: 72746 ms
Total hot run time: 65629 ms

@mrhhsg

mrhhsg commented Oct 19, 2026

Copy link
Copy Markdown
Member Author

/review

@hello-stephen

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

query5	4302	601	419	419
query6	423	203	188	188
query7	4812	439	243	243
query8	328	166	143	143
query9	8801	3038	3070	3038
query10	477	304	247	247
query11	5988	3865	3565	3565
query12	146	92	85	85
query13	1258	425	315	315
query14	6069	3909	3608	3608
query14_1	3389	3406	3370	3370
query15	210	192	181	181
query16	928	426	389	389
query17	859	656	506	506
query18	2403	408	295	295
query19	184	156	126	126
query20	82	81	79	79
query21	205	122	103	103
query22	12916	12948	12866	12866
query23	13451	12761	12532	12532
query23_1	12482	12618	12450	12450
query24	7386	820	459	459
query24_1	457	458	484	458
query25	510	395	335	335
query26	1276	254	135	135
query27	2773	450	262	262
query28	4634	1907	1907	1907
query29	1541	603	450	450
query30	296	221	178	178
query31	1013	946	819	819
query32	135	91	90	90
query33	542	304	243	243
query34	879	845	499	499
query35	730	759	664	664
query36	828	807	716	716
query37	120	96	81	81
query38	1783	1748	1687	1687
query39	787	785	740	740
query39_1	727	732	743	732
query40	225	120	100	100
query41	72	67	70	67
query42	87	86	90	86
query43	344	366	313	313
query44	1309	689	688	688
query45	175	184	168	168
query46	836	963	561	561
query47	2916	2799	2650	2650
query48	301	316	231	231
query49	601	408	294	294
query50	685	281	204	204
query51	10567	10336	10389	10336
query52	79	80	71	71
query53	186	208	159	159
query54	249	204	184	184
query55	73	73	64	64
query56	242	238	235	235
query57	1701	1586	1578	1578
query58	283	275	260	260
query59	2113	2165	2048	2048
query60	314	248	226	226
query61	187	196	168	168
query62	391	338	295	295
query63	192	161	162	161
query64	2872	1048	935	935
query65	3294	3271	3234	3234
query66	1773	412	301	301
query67	20083	20149	20022	20022
query68	3059	1018	611	611
query69	360	280	245	245
query70	832	784	770	770
query71	295	235	211	211
query72	2995	2601	2277	2277
query73	524	521	287	287
query74	4643	4500	4337	4337
query75	2324	2259	1917	1917
query76	2329	1010	596	596
query77	335	360	267	267
query78	9783	9834	9101	9101
query79	991	895	523	523
query80	770	416	329	329
query81	562	315	269	269
query82	562	132	102	102
query83	290	193	174	174
query84	314	115	103	103
query85	934	430	360	360
query86	336	238	218	218
query87	2014	1964	1789	1789
query88	3658	2676	2633	2633
query89	327	293	237	237
query90	1736	167	156	156
query91	163	155	125	125
query92	96	88	86	86
query93	1012	968	572	572
query94	464	288	276	276
query95	572	331	308	308
query96	672	473	232	232
query97	2451	2436	2330	2330
query98	156	149	147	147
query99	777	758	644	644
Total cold run time: 234363 ms
Total hot run time: 150450 ms

@mrhhsg

mrhhsg commented Oct 19, 2026

Copy link
Copy Markdown
Member Author

Re-checked the full review history at HEAD ef01c98e4dcfe07e279fde164037bf539e476dc6.

Previous inline findings — fixed; both threads are resolved:

  • Sparse-accounting overcount in segment_iterator.cpp: _get_row_ranges_from_conditions() now derives each stage's delta through _count_alive_rows() (be/src/storage/segment/segment_iterator.cpp:1162), which uses roaring_bitmap_range_cardinality against the surviving _row_bitmap instead of the dense min/max envelope. DisjointKeyRangesOnlyCountAliveRows (be/test/storage/segment/segment_iterator_key_range_stats_test.cpp:204) covers key ranges {1} and {5000} and asserts RowsStatsFiltered == 1.
  • Trailing DROP TABLE in point_lookup_zone_map_profile.groovy: removed; both tables are dropped only before creation (lines 21 and 161).

Latest review: the most recent github-actions review (2026-10-19, at ac69ac76305) reports NO_NEW_VALUABLE_FINDINGS and states both earlier concerns are addressed with no remaining P0/P1. The only delta since that reviewed commit is ef01c98e4dc, which adapts BE unit-test fixtures to the check_duplicate_json_path option removed on master (test-only, four files).

Other top-level entries: /review and run buildall commands, two stale "Codex review failed" notices, a local PASS receipt, and TPC-H / TPC-DS / ClickBench / coverage payloads. None contains a code finding.

The CHANGES_REQUESTED decision comes from the 2026-09-20 automated review; I cannot dismiss it. Could a maintainer take another look and clear it if the remaining concerns are satisfied?

@hello-stephen

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

query1	0.01	0.01	0.01
query2	0.09	0.05	0.05
query3	0.26	0.09	0.08
query4	1.62	0.10	0.13
query5	0.24	0.25	0.23
query6	1.16	0.67	0.68
query7	0.03	0.00	0.00
query8	0.05	0.04	0.04
query9	0.41	0.35	0.32
query10	0.57	0.59	0.61
query11	0.20	0.13	0.14
query12	0.18	0.15	0.15
query13	0.48	0.48	0.48
query14	1.02	1.02	0.99
query15	0.63	0.60	0.60
query16	0.34	0.35	0.35
query17	1.16	1.12	1.11
query18	0.19	0.19	0.19
query19	2.11	2.00	1.95
query20	0.02	0.01	0.01
query21	15.48	0.18	0.13
query22	4.93	0.05	0.04
query23	16.32	0.31	0.11
query24	2.88	0.56	0.55
query25	0.10	0.07	0.04
query26	1.50	0.22	0.16
query27	0.06	0.05	0.03
query28	3.55	0.76	0.37
query29	12.48	4.10	3.23
query30	0.28	0.14	0.09
query31	2.78	0.55	0.32
query32	3.21	0.60	0.51
query33	3.18	3.25	3.20
query34	15.42	3.99	3.39
query35	3.34	3.34	3.34
query36	0.56	0.49	0.41
query37	0.09	0.07	0.06
query38	0.04	0.04	0.04
query39	0.04	0.03	0.03
query40	0.16	0.16	0.14
query41	0.09	0.03	0.03
query42	0.04	0.03	0.03
query43	0.04	0.03	0.04
Total cold run time: 97.34 s
Total hot run time: 24.33 s

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

Static review of all 20 authoritative changed paths at ef01c98 found no new substantiated issue. Review converged after round 1: both complete-review specialists and the separate risk-focused reviewer returned NO_NEW_VALUABLE_FINDINGS, and all in-tree risks/candidates have evidence-backed dispositions.

The reviewed flow is:

bounded segment bitmap -> key/index/delete/split restrictions
  -> Bloom -> ordinary ZoneMap -> expression ZoneMap
  -> exact bitmap intersection -> materialization -> scanner profile

Each column selects pages using its own ordinal index and the surviving bitmap; ranges only narrow between stages. The pinned CRoaring iterator contract confirms the seek semantics used here.

Critical checkpoint conclusions:

  1. Goal and evidence: candidate-only page evaluation and exact sparse-row accounting are implemented. Ten new key-range/page-selection unit tests, four new expression tests and SQL/profile assertions cover the intended behavior; these were inspected statically.
  2. Scope, clarity and reuse: the shared candidate helper covers all three index paths. The four Variant test initializer changes adapt to the current options struct without adding product behavior.
  3. Concurrency and locks: pruning state is scanner-local; shared index loading retains existing call-once synchronization and profile aggregation uses existing atomic counters. No new threads, locks, lock ordering or work inside new critical sections.
  4. Lifecycle and static initialization: temporary page/range/evaluation objects retain lexical ownership, reader lifetimes remain valid, and no new ownership cycle or cross-translation-unit initialization dependency appears.
  5. Configuration: none added. Existing expression-filter enable/disable behavior remains intact.
  6. Compatibility: internal C++ filter callers and overrides are updated. No storage/wire-format or rolling-upgrade protocol change. Adding two page counters and removing the unused zero counter intentionally changes profile output.
  7. Thrift/protobuf: unchanged; field-id compatibility checks are not applicable.
  8. Parallel paths: ordinary ZoneMap, Bloom, expression ZoneMap, Variant forwarding, synthetic constants, sparse-only leaves and unsupported/disabled-expression fallbacks were checked. Local and cloud scans share the modified reader path.
  9. Conditions and errors: empty/same-page/synthetic branches explain concrete cases; inconsistent physical ZoneMap/ordinal page counts return Corruption. Status propagation remains intact.
  10. Test coverage: point, disjoint, same-page, empty and rejecting candidates, Bloom, cross-column pruning, randomized page oracle, malformed metadata and synthetic/disabled expressions are covered. New direct reader fixtures do not explicitly vary nullable/different-column page layouts; their ordinal invariants were traced through writers/readers.
  11. Expected results: all nine new golden outputs match the inserted values and SQL predicates; the multirow result has ORDER BY. Golden-generation provenance and runtime success were not independently verified.
  12. Observability: both evaluated-page counters are initialized and published once through scanner close; expression/ordinary counts intentionally measure column-page evaluations. Sparse filtered-row deltas count only still-live rows.
  13. Transactions, persistence and failover: no write, version-selection, EditLog or persisted-state changes. Existing rowset visibility and version-aligned delete-bitmap selection are preserved.
  14. Writes, atomicity and crash behavior: no data-write path changes; read-side temporaries retain cleanup on errors.
  15. FE-BE variables: none added; no sender/receiver protocol work is required.
  16. Performance: sparse seeks skip irrelevant pages and later stages reuse narrowed ranges; unique page vectors and incremental range construction remove redundant work. Whole-index ZoneMap metadata loading remains unchanged. Author benchmark numbers and runtime performance were not reproduced.
  17. Other invariants: nullable scalar ordinals include NULL rows, materialized Variant paths backfill row gaps, and synthetic readers skip physical page pruning. No additional visibility, memory-ownership, nullable-cast or error-handling defect was identified.

Existing review context: 4057083753 is fixed by alive-bitmap accounting and the disjoint-key test. 4057083754 is fixed by retaining regression tables after execution. Neither is an existing blocker; neither is reposted. The supplied user-focus file has no additional focus points.

Limits: static analysis only, with no Doris builds or tests run and no source edits. The optional out-of-tree nested-group provider is absent and was not assessed; its in-tree default is disabled. All requested in-tree paths and checkpoints are covered, with no unresolved in-tree candidate.

Review converged after 1 round(s).

@mrhhsg

mrhhsg commented Oct 19, 2026

Copy link
Copy Markdown
Member Author

Re-checked the full review history at HEAD ef01c98e4dcfe07e279fde164037bf539e476dc6.

Latest automated review: the github-actions review submitted at 2026-10-19T14:50:49Z covers this exact HEAD and reports no new substantiated issue; it converged in round 1 with no remaining P0/P1. The only delta since the previously reviewed commit is the four test-fixture files, which adapt Variant unit tests to the parse-option removal on master.

Previous inline findings — fixed; both threads are resolved and outdated:

  • Sparse-accounting overcount in segment_iterator.cpp: _get_row_ranges_from_conditions() derives each stage delta through _count_alive_rows() (be/src/storage/segment/segment_iterator.cpp:1162), which uses roaring_bitmap_range_cardinality against the surviving _row_bitmap instead of the dense min/max envelope. DisjointKeyRangesOnlyCountAliveRows (be/test/storage/segment/segment_iterator_key_range_stats_test.cpp:204) covers key ranges {1} and {5000} and asserts RowsStatsFiltered == 1.
  • Trailing DROP TABLE in point_lookup_zone_map_profile.groovy: removed; both tables are dropped only before creation (lines 21 and 161).

New top-level comments since the previous report: only a ClickBench benchmark payload on ac69ac76305; it contains no code finding. The other entries are /review and run buildall commands, stale "Codex review failed" notices from 2026-09-22, a local PASS receipt, and TPC-H / TPC-DS / ClickBench / coverage payloads. None contains a code finding.

Validation at this HEAD (fresh local runs):

  • SegmentIteratorKeyRangeStatsTest.* + SegmentIteratorExprZonemapTest.*: 31 tests, all passed.
  • DataTypeSerDeArrowTest.* + DataTypeVariantV2SerdeJsonbTest.* + VariantV2ExecutionTest.* + VParquetWriterTest.*: 53 tests, all passed (these cover the test-fixture adaptation).
  • query_profile/point_lookup_zone_map_profile: 1 suite, 0 failures.
  • variant_p0/predefine/test_variant_predefine_types_with_indexes_profile: 1 suite, 0 failures.

The current CHANGES_REQUESTED decision comes from the 2026-09-20 automated review; I cannot dismiss it. Could a maintainer take another look and clear it if the remaining concerns are satisfied?

@mrhhsg

mrhhsg commented Oct 19, 2026

Copy link
Copy Markdown
Member Author

run buildall

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17617	5147	5029	5029
q2	2096	313	262	262
q3	10265	1381	806	806
q4	4676	458	336	336
q5	7413	787	542	542
q6	181	181	151	151
q7	735	800	598	598
q8	9245	1348	1075	1075
q9	5575	4179	4166	4166
q10	6821	1293	1015	1015
q11	441	244	224	224
q12	635	392	275	275
q13	18081	3520	3016	3016
q14	264	266	246	246
q15	q16	717	726	659	659
q17	1194	758	580	580
q18	6979	6153	6116	6116
q19	1118	979	583	583
q20	386	335	228	228
q21	5088	2416	2413	2413
q22	389	313	285	285
Total cold run time: 99916 ms
Total hot run time: 28605 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	5808	6216	5931	5931
q2	705	570	559	559
q3	5569	5696	5311	5311
q4	1992	2145	1538	1538
q5	5952	5761	5715	5715
q6	248	188	140	140
q7	2236	1973	1831	1831
q8	2963	2545	2589	2545
q9	7573	7512	7482	7482
q10	3585	3561	3112	3112
q11	576	430	384	384
q12	657	656	496	496
q13	3257	3542	3048	3048
q14	290	291	259	259
q15	q16	652	670	615	615
q17	7783	7030	6889	6889
q18	12975	12162	12883	12162
q19	912	778	783	778
q20	2123	2145	1902	1902
q21	5562	4559	4673	4559
q22	488	440	409	409
Total cold run time: 71906 ms
Total hot run time: 65665 ms

@mrhhsg

mrhhsg commented Oct 19, 2026

Copy link
Copy Markdown
Member Author

Re-checked the full review history at HEAD ef01c98e4dcfe07e279fde164037bf539e476dc6.

New top-level comment since the previous report: IC_kwDOBfSlxs8AAAABdf2LEA is a TPC-H benchmark payload for this commit; it contains no code finding. The run buildall entry is a build trigger. No other new comments.

Previous inline findings — fixed; both threads are resolved and outdated:

  • Sparse-accounting overcount in segment_iterator.cpp: _count_alive_rows() now uses roaring_bitmap_range_cardinality over the surviving _row_bitmap (be/src/storage/segment/segment_iterator.cpp:1162), and DisjointKeyRangesOnlyCountAliveRows (be/test/storage/segment/segment_iterator_key_range_stats_test.cpp:204) asserts RowsStatsFiltered == 1 for disjoint key ranges {1} and {5000}.
  • Trailing DROP TABLE in point_lookup_zone_map_profile.groovy: removed; both tables are dropped only before creation (lines 21 and 161).

Latest automated review: the github-actions review at this exact HEAD (2026-10-19T14:50:49Z) reports no new substantiated issue and states that no previously reported blocking finding remains applicable.

Validation at this HEAD (fresh local run): SegmentIteratorKeyRangeStatsTest.* and SegmentIteratorExprZonemapTest.* — 31 tests, all passed.

The current CHANGES_REQUESTED decision dates from the 2026-09-20 automated review; the author cannot dismiss it. Could a maintainer take another look and clear it if the remaining concerns are satisfied?

@hello-stephen

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

query5	4310	576	466	466
query6	426	205	189	189
query7	4826	453	221	221
query8	335	153	146	146
query9	8756	3088	3118	3088
query10	478	304	249	249
query11	5975	3863	3563	3563
query12	144	90	86	86
query13	1240	454	323	323
query14	6121	3861	3604	3604
query14_1	3331	3373	3379	3373
query15	206	200	183	183
query16	959	424	411	411
query17	847	658	542	542
query18	2422	429	315	315
query19	205	166	140	140
query20	86	82	82	82
query21	211	124	106	106
query22	12917	12945	12740	12740
query23	13443	12778	12475	12475
query23_1	12626	12514	12540	12514
query24	7397	801	470	470
query24_1	464	469	461	461
query25	511	389	333	333
query26	1253	253	134	134
query27	2776	427	261	261
query28	4621	1918	1962	1918
query29	1529	575	437	437
query30	298	218	177	177
query31	996	905	812	812
query32	143	90	92	90
query33	519	285	229	229
query34	900	842	497	497
query35	726	752	635	635
query36	825	825	738	738
query37	136	91	79	79
query38	1762	1760	1670	1670
query39	780	798	724	724
query39_1	726	712	737	712
query40	216	113	94	94
query41	64	62	64	62
query42	85	83	82	82
query43	339	373	310	310
query44	1308	681	672	672
query45	173	173	158	158
query46	820	957	563	563
query47	2847	2864	2916	2864
query48	292	305	207	207
query49	581	398	293	293
query50	662	272	215	215
query51	10482	10449	10381	10381
query52	78	83	74	74
query53	187	203	149	149
query54	227	198	179	179
query55	70	69	60	60
query56	250	227	222	222
query57	1671	1620	1570	1570
query58	291	263	251	251
query59	2136	2253	1995	1995
query60	288	238	225	225
query61	146	143	144	143
query62	379	336	288	288
query63	186	153	160	153
query64	2784	1093	885	885
query65	3290	3268	3245	3245
query66	1790	434	310	310
query67	20275	20115	20060	20060
query68	3031	1017	627	627
query69	395	306	271	271
query70	826	767	816	767
query71	321	246	217	217
query72	2878	2745	2275	2275
query73	520	524	295	295
query74	4603	4506	4320	4320
query75	2325	2257	1898	1898
query76	2322	1005	583	583
query77	341	376	271	271
query78	9711	9682	9137	9137
query79	969	888	512	512
query80	540	414	336	336
query81	545	319	268	268
query82	583	130	100	100
query83	308	189	175	175
query84	310	123	99	99
query85	826	432	362	362
query86	315	239	232	232
query87	1999	1987	1790	1790
query88	3629	2654	2627	2627
query89	328	282	241	241
query90	1891	158	165	158
query91	155	150	126	126
query92	96	89	88	88
query93	987	981	580	580
query94	461	319	264	264
query95	579	379	299	299
query96	678	477	230	230
query97	2446	2465	2314	2314
query98	170	153	148	148
query99	777	749	640	640
Total cold run time: 233795 ms
Total hot run time: 150489 ms

@hello-stephen

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

query1	0.00	0.00	0.00
query2	0.09	0.04	0.05
query3	0.26	0.09	0.08
query4	1.60	0.09	0.10
query5	0.24	0.23	0.25
query6	1.17	0.68	0.68
query7	0.04	0.01	0.00
query8	0.06	0.04	0.04
query9	0.41	0.32	0.35
query10	0.61	0.57	0.58
query11	0.20	0.15	0.13
query12	0.18	0.15	0.15
query13	0.51	0.50	0.49
query14	1.01	1.00	1.02
query15	0.63	0.60	0.59
query16	0.35	0.35	0.34
query17	1.10	1.17	1.14
query18	0.21	0.20	0.18
query19	2.13	1.91	1.96
query20	0.02	0.01	0.02
query21	15.48	0.18	0.13
query22	4.93	0.04	0.04
query23	16.30	0.31	0.11
query24	2.97	0.57	0.51
query25	0.12	0.06	0.05
query26	1.49	0.21	0.16
query27	0.06	0.05	0.03
query28	3.54	0.75	0.33
query29	12.49	4.12	3.28
query30	0.28	0.13	0.09
query31	2.76	0.55	0.32
query32	3.23	0.61	0.49
query33	3.24	3.27	3.29
query34	15.47	3.97	3.39
query35	3.32	3.32	3.33
query36	0.56	0.44	0.43
query37	0.09	0.07	0.06
query38	0.04	0.03	0.04
query39	0.03	0.02	0.02
query40	0.17	0.14	0.15
query41	0.08	0.02	0.02
query42	0.03	0.02	0.03
query43	0.05	0.03	0.04
Total cold run time: 97.55 s
Total hot run time: 24.26 s

@mrhhsg

mrhhsg commented Oct 19, 2026

Copy link
Copy Markdown
Member Author

Re-checked the full review history at HEAD ef01c98e4dcfe07e279fde164037bf539e476dc6.

New top-level comments since the previous report (both are benchmark payloads and contain no code finding):

  • IC_kwDOBfSlxs8AAAABdgB7TQ — TPC-DS result on this HEAD.
  • IC_kwDOBfSlxs8AAAABdgHjEg — ClickBench result on this HEAD.

The other entries are /review and run buildall commands, two stale "Codex review failed" notices from 2026-09-22, a local PASS receipt, and TPC-H / TPC-DS / ClickBench / coverage payloads; none contains a code finding.

Previous inline findings — fixed; both threads are resolved and outdated:

  • Sparse-accounting overcount in segment_iterator.cpp: _get_row_ranges_from_conditions() derives each stage's delta through _count_alive_rows() (be/src/storage/segment/segment_iterator.cpp:1162), which uses roaring_bitmap_range_cardinality against the surviving _row_bitmap instead of the dense min/max envelope. DisjointKeyRangesOnlyCountAliveRows (be/test/storage/segment/segment_iterator_key_range_stats_test.cpp:204) covers key ranges {1} and {5000} and asserts RowsStatsFiltered == 1.
  • Trailing DROP TABLE in point_lookup_zone_map_profile.groovy: removed; both tables are dropped only before creation (lines 21 and 161).

Latest automated review: the github-actions review at this exact HEAD (2026-10-19T14:50:49Z) reports no new substantiated issue and states that no previously reported blocking finding remains applicable.

Validation at this HEAD (fresh local run): SegmentIteratorKeyRangeStatsTest.* + SegmentIteratorExprZonemapTest.* — 31 tests, all passed.

The CHANGES_REQUESTED decision dates from the 2026-09-20 automated review; the author cannot dismiss it. Could a maintainer take another look and clear it if the remaining concerns are satisfied?

@mrhhsg

mrhhsg commented Oct 19, 2026

Copy link
Copy Markdown
Member Author

run beut

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 100.00% (1/1) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 77.16% (35767/46354)
Line Coverage 62.44% (403958/646906)
Region Coverage 58.92% (341279/579234)
Branch Coverage 59.81% (157581/263449)

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 100.00% (1/1) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 77.16% (35767/46354)
Line Coverage 62.44% (403953/646906)
Region Coverage 58.90% (341193/579234)
Branch Coverage 59.81% (157575/263449)

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants