Skip to content

[fix](rbo) Preserve semantics in predicate inference - #67919

Open
feiniaofeiafei wants to merge 2 commits into
apache:masterfrom
feiniaofeiafei:codex/fix-predicate-inference-semantics
Open

[fix](rbo) Preserve semantics in predicate inference#67919
feiniaofeiafei wants to merge 2 commits into
apache:masterfrom
feiniaofeiafei:codex/fix-predicate-inference-semantics

Conversation

@feiniaofeiafei

Copy link
Copy Markdown
Collaborator

What problem does this PR solve?

Problem Summary:

Fix two predicate inference errors that change query results:

  • chooseInputPredicates records a retained GT/GTE predicate as EQ. The false equality can make another necessary predicate appear redundant. For example, a > b AND rn > b AND a > rn can lose a > rn and return extra rows in a QUALIFY query. Record the actual relation in the working graph.
  • Comparison-equal operands are not interchangeable inside arbitrary expressions. DATE and DATETIME values can compare equal but have different string lengths; negative and positive floating-point zero compare equal but have different SIGNBIT results. Substitution can therefore add filters that discard matching rows. Restrict expression substitution to exactly matching supported scalar types with value-preserving equality. Preserve direct comparisons, IN and their negations on the unwrapped operand, along with the existing determinism and cast-analysis checks.

The fixes are in separate commits. Shared cast extraction is unchanged, and existing regression expectations are unchanged.

Release note

Fix extra or missing rows caused by incorrect predicate inference, including QUALIFY inequality chains and substitutions inside type-sensitive or representation-sensitive expressions.

Check List (For Author)

  • Test:
    • Regression test: all six suites passed: infer_predicate_qualify, infer_predicate_replace_type, infer_unequal_predicates, extend_infer_equal_predicate, infer_predicate, and infer_datetimev2_cast_precision. New expected files were generated by the regression runner and verified by rerunning the suites.
    • Unit Test: all 65 tests in UnequalPredicateInferTest and InferPredicateByReplaceTest passed. New inequality checks cover 234 relation/order/qualifier combinations with 64 value assignments per combination. Substitution tests cover type/precision boundaries, signed zero, safe same-type substitutions, widening casts, and direct comparison/IN/NOT IN propagation.
    • Manual test: reproduced extra QUALIFY rows and missing DATE/signed-zero rows before deployment; the rebuilt FE returned the expected results. Verified the deployed FE jar checksum.
    • Build: DISABLE_BUILD_UI=ON ./build.sh --fe passed, including Checkstyle.
  • Behavior changed:
    • Yes. Necessary inequalities are retained and unsafe expression substitutions are rejected while direct comparison propagation is preserved.
  • Does this need documentation?
    • No.

Check List (For Reviewer who merge this PR)

  • Confirm the release note
  • Confirm test cases
  • Confirm document
  • Add branch pick label

### What problem does this PR solve?

Problem Summary: Predicate inference records retained greater-than and greater-than-or-equal predicates as equalities. The false equality can make another necessary input predicate appear redundant. A QUALIFY condition a > b AND rn > b AND a > rn can consequently lose a > rn and return extra rows. Record the retained predicate's actual relation in the working graph.

### Release note

Fix extra rows returned when inequality predicate inference removes a necessary filter, including QUALIFY queries over window outputs.

### Check List (For Author)

- Test: Unit Test / Regression test / Manual test
    - All 25 UnequalPredicateInferTest tests passed. New semantic checks cover 234 relation/order/qualifier combinations and 64 value assignments per combination; the new test fails on the unmodified baseline.
    - infer_predicate_qualify passed after generating expected output with the regression runner and rerunning comparisons.
    - DISABLE_BUILD_UI=ON ./build.sh --fe passed, including Checkstyle. Deployed the FE library and verified the SQL wrong-result reproducer.
- Behavior changed: Yes. Necessary inequality predicates are retained.
- Does this need documentation: No.
### What problem does this PR solve?

