This is an automated email from the ASF dual-hosted git repository. morrysnow pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push: new d0f9dafcd2b [opt](nereids) simplify cast date like from high scale to small scale (#47036) d0f9dafcd2b is described below commit d0f9dafcd2bc33931f0edb1d8332e3d1febd57ab Author: yujun <yu...@selectdb.com> AuthorDate: Tue Jan 21 17:46:37 2025 +0800 [opt](nereids) simplify cast date like from high scale to small scale (#47036) ### What problem does this PR solve? Problem Summary: PR do two things: 1. simplify cast date like from high scale to small scale. example: ``` # suppose c_datetime_2 is datetime(2) cast(c_datetime_2 as date) = '2020-12-20' ---> c_datetime_2 >= '2020-12-20 00:00:00.00' and c_datetime_2 <= '2020-12-20 23:59:59.99' cast(c_datetime_2 as datetime(1)) > '2020-12-20 12:34:56.7' --> c_datetime_2 > '2020-12-20 12:34:56.79' ``` 2. handle compare date like with overflow. before this PR, it will not simplify if met overflow, but this PR will simplify too. example: ``` # suppose c_datetime_2 is datetime(2), c_date is date cast(c_date as datetime) < '9999-12-31 23:59:59' --> c_date <= '9999-12-31' cast(c_date as datetime) >= '9999-12-31 23:59:59' --> c_date > '9999-12-31' cast(c_datetime_2 as datetime(3)) < '9999-12-31 23:59:59.995' --> c_datetime_2 <= '9999-12-31 23:59:59.99' cast(c_datetime_2 as datetime(3)) >= '9999-12-31 23:59:59.995' --> c_datetime_2 > '9999-12-31 23:59:59.99' ``` --- .../rules/SimplifyComparisonPredicate.java | 250 +++++++++++++++------ .../rules/SimplifyComparisonPredicateTest.java | 142 +++++++++++- .../extend_infer_equal_predicate.out | Bin 30509 -> 30505 bytes .../month_quarter_cast_in_prune.groovy | 6 +- 4 files changed, 321 insertions(+), 77 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 e2bba0173b0..43ba84fb7a4 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 @@ -24,14 +24,17 @@ import org.apache.doris.nereids.rules.expression.ExpressionPatternMatcher; import org.apache.doris.nereids.rules.expression.ExpressionPatternRuleFactory; import org.apache.doris.nereids.rules.expression.ExpressionRewriteContext; import org.apache.doris.nereids.rules.expression.ExpressionRuleType; +import org.apache.doris.nereids.trees.expressions.And; import org.apache.doris.nereids.trees.expressions.Cast; import org.apache.doris.nereids.trees.expressions.ComparisonPredicate; import org.apache.doris.nereids.trees.expressions.EqualTo; import org.apache.doris.nereids.trees.expressions.Expression; import org.apache.doris.nereids.trees.expressions.GreaterThan; import org.apache.doris.nereids.trees.expressions.GreaterThanEqual; +import org.apache.doris.nereids.trees.expressions.IsNull; import org.apache.doris.nereids.trees.expressions.LessThan; import org.apache.doris.nereids.trees.expressions.LessThanEqual; +import org.apache.doris.nereids.trees.expressions.Not; import org.apache.doris.nereids.trees.expressions.NullSafeEqual; import org.apache.doris.nereids.trees.expressions.literal.BigIntLiteral; import org.apache.doris.nereids.trees.expressions.literal.BooleanLiteral; @@ -60,6 +63,7 @@ import org.apache.doris.nereids.util.TypeCoercionUtils; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; import java.math.BigDecimal; import java.math.RoundingMode; @@ -117,22 +121,46 @@ public class SimplifyComparisonPredicate extends AbstractExpressionRewriteRule i return result; } + private static Expression processDateLikeTypeCoercion(ComparisonPredicate cp, Expression left, Expression right) { + if (left instanceof Cast && right instanceof DateLiteral + && ((Cast) left).getDataType().equals(right.getDataType())) { + Cast cast = (Cast) left; + if (cast.child().getDataType() instanceof DateTimeType + || cast.child().getDataType() instanceof DateTimeV2Type) { + // right is datetime + if (right instanceof DateTimeV2Literal) { + return processDateTimeLikeComparisonPredicateDateTimeV2Literal( + cp, cast.child(), (DateTimeV2Literal) right); + } + // right is date, not datetime + if (!(right instanceof DateTimeLiteral)) { + return processDateTimeLikeComparisonPredicateDateLiteral( + cp, cast.child(), (DateLiteral) right); + } + } + + // datetime to datev2 + if (cast.child().getDataType() instanceof DateType || cast.child().getDataType() instanceof DateV2Type) { + return processDateLikeComparisonPredicateDateLiteral(cp, cast.child(), (DateLiteral) right); + } + } + + return cp; + } + + // process cast(datetime as datetime) cmp datetime private static Expression processDateTimeLikeComparisonPredicateDateTimeV2Literal( ComparisonPredicate comparisonPredicate, Expression left, DateTimeV2Literal right) { DataType leftType = left.getDataType(); - int toScale = 0; - if (leftType instanceof DateTimeType) { - toScale = 0; - } else if (leftType instanceof DateTimeV2Type) { - toScale = ((DateTimeV2Type) leftType).getScale(); - } else { + if (!(leftType instanceof DateTimeType) && !(leftType instanceof DateTimeV2Type)) { return comparisonPredicate; } + int toScale = leftType instanceof DateTimeV2Type ? ((DateTimeV2Type) leftType).getScale() : 0; DateTimeV2Type rightType = right.getDataType(); if (toScale < rightType.getScale()) { if (comparisonPredicate instanceof EqualTo) { long originValue = right.getMicroSecond(); - right = right.roundCeiling(toScale); + right = right.roundFloor(toScale); if (right.getMicroSecond() != originValue) { // TODO: the ideal way is to return an If expr like: // return new If(new IsNull(left), new NullLiteral(BooleanType.INSTANCE), @@ -144,7 +172,7 @@ public class SimplifyComparisonPredicate extends AbstractExpressionRewriteRule i } } else if (comparisonPredicate instanceof NullSafeEqual) { long originValue = right.getMicroSecond(); - right = right.roundCeiling(toScale); + right = right.roundFloor(toScale); if (right.getMicroSecond() != originValue) { return BooleanLiteral.of(false); } @@ -153,76 +181,156 @@ public class SimplifyComparisonPredicate extends AbstractExpressionRewriteRule i right = right.roundFloor(toScale); } else if (comparisonPredicate instanceof LessThan || comparisonPredicate instanceof GreaterThanEqual) { - right = right.roundCeiling(toScale); + try { + right = right.roundCeiling(toScale); + } catch (AnalysisException e) { + // '9999-12-31 23:59:59.9'.roundCeiling(0) overflow + DateTimeLiteral newRight = right.roundFloor(toScale); + if (leftType instanceof DateTimeType) { + newRight = migrateToDateTime((DateTimeV2Literal) newRight); + } + if (comparisonPredicate instanceof LessThan) { + return new LessThanEqual(left, newRight); + } else { + return new GreaterThan(left, newRight); + } + } } else { return comparisonPredicate; } Expression newRight = leftType instanceof DateTimeType ? migrateToDateTime(right) : right; return comparisonPredicate.withChildren(left, newRight); - } else { - if (leftType instanceof DateTimeType) { - return comparisonPredicate.withChildren(left, migrateToDateTime(right)); - } else { - return comparisonPredicate; + } 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 (leftType instanceof DateTimeType) { + return comparisonPredicate.withChildren(left, migrateToDateTime(right)); + } else { + return comparisonPredicate; } } - private static Expression processDateLikeTypeCoercion(ComparisonPredicate cp, Expression left, Expression right) { - if (left instanceof Cast && right instanceof DateLiteral) { - Cast cast = (Cast) left; - if (cast.child().getDataType() instanceof DateTimeType - || cast.child().getDataType() instanceof DateTimeV2Type) { - if (right instanceof DateTimeV2Literal) { - try { - return processDateTimeLikeComparisonPredicateDateTimeV2Literal( - cp, cast.child(), (DateTimeV2Literal) right); - } catch (AnalysisException e) { - // '9999-12-31 23:59:59.9'.roundCeiling(0) overflow - return cp; - } - } + // process cast(datetime as date) cmp date + private static Expression processDateTimeLikeComparisonPredicateDateLiteral( + ComparisonPredicate comparisonPredicate, Expression left, DateLiteral right) { + DataType leftType = left.getDataType(); + if (!(leftType instanceof DateTimeType) && !(leftType instanceof DateTimeV2Type)) { + return comparisonPredicate; + } + if (right instanceof DateTimeLiteral) { + return comparisonPredicate; + } + + DateTimeLiteral lowBound = null; + DateTimeLiteral upBound = null; + if (leftType instanceof DateTimeType) { + lowBound = new DateTimeLiteral(right.getYear(), right.getMonth(), right.getDay(), 0, 0, 0); + upBound = new DateTimeLiteral(right.getYear(), right.getMonth(), right.getDay(), 23, 59, 59); + } else { + long upMicroSecond = 0; + for (int i = 0; i < ((DateTimeV2Type) leftType).getScale(); i++) { + upMicroSecond = 10 * upMicroSecond + 9; } + upMicroSecond *= (int) Math.pow(10, 6 - ((DateTimeV2Type) leftType).getScale()); + lowBound = new DateTimeV2Literal((DateTimeV2Type) leftType, + right.getYear(), right.getMonth(), right.getDay(), 0, 0, 0, 0); + upBound = new DateTimeV2Literal((DateTimeV2Type) leftType, + right.getYear(), right.getMonth(), right.getDay(), 23, 59, 59, upMicroSecond); + } - // datetime to datev2 - if (cast.child().getDataType() instanceof DateType || cast.child().getDataType() instanceof DateV2Type) { - if (right instanceof DateTimeLiteral) { - DateTimeLiteral dateTimeLiteral = (DateTimeLiteral) right; - right = migrateToDateV2(dateTimeLiteral); - if (dateTimeLiteral.getHour() != 0 || dateTimeLiteral.getMinute() != 0 - || dateTimeLiteral.getSecond() != 0 || dateTimeLiteral.getMicroSecond() != 0) { - if (cp instanceof EqualTo) { - return ExpressionUtils.falseOrNull(cast.child()); - } else if (cp instanceof NullSafeEqual) { - return BooleanLiteral.FALSE; - } else if (cp instanceof GreaterThanEqual || cp instanceof LessThan) { - // '9999-12-31' + 1 will overflow - if (DateLiteral.isDateOutOfRange(((DateV2Literal) right).toJavaDateType().plusDays(1))) { - return cp; - } - right = ((DateV2Literal) right).plusDays(1); - } - } - if (cast.child().getDataType() instanceof DateV2Type) { - left = cast.child(); - } - } + 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); + } + + return comparisonPredicate; + } - // datev2 to date - if (cast.child().getDataType() instanceof DateType) { - if (right instanceof DateV2Literal) { - left = cast.child(); - right = migrateToDate((DateV2Literal) right); + // process cast(date as datetime/date) cmp datetime/date + private static Expression processDateLikeComparisonPredicateDateLiteral( + ComparisonPredicate comparisonPredicate, Expression left, DateLiteral right) { + if (!(left.getDataType() instanceof DateType) && !(left.getDataType() instanceof DateV2Type)) { + return comparisonPredicate; + } + if (right instanceof DateTimeLiteral) { + DateTimeLiteral dateTimeLiteral = (DateTimeLiteral) right; + right = migrateToDateV2(dateTimeLiteral); + if (dateTimeLiteral.getHour() != 0 || dateTimeLiteral.getMinute() != 0 + || dateTimeLiteral.getSecond() != 0 || dateTimeLiteral.getMicroSecond() != 0) { + if (comparisonPredicate instanceof EqualTo) { + return ExpressionUtils.falseOrNull(left); + } else if (comparisonPredicate instanceof NullSafeEqual) { + return BooleanLiteral.FALSE; + } else if (comparisonPredicate instanceof GreaterThanEqual + || comparisonPredicate instanceof LessThan) { + // '9999-12-31' + 1 will overflow + if (DateLiteral.isDateOutOfRange(right.toJavaDateType().plusDays(1))) { + right = convertDateLiteralToDateType(right, left.getDataType()); + if (comparisonPredicate instanceof GreaterThanEqual) { + return new GreaterThan(left, right); + } else { + return new LessThanEqual(left, right); + } + } + right = (DateLiteral) right.plusDays(1); } } } - - if (left != cp.left() || right != cp.right()) { - return cp.withChildren(left, right); - } else { - return cp; + right = convertDateLiteralToDateType(right, left.getDataType()); + if (right != comparisonPredicate.right()) { + return comparisonPredicate.withChildren(left, right); } + return comparisonPredicate; } private static Expression processFloatLikeTypeCoercion(ComparisonPredicate comparisonPredicate, @@ -475,15 +583,29 @@ public class SimplifyComparisonPredicate extends AbstractExpressionRewriteRule i } } - private static Expression migrateToDateTime(DateTimeV2Literal l) { + private static DateLiteral convertDateLiteralToDateType(DateLiteral l, DataType dateType) { + if (dateType instanceof DateType) { + if (l instanceof DateV2Literal) { + return migrateToDate((DateV2Literal) l); + } + } + if (dateType instanceof DateV2Type) { + if (!(l instanceof DateV2Literal)) { + return migrateToDateV2(l); + } + } + return l; + } + + private static DateTimeLiteral migrateToDateTime(DateTimeV2Literal l) { return new DateTimeLiteral(l.getYear(), l.getMonth(), l.getDay(), l.getHour(), l.getMinute(), l.getSecond()); } - private static Expression migrateToDateV2(DateTimeLiteral l) { + private static DateV2Literal migrateToDateV2(DateLiteral l) { return new DateV2Literal(l.getYear(), l.getMonth(), l.getDay()); } - private static Expression migrateToDate(DateV2Literal l) { + private static DateLiteral migrateToDate(DateV2Literal l) { return new DateLiteral(l.getYear(), l.getMonth(), l.getDay()); } } 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 b4b5877c07d..a4faf95146e 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 @@ -30,6 +30,7 @@ import org.apache.doris.nereids.trees.expressions.GreaterThanEqual; import org.apache.doris.nereids.trees.expressions.IsNull; import org.apache.doris.nereids.trees.expressions.LessThan; import org.apache.doris.nereids.trees.expressions.LessThanEqual; +import org.apache.doris.nereids.trees.expressions.Not; import org.apache.doris.nereids.trees.expressions.NullSafeEqual; import org.apache.doris.nereids.trees.expressions.SlotReference; import org.apache.doris.nereids.trees.expressions.literal.BigIntLiteral; @@ -302,23 +303,144 @@ class SimplifyComparisonPredicateTest extends ExpressionRewriteTestHelper { assertRewrite(new GreaterThan(new Cast(datetimev1, DateTimeV2Type.of(1)), new DateTimeV2Literal("0000-01-01 00:00:00.1")), new GreaterThan(datetimev1, new DateTimeLiteral("0000-01-01 00:00:00"))); - // test overflow, not cast assertRewrite(new LessThan(new Cast(date, DateTimeType.INSTANCE), new DateTimeLiteral("9999-12-31 23:59:59")), - new LessThan(new Cast(date, DateTimeType.INSTANCE), new DateTimeLiteral("9999-12-31 23:59:59"))); + new LessThanEqual(date, new DateV2Literal("9999-12-31"))); assertRewrite(new LessThan(new Cast(date, DateTimeV2Type.SYSTEM_DEFAULT), new DateTimeV2Literal("9999-12-31 23:59:59")), - new LessThan(new Cast(date, DateTimeV2Type.SYSTEM_DEFAULT), new DateTimeV2Literal("9999-12-31 23:59:59"))); + new LessThanEqual(date, new DateV2Literal("9999-12-31"))); assertRewrite(new LessThan(new Cast(datev1, DateTimeType.INSTANCE), new DateTimeLiteral("9999-12-31 23:59:59")), - new LessThan(new Cast(datev1, DateTimeType.INSTANCE), new DateTimeLiteral("9999-12-31 23:59:59"))); + new LessThanEqual(datev1, new DateLiteral("9999-12-31"))); assertRewrite(new LessThan(new Cast(datev1, DateTimeV2Type.SYSTEM_DEFAULT), new DateTimeV2Literal("9999-12-31 23:59:59")), - new LessThan(new Cast(datev1, DateTimeV2Type.SYSTEM_DEFAULT), new DateTimeV2Literal("9999-12-31 23:59:59"))); + new LessThanEqual(datev1, new DateLiteral("9999-12-31"))); + assertRewrite(new GreaterThanEqual(new Cast(date, DateTimeType.INSTANCE), new DateTimeLiteral("9999-12-31 23:59:59")), + new GreaterThan(date, new DateV2Literal("9999-12-31"))); + assertRewrite(new GreaterThanEqual(new Cast(date, DateTimeV2Type.SYSTEM_DEFAULT), new DateTimeV2Literal("9999-12-31 23:59:59")), + new GreaterThan(date, new DateV2Literal("9999-12-31"))); + assertRewrite(new GreaterThanEqual(new Cast(datev1, DateTimeType.INSTANCE), new DateTimeLiteral("9999-12-31 23:59:59")), + new GreaterThan(datev1, new DateLiteral("9999-12-31"))); + assertRewrite(new GreaterThanEqual(new Cast(datev1, DateTimeV2Type.SYSTEM_DEFAULT), new DateTimeV2Literal("9999-12-31 23:59:59")), + new GreaterThan(datev1, new DateLiteral("9999-12-31"))); + + // test from high datetime to low datetime or date + assertRewrite(new GreaterThan(new Cast(datetime0, DateType.INSTANCE), new DateLiteral("9999-12-31")), + new GreaterThan(datetime0, new DateTimeV2Literal(DateTimeV2Type.of(0), "9999-12-31 23:59:59"))); + assertRewrite(new GreaterThanEqual(new Cast(datetime0, DateType.INSTANCE), new DateLiteral("9999-12-31")), + new GreaterThanEqual(datetime0, new DateTimeV2Literal(DateTimeV2Type.of(0), "9999-12-31 00:00:00"))); + assertRewrite(new LessThan(new Cast(datetime0, DateType.INSTANCE), new DateLiteral("9999-12-31")), + new LessThan(datetime0, new DateTimeV2Literal(DateTimeV2Type.of(0), "9999-12-31 00:00:00"))); + assertRewrite(new LessThanEqual(new Cast(datetime0, DateType.INSTANCE), new DateLiteral("9999-12-31")), + new LessThanEqual(datetime0, new DateTimeV2Literal(DateTimeV2Type.of(0), "9999-12-31 23:59:59"))); + assertRewrite(new EqualTo(new Cast(datetime0, DateType.INSTANCE), new DateLiteral("9999-12-31")), + new And( + new GreaterThanEqual(datetime0, new DateTimeV2Literal(DateTimeV2Type.of(0), "9999-12-31 00:00:00")), + new LessThanEqual(datetime0, new DateTimeV2Literal(DateTimeV2Type.of(0), "9999-12-31 23:59:59")))); + assertRewrite(new NullSafeEqual(new Cast(datetime0, DateType.INSTANCE), new DateLiteral("9999-12-31")), + new And(ImmutableList.of( + new GreaterThanEqual(datetime0, new DateTimeV2Literal(DateTimeV2Type.of(0), "9999-12-31 00:00:00")), + new LessThanEqual(datetime0, new DateTimeV2Literal(DateTimeV2Type.of(0), "9999-12-31 23:59:59")), + new Not(new IsNull(datetime0))))); + assertRewrite(new GreaterThan(new Cast(datetimev1, DateType.INSTANCE), new DateLiteral("9999-12-31")), + new GreaterThan(datetimev1, new DateTimeLiteral("9999-12-31 23:59:59"))); + assertRewrite(new GreaterThanEqual(new Cast(datetimev1, DateType.INSTANCE), new DateLiteral("9999-12-31")), + new GreaterThanEqual(datetimev1, new DateTimeLiteral("9999-12-31 00:00:00"))); + assertRewrite(new LessThan(new Cast(datetimev1, DateType.INSTANCE), new DateLiteral("9999-12-31")), + new LessThan(datetimev1, new DateTimeLiteral("9999-12-31 00:00:00"))); + assertRewrite(new LessThanEqual(new Cast(datetimev1, DateType.INSTANCE), new DateLiteral("9999-12-31")), + new LessThanEqual(datetimev1, new DateTimeLiteral("9999-12-31 23:59:59"))); + assertRewrite(new EqualTo(new Cast(datetimev1, DateType.INSTANCE), new DateLiteral("9999-12-31")), + new And( + new GreaterThanEqual(datetimev1, new DateTimeLiteral("9999-12-31 00:00:00")), + new LessThanEqual(datetimev1, new DateTimeLiteral("9999-12-31 23:59:59")))); + assertRewrite(new NullSafeEqual(new Cast(datetimev1, DateType.INSTANCE), new DateLiteral("9999-12-31")), + new And(ImmutableList.of( + new GreaterThanEqual(datetimev1, new DateTimeLiteral("9999-12-31 00:00:00")), + new LessThanEqual(datetimev1, new DateTimeLiteral("9999-12-31 23:59:59")), + new Not(new IsNull(datetimev1))))); + assertRewrite(new GreaterThan(new Cast(datetime2, DateType.INSTANCE), new DateLiteral("9999-12-31")), + new GreaterThan(datetime2, new DateTimeV2Literal(DateTimeV2Type.of(2), "9999-12-31 23:59:59.99"))); + assertRewrite(new GreaterThanEqual(new Cast(datetime2, DateType.INSTANCE), new DateLiteral("9999-12-31")), + new GreaterThanEqual(datetime2, new DateTimeV2Literal(DateTimeV2Type.of(2), "9999-12-31 00:00:00.00"))); + assertRewrite(new LessThan(new Cast(datetime2, DateType.INSTANCE), new DateLiteral("9999-12-31")), + new LessThan(datetime2, new DateTimeV2Literal(DateTimeV2Type.of(2), "9999-12-31 00:00:00.00"))); + assertRewrite(new LessThanEqual(new Cast(datetime2, DateType.INSTANCE), new DateLiteral("9999-12-31")), + new LessThanEqual(datetime2, new DateTimeV2Literal(DateTimeV2Type.of(2), "9999-12-31 23:59:59.99"))); + assertRewrite(new EqualTo(new Cast(datetime2, DateType.INSTANCE), new DateLiteral("9999-12-31")), + new And( + 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")))); + assertRewrite(new NullSafeEqual(new Cast(datetime2, DateType.INSTANCE), new DateLiteral("9999-12-31")), + new And(ImmutableList.of( + 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))))); + 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"))); + 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"))); + 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"))); + 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"))); + 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")))); + 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))))); + 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"))); + 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"))); + 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"))); + 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"))); + 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")))); + 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))))); + + assertRewrite(new EqualTo(new Cast(datetime0, DateTimeV2Type.of(1)), new DateTimeV2Literal("9999-12-31 23:59:59.1")), + ExpressionUtils.falseOrNull(datetime0)); + assertRewrite(new NullSafeEqual(new Cast(datetime0, DateTimeV2Type.of(1)), new DateTimeV2Literal("9999-12-31 23:59:59.1")), + BooleanLiteral.FALSE); + assertRewrite(new GreaterThan(new Cast(datetime0, DateTimeV2Type.of(1)), new DateTimeV2Literal("9999-12-31 23:59:59.1")), + new GreaterThan(datetime0, new DateTimeV2Literal(DateTimeV2Type.of(0), "9999-12-31 23:59:59"))); + assertRewrite(new GreaterThanEqual(new Cast(datetime0, DateTimeV2Type.of(1)), new DateTimeV2Literal("9999-12-31 23:59:59.1")), + new GreaterThan(datetime0, new DateTimeV2Literal(DateTimeV2Type.of(0), "9999-12-31 23:59:59"))); assertRewrite(new LessThan(new Cast(datetime0, DateTimeV2Type.of(1)), new DateTimeV2Literal("9999-12-31 23:59:59.1")), - new LessThan(new Cast(datetime0, DateTimeV2Type.of(1)), new DateTimeV2Literal("9999-12-31 23:59:59.1"))); + new LessThanEqual(datetime0, new DateTimeV2Literal(DateTimeV2Type.of(0), "9999-12-31 23:59:59"))); + assertRewrite(new LessThanEqual(new Cast(datetime0, DateTimeV2Type.of(1)), new DateTimeV2Literal("9999-12-31 23:59:59.1")), + new LessThanEqual(datetime0, new DateTimeV2Literal(DateTimeV2Type.of(0), "9999-12-31 23:59:59"))); + assertRewrite(new EqualTo(new Cast(datetimev1, DateTimeV2Type.of(1)), new DateTimeV2Literal("9999-12-31 23:59:59.1")), + ExpressionUtils.falseOrNull(datetimev1)); + assertRewrite(new NullSafeEqual(new Cast(datetimev1, DateTimeV2Type.of(1)), new DateTimeV2Literal("9999-12-31 23:59:59.1")), + BooleanLiteral.FALSE); + assertRewrite(new GreaterThan(new Cast(datetimev1, DateTimeV2Type.of(1)), new DateTimeV2Literal("9999-12-31 23:59:59.1")), + new GreaterThan(datetimev1, new DateTimeLiteral("9999-12-31 23:59:59"))); + assertRewrite(new GreaterThanEqual(new Cast(datetimev1, DateTimeV2Type.of(1)), new DateTimeV2Literal("9999-12-31 23:59:59.1")), + new GreaterThan(datetimev1, new DateTimeLiteral("9999-12-31 23:59:59"))); + assertRewrite(new LessThan(new Cast(datetimev1, DateTimeV2Type.of(1)), new DateTimeV2Literal("9999-12-31 23:59:59.1")), + new LessThanEqual(datetimev1, new DateTimeLiteral("9999-12-31 23:59:59"))); + assertRewrite(new LessThanEqual(new Cast(datetimev1, DateTimeV2Type.of(1)), new DateTimeV2Literal("9999-12-31 23:59:59.1")), + new LessThanEqual(datetimev1, new DateTimeLiteral("9999-12-31 23:59:59"))); assertRewrite(new LessThan(new Cast(datetime2, DateTimeV2Type.of(3)), new DateTimeV2Literal("9999-12-31 23:59:59.991")), - new LessThan(new Cast(datetime2, DateTimeV2Type.of(3)), new DateTimeV2Literal("9999-12-31 23:59:59.991"))); + new LessThanEqual(datetime2, new DateTimeV2Literal("9999-12-31 23:59:59.99"))); assertRewrite(new LessThan(new Cast(datetime2, DateTimeV2Type.of(6)), new DateTimeV2Literal("9999-12-31 23:59:59.999999")), - new LessThan(new Cast(datetime2, DateTimeV2Type.of(6)), new DateTimeV2Literal("9999-12-31 23:59:59.999999"))); - assertRewrite(new LessThan(new Cast(datetimev1, DateTimeV2Type.of(1)), new DateTimeV2Literal("9999-12-31 23:59:59.1")), - new LessThan(new Cast(datetimev1, DateTimeV2Type.of(1)), new DateTimeV2Literal("9999-12-31 23:59:59.1"))); + new LessThanEqual(datetime2, new DateTimeV2Literal("9999-12-31 23:59:59.99"))); + assertRewrite(new GreaterThanEqual(new Cast(datetime2, DateTimeV2Type.of(3)), new DateTimeV2Literal("9999-12-31 23:59:59.991")), + new GreaterThan(datetime2, new DateTimeV2Literal("9999-12-31 23:59:59.99"))); + assertRewrite(new GreaterThanEqual(new Cast(datetime2, DateTimeV2Type.of(6)), new DateTimeV2Literal("9999-12-31 23:59:59.999999")), + new GreaterThan(datetime2, new DateTimeV2Literal("9999-12-31 23:59:59.99"))); + assertRewrite(new EqualTo(new Cast(datetime2, DateTimeV2Type.of(6)), new DateTimeV2Literal("9999-12-31 23:59:59.999999")), + ExpressionUtils.falseOrNull(datetime2)); } @Test diff --git a/regression-test/data/nereids_rules_p0/infer_predicate/extend_infer_equal_predicate.out b/regression-test/data/nereids_rules_p0/infer_predicate/extend_infer_equal_predicate.out index ed43d254b50..470f044da34 100644 Binary files a/regression-test/data/nereids_rules_p0/infer_predicate/extend_infer_equal_predicate.out and b/regression-test/data/nereids_rules_p0/infer_predicate/extend_infer_equal_predicate.out differ diff --git a/regression-test/suites/nereids_rules_p0/partition_prune/month_quarter_cast_in_prune.groovy b/regression-test/suites/nereids_rules_p0/partition_prune/month_quarter_cast_in_prune.groovy index f2ac6c85d54..88235c9ab81 100644 --- a/regression-test/suites/nereids_rules_p0/partition_prune/month_quarter_cast_in_prune.groovy +++ b/regression-test/suites/nereids_rules_p0/partition_prune/month_quarter_cast_in_prune.groovy @@ -79,7 +79,7 @@ suite("month_quarter_cast_in_prune") { }; explain { sql "select * from test_month where cast(dt as date) > '2022-02-26'" - contains("partitions=5/11 (p7,p8,p9,p10,p11)") + contains("partitions=1/11 (p11)") } explain { @@ -88,7 +88,7 @@ suite("month_quarter_cast_in_prune") { } explain { sql "select * from test_month where quarter(dt)>1 or cast(dt as date) > '2022-02-26'" - contains("partitions=8/11 (p1,p4,p5,p7,p8,p9,p10,p11)") + contains("partitions=4/11 (p1,p4,p5,p11)") } explain { sql "select * from test_month where day(dt)>80" @@ -223,4 +223,4 @@ suite("month_quarter_cast_in_prune") { sql """select * from from_unixtime_t where from_unixtime(a,"yyyyMMdd %T") <='2001-05-16 16:00:00'""" contains("partitions=5/5 (p1,p2,p3,p4,p5)") } -} \ No newline at end of file +} --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org