This is an automated email from the ASF dual-hosted git repository.
yiguolei pushed a commit to branch branch-4.0
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-4.0 by this push:
new 61242ee8ab0 branch-4.0: [fix](date time comparison) fix date time
compare with low scale literal #59630 (#59659)
61242ee8ab0 is described below
commit 61242ee8ab0005cff8bf94f417e7a2aaffa1ff04
Author: github-actions[bot]
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Thu Jan 8 18:25:37 2026 +0800
branch-4.0: [fix](date time comparison) fix date time compare with low
scale literal #59630 (#59659)
Cherry-picked from #59630
Co-authored-by: yujun <[email protected]>
---
.../rules/SimplifyComparisonPredicate.java | 48 ++++------------------
.../nereids/trees/expressions/LessThanEqual.java | 2 +-
.../rules/SimplifyComparisonPredicateTest.java | 36 +++++++---------
3 files changed, 24 insertions(+), 62 deletions(-)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/SimplifyComparisonPredicate.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/SimplifyComparisonPredicate.java
index 1f8dc5ecaca..335fe783071 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/SimplifyComparisonPredicate.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/SimplifyComparisonPredicate.java
@@ -255,47 +255,17 @@ public class SimplifyComparisonPredicate implements
ExpressionPatternRuleFactory
}
Expression newRight = leftType instanceof DateTimeType ?
migrateToDateTime(right) : right;
return comparisonPredicate.withChildren(left, newRight);
- } else if (toScale > rightType.getScale()) {
- // when toScale > right's scale, then left must be datetimev2, not
datetimev1
- Preconditions.checkArgument(leftType instanceof DateTimeV2Type,
leftType);
-
- // for expression cast(left as datetime(2)) = '2020-12-20
01:02:03.45'
- // then left scale is 5, right = '2020-12-20 01:02:03.45", right
scale is 2,
- // then left >= '2020-12-20 01:02:03.45000' && left <= '2020-12-20
01:02:03.45999'
- // for low bound, it add (5-2) '0' to the origin right's tail
- // for up bound, it add (5-2) '9' to the origin right's tail
- // when roundFloor to high scale, its microsecond shouldn't
change, only change its data type.
- DateTimeV2Literal lowBound = right.roundFloor(toScale);
- long upMicroSecond = 0;
- for (int i = 0; i < toScale - rightType.getScale(); i++) {
- upMicroSecond = 10 * upMicroSecond + 9;
- }
- upMicroSecond *= (int) Math.pow(10, 6 - toScale);
- upMicroSecond += lowBound.getMicroSecond();
- // left must be a datetimev2
- DateTimeV2Literal upBound = new DateTimeV2Literal((DateTimeV2Type)
leftType,
- right.getYear(), right.getMonth(), right.getDay(),
- right.getHour(), right.getMinute(), right.getSecond(),
upMicroSecond);
-
- if (comparisonPredicate instanceof GreaterThanEqual ||
comparisonPredicate instanceof LessThan) {
- return comparisonPredicate.withChildren(left, lowBound);
- }
-
- if (comparisonPredicate instanceof GreaterThan ||
comparisonPredicate instanceof LessThanEqual) {
- return comparisonPredicate.withChildren(left, upBound);
- }
-
- if (comparisonPredicate instanceof EqualTo || comparisonPredicate
instanceof NullSafeEqual) {
- List<Expression> conjunctions =
Lists.newArrayListWithExpectedSize(3);
- conjunctions.add(new GreaterThanEqual(left, lowBound));
- conjunctions.add(new LessThanEqual(left, upBound));
- if (left.nullable() && comparisonPredicate instanceof
NullSafeEqual) {
- conjunctions.add(new Not(new IsNull(left)));
- }
- return new And(conjunctions);
- }
}
+ // if toScale > rightType.scale, don't try to rewrite it like
+ // "A > '2020-12-20 01:02:03.23450' and A < '2020-12-20
01:02:03.23459'"
+ // because the cast will use rounding, not truncating.
+ // and the rounding may generate null result.
+ // for example: for expression E = "cast(A as datetime(4))) >
'2020-12-20 01:02:03.23456'"
+ // if one row for A is '9999-12-31 23:59:59.99995', then 'cast(A as
datetime(4))' will be null
+ // (because the cast result will exceed year 9999),
+ // so this row for E will be null too.
+
if (leftType instanceof DateTimeType) {
return comparisonPredicate.withChildren(left,
migrateToDateTime(right));
} else {
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/LessThanEqual.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/LessThanEqual.java
index cc8c64ff106..bae278e4c4b 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/LessThanEqual.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/LessThanEqual.java
@@ -41,7 +41,7 @@ public class LessThanEqual extends ComparisonPredicate
implements PropagateNulla
}
public LessThanEqual(Expression left, Expression right, boolean inferred) {
- super(ImmutableList.of(left, right), "<=", inferred);
+ this(ImmutableList.of(left, right), inferred);
}
private LessThanEqual(List<Expression> children) {
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rules/SimplifyComparisonPredicateTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rules/SimplifyComparisonPredicateTest.java
index b5ad2dda3d4..7d6967e6b3b 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rules/SimplifyComparisonPredicateTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rules/SimplifyComparisonPredicateTest.java
@@ -397,40 +397,32 @@ class SimplifyComparisonPredicateTest extends
ExpressionRewriteTestHelper {
new GreaterThanEqual(datetime2, new
DateTimeV2Literal(DateTimeV2Type.of(2), "9999-12-31 00:00:00.00")),
new LessThanEqual(datetime2, new
DateTimeV2Literal(DateTimeV2Type.of(2), "9999-12-31 23:59:59.99")),
new Not(new IsNull(datetime2)))));
+
+ // when cast from high scale datetime to low scale datetime, don't
change anything because the cast may generate null
assertRewrite(new GreaterThan(new Cast(datetime2,
DateTimeV2Type.of(0)), new DateTimeV2Literal(DateTimeV2Type.of(0), "9999-12-31
12:34:56")),
- new GreaterThan(datetime2, new
DateTimeV2Literal(DateTimeV2Type.of(2), "9999-12-31 12:34:56.99")));
+ new GreaterThan(new Cast(datetime2, DateTimeV2Type.of(0)), new
DateTimeV2Literal(DateTimeV2Type.of(0), "9999-12-31 12:34:56")));
assertRewrite(new GreaterThanEqual(new Cast(datetime2,
DateTimeV2Type.of(0)), new DateTimeV2Literal(DateTimeV2Type.of(0), "9999-12-31
12:34:56")),
- new GreaterThanEqual(datetime2, new
DateTimeV2Literal(DateTimeV2Type.of(2), "9999-12-31 12:34:56.00")));
+ new GreaterThanEqual(new Cast(datetime2,
DateTimeV2Type.of(0)), new DateTimeV2Literal(DateTimeV2Type.of(0), "9999-12-31
12:34:56")));
assertRewrite(new LessThan(new Cast(datetime2, DateTimeV2Type.of(0)),
new DateTimeV2Literal(DateTimeV2Type.of(0), "9999-12-31 12:34:56")),
- new LessThan(datetime2, new
DateTimeV2Literal(DateTimeV2Type.of(2), "9999-12-31 12:34:56.00")));
+ new LessThan(new Cast(datetime2, DateTimeV2Type.of(0)), new
DateTimeV2Literal(DateTimeV2Type.of(0), "9999-12-31 12:34:56")));
assertRewrite(new LessThanEqual(new Cast(datetime2,
DateTimeV2Type.of(0)), new DateTimeV2Literal(DateTimeV2Type.of(0), "9999-12-31
12:34:56")),
- new LessThanEqual(datetime2, new
DateTimeV2Literal(DateTimeV2Type.of(2), "9999-12-31 12:34:56.99")));
+ new LessThanEqual(new Cast(datetime2, DateTimeV2Type.of(0)),
new DateTimeV2Literal(DateTimeV2Type.of(0), "9999-12-31 12:34:56")));
assertRewrite(new EqualTo(new Cast(datetime2, DateTimeV2Type.of(0)),
new DateTimeV2Literal(DateTimeV2Type.of(0), "9999-12-31 12:34:56")),
- new And(
- new GreaterThanEqual(datetime2, new
DateTimeV2Literal(DateTimeV2Type.of(2), "9999-12-31 12:34:56.00")),
- new LessThanEqual(datetime2, new
DateTimeV2Literal(DateTimeV2Type.of(2), "9999-12-31 12:34:56.99"))));
+ new EqualTo(new Cast(datetime2, DateTimeV2Type.of(0)), new
DateTimeV2Literal(DateTimeV2Type.of(0), "9999-12-31 12:34:56")));
assertRewrite(new NullSafeEqual(new Cast(datetime2,
DateTimeV2Type.of(0)), new DateTimeV2Literal(DateTimeV2Type.of(0), "9999-12-31
12:34:56")),
- new And(ImmutableList.of(
- new GreaterThanEqual(datetime2, new
DateTimeV2Literal(DateTimeV2Type.of(2), "9999-12-31 12:34:56.00")),
- new LessThanEqual(datetime2, new
DateTimeV2Literal(DateTimeV2Type.of(2), "9999-12-31 12:34:56.99")),
- new Not(new IsNull(datetime2)))));
+ new NullSafeEqual(new Cast(datetime2, DateTimeV2Type.of(0)),
new DateTimeV2Literal(DateTimeV2Type.of(0), "9999-12-31 12:34:56")));
assertRewrite(new GreaterThan(new Cast(datetime2,
DateTimeV2Type.of(1)), new DateTimeV2Literal(DateTimeV2Type.of(1), "9999-12-31
12:34:56.7")),
- new GreaterThan(datetime2, new
DateTimeV2Literal(DateTimeV2Type.of(2), "9999-12-31 12:34:56.79")));
+ new GreaterThan(new Cast(datetime2, DateTimeV2Type.of(1)), new
DateTimeV2Literal(DateTimeV2Type.of(1), "9999-12-31 12:34:56.7")));
assertRewrite(new GreaterThanEqual(new Cast(datetime2,
DateTimeV2Type.of(1)), new DateTimeV2Literal(DateTimeV2Type.of(1), "9999-12-31
12:34:56.7")),
- new GreaterThanEqual(datetime2, new
DateTimeV2Literal(DateTimeV2Type.of(2), "9999-12-31 12:34:56.70")));
+ new GreaterThanEqual(new Cast(datetime2,
DateTimeV2Type.of(1)), new DateTimeV2Literal(DateTimeV2Type.of(1), "9999-12-31
12:34:56.7")));
assertRewrite(new LessThan(new Cast(datetime2, DateTimeV2Type.of(1)),
new DateTimeV2Literal(DateTimeV2Type.of(1), "9999-12-31 12:34:56.7")),
- new LessThan(datetime2, new
DateTimeV2Literal(DateTimeV2Type.of(2), "9999-12-31 12:34:56.70")));
+ new LessThan(new Cast(datetime2, DateTimeV2Type.of(1)), new
DateTimeV2Literal(DateTimeV2Type.of(1), "9999-12-31 12:34:56.7")));
assertRewrite(new LessThanEqual(new Cast(datetime2,
DateTimeV2Type.of(1)), new DateTimeV2Literal(DateTimeV2Type.of(1), "9999-12-31
12:34:56.7")),
- new LessThanEqual(datetime2, new
DateTimeV2Literal(DateTimeV2Type.of(2), "9999-12-31 12:34:56.79")));
+ new LessThanEqual(new Cast(datetime2, DateTimeV2Type.of(1)),
new DateTimeV2Literal(DateTimeV2Type.of(1), "9999-12-31 12:34:56.7")));
assertRewrite(new EqualTo(new Cast(datetime2, DateTimeV2Type.of(1)),
new DateTimeV2Literal(DateTimeV2Type.of(1), "9999-12-31 12:34:56.7")),
- new And(
- new GreaterThanEqual(datetime2, new
DateTimeV2Literal(DateTimeV2Type.of(2), "9999-12-31 12:34:56.70")),
- new LessThanEqual(datetime2, new
DateTimeV2Literal(DateTimeV2Type.of(2), "9999-12-31 12:34:56.79"))));
+ new EqualTo(new Cast(datetime2, DateTimeV2Type.of(1)), new
DateTimeV2Literal(DateTimeV2Type.of(1), "9999-12-31 12:34:56.7")));
assertRewrite(new NullSafeEqual(new Cast(datetime2,
DateTimeV2Type.of(1)), new DateTimeV2Literal(DateTimeV2Type.of(1), "9999-12-31
12:34:56.7")),
- new And(ImmutableList.of(
- new GreaterThanEqual(datetime2, new
DateTimeV2Literal(DateTimeV2Type.of(2), "9999-12-31 12:34:56.70")),
- new LessThanEqual(datetime2, new
DateTimeV2Literal(DateTimeV2Type.of(2), "9999-12-31 12:34:56.79")),
- new Not(new IsNull(datetime2)))));
+ new NullSafeEqual(new Cast(datetime2, DateTimeV2Type.of(1)),
new DateTimeV2Literal(DateTimeV2Type.of(1), "9999-12-31 12:34:56.7")));
assertRewrite(new EqualTo(new Cast(datetime0, DateTimeV2Type.of(1)),
new DateTimeV2Literal("9999-12-31 23:59:59.1")),
ExpressionUtils.falseOrNull(datetime0));
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]