From 1dbdfef4bf1ae278a07de8c72a390b5ceb3a2eff Mon Sep 17 00:00:00 2001 From: LiBinfeng Date: Thu, 26 Dec 2024 16:07:39 +0800 Subject: [PATCH] fix p0 and fe ut --- .../rules/SimplifyComparisonPredicate.java | 44 +++++++++++++------ .../expressions/literal/DateLiteral.java | 2 +- .../SimplifyComparisonPredicateTest.java | 32 ++++++++++---- 3 files changed, 55 insertions(+), 23 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 78e817cf4f813a..420f69f26f8d90 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 @@ -130,7 +130,12 @@ private static Expression processDateTimeLikeComparisonPredicateDateTimeV2Litera if (toScale < rightType.getScale()) { if (comparisonPredicate instanceof EqualTo) { long originValue = right.getMicroSecond(); - right = right.roundCeiling(toScale); + try { + right = right.roundCeiling(toScale); + } catch (AnalysisException e) { + // '9999-12-31 23:59:59.9'.roundCeiling(0) overflow + return ExpressionUtils.falseOrNull(left); + } 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), @@ -142,7 +147,12 @@ private static Expression processDateTimeLikeComparisonPredicateDateTimeV2Litera } } else if (comparisonPredicate instanceof NullSafeEqual) { long originValue = right.getMicroSecond(); - right = right.roundCeiling(toScale); + try { + right = right.roundCeiling(toScale); + } catch (AnalysisException e) { + // '9999-12-31 23:59:59.9'.roundCeiling(0) overflow + return BooleanLiteral.FALSE; + } if (right.getMicroSecond() != originValue) { return BooleanLiteral.of(false); } @@ -151,7 +161,15 @@ private static Expression processDateTimeLikeComparisonPredicateDateTimeV2Litera 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 + if (comparisonPredicate instanceof LessThan) { + return ExpressionUtils.trueOrNull(left); + } + return ExpressionUtils.falseOrNull(left); + } } else { return comparisonPredicate; } @@ -172,13 +190,8 @@ private static Expression processDateLikeTypeCoercion(ComparisonPredicate cp, Ex 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; - } + return processDateTimeLikeComparisonPredicateDateTimeV2Literal( + cp, cast.child(), (DateTimeV2Literal) right); } } @@ -195,11 +208,14 @@ private static Expression processDateLikeTypeCoercion(ComparisonPredicate cp, Ex return BooleanLiteral.FALSE; } else if (cp instanceof GreaterThanEqual || cp instanceof LessThan) { // '9999-12-31' + 1 will overflow - Expression tomorrow = ((DateV2Literal) right).plusDays(1); - if (tomorrow.isNullLiteral()) { - return cp; + if (DateLiteral.isDateOutOfRange(((DateV2Literal) right).toJavaDateType().plusDays(1))) { + if (cp instanceof LessThan) { + return ExpressionUtils.trueOrNull(cast.child()); + } else { + return ExpressionUtils.falseOrNull(cast.child()); + } } - right = tomorrow; + right = ((DateV2Literal) right).plusDays(1); } } if (cast.child().getDataType() instanceof DateV2Type) { diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DateLiteral.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DateLiteral.java index fa443bd9c26a01..04300891c45a8d 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DateLiteral.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DateLiteral.java @@ -384,7 +384,7 @@ protected static boolean checkDate(long year, long month, long day) { return false; } - protected static boolean isDateOutOfRange(LocalDateTime dateTime) { + public static boolean isDateOutOfRange(LocalDateTime dateTime) { return dateTime == null || dateTime.isBefore(START_OF_A_DAY) || dateTime.isAfter(END_OF_A_DAY); } 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 7696c50b39441d..4edc462fa26553 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 @@ -304,21 +304,37 @@ void testDateTimeV2CmpDateTimeV2() { // 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"))); + ExpressionUtils.trueOrNull(date)); 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"))); + ExpressionUtils.trueOrNull(date)); 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"))); + ExpressionUtils.trueOrNull(datev1)); 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"))); + ExpressionUtils.trueOrNull(datev1)); 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"))); + ExpressionUtils.trueOrNull(datetime0)); 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"))); + ExpressionUtils.trueOrNull(datetime2)); 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"))); + ExpressionUtils.trueOrNull(datetime2)); 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"))); + ExpressionUtils.trueOrNull(datetimev1)); + assertRewrite(new GreaterThanEqual(new Cast(date, DateTimeType.INSTANCE), new DateTimeLiteral("9999-12-31 23:59:59")), + ExpressionUtils.falseOrNull(date)); + assertRewrite(new GreaterThanEqual(new Cast(date, DateTimeV2Type.SYSTEM_DEFAULT), new DateTimeV2Literal("9999-12-31 23:59:59")), + ExpressionUtils.falseOrNull(date)); + assertRewrite(new GreaterThanEqual(new Cast(datev1, DateTimeType.INSTANCE), new DateTimeLiteral("9999-12-31 23:59:59")), + ExpressionUtils.falseOrNull(datev1)); + assertRewrite(new GreaterThanEqual(new Cast(datev1, DateTimeV2Type.SYSTEM_DEFAULT), new DateTimeV2Literal("9999-12-31 23:59:59")), + ExpressionUtils.falseOrNull(datev1)); + assertRewrite(new GreaterThanEqual(new Cast(datetime0, DateTimeV2Type.of(1)), new DateTimeV2Literal("9999-12-31 23:59:59.1")), + ExpressionUtils.falseOrNull(datetime0)); + assertRewrite(new GreaterThanEqual(new Cast(datetime2, DateTimeV2Type.of(3)), new DateTimeV2Literal("9999-12-31 23:59:59.991")), + ExpressionUtils.falseOrNull(datetime2)); + assertRewrite(new GreaterThanEqual(new Cast(datetime2, DateTimeV2Type.of(6)), new DateTimeV2Literal("9999-12-31 23:59:59.999999")), + ExpressionUtils.falseOrNull(datetime2)); + assertRewrite(new GreaterThanEqual(new Cast(datetimev1, DateTimeV2Type.of(1)), new DateTimeV2Literal("9999-12-31 23:59:59.1")), + ExpressionUtils.falseOrNull(datetimev1)); } @Test