From 6c729be3206be551ffc5c7a269df19242ec09537 Mon Sep 17 00:00:00 2001 From: morrySnow Date: Tue, 21 May 2024 22:01:19 +0800 Subject: [PATCH] [fix](Nereids) DatetimeV2 round floor was incorrectly implemented as round ceil pick from master #35153 --- .../literal/DateTimeV2Literal.java | 32 +++---------------- .../literal/DateTimeLiteralTest.java | 32 +++++++++++++++++++ 2 files changed, 36 insertions(+), 28 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DateTimeV2Literal.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DateTimeV2Literal.java index 2417d92e89addf3..945c2420d26585a 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DateTimeV2Literal.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DateTimeV2Literal.java @@ -222,37 +222,13 @@ public Expression plusMicroSeconds(long microSeconds) { * roundCeiling */ public DateTimeV2Literal roundCeiling(int newScale) { - long remain = Double.valueOf(microSecond % (Math.pow(10, 6 - newScale))).longValue(); - long newMicroSecond = microSecond; - long newSecond = second; - long newMinute = minute; - long newHour = hour; - long newDay = day; - long newMonth = month; - long newYear = year; - if (remain != 0) { - newMicroSecond = Double - .valueOf((microSecond + (Math.pow(10, 6 - newScale))) - / (int) (Math.pow(10, 6 - newScale)) * (Math.pow(10, 6 - newScale))) - .longValue(); - } - if (newMicroSecond > MAX_MICROSECOND) { - newMicroSecond %= newMicroSecond; - DateTimeV2Literal result = (DateTimeV2Literal) this.plusSeconds(1); - newSecond = result.second; - newMinute = result.minute; - newHour = result.hour; - newDay = result.day; - newMonth = result.month; - newYear = result.year; - } - return new DateTimeV2Literal(DateTimeV2Type.of(newScale), newYear, newMonth, newDay, - newHour, newMinute, newSecond, newMicroSecond); + // use roundMicroSecond in constructor + return new DateTimeV2Literal(DateTimeV2Type.of(newScale), year, month, day, hour, minute, second, microSecond); } public DateTimeV2Literal roundFloor(int newScale) { - // use roundMicroSecond in constructor - return new DateTimeV2Literal(DateTimeV2Type.of(newScale), year, month, day, hour, minute, second, microSecond); + return new DateTimeV2Literal(DateTimeV2Type.of(newScale), year, month, day, hour, minute, second, + microSecond / (int) Math.pow(10, 6 - newScale) * (int) Math.pow(10, 6 - newScale)); } public static Expression fromJavaDateType(LocalDateTime dateTime) { diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/literal/DateTimeLiteralTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/literal/DateTimeLiteralTest.java index 184cf5dbf6342f4..94e456cf9289af3 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/literal/DateTimeLiteralTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/literal/DateTimeLiteralTest.java @@ -443,4 +443,36 @@ void testDateTimeV2Scale() { new DateTimeV2Literal(DateTimeV2Type.of(5), "2016-12-31 23:59:59.999999"), new DateTimeV2Literal("2017-01-01 00:00:00.0")); } + + @Test + void testRoundFloor() { + DateTimeV2Literal literal; + literal = new DateTimeV2Literal(DateTimeV2Type.of(6), 2000, 2, 2, 2, 2, 2, 222222); + Assertions.assertEquals(222222, literal.roundFloor(6).microSecond); + Assertions.assertEquals(222220, literal.roundFloor(5).microSecond); + Assertions.assertEquals(222200, literal.roundFloor(4).microSecond); + Assertions.assertEquals(222000, literal.roundFloor(3).microSecond); + Assertions.assertEquals(220000, literal.roundFloor(2).microSecond); + Assertions.assertEquals(200000, literal.roundFloor(1).microSecond); + Assertions.assertEquals(0, literal.roundFloor(0).microSecond); + } + + @Test + void testRoundCeiling() { + DateTimeV2Literal literal; + literal = new DateTimeV2Literal(DateTimeV2Type.of(6), 2000, 12, 31, 23, 59, 59, 888888); + Assertions.assertEquals(888888, literal.roundCeiling(6).microSecond); + Assertions.assertEquals(888890, literal.roundCeiling(5).microSecond); + Assertions.assertEquals(888900, literal.roundCeiling(4).microSecond); + Assertions.assertEquals(889000, literal.roundCeiling(3).microSecond); + Assertions.assertEquals(890000, literal.roundCeiling(2).microSecond); + Assertions.assertEquals(900000, literal.roundCeiling(1).microSecond); + Assertions.assertEquals(0, literal.roundCeiling(0).microSecond); + Assertions.assertEquals(0, literal.roundCeiling(0).second); + Assertions.assertEquals(0, literal.roundCeiling(0).minute); + Assertions.assertEquals(0, literal.roundCeiling(0).hour); + Assertions.assertEquals(1, literal.roundCeiling(0).day); + Assertions.assertEquals(1, literal.roundCeiling(0).month); + Assertions.assertEquals(2001, literal.roundCeiling(0).year); + } }