Skip to content

[fix](be) Preserve condition cache granule base#65496

Merged
yiguolei merged 4 commits into
apache:masterfrom
Gabriel39:codex/fix-condition-cache-granule-base
Jul 13, 2026
Merged

[fix](be) Preserve condition cache granule base#65496
yiguolei merged 4 commits into
apache:masterfrom
Gabriel39:codex/fix-condition-cache-granule-base

Conversation

@Gabriel39

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: None

Related PR: None

Problem Summary: External file condition-cache entries stored only their survivor bitmap. On a
later cache hit, the physical reader recomputed the bitmap base from the current metadata-pruned
scan plan. If pruning selected a different first row group, bitmap indexes shifted and valid rows
could be silently skipped.

This change stores the bitmap's base granule with the cache value. The V2 table reader restores the
stored base on cache hits, while V2 Parquet and ORC readers derive a base from their current plan
only when producing a new cache entry. V1 reader behavior is unchanged.

Release note

Fix incorrect row filtering when a V2 external file condition-cache hit uses a different pruned
scan plan from the cache-producing scan.

Check List (For Author)

  • Test: Unit Test
    • ParquetScanConditionCacheTest.HitKeepsCachedBaseWhenCurrentPlanStartsLater
    • TableReaderTest.ConditionCacheMissPublishesBitmapAfterReaderEof
    • NewOrcReaderTest.ConditionCacheHitUsesSplitBaseGranule
  • Behavior changed: Yes. V2 condition-cache hits use the bitmap coordinate base stored with the
    cache entry instead of recomputing it from the current scan plan.
  • Does this need documentation: No

### What problem does this PR solve?

Issue Number: None

Related PR: None

Problem Summary: External file condition-cache entries stored only their survivor bitmap. On a
later cache hit, the physical reader recomputed the bitmap base from the current metadata-pruned
scan plan. If pruning selected a different first row group, bitmap indexes shifted and valid rows
could be silently skipped. Store the bitmap's base granule with the cache value, restore it on V2
cache hits, and only derive it from the V2 reader plan when building a cache entry.

### Release note

Fix incorrect row filtering when a V2 external file condition-cache hit uses a different pruned
scan plan from the cache-producing scan.

### Check List (For Author)

- Test: Unit Test
    - `ParquetScanConditionCacheTest.HitKeepsCachedBaseWhenCurrentPlanStartsLater`
    - `TableReaderTest.ConditionCacheMissPublishesBitmapAfterReaderEof`
    - `NewOrcReaderTest.ConditionCacheHitUsesSplitBaseGranule`
- Behavior changed: Yes. V2 condition-cache hits use the bitmap coordinate base stored with the
  cache entry instead of recomputing it from the current scan plan.
- 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?

@Gabriel39

Copy link
Copy Markdown
Contributor Author

run buildall

@Gabriel39 Gabriel39 marked this pull request as ready for review July 12, 2026 06:49
@Gabriel39

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.

I found two data-correctness blockers in the condition-cache coordinate handling.

Critical checkpoint conclusions: the PR's goal is to preserve the V2 cache bitmap origin, but the implementation still allows valid rows to be skipped in two cases. The code change is small, but it changes the shared condition-cache value contract used by both V1 and V2 scanners. I did not find a new locking/lifecycle issue in the LRU cache path. Compatibility/config is a problem because enable_file_scanner_v2 can switch scanners while both modes share the same ExternalCacheKey. Tests cover basic V2 base restore and publish behavior, but not the persisted guard bit or mixed V1/V2 cache consumption. I fetched the exact base and git diff --check passed; I did not run BE unit tests because this runner is missing thirdparty/installed and thirdparty/installed/bin/protoc.

Subagent conclusions: optimizer-rewrite reported no candidates. tests-session-config reported TSC-1, which I accepted as MAIN-002. MAIN-001 was found and verified by the main review. Convergence round 1 ended with both live subagents reporting NO_NEW_VALUABLE_FINDINGS for this exact two-comment set. User focus: no additional user-provided review focus was supplied.

Comment thread be/src/format_v2/table_reader.cpp
Comment thread be/src/storage/segment/condition_cache.h
### What problem does this PR solve?

Issue Number: None

Related PR: apache#65496

Problem Summary: A condition-cache MISS allocated an extra guard bit that was published as if it
covered real rows. A later plan could therefore interpret the false guard as proof that the next
real granule had no matches. In addition, legacy and V2 scanners shared external cache keys even
though only V2 understands the persisted bitmap base. Track the authoritative granule count and
trim allocation-only guards before publication, and version V2 external cache keys to isolate the
base-aware coordinate protocol from legacy entries.

