Skip to content

[fix](be) Fix nested array_map lambda captures#64563

Open
mrhhsg wants to merge 2 commits into
apache:masterfrom
mrhhsg:fix/nested-array-map-crash
Open

[fix](be) Fix nested array_map lambda captures#64563
mrhhsg wants to merge 2 commits into
apache:masterfrom
mrhhsg:fix/nested-array-map-crash

Conversation

@mrhhsg

@mrhhsg mrhhsg commented Jun 16, 2026

Copy link
Copy Markdown
Member

What problem does this PR solve?

Issue Number: None

Problem Summary: Nested array_map expressions can capture variables from an outer lambda while also defining their own lambda arguments. The BE previously assigned lambda argument column offsets by recursively mutating every VColumnRef under the outer lambda. This could make an inner lambda argument reuse the outer lambda block offset and read the wrong column during INSERT ... SELECT, causing a BE crash. This change serializes lambda argument metadata to BE, preserves captured input columns in lambda blocks, and resolves lambda arguments by the current runtime lambda scope while respecting nested-lambda shadowing.

array_sort comparator arguments are intentionally position-based because FE may distinguish the two comparator arguments only by column id. A comparator that captures an outer lambda argument cannot be represented in the current two-column comparator block and could otherwise be silently resolved as one of the comparator arguments. This PR now returns a clear error for unsupported captured column or slot references in array_sort comparators.

A follow-up refactor moves LambdaExecutionContext into be/src/exprs/lambda_function/lambda_execution_context.h. VExprContext now keeps the lambda execution context as a private implementation detail and includes the concrete definition only from vexpr_context.cpp, while lambda functions and VColumnRef include the dedicated lambda header where they need the concrete type.

Release note

Fix nested array_map lambda captures and reject unsupported captured references in array_sort comparators.

Check List (For Author)

  • Test:
    • Unit Test: ./run-be-ut.sh --run --filter=ArrayMapFunctionTest.NamedLambdaWithFewerArgumentsThanArraysUsesDeclaredBindings:ArrayMapFunctionTest.*:VColumnRefTest.*
    • Unit Test: ./run-be-ut.sh --run --filter=ArrayMapFunctionTest.NestedArraySortComparatorCapturingOuterArgumentReturnsError:ArrayMapFunctionTest.NestedArraySortInsideArrayMapSkipsArrayMapArgumentInference
    • Unit Test: ./run-be-ut.sh --run --filter=ArrayMapFunctionTest.*
    • Build: ./build.sh --be --fe
    • Build: ./build.sh --be
    • Regression test: ./run-regression-test.sh --run -d query_p0/sql_functions/array_functions -s test_nested_array_map_insert -forceGenOut
    • Regression test: ./run-regression-test.sh --run -d query_p0/sql_functions/array_functions -s test_nested_array_map_insert
    • Regression test: ./run-regression-test.sh --run -d query_p0/sql_functions/array_functions -s test_nested_array_map
    • Regression test: ./run-regression-test.sh --run -d query_p0/virtual_slot_ref -s fix_array_type_and_lambda_func
    • Regression test: ./run-regression-test.sh --run -d query_p0/virtual_slot_ref
    • Regression test: ./run-regression-test.sh --run -d query_p0/sql_functions/array_functions
    • Format check: ./build-support/clang-format.sh; ./build-support/check-format.sh; git diff --check
    • Static analysis: attempted ./build-support/run-clang-tidy.sh --build-dir be/ut_build_ASAN --base HEAD, but local clang-tidy analysis was blocked by existing/local diagnostics including missing stddef.h, unmatched NOLINTEND in be/src/core/types.h, and pre-existing function-size/cognitive-complexity diagnostics.
    • Static analysis: attempted build-support/run-clang-tidy.sh --build-dir be/build_Release, but it is still blocked by the same existing/toolchain diagnostics.
  • Behavior changed: Yes. Nested lambda arguments are resolved by FE-provided lambda metadata when available; old nested lambda plans without metadata fail fast; unsupported captured references in array_sort comparators now return an error instead of being silently position-bound.
  • 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?

