Skip to content

[fix](join) Preserve input nullability for ASOF match conditions - #69630

Open
Mryange wants to merge 1 commit into
apache:masterfrom
Mryange:fix-asof-match-input-nullability-master
Open

Mryange wants to merge 1 commit into
apache:masterfrom
Mryange:fix-asof-match-input-nullability-master

Conversation

@Mryange

@Mryange Mryange commented Oct 26, 2026

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: N/A

Related PR: #69616

Problem Summary: Outer ASOF joins can declare a NOT NULL input expression as nullable while BE evaluates the match key before null padding. Root cause: the final AdjustNullable pass uses join output nullability for the match condition. Preserve child input nullability for ASOF match conditions, retaining existing behavior for ordinary joins.

Release note

Fix incorrect nullability in ASOF JOIN match conditions.

Check List (For Author)

  • Test: Added FE unit coverage for all four ASOF join types and a regular LEFT OUTER JOIN control; tests not run locally. Targeted Checkstyle passed with zero violations.
  • Manual diagnosis: The full CTAS reproducer fails on master with nullable output normalization removed (declared=Nullable(DateTimeV2(0)), actual=DATETIMEV2). No post-fix build or runtime validation performed.
  • Behavior changed: Yes. ASOF match conditions retain child input nullability.
  • Does this need documentation: No

### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#69616

Problem Summary: Outer ASOF joins can declare a NOT NULL input expression as nullable while BE evaluates the match key before null padding. Root cause: the final `AdjustNullable` pass uses join output nullability for the match condition. Preserve child input nullability for ASOF match conditions, retaining existing behavior for ordinary joins.

### Release note

Fix incorrect nullability in ASOF JOIN match conditions.

### Check List (For Author)

- Test: Added FE unit coverage for all four ASOF join types and a regular LEFT OUTER JOIN control; tests not run locally. Targeted Checkstyle passed with zero violations.
- Manual diagnosis: The full CTAS reproducer fails on master with nullable output normalization removed (`declared=Nullable(DateTimeV2(0)), actual=DATETIMEV2`). No post-fix build or runtime validation performed.
- Behavior changed: Yes. ASOF match conditions retain child input nullability.
- 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?

@Mryange

Mryange commented Oct 26, 2026

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 both changed files at head e4fe1ff13272ce0ac7a0021ccfacae4b31d1f1c1. No verified new defects were found, and there are no existing inline findings to carry forward.

The change aligns ASOF match expressions with their immediate child inputs: FE translates the match condition before outer output null extension, and BE prepares/evaluates the two match keys against the corresponding child schemas. The helper still registers nullable outer outputs for parent operators. Nullable children, nested outer joins, aliases/casts, ordinary joins, and hash/mark predicates were traced without finding a new mismatch.

Critical checkpoint conclusions:

  1. Goal and evidence: child nullability is retained for ASOF matching. The added outer ASOF cases distinguish the previous ordering by inspection; the inner cases and ordinary LEFT OUTER case provide controls.
  2. Scope and reuse: the change is focused in the existing shared helper, with a small unit-test addition.
  3. Concurrency and locks: no new shared state, thread, lock, I/O, or locking-order change; the map remains local to a sequential rewrite traversal.
  4. Lifecycle and static initialization: no new ownership, resource lifetime, or production static initialization behavior.
  5. Configuration: none added or modified.
  6. Compatibility: no API signature, storage format, or protocol schema change; existing match-condition metadata is corrected.
  7. Thrift/protobuf IDs: no definition changes; cross-branch ID comparison is not applicable.
  8. Parallel paths: analyzed-phase and ordinary-join ordering is retained; all four ASOF enums select the child-input branch. Current SQL/BE execution uses left ASOF variants; right enum cases validate the helper contract. Hash/mark ordering and outer output null extension remain intact.
  9. Conditional logic: the new boolean exactly separates final-phase ordinary joins from ASOF joins, and the comment explains evaluation before padding.
  10. Test coverage: JUnit 5 tests cover all four ASOF enums and a regular LEFT OUTER control. They exercise the helper directly; populated maps, nullable/nested inputs, and parent outputs were checked by static tracing rather than additional executed tests.
  11. Expected results: no regression result files changed; the new nullability expectations agree with the input/output distinction by inspection.
  12. Observability: no new execution path requiring metrics or logging was introduced; existing assertions and error propagation are preserved.
  13. Transactions and persistence: no transaction, EditLog, replay, or failover behavior changed.
  14. Writes and atomicity: no data-write or crash-recovery path changed.
  15. FE-to-BE variables: no new variable or sending point; existing ASOF match serialization carries the corrected metadata.
  16. Performance: the same expression replacement and output-map traversals remain, with one constant-time join-type check and no additional asymptotic work.
  17. Other invariants: no new slot/ExprId, expression-type, error-handling, or query-correctness defect was found. Version visibility, delete bitmaps, and BE allocation ownership are not modified by this patch.