### Release note

Fix condition-cache filtering across changed metadata-pruning plans and mixed scanner modes.

### Check List (For Author)

- Test: Unit Test
    - `ParquetScanConditionCacheTest.*`
    - `TableReaderTest.ConditionCacheMissPublishesBitmapAfterReaderEof`
    - `TableReaderTest.ConditionCacheMissIsDroppedWhenReaderClosesBeforeEof`
    - `NewOrcReaderTest.ConditionCacheMissMarksSurvivingGranules`
    - `NewOrcReaderTest.ConditionCacheHitUsesSplitBaseGranule`
- Behavior changed: Yes. Guard bits are not published as authoritative cache coverage, and V2
  external condition-cache entries cannot be consumed by legacy scanners.
- Does this need documentation: No
@Gabriel39

Copy link
Copy Markdown
Contributor Author

run buildall

@Gabriel39

Copy link
Copy Markdown
Contributor Author

/review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Automated review completed for PR 65496 at head f019e5d.

I found one correctness issue in the ORC V2 condition-cache MISS lifecycle and left it inline. The prior cache-coordinate concerns in existing threads appear addressed by the current head (V2 external key versioning and trim-to-authoritative num_granules), so I did not duplicate them.

Checkpoint conclusions:

  • Goal/test: PR aims to store base-aware condition-cache bitmaps for V2 readers and add focused tests; coverage misses the TableReader + ORC all-stripes-pruned condition-cache path.
  • Scope: Change is focused, but the ORC zero-range lifecycle needs handling.
  • Concurrency/lifecycle: No new shared-lock issue found; lifecycle issue accepted inline for no row reader after ORC pruning.
  • Compatibility: V2 external key is versioned separately from legacy FileScanner; OLAP CacheKey is unaffected.
  • Parallel paths/performance/observability: Parquet and ORC hit paths keep out-of-bitmap rows conservatively; no additional performance or observability blocker found.
  • Tests: Static review only per review prompt; no builds/tests were run. Existing direct ORC EOF coverage does not exercise TableReader condition-cache setup.

User focus: No additional user-provided review focus.

Comment thread be/src/format_v2/orc/orc_reader.cpp Outdated
### What problem does this PR solve?

Issue Number: None

Related PR: apache#65496

Problem Summary: When ORC SARG or min/max pruning removed every stripe, no row reader range was created. The reader still reported the full file row count, so TableReader initialized a condition-cache MISS bitmap and ORC attempted to derive its authoritative granule span from an empty range. Report zero selected rows for this known fully-pruned state so TableReader skips condition-cache setup and the scan completes as EOF.

### Release note

Fix ORC scans with condition cache enabled when all stripes are pruned by statistics.

### Check List (For Author)

- Test: Unit Test
    - NewOrcReaderTest.SargConjunctReturnsEofWhenAllStripesArePruned
    - NewOrcReaderTest.ConditionCacheMissMarksSurvivingGranules
    - NewOrcReaderTest.ConditionCacheHitHandlesSplitWithoutSelectedStripe
    - NewOrcReaderTest.ConditionCacheHitUsesSplitBaseGranule
- Behavior changed: Yes, fully pruned ORC scans no longer initialize or publish a condition-cache MISS bitmap.
- Does this need documentation: No
@Gabriel39

Copy link
Copy Markdown
Contributor Author

run buildall

@Gabriel39

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 the condition-cache follow-up across TableReader, ORC, Parquet, ConditionCache, legacy FileScanner, and internal SegmentIterator paths. I found two issues that should be fixed before this lands.

Critical checkpoint conclusions:

  • Goal/test coverage: the V2 base/guard fixes are mostly covered, but the PR still misses non-adjacent ORC selected ranges and stop-during-read MISS publication.
  • Scope/compatibility: the new external key version separates V2 from legacy FileScanner entries, and internal segment cache behavior is unaffected.
  • Concurrency/lifecycle: scanner stop can still be mistaken for complete physical EOF and publish a partial bitmap.
  • Parallel paths: Parquet HIT filtering is conservative outside the cached span; ORC MISS publication still only records the first selected range span.
  • Validation: static review only, per the review prompt; no builds or tests were run. No additional user focus was provided.

Comment thread be/src/format_v2/orc/orc_reader.cpp Outdated
Comment thread be/src/format_v2/table_reader.cpp
### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#65496

Problem Summary: Extend ORC condition-cache MISS bitmaps across non-adjacent selected stripe ranges, and avoid publishing partial MISS results when a scan is stopped during a read that reports EOF.

