From 9bc870fbe700953098ea39d21b8a53ba044e7698 Mon Sep 17 00:00:00 2001 From: wuwenchi Date: Thu, 6 Jun 2024 16:32:50 +0800 Subject: [PATCH] [bugfix](iceberg)fix datetime conversion error for 2.0 (#35831) bp: #35708 --- .../apache/doris/analysis/DateLiteral.java | 19 ++++++++++++++++--- .../external/iceberg/util/IcebergUtils.java | 3 +-- .../doris/analysis/DateLiteralTest.java | 15 +++++++++++++++ 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/DateLiteral.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/DateLiteral.java index 1dc58b4c382949..9baa583f115cc1 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/DateLiteral.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/DateLiteral.java @@ -974,12 +974,25 @@ public static DateLiteral read(DataInput in) throws IOException { } public long unixTimestamp(TimeZone timeZone) { - ZonedDateTime zonedDateTime = ZonedDateTime.of((int) year, (int) month, (int) day, (int) hour, - (int) minute, (int) second, (int) microsecond, ZoneId.of(timeZone.getID())); - Timestamp timestamp = Timestamp.from(zonedDateTime.toInstant()); + Timestamp timestamp = getTimestamp(timeZone); return timestamp.getTime(); } + private Timestamp getTimestamp(TimeZone timeZone) { + ZonedDateTime zonedDateTime = ZonedDateTime.of((int) year, (int) month, (int) day, (int) hour, + (int) minute, (int) second, (int) microsecond * 1000, ZoneId.of(timeZone.getID())); + return Timestamp.from(zonedDateTime.toInstant()); + } + + public long getUnixTimestampWithMillisecond(TimeZone timeZone) { + return unixTimestamp(timeZone); + } + + public long getUnixTimestampWithMicroseconds(TimeZone timeZone) { + Timestamp timestamp = getTimestamp(timeZone); + return timestamp.getTime() * 1000 + timestamp.getNanos() / 1000 % 1000; + } + public static boolean hasTimePart(String format) { return format.chars().anyMatch(c -> TIME_PART_SET.contains((char) c)); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/external/iceberg/util/IcebergUtils.java b/fe/fe-core/src/main/java/org/apache/doris/external/iceberg/util/IcebergUtils.java index 872096a7f325c3..3f4779ef893623 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/external/iceberg/util/IcebergUtils.java +++ b/fe/fe-core/src/main/java/org/apache/doris/external/iceberg/util/IcebergUtils.java @@ -88,7 +88,6 @@ public Integer initialValue() { return 0; } }; - static long MILLIS_TO_NANO_TIME = 1000; public static final String TOTAL_RECORDS = "total-records"; public static final String TOTAL_POSITION_DELETES = "total-position-deletes"; public static final String TOTAL_EQUALITY_DELETES = "total-equality-deletes"; @@ -454,7 +453,7 @@ private static Object extractDorisLiteral(org.apache.iceberg.types.Type icebergT case DATE: return dateLiteral.getStringValue(); case TIMESTAMP: - return dateLiteral.unixTimestamp(TimeUtils.getTimeZone()) * MILLIS_TO_NANO_TIME; + return dateLiteral.getUnixTimestampWithMicroseconds(TimeUtils.getTimeZone()); default: return null; } diff --git a/fe/fe-core/src/test/java/org/apache/doris/analysis/DateLiteralTest.java b/fe/fe-core/src/test/java/org/apache/doris/analysis/DateLiteralTest.java index 9715b7a1826f38..0a481c82ab92f1 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/analysis/DateLiteralTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/analysis/DateLiteralTest.java @@ -26,6 +26,9 @@ import org.junit.Assert; import org.junit.Test; +import java.time.ZoneOffset; +import java.util.TimeZone; + public class DateLiteralTest { @Test @@ -406,4 +409,16 @@ public void testCheckRangeForDateV2() { } Assert.assertFalse(hasException); } + + @Test + public void testUnixTimestampWithMilliMicroSecond() throws AnalysisException { + String s = "2020-12-13 12:13:14.123456"; + Type type = Type.DATETIMEV2; + DateLiteral literal = new DateLiteral(s, type); + long l = literal.getUnixTimestampWithMillisecond(TimeZone.getTimeZone(ZoneOffset.UTC)); + Assert.assertEquals(123, l % 1000); + + long l2 = literal.getUnixTimestampWithMicroseconds(TimeZone.getTimeZone(ZoneOffset.UTC)); + Assert.assertEquals(123456, l2 % 1000000); + } }