diff --git a/be/src/vec/functions/function_timestamp.cpp b/be/src/vec/functions/function_timestamp.cpp index c4c555cf9a..735b9067a7 100644 --- a/be/src/vec/functions/function_timestamp.cpp +++ b/be/src/vec/functions/function_timestamp.cpp @@ -808,7 +808,10 @@ public: size_t get_number_of_arguments() const override { return 1; } DataTypePtr get_return_type_impl(const ColumnsWithTypeAndName& arguments) const override { - return make_nullable(std::make_shared()); + if (arguments[0].type->is_nullable()) { + return make_nullable(std::make_shared()); + } + return std::make_shared(); } Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, @@ -816,31 +819,23 @@ public: const auto& arg_col = block.get_by_position(arguments[0]).column; const auto& column_data = assert_cast(*arg_col); auto res_col = ColumnInt64::create(); - auto null_vector = ColumnVector::create(); - res_col->get_data().resize_fill(input_rows_count, 0); - null_vector->get_data().resize_fill(input_rows_count, false); - NullMap& null_map = null_vector->get_data(); auto& res_data = res_col->get_data(); - const cctz::time_zone& time_zone = context->state()->timezone_obj(); + res_col->get_data().resize_fill(input_rows_count, 0); for (int i = 0; i < input_rows_count; i++) { - if (arg_col->is_null_at(i)) { - null_map[i] = true; - continue; - } StringRef source = column_data.get_data_at(i); const auto& dt = reinterpret_cast&>(*source.data); + const cctz::time_zone& time_zone = context->state()->timezone_obj(); int64_t timestamp {0}; - if (!dt.unix_timestamp(×tamp, time_zone)) { - null_map[i] = true; - } else { - auto microsecond = dt.microsecond(); - timestamp = timestamp * Impl::ratio + microsecond / ratio_to_micro; - res_data[i] = timestamp; - } + auto ret = dt.unix_timestamp(×tamp, time_zone); + // ret must be true + DCHECK(ret); + auto microsecond = dt.microsecond(); + timestamp = timestamp * Impl::ratio + microsecond / ratio_to_micro; + res_data[i] = timestamp; } - block.get_by_position(result).column = - ColumnNullable::create(std::move(res_col), std::move(null_vector)); + block.replace_by_position(result, std::move(res_col)); + return Status::OK(); } }; diff --git a/gensrc/script/doris_builtins_functions.py b/gensrc/script/doris_builtins_functions.py index 4634604f56..b519f5c79e 100644 --- a/gensrc/script/doris_builtins_functions.py +++ b/gensrc/script/doris_builtins_functions.py @@ -875,9 +875,9 @@ visible_functions = { [['from_microsecond'], 'DATETIMEV2', ['BIGINT'], 'ALWAYS_NULLABLE'], [['from_millisecond'], 'DATETIMEV2', ['BIGINT'], 'ALWAYS_NULLABLE'], [['from_second'], 'DATETIMEV2', ['BIGINT'], 'ALWAYS_NULLABLE'], - [['second_timestamp'], 'BIGINT', ['DATETIMEV2'], 'ALWAYS_NULLABLE'], - [['millisecond_timestamp'], 'BIGINT', ['DATETIMEV2'], 'ALWAYS_NULLABLE'], - [['microsecond_timestamp'], 'BIGINT', ['DATETIMEV2'], 'ALWAYS_NULLABLE'], + [['second_timestamp'], 'BIGINT', ['DATETIMEV2'], 'DEPEND_ON_ARGUMENT'], + [['millisecond_timestamp'], 'BIGINT', ['DATETIMEV2'], 'DEPEND_ON_ARGUMENT'], + [['microsecond_timestamp'], 'BIGINT', ['DATETIMEV2'], 'DEPEND_ON_ARGUMENT'], [['now', 'current_timestamp', 'localtime', 'localtimestamp'], 'DATETIME', [], 'DEPEND_ON_ARGUMENT'], [['now', 'current_timestamp', 'localtime', 'localtimestamp'], 'DATETIMEV2', ['INT'], 'DEPEND_ON_ARGUMENT'], [['curtime', 'current_time'], 'TIME', [], 'ALWAYS_NOT_NULLABLE'], diff --git a/regression-test/data/correctness/test_from_millisecond_microsecond.out b/regression-test/data/correctness/test_from_millisecond_microsecond.out index 7a5867d2c9..2dc7f81a74 100644 --- a/regression-test/data/correctness/test_from_millisecond_microsecond.out +++ b/regression-test/data/correctness/test_from_millisecond_microsecond.out @@ -65,3 +65,97 @@ 1235817896941 1970-01-15T15:16:57.896941 1235817896941 \N \N \N +-- !select13 -- +1700237372 + +-- !select14 -- +1700237372000 + +-- !select15 -- +1700237372000000 + +-- !select16 -- +1700237372 + +-- !select17 -- +1700237372000 + +-- !select18 -- +1700237372000000 + +-- !select1 -- +2030-11-02T08:35:14.514 2030-11-02T08:35:14.514 +4803-07-17T15:07:14.789 \N +2009-02-28T18:44:56.941 2009-02-28T18:44:56.941 +\N \N + +-- !select2 -- +1970-01-23T13:16:50.114514 1970-01-23T13:16:50.114514 +1972-11-01T06:18:11.234789 1972-11-01T06:18:11.234789 +1970-01-15T15:16:57.896941 1970-01-15T15:16:57.896941 +\N \N + +-- !select3 -- +3001-01-19 07:59:59 3001-01-19T07:59:59 \N 3001-01-19T08:00 2650-07-06 16:21:10 2650-07-06T16:21:10 + +-- !select4 -- +1919810114514 1919810114514 +89417891234789 488885820389 +1235817896941 1235817896941 +\N \N \N + +-- !select5 -- +1919810114514 2030-11-02T08:35:14.514 1919810114514 +89417891234789 4803-07-17T15:07:14.789 89417891234789 +1235817896941 2009-02-28T18:44:56.941 1235817896941 +\N \N \N + +-- !select6 -- +1919810114514 1970-01-23T13:16:50.114514 1919810114514 +89417891234789 1972-11-01T06:18:11.234789 89417891234789 +1235817896941 1970-01-15T15:16:57.896941 1235817896941 +\N \N \N + +-- !select7 -- +2030-11-02T08:35:14.514 +4803-07-17T15:07:14.789 +2009-02-28T18:44:56.941 +\N + +-- !select8 -- +1970-01-23T13:16:50.114514 +1972-11-01T06:18:11.234789 +1970-01-15T15:16:57.896941 +\N + +-- !select9 -- +2038-01-19 11:14:07 2038-01-19T11:14:07 2038-01-19 11:14:08 2038-01-19T11:14:08 2650-07-06 16:21:10 2650-07-06T16:21:10 + +-- !select10 -- +1919810114514 1919810114514 +89417891234789 488885820389 +1235817896941 1235817896941 +\N \N \N + +-- !select11 -- +1919810114514 2030-11-02T08:35:14.514 1919810114514 +89417891234789 4803-07-17T15:07:14.789 89417891234789 +1235817896941 2009-02-28T18:44:56.941 1235817896941 +\N \N \N + +-- !select12 -- +1919810114514 1970-01-23T13:16:50.114514 1919810114514 +89417891234789 1972-11-01T06:18:11.234789 89417891234789 +1235817896941 1970-01-15T15:16:57.896941 1235817896941 +\N \N \N + +-- !select_null_datetime -- +1 1672502400 1672502400000 1672502400000000 +2 1672502400 1672502400123 1672502400123000 +3 1672502400 1672502400123 1672502400123456 + +-- !select_not_null_datetime -- +1 1672502400 1672502400000 1672502400000000 +2 1672502400 1672502400123 1672502400123000 +3 1672502400 1672502400123 1672502400123456 + diff --git a/regression-test/suites/correctness/test_from_millisecond_microsecond.groovy b/regression-test/suites/correctness/test_from_millisecond_microsecond.groovy index 50fe8fcc5e..39b5ab9c89 100644 --- a/regression-test/suites/correctness/test_from_millisecond_microsecond.groovy +++ b/regression-test/suites/correctness/test_from_millisecond_microsecond.groovy @@ -128,4 +128,196 @@ suite("test_from_millisecond_microsecond") { microsecond_timestamp(from_microsecond(t)) from millimicro order by id; """ + qt_select13 """select SECOND_TIMESTAMP(cast('2023-11-18 00:09:32' as datetime));""" + qt_select14 """select MILLISECOND_TIMESTAMP(cast('2023-11-18 00:09:32' as datetime));""" + qt_select15 """select MICROSECOND_TIMESTAMP(cast('2023-11-18 00:09:32' as datetime));""" + sql """ + set enable_nereids_planner=false + """ + qt_select16 """select SECOND_TIMESTAMP(cast('2023-11-18 00:09:32' as datetime));""" + qt_select17 """select MILLISECOND_TIMESTAMP(cast('2023-11-18 00:09:32' as datetime));""" + qt_select18 """select MICROSECOND_TIMESTAMP(cast('2023-11-18 00:09:32' as datetime));""" + + // not null + sql """ DROP TABLE IF EXISTS millimicro """ + sql """ + CREATE TABLE IF NOT EXISTS millimicro ( + `id` INT(11) COMMENT "" , + `t` BigINT COMMENT "" + ) ENGINE=OLAP + DUPLICATE KEY(`id`) + DISTRIBUTED BY HASH(`id`) BUCKETS 1 + PROPERTIES ( + "replication_allocation" = "tag.location.default: 1", + "storage_format" = "V2" + ); + """ + + sql """ + insert into millimicro values(1,1919810114514); + """ + sql """ + insert into millimicro values(2,89417891234789); + """ + sql """ + insert into millimicro values(3,1235817896941); + """ + + sql """ + insert into millimicro values(4,NULL); + """ + + + qt_select1 """ + select + from_millisecond(t) as t1 , + microseconds_add(cast(from_unixtime(t/1000) as datetime(3)), cast((t % 1000) * 1000 as int)) as t2 + from millimicro order by id; + """ + + qt_select2 """ + select + from_microsecond(t) as t1 , + microseconds_add(cast(from_unixtime(t/1000000) as datetime(6)), cast((t % 1000000) as int)) as t2 + from millimicro order by id; + """ + // 32536771199 is max valid timestamp for from_unixtime + qt_select3 """ + select + from_unixtime(32536771199), from_second(32536771199), + from_unixtime(32536771199 + 1), from_second(32536771199 + 1), + from_unixtime(21474836470), from_second(21474836470); + """ + + qt_select4 """ + select + t, + from_second(t), + second_timestamp(from_second(t)) + from millimicro order by id; + """ + qt_select5 """ + select + t, + from_millisecond(t), + millisecond_timestamp(from_millisecond(t)) + from millimicro order by id; + """ + qt_select6 """ + select + t, + from_microsecond(t), + microsecond_timestamp(from_microsecond(t)) + from millimicro order by id; + """ + sql """ + set enable_nereids_planner=true,enable_fold_constant_by_be = false,forbid_unknown_col_stats = false + """ + + qt_select7 """ + select from_millisecond(t) as t1 from millimicro order by id; + """ + qt_select8 """ + select from_microsecond(t) as t1 from millimicro order by id; + """ + + qt_select9 """ + select + FROM_UNIXTIME(2147483647),from_second(2147483647), + FROM_UNIXTIME(2147483647 + 1),from_second(2147483647 + 1), + FROM_UNIXTIME(21474836470),from_second(21474836470); + """ + + qt_select10 """ + select + t, + from_second(t), + second_timestamp(from_second(t)) + from millimicro order by id; + """ + qt_select11 """ + select + t, + from_millisecond(t), + millisecond_timestamp(from_millisecond(t)) + from millimicro order by id; + """ + qt_select12 """ + select + t, + from_microsecond(t), + microsecond_timestamp(from_microsecond(t)) + from millimicro order by id; + """ + + // null datetime + sql """ DROP TABLE IF EXISTS millimicro """ + sql """ + CREATE TABLE IF NOT EXISTS millimicro ( + `id` INT(11) NULL COMMENT "" , + `t` Datetime(6) NULL COMMENT "" + ) ENGINE=OLAP + DUPLICATE KEY(`id`) + DISTRIBUTED BY HASH(`id`) BUCKETS 1 + PROPERTIES ( + "replication_allocation" = "tag.location.default: 1", + "storage_format" = "V2" + ); + """ + + sql """ + insert into millimicro values(1,'2023-01-01 00:00:00'); + """ + sql """ + insert into millimicro values(2,'2023-01-01 00:00:00.123'); + """ + sql """ + insert into millimicro values(3,'2023-01-01 00:00:00.123456'); + """ + + qt_select_null_datetime """ + select + id, + SECOND_TIMESTAMP(t), + MILLISECOND_TIMESTAMP(t), + MICROSECOND_TIMESTAMP(t) + from millimicro + order by id; + """ + + + // not null datetime + sql """ DROP TABLE IF EXISTS millimicro """ + sql """ + CREATE TABLE IF NOT EXISTS millimicro ( + `id` INT(11) NULL COMMENT "" , + `t` Datetime(6) COMMENT "" + ) ENGINE=OLAP + DUPLICATE KEY(`id`) + DISTRIBUTED BY HASH(`id`) BUCKETS 1 + PROPERTIES ( + "replication_allocation" = "tag.location.default: 1", + "storage_format" = "V2" + ); + """ + + sql """ + insert into millimicro values(1,'2023-01-01 00:00:00'); + """ + sql """ + insert into millimicro values(2,'2023-01-01 00:00:00.123'); + """ + sql """ + insert into millimicro values(3,'2023-01-01 00:00:00.123456'); + """ + + qt_select_not_null_datetime """ + select + id, + SECOND_TIMESTAMP(t), + MILLISECOND_TIMESTAMP(t), + MICROSECOND_TIMESTAMP(t) + from millimicro + order by id; + """ } \ No newline at end of file