### Release note

Fix incomplete condition-cache publication for non-adjacent ORC stripe ranges and stopped scans.

### Check List (For Author)

- Test: Unit Test\n    - TableReader condition-cache tests\n    - ORC non-adjacent stripe-range tests\n- Behavior changed: Yes. Condition-cache MISS entries are only published after complete reads and now cover all selected ORC ranges.\n- Does this need documentation: No
@Gabriel39

Copy link
Copy Markdown
Contributor Author

run buildall

@Gabriel39

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.

Review completed for PR #65496.

I did not find any new non-duplicate correctness issue to raise after the follow-up patch. The previously reported risks around stopped EOF publishing, guard-bit overreach, legacy/V2 cache-coordinate mixing, ORC all-stripe pruning, and ORC non-adjacent selected ranges appear addressed by the current changes.

Checkpoint conclusions:

  • Goal/test: the patch now stores base-aware V2 external condition-cache entries, trims MISS bitmaps to the authoritative span, avoids publishing stop/cancel partial MISS state, handles all-pruned ORC as zero rows, and extends ORC MISS spans across non-adjacent selected ranges. Added BE tests cover these cases plus Parquet cached-base HIT conservatism.
  • Scope: the change is focused on condition-cache coordinate/lifecycle fixes and related tests.
  • Concurrency/lifecycle: the main lifecycle risk is io_ctx->should_stop racing with physical reader EOF conversion; TableReader now samples it after reads and only publishes on real EOF. LIMIT/abort/close-before-EOF paths drop MISS state.
  • Compatibility/parallel paths: V2 external entries use a versioned key, legacy FileScanner remains on version 0, and OLAP segment condition cache uses a separate CacheKey with default base 0. I found no remaining cross-mode coordinate collision.
  • Data correctness/performance: HIT paths stay conservative outside stored bitmap spans, so sparse Parquet/ORC coverage may reduce cache benefit but should not skip valid rows. The added work is small key/base/span bookkeeping and publish-time trimming.
  • Tests/validation: review was static only per the runner instruction; no build or tests were run. Subagent convergence completed with S1/S2/S3/RF1/RF2 and round-2 C1/C2 all returning NO_NEW_VALUABLE_FINDINGS.

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

@hello-stephen

Copy link
Copy Markdown
Contributor

BE UT Coverage Report

Increment line coverage 96.67% (58/60) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 56.90% (23544/41375)
Line Coverage 40.57% (230251/567488)
Region Coverage 36.47% (181896/498781)
Branch Coverage 37.55% (81224/216309)

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17644	3966	3945	3945
q2	2035	329	209	209
q3	10265	1469	830	830
q4	4688	474	340	340
q5	7515	847	578	578
q6	178	167	135	135
q7	775	841	632	632
q8	9365	1619	1544	1544
q9	5711	4396	4424	4396
q10	6796	1834	1518	1518
q11	501	339	307	307
q12	688	550	428	428
q13	18135	3402	2793	2793
q14	265	267	236	236
q15	q16	791	776	717	717
q17	1035	999	878	878
q18	7108	5869	5628	5628
q19	1294	1209	1075	1075
q20	775	641	513	513
q21	5994	2563	2438	2438
q22	419	354	294	294
Total cold run time: 101977 ms
Total hot run time: 29434 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4338	4277	4251	4251
q2	296	315	212	212
q3	4589	4969	4409	4409
q4	2046	2147	1351	1351
q5	4439	4339	4349	4339
q6	225	175	127	127
q7	1730	1851	1845	1845
q8	2591	2194	2204	2194
q9	8089	8211	7796	7796
q10	4766	4710	4251	4251
q11	577	425	383	383
q12	754	793	538	538
q13	3251	3649	2926	2926
q14	297	300	298	298
q15	q16	707	723	653	653
q17	1341	1323	1312	1312
q18	8167	7311	7193	7193
q19	1135	1109	1058	1058
q20	2203	2205	1945	1945
q21	5233	4543	4420	4420
q22	515	438	393	393
Total cold run time: 57289 ms
Total hot run time: 51894 ms

@hello-stephen

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