Problem Summary: Comparison equality does not imply that raw operands are interchangeable inside arbitrary expressions. Replacing a DATE slot with an equal DATETIME slot changes CAST-to-string output, and replacing negative floating-point zero with positive zero changes SIGNBIT. Predicate inference can therefore add filters not implied by the query and discard matching rows.

Restrict substitution inside expressions to exactly matching supported scalar types with value-preserving equality. Keep direct comparisons, IN and their negations on the unwrapped operand, while retaining the existing determinism and cast-analysis checks. Do not change the shared cast extraction or inequality inference paths.

### Release note

Fix missing rows caused by inferred predicates that substitute comparison-equal values inside type-sensitive or representation-sensitive expressions.

### Check List (For Author)

- Test: Unit Test / Regression test / Manual test
    - All 65 tests in InferPredicateByReplaceTest and UnequalPredicateInferTest passed. New tests cover type/precision boundaries, floating-point signed zero, safe same-type substitutions, widening casts, and direct comparison/IN/NOT IN propagation.
    - Six regression suites passed: infer_predicate_replace_type, infer_predicate_qualify, infer_unequal_predicates, extend_infer_equal_predicate, infer_predicate, infer_datetimev2_cast_precision. Existing expected files are unchanged; new expected files were generated with the regression runner.
    - Date/string-length and signed-zero SQL witnesses returned no rows before the fix and the expected rows after deployment.
    - DISABLE_BUILD_UI=ON ./build.sh --fe passed, including Checkstyle. Deployed the final FE lib to the test cluster and verified the jar checksum.
- Behavior changed: Yes. Unsafe expression substitutions are rejected while direct comparison propagation is preserved.
- 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?

@feiniaofeiafei

Copy link
Copy Markdown
Collaborator Author

run buildall

@morrySnow morrySnow changed the title [fix](fe) Preserve semantics in predicate inference [fix](rbo) Preserve semantics in predicate inference Sep 14, 2026
@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17654	3033	2999	2999
q2	2068	250	213	213
q3	10280	860	512	512
q4	4668	245	208	208
q5	7675	561	383	383
q6	136	114	92	92
q7	541	495	383	383
q8	9237	860	952	860
q9	3463	2395	2353	2353
q10	6525	849	748	748
q11	397	197	180	180
q12	614	261	202	202
q13	18120	1519	1160	1160
q14	155	157	140	140
q15	q16	433	393	371	371
q17	1373	901	813	813
q18	3086	2232	2238	2232
q19	1133	893	779	779
q20	366	276	197	197
q21	5341	1616	1826	1616
q22	324	264	227	227
Total cold run time: 93589 ms
Total hot run time: 16668 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	3392	3336	3319	3319
q2	510	392	370	370
q3	2308	2278	2157	2157
q4	1186	1163	903	903
q5	2184	2098	2088	2088
q6	172	121	86	86
q7	1031	907	868	868
q8	1590	1378	1396	1378
q9	3085	3067	3074	3067
q10	1850	1844	1642	1642
q11	360	262	246	246
q12	449	429	342	342
q13	1474	1542	1150	1150
q14	167	173	161	161
q15	q16	389	396	359	359
q17	3586	3253	3252	3252
q18	4789	4412	4736	4412
q19	898	788	850	788
q20	1047	999	814	814
q21	3831	3087	3349	3087
q22	395	353	307	307
Total cold run time: 34693 ms
Total hot run time: 30796 ms

@hello-stephen

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

