From 06647ec4a34bc438822e30a7e045d7e66f9a4d7d Mon Sep 17 00:00:00 2001 From: starocean999 <12095047@qq.com> Date: Wed, 21 Aug 2024 11:07:21 +0800 Subject: [PATCH 1/2] [fix](nereids)prevent null pointer exception if datetime value overflows --- .../rules/SimplifyComparisonPredicate.java | 5 ++-- .../functions/executable/TimeRoundSeries.java | 25 +++++++++++++------ .../expressions/literal/DateLiteral.java | 2 +- 3 files changed, 22 insertions(+), 10 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 d26b5a53036897..522a539e4a7913 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 @@ -346,9 +346,10 @@ private static boolean cannotAdjust(DateTimeLiteral l, ComparisonPredicate cp) { private static Expression migrateToDateV2(DateTimeLiteral l, AdjustType type) { DateV2Literal d = new DateV2Literal(l.getYear(), l.getMonth(), l.getDay()); if (type == AdjustType.UPPER && (l.getHour() != 0 || l.getMinute() != 0 || l.getSecond() != 0)) { - d = ((DateV2Literal) d.plusDays(1)); + return d.plusDays(1); + } else { + return d; } - return d; } private static Expression migrateToDate(DateV2Literal l) { diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/TimeRoundSeries.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/TimeRoundSeries.java index a9337f05370ce6..3a98ee6252791a 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/TimeRoundSeries.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/TimeRoundSeries.java @@ -104,23 +104,34 @@ private static LocalDateTime getDateCeilOrFloor(DATE tag, LocalDateTime date, in if (getCeil) { step = step + (deltaInsidePeriod == 0 ? 0 : period); } + Expression result = null; switch (tag) { case YEAR: - return ((DateTimeLiteral) start.plusYears(step)).toJavaDateType(); + result = start.plusYears(step); + break; case MONTH: - return ((DateTimeLiteral) start.plusMonths(step)).toJavaDateType(); + result = start.plusMonths(step); + break; case DAY: - return ((DateTimeLiteral) start.plusDays(step)).toJavaDateType(); + result = start.plusDays(step); + break; case HOUR: - return ((DateTimeLiteral) start.plusHours(step)).toJavaDateType(); + result = start.plusHours(step); + break; case MINUTE: - return ((DateTimeLiteral) start.plusMinutes(step)).toJavaDateType(); + result = start.plusMinutes(step); + break; case SECOND: - return ((DateTimeLiteral) start.plusSeconds(step)).toJavaDateType(); + result = start.plusSeconds(step); + break; default: break; } - return null; + if (result != null && result instanceof DateTimeLiteral) { + return ((DateTimeLiteral) result).toJavaDateType(); + } else { + return null; + } } /** 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 b4ea42d42779f7..4b990ff09b33e2 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 @@ -336,7 +336,7 @@ protected boolean checkDate() { } protected static boolean isDateOutOfRange(LocalDateTime dateTime) { - return dateTime.isBefore(START_OF_A_DAY) || dateTime.isAfter(END_OF_A_DAY); + return dateTime == null || dateTime.isBefore(START_OF_A_DAY) || dateTime.isAfter(END_OF_A_DAY); } private boolean checkDatetime(TemporalAccessor dateTime) { From b7441df49ce305437c3a0add5fdd50ac216afb8e Mon Sep 17 00:00:00 2001 From: starocean999 <12095047@qq.com> Date: Wed, 21 Aug 2024 11:12:44 +0800 Subject: [PATCH 2/2] add case --- .../datatype/test_datetime_overflow.groovy | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 regression-test/suites/nereids_p0/datatype/test_datetime_overflow.groovy diff --git a/regression-test/suites/nereids_p0/datatype/test_datetime_overflow.groovy b/regression-test/suites/nereids_p0/datatype/test_datetime_overflow.groovy new file mode 100644 index 00000000000000..27f7addbd26293 --- /dev/null +++ b/regression-test/suites/nereids_p0/datatype/test_datetime_overflow.groovy @@ -0,0 +1,36 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +suite("test_datetime_overflow") { + sql 'set enable_nereids_planner=true' + sql 'set enable_fallback_to_original_planner=false' + sql """drop table if exists datetime_overflow_t""" + sql """CREATE TABLE datetime_overflow_t ( + `id` bigint NULL, + `c` datetime NULL, + `d` date NULL, + INDEX idx_c (`c`) USING INVERTED + ) ENGINE=OLAP + DUPLICATE KEY(`id`) + DISTRIBUTED BY RANDOM BUCKETS AUTO + PROPERTIES ( + "replication_num" = "1" + );""" + + sql """select * from datetime_overflow_t where d between "9999-12-31 00:00:01" and "9999-12-31 10:00:01";""" + sql """select * from datetime_overflow_t where d > "9999-12-31 00:00:01";""" +} \ No newline at end of file