query5	4298	659	504	504
query6	464	213	206	206
query7	4834	578	339	339
query8	333	188	169	169
query9	8766	4009	4016	4009
query10	471	353	294	294
query11	5943	2366	2178	2178
query12	152	105	104	104
query13	1257	607	440	440
query14	6274	5265	4922	4922
query14_1	4279	4268	4274	4268
query15	220	217	185	185
query16	1011	490	468	468
query17	967	731	595	595
query18	2452	481	351	351
query19	212	193	158	158
query20	114	110	108	108
query21	236	159	136	136
query22	13696	13655	13358	13358
query23	17367	16476	16145	16145
query23_1	16309	16339	16247	16247
query24	7568	1802	1318	1318
query24_1	1316	1298	1314	1298
query25	568	472	385	385
query26	1338	367	211	211
query27	2625	581	390	390
query28	4535	2021	2010	2010
query29	1089	644	498	498
query30	335	268	227	227
query31	1109	1089	974	974
query32	121	65	63	63
query33	553	333	258	258
query34	1159	1149	674	674
query35	764	804	675	675
query36	1415	1424	1238	1238
query37	150	109	96	96
query38	1864	1699	1644	1644
query39	921	920	938	920
query39_1	868	890	898	890
query40	240	164	136	136
query41	72	62	66	62
query42	92	89	91	89
query43	321	326	276	276
query44	1410	793	765	765
query45	206	196	182	182
query46	1077	1192	752	752
query47	2399	2420	2244	2244
query48	394	394	302	302
query49	607	435	312	312
query50	1105	437	342	342
query51	10917	11001	10998	10998
query52	84	85	80	80
query53	256	283	204	204
query54	284	240	211	211
query55	73	70	66	66
query56	287	298	264	264
query57	1455	1411	1317	1317
query58	296	265	250	250
query59	1554	1657	1419	1419
query60	301	266	254	254
query61	151	142	149	142
query62	697	645	565	565
query63	248	208	210	208
query64	2883	1094	866	866
query65	4882	4749	4773	4749
query66	1864	516	443	443
query67	28950	29514	29502	29502
query68	3198	1514	918	918
query69	415	302	257	257
query70	1062	974	973	973
query71	344	326	299	299
query72	3170	2742	2417	2417
query73	845	724	416	416
query74	5097	4972	4786	4786
query75	2611	2564	2234	2234
query76	2317	1150	763	763
query77	353	371	284	284
query78	12458	12083	11800	11800
query79	1401	1134	773	773
query80	1296	565	470	470
query81	534	325	278	278
query82	594	163	122	122
query83	414	326	291	291
query84	331	155	133	133
query85	1012	611	528	528
query86	423	281	264	264
query87	1826	1826	1766	1766
query88	3680	2788	2790	2788
query89	443	399	362	362
query90	1907	193	195	193
query91	203	191	157	157
query92	66	61	55	55
query93	1731	1497	1003	1003
query94	714	353	334	334
query95	769	493	574	493
query96	1066	867	331	331
query97	2690	2694	2569	2569
query98	206	212	204	204
query99	1154	1194	1034	1034
Total cold run time: 265831 ms
Total hot run time: 180729 ms

@hello-stephen

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

query1	0.01	0.01	0.01
query2	0.09	0.05	0.05
query3	0.28	0.14	0.14
query4	1.60	0.14	0.14
query5	0.25	0.22	0.22
query6	1.23	1.10	1.10
query7	0.04	0.01	0.00
query8	0.05	0.04	0.03
query9	0.36	0.33	0.31
query10	0.60	0.53	0.54
query11	0.20	0.14	0.15
query12	0.18	0.14	0.14
query13	0.47	0.46	0.48
query14	1.03	0.98	0.98
query15	0.61	0.58	0.60
query16	0.33	0.30	0.32
query17	1.10	1.10	1.13
query18	0.21	0.21	0.21
query19	2.03	1.96	1.93
query20	0.02	0.01	0.02
query21	15.41	0.23	0.13
query22	4.87	0.05	0.06
query23	16.13	0.31	0.12
query24	2.98	0.42	0.31
query25	0.12	0.04	0.04
query26	0.72	0.21	0.16
query27	0.04	0.03	0.04
query28	3.51	0.89	0.54
query29	12.53	4.06	3.20
query30	0.27	0.16	0.16
query31	2.78	0.58	0.31
query32	3.21	0.59	0.48
query33	3.29	3.18	3.25
query34	15.48	4.29	3.56
query35	3.53	3.50	3.52
query36	0.55	0.45	0.43
query37	0.08	0.06	0.06
query38	0.06	0.04	0.04
query39	0.04	0.03	0.03
query40	0.18	0.16	0.15
query41	0.09	0.03	0.02
query42	0.04	0.03	0.03
query43	0.04	0.04	0.04
Total cold run time: 96.64 s
Total hot run time: 24.95 s

@yiguolei yiguolei merged commit 126bb22 into apache:master Jul 13, 2026
31 of 32 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants