This is an automated email from the ASF dual-hosted git repository.
yiguolei pushed a commit to branch branch-4.2
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-4.2 by this push:
new 6281a99c31a branch-4.2: [fix](infer-predicate) Preserve datetime
precision in predicate inference #67653 (#70015)
6281a99c31a is described below
commit 6281a99c31ac35e05e58bcf1beaf6b9880cdf2a6
Author: morrySnow <[email protected]>
AuthorDate: Tue Nov 3 16:59:36 2026 +0800
branch-4.2: [fix](infer-predicate) Preserve datetime precision in predicate
inference #67653 (#70015)
picked from master #67653
Co-authored-by: feiniaofeiafei <[email protected]>
---
.../doris/nereids/util/PredicateInferUtils.java | 4 +-
.../rules/rewrite/InferPredicateByReplaceTest.java | 26 +++++++++++
.../infer_datetimev2_cast_precision.out | 7 +++
.../infer_datetimev2_cast_precision.groovy | 50 ++++++++++++++++++++++
4 files changed, 86 insertions(+), 1 deletion(-)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/PredicateInferUtils.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/PredicateInferUtils.java
index d6f7dfc145c..2a3ac016c49 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/PredicateInferUtils.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/PredicateInferUtils.java
@@ -156,7 +156,9 @@ public class PredicateInferUtils {
if (childType.isTimeStampNsType()) {
return Optional.empty();
}
- return validForInfer(child, inferType);
+ if (!(childType instanceof DateTimeV2Type) ||
childType.isInjectiveCastTo(dataType)) {
+ return validForInfer(child, inferType);
+ }
}
} else if (inferType == InferType.STRING) {
// avoid substring cast such as cast(char(3) as char(2))
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/InferPredicateByReplaceTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/InferPredicateByReplaceTest.java
index 2fec983dd21..ca2d9dc1c79 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/InferPredicateByReplaceTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/InferPredicateByReplaceTest.java
@@ -232,6 +232,32 @@ public class InferPredicateByReplaceTest {
Assertions.assertEquals(3, result.size());
}
+ @Test
+ public void testInferWithDateTimeV2CastPrecision() {
+ for (int sourceScale : new int[] {0, 3, 6}) {
+ SlotReference a = new SlotReference("a",
DateTimeV2Type.of(sourceScale));
+ SlotReference b = new SlotReference("b",
DateTimeV2Type.of(sourceScale));
+ InPredicate predicate = new InPredicate(a, ImmutableList.of(
+ new DateTimeV2Literal(DateTimeV2Type.of(sourceScale),
"2025-01-01 00:00:00"),
+ new DateTimeV2Literal(DateTimeV2Type.of(sourceScale),
"2025-01-01 00:00:01")));
+ InPredicate expected = new InPredicate(b, predicate.getOptions());
+ for (int targetScale : new int[] {0, 3, 6}) {
+ EqualTo equality = new EqualTo(new Cast(a,
DateTimeV2Type.of(targetScale)),
+ new Cast(b, DateTimeV2Type.of(targetScale)));
+ Set<Expression> inputs = new
HashSet<>(ImmutableList.of(equality, predicate));
+ Assertions.assertEquals(sourceScale <= targetScale,
+
InferPredicateByReplace.infer(inputs).contains(expected),
+ "Unexpected inference for scale " + sourceScale + " ->
" + targetScale);
+ }
+ EqualTo nestedEquality = new EqualTo(
+ new Cast(new Cast(a, DateTimeV2Type.of(0)),
DateTimeV2Type.of(6)),
+ new Cast(new Cast(b, DateTimeV2Type.of(0)),
DateTimeV2Type.of(6)));
+ Set<Expression> inputs = new
HashSet<>(ImmutableList.of(nestedEquality, predicate));
+ Assertions.assertEquals(sourceScale == 0,
InferPredicateByReplace.infer(inputs).contains(expected),
+ "Nested casts must not hide precision loss");
+ }
+ }
+
@Test
public void testValidForInfer() {
SlotReference a = new SlotReference("a", TinyIntType.INSTANCE);
diff --git
a/regression-test/data/nereids_rules_p0/infer_predicate/infer_datetimev2_cast_precision.out
b/regression-test/data/nereids_rules_p0/infer_predicate/infer_datetimev2_cast_precision.out
new file mode 100644
index 00000000000..d037fd99f05
--- /dev/null
+++
b/regression-test/data/nereids_rules_p0/infer_predicate/infer_datetimev2_cast_precision.out
@@ -0,0 +1,7 @@
+-- This file is automatically generated. You should know what you did if you
want to edit this
+-- !without_inference --
+1 1 10
+
+-- !with_inference --
+1 1 10
+
diff --git
a/regression-test/suites/nereids_rules_p0/infer_predicate/infer_datetimev2_cast_precision.groovy
b/regression-test/suites/nereids_rules_p0/infer_predicate/infer_datetimev2_cast_precision.groovy
new file mode 100644
index 00000000000..5047cd9a0e7
--- /dev/null
+++
b/regression-test/suites/nereids_rules_p0/infer_predicate/infer_datetimev2_cast_precision.groovy
@@ -0,0 +1,50 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+suite("infer_datetimev2_cast_precision", "p0") {
+ sql "DROP TABLE IF EXISTS infer_datetimev2_cast_l"
+ sql "DROP TABLE IF EXISTS infer_datetimev2_cast_r"
+ sql """
+ CREATE TABLE infer_datetimev2_cast_l (id INT, a DATETIMEV2(6))
+ DUPLICATE KEY(id)
+ DISTRIBUTED BY HASH(id) BUCKETS 1
+ PROPERTIES ("replication_num" = "1")
+ """
+ sql """
+ CREATE TABLE infer_datetimev2_cast_r (id INT, b DATETIMEV2(6))
+ DUPLICATE KEY(id)
+ DISTRIBUTED BY HASH(id) BUCKETS 1
+ PROPERTIES ("replication_num" = "1")
+ """
+ sql "INSERT INTO infer_datetimev2_cast_l VALUES (1, '2025-01-01
00:00:00.100000')"
+ sql "INSERT INTO infer_datetimev2_cast_r VALUES (10, '2025-01-01
00:00:00.200000')"
+
+ // Distinct raw values become equal after narrowing the fractional-second
precision.
+ sql "SET disable_nereids_rules = 'INFER_PREDICATES'"
+ order_qt_without_inference """
+ SELECT COUNT(*) AS cnt, MIN(l.id) AS left_id, MIN(r.id) AS right_id
+ FROM infer_datetimev2_cast_l l JOIN infer_datetimev2_cast_r r
+ ON CAST(l.a AS DATETIMEV2(0)) = CAST(r.b AS DATETIMEV2(0))
+ WHERE l.a IN ('2025-01-01 00:00:00.100000', '2025-01-01
00:00:00.300000')
+ """
+ sql "SET disable_nereids_rules = ''"
+ order_qt_with_inference """
+ SELECT COUNT(*) AS cnt, MIN(l.id) AS left_id, MIN(r.id) AS right_id
+ FROM infer_datetimev2_cast_l l JOIN infer_datetimev2_cast_r r
+ ON CAST(l.a AS DATETIMEV2(0)) = CAST(r.b AS DATETIMEV2(0))
+ WHERE l.a IN ('2025-01-01 00:00:00.100000', '2025-01-01
00:00:00.300000')
+ """
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]