User focus: no additional focus was supplied. Both initial risk items were dismissed with concrete evidence; all assigned reviewers returned NO_NEW_VALUABLE_FINDINGS, with no unresolved candidate or uncovered changed-file scope.

Validation limits: this was a static-only review. No builds, style checks, unit tests, regression tests, or runtime reproducer were run. The new tests do not provide full planner/BE reproduction coverage, and this review does not claim runtime correctness or passing CI.

Review converged after 1 round(s).

@Mryange

Mryange commented Oct 26, 2026

Copy link
Copy Markdown
Contributor Author

run buildall

@HappenLee HappenLee 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 e4fe1ff. No blocking correctness, performance, or reuse issues found. ASOF match conditions now retain immediate child nullability, while null-extended join outputs remain available to parent operators. The change is focused in the existing shared helper.

Non-blocking follow-up: add end-to-end coverage with NOT NULL DATETIMEV2 computed match keys and matched/unmatched rows, plus nullable nested-child and parent-output propagation coverage.

Validation: static review of both changed files and the FE-to-BE call chain; git diff --check passed. No local build, unit test, or SQL regression was run.

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17597	5324	5114	5114
q2	2142	358	256	256
q3	10191	1371	828	828
q4	4678	461	340	340
q5	7444	802	554	554
q6	187	187	158	158
q7	750	835	634	634
q8	9263	1365	1114	1114
q9	5652	4263	4228	4228
q10	6811	1293	1033	1033
q11	425	245	232	232
q12	646	399	295	295
q13	18093	4375	3031	3031
q14	274	277	250	250
q15	q16	719	732	648	648
q17	1206	753	568	568
q18	6958	6212	6116	6116
q19	1114	948	584	584
q20	376	334	224	224
q21	5614	2420	2542	2420
q22	386	332	285	285
Total cold run time: 100526 ms
Total hot run time: 28912 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	6032	5965	6322	5965
q2	739	598	597	597
q3	5676	5808	5334	5334
q4	2095	2166	1563	1563
q5	5582	5763	5581	5581
q6	242	185	142	142
q7	2250	2036	1853	1853
q8	3077	2703	2722	2703
q9	7953	7691	7473	7473
q10	3634	3582	3162	3162
q11	601	416	395	395
q12	676	672	518	518
q13	3383	3607	3088	3088
q14	284	295	266	266
q15	q16	682	681	631	631
q17	7800	7102	6884	6884
q18	12995	12210	12870	12210
q19	948	845	843	843
q20	2147	2157	1929	1929
q21	5947	5029	4974	4974
q22	498	458	447	447
Total cold run time: 73241 ms
Total hot run time: 66558 ms

@hello-stephen

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

