This is an automated email from the ASF dual-hosted git repository. yiguolei 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 55b2988bfde [Opt](date_add/sub) Throw exception when result of date_add/sub out of range (#26475) 55b2988bfde is described below commit 55b2988bfde2f55df50f36d6c9c2d50f819c576b Author: zhiqiang <seuhezhiqi...@163.com> AuthorDate: Wed Nov 8 18:46:51 2023 -0600 [Opt](date_add/sub) Throw exception when result of date_add/sub out of range (#26475) --- .../function_date_or_datetime_computation.h | 39 ++- .../test_date_or_datetime_computation_negative.out | 91 +++++++ ...st_date_or_datetime_computation_negative.groovy | 276 +++++++++++++++++++++ 3 files changed, 400 insertions(+), 6 deletions(-) diff --git a/be/src/vec/functions/function_date_or_datetime_computation.h b/be/src/vec/functions/function_date_or_datetime_computation.h index a4d230180db..3d0e0a8fd4a 100644 --- a/be/src/vec/functions/function_date_or_datetime_computation.h +++ b/be/src/vec/functions/function_date_or_datetime_computation.h @@ -27,6 +27,8 @@ #include <type_traits> #include <utility> +#include "common/compiler_util.h" +#include "common/exception.h" #include "common/logging.h" #include "common/status.h" #include "fmt/format.h" @@ -400,7 +402,11 @@ struct DateTimeOp { // otherwise it will be implicitly converted to bool, causing the rvalue to fail to match the lvalue. // the same goes for the following. vec_to[i] = Transform::execute(vec_from0[i], vec_from1[i], invalid); - DCHECK(!invalid); + + if (UNLIKELY(invalid)) { + throw Exception(ErrorCode::OUT_OF_BOUND, "Operation {} {} {} out of range", + Transform::name, vec_from0[i], vec_from1[i]); + } } } @@ -425,7 +431,11 @@ struct DateTimeOp { bool invalid = true; for (size_t i = 0; i < size; ++i) { vec_to[i] = Transform::execute(vec_from0[i], vec_from1[i], invalid); - DCHECK(!invalid); + + if (UNLIKELY(invalid)) { + throw Exception(ErrorCode::OUT_OF_BOUND, "Operation {} {} {} out of range", + Transform::name, vec_from0[i], vec_from1[i]); + } } } @@ -449,7 +459,11 @@ struct DateTimeOp { bool invalid = true; for (size_t i = 0; i < size; ++i) { vec_to[i] = Transform::execute(vec_from[i], delta, invalid); - DCHECK(!invalid); + + if (UNLIKELY(invalid)) { + throw Exception(ErrorCode::OUT_OF_BOUND, "Operation {} {} {} out of range", + Transform::name, vec_from[i], delta); + } } } @@ -473,7 +487,11 @@ struct DateTimeOp { for (size_t i = 0; i < size; ++i) { vec_to[i] = Transform::execute(vec_from[i], delta, invalid); - DCHECK(!invalid); + + if (UNLIKELY(invalid)) { + throw Exception(ErrorCode::OUT_OF_BOUND, "Operation {} {} {} out of range", + Transform::name, vec_from[i], delta); + } } } @@ -497,7 +515,11 @@ struct DateTimeOp { for (size_t i = 0; i < size; ++i) { vec_to[i] = Transform::execute(from, delta.get_int(i), invalid); - DCHECK(!invalid); + + if (UNLIKELY(invalid)) { + throw Exception(ErrorCode::OUT_OF_BOUND, "Operation {} {} {} out of range", + Transform::name, from, delta.get_int(i)); + } } } @@ -511,6 +533,7 @@ struct DateTimeOp { vec_to[i] = Transform::execute(from, delta[i], reinterpret_cast<bool&>(null_map[i])); } } + static void constant_vector(const FromType1& from, PaddedPODArray<ToType>& vec_to, const PaddedPODArray<FromType2>& delta) { size_t size = delta.size(); @@ -519,7 +542,11 @@ struct DateTimeOp { for (size_t i = 0; i < size; ++i) { vec_to[i] = Transform::execute(from, delta[i], invalid); - DCHECK(!invalid); + + if (UNLIKELY(invalid)) { + throw Exception(ErrorCode::OUT_OF_BOUND, "Operation {} {} {} out of range", + Transform::name, from, delta[i]); + } } } }; diff --git a/regression-test/data/nereids_p0/sql_functions/datetime_functions/test_date_or_datetime_computation_negative.out b/regression-test/data/nereids_p0/sql_functions/datetime_functions/test_date_or_datetime_computation_negative.out new file mode 100644 index 00000000000..9a3dd1db9cc --- /dev/null +++ b/regression-test/data/nereids_p0/sql_functions/datetime_functions/test_date_or_datetime_computation_negative.out @@ -0,0 +1,91 @@ +-- This file is automatically generated. You should know what you did if you want to edit this +-- !select_nullable_1 -- +\N \N \N +\N \N \N +9998-12-31 9998-12-31 9998-12-31T23:59:59 +\N \N \N + +-- !select_nullable_2 -- +\N \N \N +\N \N \N +9999-11-30 9999-11-30 9999-11-30T23:59:59 +\N \N \N + +-- !select_nullable_3 -- +\N \N \N +\N \N \N +9999-12-24 9999-12-24 9999-12-24T23:59:59 +\N \N \N + +-- !select_nullable_4 -- +\N \N \N +\N \N \N +9999-12-30 9999-12-30 9999-12-30T23:59:59 +\N \N \N + +-- !select_nullable_5 -- +\N \N \N +\N \N \N +9999-12-30T23:00 9999-12-30T23:00 9999-12-31T22:59:59 +\N \N \N + +-- !select_nullable_6 -- +\N \N \N +\N \N \N +9999-12-30T23:59 9999-12-30T23:59 9999-12-31T23:58:59 +\N \N \N + +-- !select_nullable_7 -- +\N \N \N +\N \N \N +9999-12-30T23:59:59 9999-12-30T23:59:59 9999-12-31T23:59:58 +\N \N \N + +-- !select_nullable_8 -- +0001-01-01 0001-01-01 0001-01-01T00:00 +\N \N \N +\N \N \N +\N \N \N + +-- !select_nullable_9 -- +0000-02-01 0000-02-01 0000-02-01T00:00 +\N \N \N +\N \N \N +\N \N \N + +-- !select_nullable_10 -- +0000-01-08 0000-01-08 0000-01-08T00:00 +\N \N \N +\N \N \N +\N \N \N + +-- !select_nullable_11 -- +0000-01-02 0000-01-02 0000-01-02T00:00 +\N \N \N +\N \N \N +\N \N \N + +-- !select_nullable_12 -- +0000-01-01T01:00 0000-01-01T01:00 0000-01-01T01:00 +\N \N \N +9999-12-31T01:00 9999-12-31T01:00 \N +\N \N \N + +-- !select_nullable_13 -- +0000-01-01T00:01 0000-01-01T00:01 0000-01-01T00:01 +\N \N \N +9999-12-31T00:01 9999-12-31T00:01 \N +\N \N \N + +-- !select_nullable_14 -- +0000-01-01T00:00:01 0000-01-01T00:00:01 0000-01-01T00:00:01 +\N \N \N +9999-12-31T00:00:01 9999-12-31T00:00:01 \N +\N \N \N + +-- !select_nullable_15 -- +0000-01-02T00:00 0000-01-02T00:00 0000-01-02T00:00 +\N \N \N +\N \N \N +\N \N \N + diff --git a/regression-test/suites/nereids_p0/sql_functions/datetime_functions/test_date_or_datetime_computation_negative.groovy b/regression-test/suites/nereids_p0/sql_functions/datetime_functions/test_date_or_datetime_computation_negative.groovy new file mode 100644 index 00000000000..83431ede6ab --- /dev/null +++ b/regression-test/suites/nereids_p0/sql_functions/datetime_functions/test_date_or_datetime_computation_negative.groovy @@ -0,0 +1,276 @@ +// 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. +test_date_or_datetime_computation_negative +suite("test_date_or_datetime_computation_negative") { + sql """ CREATE TABLE IF NOT EXISTS test_date_or_datetime_computation_negative ( + `row_id` LARGEINT NOT NULL, + `date` DATE NOT NULL, + `date_null` DATE NULL, + `dateV2` DATEV2 NOT NULL, + `dateV2_null` DATEV2 NULL, + `datetime` DATETIME NOT NULL, + `datetime_null` DATETIME NULL, ) + DUPLICATE KEY(`row_id`) + DISTRIBUTED BY HASH(`row_id`) BUCKETS 1 + PROPERTIES ( + "replication_allocation" = "tag.location.default: 1" + );""" + + sql "set enable_insert_strict = false;" + sql "set parallel_fragment_exec_instance_num = 3;" + sql "set enable_nereids_planner = true;" + + sql """INSERT INTO test_date_or_datetime_computation_negative VALUES (1, '0000-01-01', '0000-01-01', '0000-01-01', '0000-01-01', '0000-01-01 00:00:00', '0000-01-01 00:00:00');""" + sql """INSERT INTO test_date_or_datetime_computation_negative VALUES (2, '0000-01-01', NULL, '0000-01-01', NULL, '0000-01-01 00:00:00', NULL);""" + sql """INSERT INTO test_date_or_datetime_computation_negative VALUES (3, '9999-12-31', '9999-12-31', '9999-12-31', '9999-12-31', '9999-12-31 23:59:59', '9999-12-31 23:59:59');""" + sql """INSERT INTO test_date_or_datetime_computation_negative VALUES (4, '9999-12-31', NULL, '9999-12-31', NULL, '9999-12-31 23:59:59', NULL);""" + + test { + sql """SELECT date_sub(date, interval 1 year) FROM test_date_or_datetime_computation_negative WHERE row_id=1;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + + sql """SELECT date_sub(dateV2, interval 1 year) FROM test_date_or_datetime_computation_negative WHERE row_id=1;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + + sql """SELECT date_sub(datetime, interval 1 year) FROM test_date_or_datetime_computation_negative WHERE row_id=1;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + } + qt_select_nullable_1 """SELECT date_sub(date_null, interval 1 year), date_sub(dateV2_null, interval 1 year), date_sub(datetime_null, interval 1 year) FROM test_date_or_datetime_computation_negative ORDER BY row_id;""" + + test { + sql """SELECT date_sub(date, interval 1 month) FROM test_date_or_datetime_computation_negative WHERE row_id=1;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + + sql """SELECT date_sub(dateV2, interval 1 month) FROM test_date_or_datetime_computation_negative WHERE row_id=1;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + + sql """SELECT date_sub(datetime, interval 1 month) FROM test_date_or_datetime_computation_negative WHERE row_id=1;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + } + qt_select_nullable_2 """SELECT date_sub(date_null, interval 1 month), date_sub(dateV2_null, interval 1 month), date_sub(datetime_null, interval 1 month) FROM test_date_or_datetime_computation_negative ORDER BY row_id;""" + + test { + sql """ SELECT date_sub(date, interval 1 week) FROM test_date_or_datetime_computation_negative WHERE row_id=1;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + + sql """ SELECT date_sub(dateV2, interval 1 week) FROM test_date_or_datetime_computation_negative WHERE row_id=1;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + + sql """ SELECT date_sub(datetime, interval 1 week) FROM test_date_or_datetime_computation_negative WHERE row_id=1; """ + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + } + + qt_select_nullable_3 """SELECT date_sub(date_null, interval 1 week), date_sub(dateV2_null, interval 1 week), date_sub(datetime_null, interval 1 week) FROM test_date_or_datetime_computation_negative ORDER BY row_id;""" + + test { + sql """SELECT date_sub(date, interval 1 day) FROM test_date_or_datetime_computation_negative WHERE row_id=1;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + + sql """SELECT date_sub(dateV2, interval 1 day) FROM test_date_or_datetime_computation_negative WHERE row_id=1;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + + sql """SELECT date_sub(datetime, interval 1 day) FROM test_date_or_datetime_computation_negative WHERE row_id=1;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + } + + qt_select_nullable_4 """SELECT date_sub(date_null, interval 1 day), date_sub(dateV2_null, interval 1 day), date_sub(datetime_null, interval 1 day) FROM test_date_or_datetime_computation_negative ORDER BY row_id;""" + + test { + sql """SELECT date_sub(date, interval 1 hour) FROM test_date_or_datetime_computation_negative WHERE row_id=1;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + + sql """SELECT date_sub(dateV2, interval 1 hour) FROM test_date_or_datetime_computation_negative WHERE row_id=1;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + + sql """SELECT date_sub(datetime, interval 1 hour) FROM test_date_or_datetime_computation_negative WHERE row_id=1;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + } + qt_select_nullable_5 """ SELECT date_sub(date_null, interval 1 hour), date_sub(dateV2_null, interval 1 hour), date_sub(datetime_null, interval 1 hour) FROM test_date_or_datetime_computation_negative ORDER BY row_id;""" + + test { + sql """SELECT date_sub(date, interval 1 minute) FROM test_date_or_datetime_computation_negative WHERE row_id=1;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + + sql """SELECT date_sub(dateV2, interval 1 minute) FROM test_date_or_datetime_computation_negative WHERE row_id=1;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + + sql """SELECT date_sub(datetime, interval 1 minute) FROM test_date_or_datetime_computation_negative WHERE row_id=1;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + } + qt_select_nullable_6 """SELECT date_sub(date_null, interval 1 minute), date_sub(dateV2_null, interval 1 minute), date_sub(datetime_null, interval 1 minute) FROM test_date_or_datetime_computation_negative ORDER BY row_id;""" + + test { + sql """SELECT date_sub(date, interval 1 second) FROM test_date_or_datetime_computation_negative WHERE row_id=1;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + + sql """SELECT date_sub(dateV2, interval 1 second) FROM test_date_or_datetime_computation_negative WHERE row_id=1;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + + sql """SELECT date_sub(datetime, interval 1 second) FROM test_date_or_datetime_computation_negative WHERE row_id=1;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + } + qt_select_nullable_7 """SELECT date_sub(date_null, interval 1 second), date_sub(dateV2_null, interval 1 second), date_sub(datetime_null, interval 1 second) FROM test_date_or_datetime_computation_negative ORDER BY row_id;""" + + + test { + sql """SELECT date_add(date, interval 1 year) FROM test_date_or_datetime_computation_negative WHERE row_id=3;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + + sql """SELECT date_add(dateV2, interval 1 year) FROM test_date_or_datetime_computation_negative WHERE row_id=3;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + + sql """SELECT date_add(datetime, interval 1 year) FROM test_date_or_datetime_computation_negative WHERE row_id=3;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + } + qt_select_nullable_8 """SELECT date_add(date_null, interval 1 year), date_add(dateV2_null, interval 1 year), date_add(datetime_null, interval 1 year) FROM test_date_or_datetime_computation_negative ORDER BY row_id;""" + + test { + sql """SELECT date_add(date, interval 1 month) FROM test_date_or_datetime_computation_negative WHERE row_id=3;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + + sql """SELECT date_add(dateV2, interval 1 month) FROM test_date_or_datetime_computation_negative WHERE row_id=3;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + + sql """SELECT date_add(datetime, interval 1 month) FROM test_date_or_datetime_computation_negative WHERE row_id=3;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + } + qt_select_nullable_9 """SELECT date_add(date_null, interval 1 month), date_add(dateV2_null, interval 1 month), date_add(datetime_null, interval 1 month) FROM test_date_or_datetime_computation_negative ORDER BY row_id;""" + + test { + sql """ SELECT date_add(date, interval 1 week) FROM test_date_or_datetime_computation_negative WHERE row_id=3;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + + sql """ SELECT date_add(dateV2, interval 1 week) FROM test_date_or_datetime_computation_negative WHERE row_id=3;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + + sql """ SELECT date_add(datetime, interval 1 week) FROM test_date_or_datetime_computation_negative WHERE row_id=3; """ + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + } + + qt_select_nullable_10 """SELECT date_add(date_null, interval 1 week), date_add(dateV2_null, interval 1 week), date_add(datetime_null, interval 1 week) FROM test_date_or_datetime_computation_negative ORDER BY row_id;""" + + test { + sql """SELECT date_add(date, interval 1 day) FROM test_date_or_datetime_computation_negative WHERE row_id=3;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + + sql """SELECT date_add(dateV2, interval 1 day) FROM test_date_or_datetime_computation_negative WHERE row_id=3;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + + sql """SELECT date_add(datetime, interval 1 day) FROM test_date_or_datetime_computation_negative WHERE row_id=3;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + } + + qt_select_nullable_11 """SELECT date_add(date_null, interval 1 day), date_add(dateV2_null, interval 1 day), date_add(datetime_null, interval 1 day) FROM test_date_or_datetime_computation_negative ORDER BY row_id;""" + + test { + sql """SELECT date_add(date, interval 1 hour) FROM test_date_or_datetime_computation_negative WHERE row_id=3;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + + sql """SELECT date_add(dateV2, interval 1 hour) FROM test_date_or_datetime_computation_negative WHERE row_id=3;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + + sql """SELECT date_add(datetime, interval 1 hour) FROM test_date_or_datetime_computation_negative WHERE row_id=3;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + } + qt_select_nullable_12 """ SELECT date_add(date_null, interval 1 hour), date_add(dateV2_null, interval 1 hour), date_add(datetime_null, interval 1 hour) FROM test_date_or_datetime_computation_negative ORDER BY row_id;""" + + test { + sql """SELECT date_add(date, interval 1 minute) FROM test_date_or_datetime_computation_negative WHERE row_id=3;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + + sql """SELECT date_add(dateV2, interval 1 minute) FROM test_date_or_datetime_computation_negative WHERE row_id=3;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + + sql """SELECT date_add(datetime, interval 1 minute) FROM test_date_or_datetime_computation_negative WHERE row_id=3;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + } + qt_select_nullable_13 """SELECT date_add(date_null, interval 1 minute), date_add(dateV2_null, interval 1 minute), date_add(datetime_null, interval 1 minute) FROM test_date_or_datetime_computation_negative ORDER BY row_id;""" + + test { + sql """SELECT date_add(date, interval 1 second) FROM test_date_or_datetime_computation_negative WHERE row_id=3;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + + sql """SELECT date_add(dateV2, interval 1 second) FROM test_date_or_datetime_computation_negative WHERE row_id=3;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + + sql """SELECT date_add(datetime, interval 1 second) FROM test_date_or_datetime_computation_negative WHERE row_id=3;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + } + qt_select_nullable_14 """SELECT date_add(date_null, interval 1 second), date_add(dateV2_null, interval 1 second), date_add(datetime_null, interval 1 second) FROM test_date_or_datetime_computation_negative ORDER BY row_id;""" + + // TODO: + // nagetive test for microseconds_add/milliseconds_add/seconds_add/minutes_add/hours_add/days_add/weeks_add/months_add/years_add + + test { + sql """SELECT hours_add(date, 24) FROM test_date_or_datetime_computation_negative WHERE row_id = 3;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + + sql """SELECT hours_add(dateV2, 24) FROM test_date_or_datetime_computation_negative WHERE row_id = 3;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + + sql """SELECT hours_add(datetime, 24) FROM test_date_or_datetime_computation_negative WHERE row_id = 3;""" + check {result, exception, startTime, endTime -> + assertTrue (exception != null)} + } + qt_select_nullable_15 """SELECT hours_add(date_null, 24), hours_add(dateV2_null, 24), hours_add(datetime_null, 24) FROM test_date_or_datetime_computation_negative ORDER BY row_id;""" + + sql "DROP TABLE test_date_or_datetime_computation_negative" +} --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org