@mrhhsg mrhhsg force-pushed the fix/nested-array-map-crash branch 4 times, most recently from 9bc9cf0 to 9a2a8ec Compare June 18, 2026 09:34
@mrhhsg

mrhhsg commented Jun 22, 2026

Copy link
Copy Markdown
Member Author

run buildall

@hello-stephen

Copy link
Copy Markdown
Contributor

Cloud UT Coverage Report

Increment line coverage 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 77.32% (1889/2443)
Line Coverage 64.40% (33955/52726)
Region Coverage 64.77% (17453/26948)
Branch Coverage 53.95% (9342/17316)

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 83.10% (236/284) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 64.27% (24649/38352)
Line Coverage 48.04% (256501/533893)
Region Coverage 44.75% (211702/473079)
Branch Coverage 45.82% (91900/200568)

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 0.17% (1/585) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17873	4124	3992	3992
q2	2012	314	186	186
q3	10365	1407	840	840
q4	4740	483	339	339
q5	8046	878	597	597
q6	277	175	139	139
q7	807	870	624	624
q8	10595	1693	1656	1656
q9	5997	4531	4556	4531
q10	6834	1803	1529	1529
q11	446	275	245	245
q12	686	435	304	304
q13	18185	3323	2804	2804
q14	270	258	243	243
q15	q16	789	779	712	712
q17	1035	962	997	962
q18	7043	5860	5442	5442
q19	1192	1356	1080	1080
q20	497	417	251	251
q21	5944	2914	2733	2733
q22	459	377	307	307
Total cold run time: 104092 ms
Total hot run time: 29516 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	5116	4767	4694	4694
q2	337	391	247	247
q3	4879	5314	4649	4649
q4	2087	2147	1397	1397
q5	5071	4627	4744	4627
q6	227	187	126	126
q7	1862	1720	1534	1534
q8	2416	2113	2098	2098
q9	7532	7385	7369	7369
q10	4748	4635	4203	4203
q11	523	377	347	347
q12	738	740	526	526
q13	2944	3333	2780	2780
q14	270	277	258	258
q15	q16	678	695	612	612
q17	1275	1256	1250	1250
q18	7387	6947	6979	6947
q19	1146	1124	1111	1111
q20	2223	2220	1936	1936
q21	5309	4596	4438	4438
q22	527	455	407	407
Total cold run time: 57295 ms
Total hot run time: 51556 ms

@hello-stephen

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

