Skip to content

[refactor](search) Simplify Variant search iterator binding - #66449

Merged
eldenmoon merged 1 commit into
apache:masterfrom
eldenmoon:codex/refactor-vsearch-variant-iterator-20260804
Aug 5, 2026
Merged

[refactor](search) Simplify Variant search iterator binding#66449
eldenmoon merged 1 commit into
apache:masterfrom
eldenmoon:codex/refactor-vsearch-variant-iterator-20260804

Conversation

@eldenmoon

Copy link
Copy Markdown
Member

What problem does this PR solve?

Issue Number: None

Related PR: #60847, #63660

Problem Summary:

OlapScanner materializes a requested Variant path as a scan-schema column. For example, data.items.message gets its own SlotRef and scan column position. VariantColumnReader then resolves either direct subcolumn index metadata or metadata inherited from data, and SegmentIterator constructs the runtime iterator for that child column with the complete stored Variant path.

VSearch duplicated that storage responsibility. When the child iterator was absent, it resolved the tablet ColumnId for data, borrowed the parent iterator, and synthesized a stored field name. This mixed scan column positions with tablet ColumnIds and could bypass the path and physical index selection already performed by the storage layer, including NestedGroup selection.

This PR removes the expression-level parent rebinding. VSearch now consumes only the iterator attached to the SlotRef scan column. If that iterator is absent, the field remains an empty index input. It also removes the three fallback-only IndexExecContext APIs and separates SlotRef collection into a small helper that names the scan column index explicitly.

A focused unit test constructs the exact boundary case: the data parent iterator exists, while the data.items.message child iterator does not. The test verifies that SEARCH does not mark or execute the parent iterator.

Release note

Variant SEARCH no longer borrows a parent Variant iterator when the materialized child iterator is absent.

Check List (For Author)

  • Test: Unit Test and Regression Test
    • ASAN BE build: ./build.sh --be
    • Unit Test: 60 tests passed across VSearchExprTest, NestedGroupProviderTest, DefaultNestedGroupReadProviderTest, NestedGroupReaderTest, and NestedGroupPathMatchTest
    • Regression Test: variant_p0/test_variant_search_subcolumn passed; 1 suite, 0 failed, 0 fatal, 0 skipped
    • Format: build-support/check-format.sh passed with clang-format 16
    • Static analysis: build-support/run-clang-tidy.sh was attempted. The actionable function-size diagnostic in this diff was fixed; completion remains blocked by the existing unmatched NOLINTEND in be/src/core/types.h and the toolchain failing to find system stddef.h.
  • Behavior changed: Yes. A missing Variant child iterator now produces an empty index result instead of being reinterpreted through the parent iterator.
  • Does this need documentation: No

### What problem does this PR solve?

Issue Number: None

Related PR: apache#60847, apache#63660

Problem Summary: The scanner materializes Variant path slots, and the storage layer resolves direct or inherited index metadata before constructing an iterator for that child scan column. VSearch additionally tried to resolve a physical parent ColumnId, borrow the parent iterator, and synthesize the stored field name when the child iterator was absent. That duplicated storage ownership, mixed scan column indexes with tablet ColumnIds, and could bypass the path and index selection used by NestedGroup. Remove the expression-level parent rebinding, use only the iterator associated with the SlotRef scan column, remove the fallback-only IndexExecContext APIs, and add a focused parent-present child-missing test.

### Release note

Variant SEARCH no longer borrows a parent Variant iterator when the materialized child iterator is absent.

### Check List (For Author)

- Test: Unit Test and Regression Test
    - ASAN BE build: ./build.sh --be
    - Unit Test: 60 focused VSearch and NestedGroup provider tests passed
    - Regression Test: variant_p0/test_variant_search_subcolumn passed
    - Static analysis: run-clang-tidy was attempted; repository core/types.h NOLINT parsing and system stddef.h discovery errors prevented completion
- Behavior changed: Yes. A missing Variant child iterator now produces an empty index result instead of being reinterpreted through the parent iterator.
- 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?

@eldenmoon

Copy link
Copy Markdown
Member Author

run buildall

1 similar comment
@eldenmoon

Copy link
Copy Markdown
Member Author