query5	4319	606	454	454
query6	430	219	193	193
query7	4803	439	219	219
query8	317	171	150	150
query9	8802	3070	3140	3070
query10	483	313	249	249
query11	6009	3860	3577	3577
query12	156	92	87	87
query13	1247	453	320	320
query14	6066	3926	3645	3645
query14_1	3407	3380	3442	3380
query15	205	197	183	183
query16	941	423	400	400
query17	852	638	530	530
query18	2403	415	304	304
query19	186	168	132	132
query20	84	88	80	80
query21	209	124	104	104
query22	12951	13046	12794	12794
query23	13437	12892	12463	12463
query23_1	12497	12453	12441	12441
query24	7362	843	478	478
query24_1	474	477	476	476
query25	530	416	368	368
query26	1281	260	151	151
query27	2738	445	288	288
query28	4589	1960	1940	1940
query29	1564	593	458	458
query30	304	223	183	183
query31	1017	928	820	820
query32	161	99	97	97
query33	544	311	241	241
query34	887	839	497	497
query35	755	768	653	653
query36	808	834	719	719
query37	133	98	83	83
query38	1777	1752	1647	1647
query39	782	795	738	738
query39_1	730	726	735	726
query40	227	122	100	100
query41	73	71	69	69
query42	90	88	88	88
query43	353	362	322	322
query44	1371	708	703	703
query45	184	174	163	163
query46	858	958	557	557
query47	2930	2910	2659	2659
query48	314	312	232	232
query49	590	420	315	315
query50	716	291	208	208
query51	10643	10830	10437	10437
query52	84	85	74	74
query53	197	214	159	159
query54	262	221	194	194
query55	75	71	66	66
query56	253	242	232	232
query57	1666	1638	1552	1552
query58	297	277	267	267
query59	2240	2170	1999	1999
query60	298	262	250	250
query61	179	166	173	166
query62	397	342	291	291
query63	190	158	162	158
query64	2869	953	761	761
query65	3382	3251	3277	3251
query66	1781	409	294	294
query67	20255	19949	19829	19829
query68	2977	1007	613	613
query69	391	304	254	254
query70	853	752	758	752
query71	303	231	207	207
query72	2707	2552	2246	2246
query73	526	522	294	294
query74	4667	4505	4319	4319
query75	2312	2289	1933	1933
query76	2311	1009	625	625
query77	355	374	272	272
query78	9765	9762	9183	9183
query79	1019	842	517	517
query80	1158	418	334	334
query81	583	310	267	267
query82	808	139	106	106
query83	308	198	179	179
query84	317	125	93	93
query85	867	426	412	412
query86	392	236	224	224
query87	2009	1932	1817	1817
query88	3703	2654	2652	2652
query89	341	284	241	241
query90	1845	172	166	166
query91	169	152	126	126
query92	103	93	88	88
query93	1032	1016	572	572
query94	606	321	280	280
query95	562	338	379	338
query96	667	498	226	226
query97	2437	2414	2311	2311
query98	161	151	147	147
query99	770	757	652	652
Total cold run time: 235739 ms
Total hot run time: 150555 ms

@hello-stephen

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

query1	0.00	0.00	0.01
query2	0.09	0.05	0.05
query3	0.26	0.10	0.10
query4	1.62	0.10	0.11
query5	0.23	0.24	0.24
query6	1.16	0.68	0.67
query7	0.04	0.01	0.01
query8	0.06	0.04	0.04
query9	0.39	0.35	0.35
query10	0.56	0.60	0.57
query11	0.21	0.15	0.14
query12	0.18	0.15	0.15
query13	0.49	0.49	0.49
query14	1.03	1.02	1.02
query15	0.62	0.62	0.61
query16	0.34	0.36	0.35
query17	1.12	1.14	1.12
query18	0.21	0.19	0.19
query19	2.15	2.04	2.01
query20	0.02	0.02	0.01
query21	15.51	0.20	0.13
query22	4.85	0.05	0.05
query23	16.27	0.32	0.13
query24	3.06	0.56	0.34
query25	0.11	0.06	0.04
query26	0.88	0.22	0.14
query27	0.05	0.04	0.06
query28	3.36	0.76	0.37
query29	12.49	4.27	3.26
query30	0.28	0.13	0.10
query31	2.77	0.56	0.32
query32	3.22	0.60	0.51
query33	3.26	3.26	3.17
query34	15.38	4.00	3.39
query35	3.33	3.31	3.33
query36	0.54	0.46	0.42
query37	0.09	0.06	0.07
query38	0.05	0.04	0.04
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.03	0.02
query43	0.04	0.04	0.03
Total cold run time: 96.63 s
Total hot run time: 24.29 s

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

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

@Mryange

Mryange commented Oct 27, 2026

Copy link
Copy Markdown
Contributor Author

run external

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 2.21% (3/136) 🎉
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.

3 participants