query5	4309	613	471	471
query6	423	187	173	173
query7	4838	566	301	301
query8	359	210	204	204
query9	8753	4030	4017	4017
query10	439	306	261	261
query11	5852	2319	2123	2123
query12	161	107	100	100
query13	1253	603	433	433
query14	6324	5364	5040	5040
query14_1	4401	4339	4383	4339
query15	208	198	178	178
query16	1059	462	464	462
query17	1139	711	583	583
query18	2738	482	349	349
query19	210	186	147	147
query20	125	114	106	106
query21	217	143	121	121
query22	13624	13681	13403	13403
query23	17348	16570	16170	16170
query23_1	16398	16243	16270	16243
query24	7564	1782	1351	1351
query24_1	1335	1324	1321	1321
query25	557	454	398	398
query26	1320	339	179	179
query27	2601	558	342	342
query28	4427	2025	2036	2025
query29	1088	619	488	488
query30	310	233	201	201
query31	1138	1068	961	961
query32	104	61	59	59
query33	563	315	249	249
query34	1150	1220	668	668
query35	743	793	671	671
query36	1361	1416	1196	1196
query37	162	107	85	85
query38	1877	1710	1654	1654
query39	937	908	896	896
query39_1	877	869	872	869
query40	215	119	95	95
query41	63	61	62	61
query42	87	88	89	88
query43	317	319	282	282
query44	1437	775	779	775
query45	202	183	176	176
query46	1086	1208	714	714
query47	2343	2338	2247	2247
query48	414	427	292	292
query49	647	458	358	358
query50	955	353	254	254
query51	4460	4297	4280	4280
query52	80	80	69	69
query53	252	260	190	190
query54	271	230	204	204
query55	72	70	66	66
query56	227	212	220	212
query57	1430	1398	1328	1328
query58	225	215	213	213
query59	1578	1617	1376	1376
query60	270	250	221	221
query61	149	148	148	148
query62	698	649	585	585
query63	233	187	186	186
query64	2482	782	594	594
query65	4852	4747	4762	4747
query66	1728	466	342	342
query67	29767	29649	29620	29620
query68	3074	1521	996	996
query69	401	310	267	267
query70	1063	972	962	962
query71	297	231	214	214
query72	2933	2635	2350	2350
query73	856	784	429	429
query74	5129	4990	4750	4750
query75	2651	2615	2213	2213
query76	2332	1187	772	772
query77	345	379	285	285
query78	12439	12555	11941	11941
query79	1425	1201	773	773
query80	707	464	363	363
query81	477	282	240	240
query82	577	152	119	119
query83	334	269	243	243
query84	263	142	111	111
query85	922	524	413	413
query86	413	301	303	301
query87	1829	1833	1750	1750
query88	3705	2774	2756	2756
query89	423	375	334	334
query90	1887	190	185	185
query91	168	157	133	133
query92	61	61	63	61
query93	1559	1441	1029	1029
query94	632	362	327	327
query95	702	385	439	385
query96	1074	817	350	350
query97	2754	2688	2551	2551
query98	220	209	197	197
query99	1160	1162	1033	1033
Total cold run time: 257904 ms
Total hot run time: 172456 ms

@hello-stephen

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

query1	0.00	0.00	0.01
query2	0.10	0.05	0.05
query3	0.25	0.14	0.13
query4	1.61	0.14	0.14
query5	0.24	0.22	0.22
query6	1.26	1.03	1.05
query7	0.04	0.00	0.00
query8	0.09	0.04	0.04
query9	0.38	0.31	0.32
query10	0.54	0.54	0.53
query11	0.20	0.14	0.14
query12	0.18	0.15	0.15
query13	0.47	0.47	0.47
query14	1.01	1.02	1.00
query15	0.62	0.59	0.59
query16	0.32	0.32	0.31
query17	1.11	1.07	1.11
query18	0.22	0.23	0.20
query19	2.06	2.01	1.97
query20	0.02	0.01	0.01
query21	15.45	0.23	0.13
query22	4.75	0.06	0.05
query23	16.13	0.31	0.13
query24	3.07	0.42	0.32
query25	0.11	0.05	0.05
query26	0.73	0.21	0.14
query27	0.04	0.04	0.04
query28	3.54	0.87	0.54
query29	12.46	4.33	3.45
query30	0.28	0.15	0.16
query31	2.78	0.61	0.30
query32	3.22	0.59	0.48
query33	3.22	3.18	3.29
query34	15.69	4.26	3.58
query35	3.57	3.52	3.48
query36	0.55	0.43	0.42
query37	0.08	0.07	0.07
query38	0.04	0.04	0.03
query39	0.04	0.03	0.03
query40	0.17	0.16	0.15
query41	0.09	0.03	0.02
query42	0.04	0.03	0.03
query43	0.04	0.04	0.03
Total cold run time: 96.81 s
Total hot run time: 25.16 s

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 76.73% (244/318) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 74.13% (28431/38353)
Line Coverage 58.03% (309792/533862)
Region Coverage 54.80% (259237/473086)
Branch Coverage 56.12% (112564/200581)

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 100.00% (1/1) 🎉
Increment coverage report
Complete coverage report

@mrhhsg mrhhsg marked this pull request as ready for review June 22, 2026 15:50
@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 76.73% (244/318) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 74.13% (28431/38353)
Line Coverage 58.03% (309795/533862)
Region Coverage 54.84% (259443/473086)
Branch Coverage 56.12% (112565/200581)

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 100.00% (1/1) 🎉
Increment coverage report
Complete coverage report