run buildall

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17638	3918	3919	3918
q2	1980	315	200	200
q3	10354	1469	814	814
q4	4680	467	338	338
q5	7519	838	542	542
q6	167	166	133	133
q7	742	803	597	597
q8	9736	1640	1561	1561
q9	5754	4035	4025	4025
q10	6757	1622	1373	1373
q11	507	348	334	334
q12	750	564	450	450
q13	18128	3277	2751	2751
q14	262	253	234	234
q15	q16	737	717	653	653
q17	950	1028	985	985
q18	6548	5605	5544	5544
q19	1167	1178	1128	1128
q20	794	682	538	538
q21	5611	2572	2317	2317
q22	427	354	299	299
Total cold run time: 101208 ms
Total hot run time: 28734 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4241	4164	4132	4132
q2	270	319	210	210
q3	4518	4928	4363	4363
q4	2168	2201	1400	1400
q5	4255	4082	4113	4082
q6	229	177	125	125
q7	1689	1598	1403	1403
q8	2612	2083	2057	2057
q9	7293	7122	7270	7122
q10	4342	4284	3924	3924
q11	584	395	359	359
q12	706	730	522	522
q13	3170	3462	3069	3069
q14	305	292	269	269
q15	q16	702	691	644	644
q17	1297	1312	1276	1276
q18	12219	11091	11819	11091
q19	1138	1124	1150	1124
q20	2287	2255	1960	1960
q21	5542	4825	4805	4805
q22	510	465	432	432
Total cold run time: 60077 ms
Total hot run time: 54369 ms

@hello-stephen

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

query5	4300	602	449	449
query6	478	218	208	208
query7	4843	567	323	323
query8	309	162	151	151
query9	8771	4006	4007	4006
query10	478	354	289	289
query11	5858	2233	2018	2018
query12	151	98	94	94
query13	1242	586	429	429
query14	6035	4220	3941	3941
query14_1	3751	3740	3734	3734
query15	204	191	180	180
query16	991	491	454	454
query17	896	683	526	526
query18	2445	453	344	344
query19	204	192	150	150
query20	104	101	101	101
query21	236	155	134	134
query22	13026	13032	12950	12950
query23	15810	14934	14536	14536
query23_1	14676	14628	14714	14628
query24	7516	1742	1223	1223
query24_1	1238	1251	1223	1223
query25	521	415	346	346
query26	1311	341	224	224
query27	2572	647	390	390
query28	4509	2059	2041	2041
query29	1042	578	459	459
query30	338	267	226	226
query31	1164	1105	1048	1048
query32	97	59	58	58
query33	528	285	227	227
query34	1168	1158	665	665
query35	731	743	631	631
query36	767	761	736	736
query37	154	104	91	91
query38	1813	1781	1647	1647
query39	826	822	789	789
query39_1	786	781	781	781
query40	242	162	141	141
query41	65	65	64	64
query42	92	91	92	91
query43	313	314	272	272
query44	1410	781	785	781
query45	185	176	166	166
query46	1069	1232	747	747
query47	1563	1552	1451	1451
query48	417	416	277	277
query49	590	398	325	325
query50	1033	433	324	324
query51	10366	10244	10289	10244
query52	86	86	73	73
query53	254	274	202	202
query54	276	231	219	219
query55	76	73	66	66
query56	280	288	301	288
query57	1032	1015	909	909
query58	299	247	262	247
query59	1566	1609	1383	1383
query60	290	269	245	245
query61	149	142	139	139
query62	392	319	268	268
query63	224	189	206	189
query64	2811	1032	817	817
query65	3898	3800	3836	3800
query66	1828	480	363	363
query67	28584	28208	28062	28062
query68	3147	1523	1008	1008
query69	401	309	291	291
query70	860	776	797	776
query71	354	336	350	336
query72	3192	2822	2493	2493
query73	866	793	450	450
query74	4600	4486	4295	4295
query75	2420	2334	1988	1988
query76	2317	1156	740	740
query77	340	363	270	270
query78	11223	11119	10586	10586
query79	1586	1090	736	736
query80	1235	541	453	453
query81	519	322	279	279
query82	635	172	131	131
query83	358	332	297	297
query84	322	162	130	130
query85	982	591	507	507
query86	407	243	221	221
query87	1988	1948	1817	1817
query88	3778	2848	2875	2848
query89	409	321	277	277
query90	1886	194	188	188
query91	195	190	161	161
query92	60	63	52	52
query93	1760	1466	957	957
query94	709	334	309	309
query95	774	508	560	508
query96	1102	756	365	365
query97	2469	2473	2344	2344
query98	203	207	201	201
query99	730	736	614	614
Total cold run time: 253095 ms
Total hot run time: 165897 ms

@hello-stephen

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