query5	4262	422	337	337
query6	384	140	120	120
query7	4947	416	235	235
query8	288	125	119	119
query9	8682	2895	2866	2866
query10	392	220	186	186
query11	5389	1018	899	899
query12	120	71	76	71
query13	1184	427	309	309
query14	5938	2203	2070	2070
query14_1	1992	1976	1989	1976
query15	174	119	111	111
query16	914	371	370	370
query17	786	454	360	360
query18	2333	337	249	249
query19	171	148	111	111
query20	90	69	73	69
query21	197	108	94	94
query22	5307	5346	5323	5323
query23	6804	6143	6126	6126
query23_1	6017	6166	6054	6054
query24	7279	1103	776	776
query24_1	783	789	785	785
query25	422	306	257	257
query26	1232	232	128	128
query27	2781	415	254	254
query28	4687	1494	1481	1481
query29	929	439	352	352
query30	258	158	130	130
query31	827	400	334	334
query32	129	77	76	76
query33	459	223	186	186
query34	990	857	493	493
query35	394	398	359	359
query36	559	578	520	520
query37	123	82	100	82
query38	996	840	826	826
query39	506	485	517	485
query39_1	473	473	478	473
query40	196	90	73	73
query41	52	49	49	49
query42	71	71	70	70
query43	239	239	213	213
query44	979	531	540	531
query45	109	107	99	99
query46	785	859	530	530
query47	735	743	704	704
query48	310	320	236	236
query49	540	235	188	188
query50	735	259	199	199
query51	8148	8083	8052	8052
query52	72	68	63	63
query53	193	205	156	156
query54	205	159	151	151
query55	73	57	55	55
query56	224	178	154	154
query57	687	777	613	613
query58	199	184	175	175
query59	1233	1216	1090	1090
query60	228	195	180	180
query61	134	113	106	106
query62	353	198	183	183
query63	167	144	140	140
query64	2804	726	614	614
query65	1623	1586	1547	1547
query66	1922	251	214	214
query67	9926	9701	9715	9701
query68	2988	1203	758	758
query69	340	222	191	191
query70	673	598	609	598
query71	255	173	169	169
query72	2299	1694	1485	1485
query73	623	578	348	348
query74	1990	1231	1143	1143
query75	1178	1095	952	952
query76	2384	712	534	534
query77	257	258	204	204
query78	3934	3530	3192	3192
query79	2345	866	568	568
query80	1604	324	275	275
query81	494	155	132	132
query82	608	129	92	92
query83	323	208	193	193
query84	305	111	86	86
query85	828	391	344	344
query86	392	177	170	170
query87	1015	977	880	880
query88	2777	2101	2109	2101
query89	283	193	175	175
query90	1931	129	118	118
query91	131	115	97	97
query92	81	71	69	69
query93	1399	1169	691	691
query94	613	254	221	221
query95	519	253	235	235
query96	802	562	280	280
query97	1064	1052	1026	1026
query98	178	143	133	133
query99	421	345	307	307
Total cold run time: 177585 ms
Total hot run time: 82069 ms

@hello-stephen

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

query1	0.00	0.01	0.00
query2	0.07	0.03	0.04
query3	0.26	0.11	0.09
query4	1.60	0.09	0.09
query5	0.17	0.16	0.15
query6	1.30	0.71	0.68
query7	0.03	0.01	0.00
query8	0.04	0.02	0.03
query9	0.29	0.23	0.21
query10	0.37	0.34	0.34
query11	0.16	0.12	0.12
query12	0.15	0.12	0.12
query13	0.31	0.32	0.31
query14	0.47	0.44	0.44
query15	0.36	0.35	0.35
query16	0.20	0.22	0.23
query17	0.70	0.70	0.71
query18	0.18	0.17	0.16
query19	1.22	1.21	1.21
query20	0.01	0.01	0.01
query21	15.46	0.17	0.12
query22	5.08	0.04	0.05
query23	16.18	0.26	0.10
query24	2.99	0.30	0.29
query25	0.10	0.05	0.04
query26	0.87	0.16	0.12
query27	0.03	0.03	0.03
query28	3.68	0.56	0.26
query29	12.48	3.11	2.56
query30	0.26	0.10	0.12
query31	2.76	0.37	0.18
query32	3.54	0.32	0.24
query33	1.44	1.37	1.46
query34	15.36	2.24	1.78
query35	1.75	1.71	1.71
query36	0.45	0.28	0.28
query37	0.06	0.04	0.04
query38	0.05	0.03	0.03
query39	0.03	0.02	0.02
query40	0.11	0.07	0.08
query41	0.07	0.03	0.02
query42	0.04	0.02	0.02
query43	0.03	0.03	0.03
Total cold run time: 90.71 s
Total hot run time: 14.7 s

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 93.33% (14/15) 🎉
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.

2 participants