@mrhhsg

mrhhsg commented Jun 23, 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.

Automated review completed. I found one correctness issue requiring changes.

Critical checkpoint conclusions:

  • Goal/test coverage: the PR addresses nested array_map binding and adds focused BE, FE, and regression coverage, but the submitted inline issue shows a remaining nested-lambda path in array_sort comparators that is neither covered nor handled correctly.
  • Scope/focus: the main changes are focused around lambda metadata and BE lambda execution; the remaining issue is in a parallel lambda execution path touched by the PR.
  • Concurrency/lifecycle: no new concurrency, locking, or lifecycle risk was found in the changed code.
  • Configuration/compatibility: no config was added. The thrift field is optional; old-FE missing lambda metadata is intentionally fail-fast in new BE, and I did not find a separate actionable compatibility issue beyond the submitted inline comment.
  • Parallel paths: nested array_map captures are handled, but nested lambdas inside array_sort comparators still cannot capture comparator-local arguments.
  • Test/style state: Linux compile, BE UT, P0 regression, CheckStyle, and clang-format checks are passing in GitHub checks. The macOS BE UT failure appears environmental (JDK 25 where the job requires JDK 17). The external coverage check is failing, but I could not tie it to a concrete code-review finding from the available evidence.

Subagent conclusions:

  • optimizer-rewrite proposed OPT-1; I independently verified it and submitted it as the inline comment.
  • tests-session-config found no new candidate.
  • Convergence round 1 ended with both live subagents replying NO_NEW_VALUABLE_FINDINGS for the current ledger/comment set after the last candidate update.

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

return Status::OK();
}

if (expr->is_slot_ref() || expr->is_virtual_slot_ref()) {

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.

This skips the nested lambda body, but the comparator frame installed during execution has bind_by_name = false, parent_bindings_visible = false, and no argument bindings. For a valid lexical shape such as array_sort((x, y) -> array_map(z -> z + x, [1, 2]), arr), the x captured by the nested array_map is not processed by this walker. At execution the inner array_map pushes a named z frame; VColumnRef("x") searches that frame, then hits the anonymous comparator frame and stops, so _get_column_position() returns -1 instead of resolving the comparator's current x. That turns a capture of the comparator's own argument into an internal "input block not contain column ref" error. Please either make comparator arguments available to nested lambda frames without breaking the direct x/y ordinal handling, or reject this nested-capture shape during prepare.

zhangstar333
zhangstar333 previously approved these changes Jun 25, 2026
@github-actions github-actions Bot added the approved Indicates a PR has been approved by one committer. label Jun 25, 2026
@github-actions

Copy link
Copy Markdown
Contributor

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

virtual doris::Status prepare(RuntimeState* state) {
virtual doris::Status prepare(RuntimeState* state, const VExprSPtrs& children) {
static_cast<void>(children);
batch_size = state->batch_size();

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.

新加的这行代码要干什么?

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

The name-based binding rewrite (serializing lambda argument names and resolving by a runtime scope stack) is sound, and the lifetime is safe — Frame/Binding hold only a std::string name and an int column position by value (no column pointer), columns are re-fetched by position from the live block, and FrameGuard is a move-only RAII push/pop. Two issues:

  1. array_sort comparator with a nested array_map capturing the comparator argument fails at runtime. In varray_sort_function.cpp, _set_comparator_argument_gap recurses from i=1 and skips the nested lambda body, so a VColumnRef to the comparator argument never gets its gap set. During execution the inner array_map pushes a named frame while the comparator frame has bind_by_name=false / parent_bindings_visible=false, so resolution returns position -1 and the query fails with an opaque "input block not contain column ref" error. This is valid SQL (e.g. array_sort((x,y) -> array_map(z -> z + x, ...), arr)); please reject it explicitly during prepare with a clear message instead of failing at execution.

  2. Performance regression: all input columns are materialized. varray_map_function.cpp sets the lambda argument base to block->columns() and repeats every input column (convert_to_full_column_if_const + insert_many_from per array-row per batch), whereas the previous code only materialized columns the lambda body references. For wide tables (INSERT ... SELECT with array_map) this raises CPU/memory noticeably. This is a deliberate trade-off for correctness (deeply-nested references can't be found by static analysis), but it should be called out in the PR description, and ideally narrowed to referenced columns plus any nested-capture set.

Issue Number: None

Related PR: None

Problem Summary: Nested lambda expressions can contain lambda argument ColumnRefs with the same column ids as outer lambda arguments. Binding lambda arguments only by column id makes BE unable to distinguish current-scope arguments from captured outer arguments, especially when inner lambdas shadow outer argument names. This change serializes per-lambda argument names through a dedicated Thrift field, uses scope-aware name binding in BE, lets inner lambda argument names shadow outer ones, and keeps a legacy single-layer fallback that infers lambda arguments from ColumnRef ids. For old FE nested lambda plans without lambda metadata, BE now returns a clear error instead of executing ambiguous bindings.

Fix nested lambda argument binding for array_map. Nested lambda plans from old FE versions without lambda metadata now return an error.

- Test:
    - Unit Test: ./run-fe-ut.sh --run org.apache.doris.analysis.ExprToThriftBehaviorTest
    - Unit Test: ./run-be-ut.sh --run --filter=ArrayMapFunctionTest.*:VColumnRefTest.*
    - Regression test: doris-local-regression all -d query_p0/sql_functions/array_functions -s test_nested_array_map -forceGenOut
    - Regression test: doris-local-regression start && doris-local-regression run -d query_p0/sql_functions/array_functions -s test_nested_array_map
    - Format: git diff --check; build-support/check-format.sh
- Behavior changed: Yes. Nested lambda arguments are resolved by FE-provided argument names, and old FE nested lambda plans without metadata fail fast.
- Does this need documentation: No
@mrhhsg

mrhhsg commented Jun 25, 2026

Copy link
Copy Markdown
Member Author

/review

@github-actions github-actions Bot removed the approved Indicates a PR has been approved by one committer. label Jun 25, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I found one correctness issue in the new array_sort nested-lambda rejection path.

Critical checkpoint conclusions:

  • Goal/test: The new nested array_map scope model is covered by BE unit tests and a regression suite, but the array_sort comparator shadowing case below is not covered.
  • Scope and compatibility: The optional lambda_argument_names behavior was reviewed. The old-FE/no-metadata nested array_map failure is documented by the PR and tests as an intentional fail-fast path, so I did not raise it as a separate issue.
  • Parallel/special paths: Direct array_map binding, VColumnRef name resolution, VExprContext cloning, and regression expected outputs look coherent. The remaining problem is specifically the array_sort comparator path where FE distinguishes comparator operands by column id while the new nested-capture rejection checks only names.
  • Existing threads: This is distinct from the existing array_sort nested-capture thread because the PR added a rejection, but the new rejection still misses the second comparator operand when it is serialized with the first operand name.
  • Verification: Scoped git diff --check over the PR changed-file list is clean. I did not run the full BE/FE build or test suites locally.

Subagent conclusions:

  • optimizer-rewrite: OPT-1 was accepted and submitted as the inline comment.
  • tests-session-config: TEST-1 was dismissed with evidence because the old-FE/no-metadata nested plan behavior is explicit in the PR body and tests.
  • Convergence round 1 ended with both live subagents replying NO_NEW_VALUABLE_FINDINGS for the same final ledger/comment set.

User focus: No additional user-provided focus was specified.

// argument instead of an unsupported capture from the array_sort comparator.
if (expr->is_column_ref()) {
if (std::ranges::find(in_scope_lambda_argument_names, expr->expr_name()) !=
in_scope_lambda_argument_names.end()) {

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.

This local-name check still misses captures of the second comparator argument. visitArraySort() builds the second comparator ref by cloning the first one and changing only column_id to 1, so a body reference to comparator y can arrive here as ColumnRef(name="x", column_id=1). If an inner lambda also declares x, this branch returns OK before looking at the column id, and runtime name resolution binds the ref to the inner x frame. A shape like array_sort((x, y) -> array_map(x -> x + y, [1, 2]), arr) is then accepted and evaluates the capture as x + x instead of rejecting the unsupported comparator capture. Please either make this validation consider comparator column ids, or serialize the second comparator ref with its own name before relying on name-based shadowing.

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 80.00% (300/375) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 74.22% (28488/38384)
Line Coverage 58.05% (310191/534389)
Region Coverage 54.89% (259929/473560)
Branch Coverage 56.11% (112706/200867)

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 20.00% (1/5) 🎉
Increment coverage report
Complete coverage report

Comment thread be/src/exprs/lambda_function/varray_map_function.cpp
ref->set_gap(lambda_argument_base + argument_index - ref->column_id());
}
return Status::OK();
}

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.

else,to remove 414 return

}
}

LambdaExecutionContext& VExprContext::lambda_execution_context() {

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.

更好的是 lazy init

LambdaExecutionContext& VExprContext::lambda_execution_context() {
if (!_lambda_execution_context) {
_lambda_execution_context = std::make_unique();
}
return *_lambda_execution_context;
}

Comment thread be/src/exprs/vcolumn_ref.h Outdated

int _column_id;
std::atomic<int> _gap = 0;
std::atomic<bool> _gap_set = false;

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.

感觉用-1初始化_gap就能规避这个变量了,你看看是否可以


private:
int _get_column_position(VExprContext* context, const Block* block) const {
if (context != nullptr) {

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.

这个什么情况下会是空指针呢?

Comment thread be/src/exprs/vcolumn_ref.h Outdated
int _get_column_position_without_context(const Block* block) const {
if (!_gap_set.load()) {
const int position_by_name = _find_column_position_by_name(block);
if (position_by_name >= 0) {

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.

如果else的话,不应该是报错吗

}

int _find_column_position_by_name(const Block* block) const {
if (block == nullptr) {

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.

这个block也不应是空的,你把这个空指针的check代码都梳理一下

names.reserve(lambda_argument_base + arguments.size());
data_types.reserve(lambda_argument_base + arguments.size());
for (int column_id : required_input_column_ids) {
if (column_id < 0 || block == nullptr ||

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.

这种随意判空的逻辑都去掉哈

Issue Number: None

Related PR: None

Problem Summary: Legacy lambda argument binding updated VColumnRef gap fields on shared expression nodes during execution. Since VExprContext clones share the same root expression tree, that mutable per-execution binding state can race across cloned contexts. This change moves legacy positional lambda bindings into LambdaExecutionContext::Frame, resolves VColumnRef by frame column id for positional frames, and removes the mutable gap fields from VColumnRef. Array sort comparator bindings are also represented as comparator-local positional frame entries.

None

- Test:
    - Unit Test: ./run-be-ut.sh --run --filter=VColumnRefTest.*:ArrayMapFunctionTest.*
    - Format: git diff --check; build-support/check-format.sh
    - Static Analysis: build-support/run-clang-tidy.sh --build-dir be/ut_build_ASAN (attempted; failed on existing/toolchain diagnostics including missing stddef.h, unmatched NOLINTEND in core/types.h, and pre-existing function-size/complexity warnings)
- Behavior changed: No
- Does this need documentation: No
@hello-stephen

Copy link
Copy Markdown
Contributor

BE UT Coverage Report

Increment line coverage 79.89% (298/373) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 55.02% (21665/39374)
Line Coverage 38.48% (207037/537987)
Region Coverage 34.53% (162877/471664)
Branch Coverage 35.56% (71378/200714)

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 79.78% (296/371) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 74.33% (28564/38431)
Line Coverage 58.16% (311053/534788)
Region Coverage 54.92% (260202/473764)
Branch Coverage 56.25% (113044/200957)

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 100.00% (1/1) 🎉
Increment coverage report
Complete coverage report

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.

5 participants