query1	0.01	0.01	0.00
query2	0.09	0.05	0.05
query3	0.24	0.13	0.13
query4	1.61	0.14	0.14
query5	0.24	0.22	0.22
query6	1.16	0.81	0.77
query7	0.03	0.01	0.00
query8	0.06	0.04	0.04
query9	0.36	0.31	0.33
query10	0.54	0.53	0.53
query11	0.18	0.14	0.13
query12	0.18	0.13	0.14
query13	0.46	0.46	0.47
query14	1.00	0.99	0.97
query15	0.59	0.58	0.58
query16	0.30	0.33	0.33
query17	1.11	1.06	1.09
query18	0.21	0.20	0.19
query19	1.96	1.97	1.92
query20	0.02	0.01	0.01
query21	15.45	0.22	0.13
query22	4.88	0.05	0.05
query23	16.14	0.31	0.12
query24	2.90	0.45	0.34
query25	0.11	0.05	0.05
query26	0.74	0.20	0.14
query27	0.04	0.04	0.04
query28	3.55	0.73	0.35
query29	12.52	3.97	3.15
query30	0.27	0.16	0.15
query31	2.79	0.55	0.31
query32	3.23	0.58	0.50
query33	3.13	3.32	3.17
query34	15.64	3.96	3.31
query35	3.27	3.22	3.22
query36	0.55	0.45	0.42
query37	0.09	0.06	0.06
query38	0.05	0.04	0.04
query39	0.04	0.03	0.03
query40	0.17	0.16	0.15
query41	0.09	0.03	0.03
query42	0.04	0.03	0.03
query43	0.04	0.04	0.04
Total cold run time: 96.08 s
Total hot run time: 23.8 s

@eldenmoon
eldenmoon marked this pull request as ready for review August 5, 2026 07:44
Copilot AI lite review requested due to automatic review settings August 5, 2026 07:44
@eldenmoon eldenmoon changed the title [refactor](be) Simplify Variant search iterator binding [refactor](search) Simplify Variant search iterator binding Aug 5, 2026
@eldenmoon

Copy link
Copy Markdown
Member Author

/review

Copilot AI 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.

Pull request overview

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Refactors Variant SEARCH iterator binding to rely solely on the SlotRef’s scan-column iterator, removing the expression-level fallback that borrowed a parent Variant iterator when a materialized subcolumn iterator is missing.

Changes:

  • Removed parent-iterator rebinding logic for Variant subcolumns in VSearchExpr input collection.
  • Introduced a helper to collect SlotRef-based search inputs using explicit scan column indexes.
  • Added a focused unit test covering the “parent iterator exists, child iterator missing” boundary case.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
be/src/exprs/vsearch.cpp Removes parent fallback logic; adds helper to bind SEARCH inputs strictly by scan column index + iterator presence.
be/src/exprs/vexpr_context.h Deletes fallback-only IndexExecContext APIs used by the removed rebinding logic.
be/test/exprs/vsearch_expr_test.cpp Adds a regression-style unit test ensuring missing Variant child iterators do not cause parent iterator usage.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread be/test/exprs/vsearch_expr_test.cpp
Comment thread be/src/exprs/vsearch.cpp
Comment thread be/src/exprs/vsearch.cpp
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Codex automated review failed and did not complete.

Error: All Codex review accounts are usage-limited; earliest retry is 2026-08-08T03:32:00Z.
Workflow run: https://github.com/apache/doris/actions/runs/30986849153

Please trigger /review again after that time.

@eldenmoon

Copy link
Copy Markdown
Member Author

skip check_coverage

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

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

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

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

PR approved by anyone and no changes requested.

@eldenmoon
eldenmoon merged commit 30a699a into apache:master Aug 5, 2026
35 of 37 checks passed
@eldenmoon
eldenmoon deleted the codex/refactor-vsearch-variant-iterator-20260804 branch August 5, 2026 09:47
github-actions Bot pushed a commit that referenced this pull request Aug 5, 2026
Related PR: #60847, #63660
Problem Summary:

OlapScanner materializes a requested Variant path as a scan-schema
column. For example, data.items.message gets its own SlotRef and scan
column position. VariantColumnReader then resolves either direct
subcolumn index metadata or metadata inherited from data, and
SegmentIterator constructs the runtime iterator for that child column
with the complete stored Variant path.

VSearch duplicated that storage responsibility. When the child iterator
was absent, it resolved the tablet ColumnId for data, borrowed the
parent iterator, and synthesized a stored field name. This mixed scan
column positions with tablet ColumnIds and could bypass the path and
physical index selection already performed by the storage layer,
including NestedGroup selection.

This PR removes the expression-level parent rebinding. VSearch now
consumes only the iterator attached to the SlotRef scan column. If that
iterator is absent, the field remains an empty index input. It also
removes the three fallback-only IndexExecContext APIs and separates
SlotRef collection into a small helper that names the scan column index
explicitly.

A focused unit test constructs the exact boundary case: the data parent
iterator exists, while the data.items.message child iterator does not.
The test verifies that SEARCH does not mark or execute the parent
iterator.

### Release note

Variant SEARCH no longer borrows a parent Variant iterator when the
materialized child iterator is absent.
yiguolei pushed a commit that referenced this pull request Aug 6, 2026
#66449 (#66487)

Cherry-picked from #66449

Co-authored-by: lihangyu <lihangyu@selectdb.com>
@yiguolei yiguolei removed the dev/4.1.x label Aug 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by one committer. dev/4.1.4-merged reviewed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants