diff --git a/be/src/vec/runtime/vdatetime_value.cpp b/be/src/vec/runtime/vdatetime_value.cpp index 58c6c25f9ba9bc..0963911dd13238 100644 --- a/be/src/vec/runtime/vdatetime_value.cpp +++ b/be/src/vec/runtime/vdatetime_value.cpp @@ -2067,6 +2067,12 @@ bool DateV2Value::from_date_str_base(const char* date_str, int len, int scale break; } + // digits are truncated if they fall outside the max precision range(currently 6), + // so that users can still use doris if migrate from other systems that have a larger precision. + while (field_idx == 6 && isdigit(*ptr)) { + ++ptr; + } + // timezone if (UNLIKELY((field_idx > 2 || !has_bar) /*dont treat xxxx-xx-xx:xx:xx as xxxx-xx(-xx:xx:xx)*/ 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 955522c9797d50..956f72d22accb2 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 @@ -234,11 +234,15 @@ static String normalize(String s) { } // parse MicroSecond - if (partNumber == 6 && i < s.length() && s.charAt(i) == '.') { - sb.append(s.charAt(i)); - i += 1; + if (partNumber == 6 && i < s.length() && s.charAt(i - 1) == '.') { + // digits are truncated if they fall outside the max precision range(currently 6), + // so that users can still use doris if migrate from other systems that have a larger precision. + int idx = 0; while (i < s.length() && Character.isDigit(s.charAt(i))) { - sb.append(s.charAt(i)); + if (idx < 6) { + sb.append(s.charAt(i)); + idx++; + } i += 1; } } diff --git a/regression-test/data/datatype_p0/datetimev2/test_precision.out b/regression-test/data/datatype_p0/datetimev2/test_precision.out new file mode 100644 index 00000000000000..1ca1f9d1e06bc2 --- /dev/null +++ b/regression-test/data/datatype_p0/datetimev2/test_precision.out @@ -0,0 +1,50 @@ +-- This file is automatically generated. You should know what you did if you want to edit this +-- !cast_on_fe -- +2024-02-21T01:23:45.123456 + +-- !cast_on_fe -- +2024-02-21T09:23:45.123456 + +-- !cast_on_fe -- +2024-02-21T01:23:45.123456 + +-- !cast_on_fe -- +2024-02-21T09:23:45.123456 + +-- !cast_on_fe -- +2024-02-21T01:23:45.123456 + +-- !cast_on_fe -- +2024-02-21T09:23:45.123456 + +-- !cast_on_fe -- +2024-02-21T01:23:45.123456 + +-- !cast_on_fe -- +2024-02-21T09:23:45.123456 + +-- !cast_on_fe -- +PLAN FRAGMENT 0 + OUTPUT EXPRS: + '2024-02-21 09:23:45.123456'[#0] + PARTITION: UNPARTITIONED + + HAS_COLO_PLAN_NODE: false + + VRESULT SINK + MYSQL_PROTOCAL + + 0:VUNION(34) + constant exprs: + '2024-02-21 09:23:45.123456' + +-- !sql_all -- +0 2024-02-21T11:11:11 2022-01-01T11:11:11.123456 2024-02-06 03:37:07.123456Z +1 2024-02-21T11:11:11 2022-01-01T11:11:11.123456 2024-02-06 03:37:07.1234567Z +2 2024-02-21T11:11:11 2022-01-01T11:11:11.123456 2024-02-06 03:37:07.12345678Z + +-- !sql_cast_on_be -- +2024-02-06 03:37:07.123456Z 2024-02-06T11:37:07.123456 +2024-02-06 03:37:07.1234567Z 2024-02-06T11:37:07.123456 +2024-02-06 03:37:07.12345678Z 2024-02-06T11:37:07.123456 + diff --git a/regression-test/suites/datatype_p0/datetimev2/test_precision.groovy b/regression-test/suites/datatype_p0/datetimev2/test_precision.groovy new file mode 100644 index 00000000000000..ba28d5d2e2489e --- /dev/null +++ b/regression-test/suites/datatype_p0/datetimev2/test_precision.groovy @@ -0,0 +1,65 @@ +// 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_precision") { + sql "set enable_fallback_to_original_planner=false;" + qt_cast_on_fe "select cast ('2024-02-21 01:23:45.123456' as Datetime(6));" + qt_cast_on_fe "select cast ('2024-02-21 01:23:45.123456Z' as Datetime(6));" + qt_cast_on_fe "select cast ('2024-02-21T01:23:45.123456' as Datetime(6));" + qt_cast_on_fe "select cast ('2024-02-21T01:23:45.123456Z' as Datetime(6));" + + qt_cast_on_fe "select cast ('2024-02-21 01:23:45.1234567' as Datetime(6));" + qt_cast_on_fe "select cast ('2024-02-21 01:23:45.1234567Z' as Datetime(6));" + qt_cast_on_fe "select cast ('2024-02-21T01:23:45.1234567' as Datetime(6));" + qt_cast_on_fe "select cast ('2024-02-21T01:23:45.1234567Z' as Datetime(6));" + // make sure expr if folded on FE (result should not contain cast expr) + qt_cast_on_fe "explain select cast ('2024-02-21T01:23:45.1234567Z' as Datetime(6));" + + + sql "drop table if exists test_datetime_precision;" + sql """ + CREATE TABLE IF NOT EXISTS test_datetime_precision ( + `rowid` int, + `col1` datetimev2 NULL COMMENT "", + `col2` datetimev2(6) NULL COMMENT "", + `str` VARCHAR NOT NULL + ) ENGINE=OLAP + DISTRIBUTED BY HASH(`rowid`) BUCKETS 2 + PROPERTIES ( + "replication_allocation" = "tag.location.default: 1", + "in_memory" = "false", + "storage_format" = "V2"); + """ + + // constants in values will be folded on FE + sql """ + insert into test_datetime_precision values + (0, '2024-02-21 11:11:11.123456', '2022-01-01 11:11:11.123456', '2024-02-06 03:37:07.123456Z'), + (1, '2024-02-21 11:11:11.1234567', '2022-01-01 11:11:11.1234567', '2024-02-06 03:37:07.1234567Z'), + (2, '2024-02-21 11:11:11.12345678', '2022-01-01 11:11:11.12345678', '2024-02-06 03:37:07.12345678Z'); + """ + + qt_sql_all """ + select * from test_datetime_precision order by rowid, str desc; + """ + + qt_sql_cast_on_be """ + select t1.str as original_str, cast(str as Datetime(6)) from test_datetime_precision t1 order by str desc; + """ + + +}