From 0449a240f47107c9c2f755bab645ee962c3348c8 Mon Sep 17 00:00:00 2001 From: zhiqiang Date: Tue, 31 Oct 2023 01:31:24 -0500 Subject: [PATCH] [Fix](from_unixtime) Keep consistent with MySQL & bug fix (#25966) Bug fix: implicit convert from int32 -> int64 makes negative time stamp valid, so change signature to int64 Consistent: keep consistent with mysql. --- be/src/vec/functions/date_time_transforms.h | 9 +++++--- be/test/vec/function/function_time_test.cpp | 5 ++-- .../date-time-functions/from-unixtime.md | 6 +++-- .../date-time-functions/from-unixtime.md | 8 ++++--- .../DateTimeExtractAndTransform.java | 20 ++++++++-------- .../functions/scalar/FromUnixtime.java | 8 +++---- .../org/apache/doris/rewrite/FEFunctions.java | 10 ++++---- .../rewrite/RewriteFromUnixTimeRule.java | 4 ++-- .../rules/expression/FoldConstantTest.java | 5 ++-- gensrc/script/doris_builtins_functions.py | 6 ++--- .../test_from_millisecond_microsecond.out | 4 ++-- .../datatype_p0/date/test_from_unixtime.out | 23 +++++++++++++++++++ .../test_from_millisecond_microsecond.groovy | 8 +++---- .../date/test_from_unixtime.groovy | 20 ++++++++++++++++ .../fold_constant/fold_constant_by_fe.groovy | 8 +++++-- .../test_date_function.groovy | 10 ++++---- .../test_date_function.groovy | 10 ++++---- 17 files changed, 112 insertions(+), 52 deletions(-) diff --git a/be/src/vec/functions/date_time_transforms.h b/be/src/vec/functions/date_time_transforms.h index d0d86ee42f..877a66e002 100644 --- a/be/src/vec/functions/date_time_transforms.h +++ b/be/src/vec/functions/date_time_transforms.h @@ -213,14 +213,17 @@ struct DateFormatImpl { // TODO: This function should be depend on arguments not always nullable template struct FromUnixTimeImpl { - using FromType = Int32; - + using FromType = Int64; + // https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_from-unixtime + // Keep consistent with MySQL + static const int64_t TIMESTAMP_VALID_MAX = 32536771199; static constexpr auto name = "from_unixtime"; static inline auto execute(FromType val, StringRef format, ColumnString::Chars& res_data, size_t& offset, const cctz::time_zone& time_zone) { DateType dt; - if (format.size > 128 || val < 0 || val > INT_MAX || !dt.from_unixtime(val, time_zone)) { + if (format.size > 128 || val < 0 || val > TIMESTAMP_VALID_MAX || + !dt.from_unixtime(val, time_zone)) { return std::pair {offset, true}; } diff --git a/be/test/vec/function/function_time_test.cpp b/be/test/vec/function/function_time_test.cpp index 5dfc2f2554..85b692a470 100644 --- a/be/test/vec/function/function_time_test.cpp +++ b/be/test/vec/function/function_time_test.cpp @@ -179,9 +179,10 @@ TEST(VTimestampFunctionsTest, from_unix_test) { std::string func_name = "from_unixtime"; TimezoneUtils::load_timezone_names(); - InputTypeSet input_types = {TypeIndex::Int32}; + InputTypeSet input_types = {TypeIndex::Int64}; - DataSet data_set = {{{1565080737}, std::string("2019-08-06 16:38:57")}, {{-123}, Null()}}; + DataSet data_set = {{{int64_t(1565080737)}, std::string("2019-08-06 16:38:57")}, + {{int64_t(-123)}, Null()}}; static_cast(check_function(func_name, input_types, data_set)); } diff --git a/docs/en/docs/sql-manual/sql-functions/date-time-functions/from-unixtime.md b/docs/en/docs/sql-manual/sql-functions/date-time-functions/from-unixtime.md index 3e9c8dc623..90eab6a8ff 100644 --- a/docs/en/docs/sql-manual/sql-functions/date-time-functions/from-unixtime.md +++ b/docs/en/docs/sql-manual/sql-functions/date-time-functions/from-unixtime.md @@ -28,16 +28,18 @@ under the License. ### description #### syntax -`DATETIME FROM UNIXTIME (INT unix timestamp [, VARCHAR string format]` +`DATETIME FROM UNIXTIME (BIGINT unix timestamp [, VARCHAR string format]` Convert the UNIX timestamp to the corresponding time format of bits, and the format returned is specified by `string_format` -Input is an integer and return is a string type +Input is an big integer and return is a string type Support `date_format`'s format, and default is `%Y-%m-%d %H:%i:%s` Other `string_format` is illegal and will returns NULL. +The current supported range for `unix_timestamp` is `[0, 32536771199]`. `unix_timestamp` values that fall outside of this range will be returned as NULL + ### example ``` diff --git a/docs/zh-CN/docs/sql-manual/sql-functions/date-time-functions/from-unixtime.md b/docs/zh-CN/docs/sql-manual/sql-functions/date-time-functions/from-unixtime.md index 2d55bed2ad..38e95990a1 100644 --- a/docs/zh-CN/docs/sql-manual/sql-functions/date-time-functions/from-unixtime.md +++ b/docs/zh-CN/docs/sql-manual/sql-functions/date-time-functions/from-unixtime.md @@ -28,16 +28,18 @@ under the License. ### description #### Syntax -`DATETIME FROM_UNIXTIME(INT unix_timestamp[, VARCHAR string_format])` +`DATETIME FROM_UNIXTIME(BIGINT unix_timestamp[, VARCHAR string_format])` 将 unix 时间戳转化为对应的 time 格式,返回的格式由 `string_format` 指定 -支持date_format中的format格式,默认为 %Y-%m-%d %H:%i:%s +支持 `date_format` 中的 format 格式,默认为 %Y-%m-%d %H:%i:%s 传入的是整型,返回的是字符串类型 -其余 `string_format` 格式是非法的,返回NULL +其余 `string_format` 格式是非法的,返回 NULL + +目前支持的 `unix_timestamp` 范围为 `[0, 32536771199]`,超出范围的 `unix_timestamp` 将会得到 NULL ### example diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeExtractAndTransform.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeExtractAndTransform.java index db824e1935..797063e860 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeExtractAndTransform.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeExtractAndTransform.java @@ -20,12 +20,15 @@ package org.apache.doris.nereids.trees.expressions.functions.executable; import org.apache.doris.nereids.exceptions.AnalysisException; import org.apache.doris.nereids.trees.expressions.ExecFunction; import org.apache.doris.nereids.trees.expressions.Expression; +import org.apache.doris.nereids.trees.expressions.literal.BigIntLiteral; import org.apache.doris.nereids.trees.expressions.literal.DateLiteral; import org.apache.doris.nereids.trees.expressions.literal.DateTimeLiteral; import org.apache.doris.nereids.trees.expressions.literal.DateTimeV2Literal; import org.apache.doris.nereids.trees.expressions.literal.DateV2Literal; import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral; +import org.apache.doris.nereids.trees.expressions.literal.NullLiteral; import org.apache.doris.nereids.trees.expressions.literal.VarcharLiteral; +import org.apache.doris.nereids.types.VarcharType; import org.apache.doris.nereids.util.DateUtils; import java.time.Duration; @@ -446,22 +449,21 @@ public class DateTimeExtractAndTransform { /** * date transformation function: from_unixtime */ - @ExecFunction(name = "from_unixtime", argTypes = {"INT"}, returnType = "VARCHAR") - public static Expression fromUnixTime(IntegerLiteral second) { - if (second.getValue() < 0 || second.getValue() >= 253402271999L) { - return null; - } + @ExecFunction(name = "from_unixtime", argTypes = {"BIGINT"}, returnType = "VARCHAR") + public static Expression fromUnixTime(BigIntLiteral second) { return fromUnixTime(second, new VarcharLiteral("%Y-%m-%d %H:%i:%s")); } /** * date transformation function: from_unixtime */ - @ExecFunction(name = "from_unixtime", argTypes = {"INT", "VARCHAR"}, returnType = "VARCHAR") - public static Expression fromUnixTime(IntegerLiteral second, VarcharLiteral format) { - if (second.getValue() < 0) { - return null; + @ExecFunction(name = "from_unixtime", argTypes = {"BIGINT", "VARCHAR"}, returnType = "VARCHAR") + public static Expression fromUnixTime(BigIntLiteral second, VarcharLiteral format) { + // 32536771199L is max valid timestamp of mysql from_unix_time + if (second.getValue() < 0 || second.getValue() > 32536771199L) { + return new NullLiteral(VarcharType.SYSTEM_DEFAULT); } + ZonedDateTime dateTime = LocalDateTime.of(1970, 1, 1, 0, 0, 0) .plusSeconds(second.getValue()) .atZone(ZoneId.of("UTC+0")) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/FromUnixtime.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/FromUnixtime.java index c51bba5aff..773942ba7b 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/FromUnixtime.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/FromUnixtime.java @@ -22,7 +22,7 @@ import org.apache.doris.nereids.trees.expressions.Expression; import org.apache.doris.nereids.trees.expressions.functions.AlwaysNullable; import org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature; import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; -import org.apache.doris.nereids.types.IntegerType; +import org.apache.doris.nereids.types.BigIntType; import org.apache.doris.nereids.types.StringType; import org.apache.doris.nereids.types.VarcharType; @@ -38,9 +38,9 @@ public class FromUnixtime extends ScalarFunction implements ExplicitlyCastableSignature, AlwaysNullable { public static final List SIGNATURES = ImmutableList.of( - FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(IntegerType.INSTANCE), - FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(IntegerType.INSTANCE, VarcharType.SYSTEM_DEFAULT), - FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(IntegerType.INSTANCE, StringType.INSTANCE) + FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(BigIntType.INSTANCE), + FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(BigIntType.INSTANCE, VarcharType.SYSTEM_DEFAULT), + FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(BigIntType.INSTANCE, StringType.INSTANCE) ); /** diff --git a/fe/fe-core/src/main/java/org/apache/doris/rewrite/FEFunctions.java b/fe/fe-core/src/main/java/org/apache/doris/rewrite/FEFunctions.java index 7442c4c0d0..6ab1c4f8c6 100755 --- a/fe/fe-core/src/main/java/org/apache/doris/rewrite/FEFunctions.java +++ b/fe/fe-core/src/main/java/org/apache/doris/rewrite/FEFunctions.java @@ -231,10 +231,11 @@ public class FEFunctions { return new IntLiteral(unixTime, Type.INT); } - @FEFunction(name = "from_unixtime", argTypes = { "INT" }, returnType = "VARCHAR") + @FEFunction(name = "from_unixtime", argTypes = { "BIGINT" }, returnType = "VARCHAR") public static StringLiteral fromUnixTime(LiteralExpr unixTime) throws AnalysisException { // if unixTime < 0, we should return null, throw a exception and let BE process - if (unixTime.getLongValue() < 0 || unixTime.getLongValue() >= Integer.MAX_VALUE) { + // 32536771199L is max valid timestamp of mysql from_unix_time + if (unixTime.getLongValue() < 0 || unixTime.getLongValue() > 32536771199L) { throw new AnalysisException("unix timestamp out of range"); } DateLiteral dl = new DateLiteral(unixTime.getLongValue() * 1000, TimeUtils.getTimeZone(), @@ -242,10 +243,11 @@ public class FEFunctions { return new StringLiteral(dl.getStringValue()); } - @FEFunction(name = "from_unixtime", argTypes = { "INT", "VARCHAR" }, returnType = "VARCHAR") + @FEFunction(name = "from_unixtime", argTypes = { "BIGINT", "VARCHAR" }, returnType = "VARCHAR") public static StringLiteral fromUnixTime(LiteralExpr unixTime, StringLiteral fmtLiteral) throws AnalysisException { // if unixTime < 0, we should return null, throw a exception and let BE process - if (unixTime.getLongValue() < 0 || unixTime.getLongValue() >= Integer.MAX_VALUE) { + // 32536771199L is max valid timestamp of mysql from_unix_time + if (unixTime.getLongValue() < 0 || unixTime.getLongValue() >= 32536771199L) { throw new AnalysisException("unix timestamp out of range"); } DateLiteral dl = new DateLiteral(unixTime.getLongValue() * 1000, TimeUtils.getTimeZone(), diff --git a/fe/fe-core/src/main/java/org/apache/doris/rewrite/RewriteFromUnixTimeRule.java b/fe/fe-core/src/main/java/org/apache/doris/rewrite/RewriteFromUnixTimeRule.java index c7a9e51c54..639116d2dd 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/rewrite/RewriteFromUnixTimeRule.java +++ b/fe/fe-core/src/main/java/org/apache/doris/rewrite/RewriteFromUnixTimeRule.java @@ -41,7 +41,7 @@ import java.util.function.Function; /* * rewrite sql: select * from table where from_unixtime(query_time) > '2021-03-02 12:12:23' * into: select * from table where query_time > 1614658343 - * query_time is integer type + * query_time is big integer type to keep consistent with mysql * 1614658343 is the timestamp of 2021-03-02 12:12:23 * this rewrite can improve the query performance, because from_unixtime is cpu-exhausted * */ @@ -115,7 +115,7 @@ public class RewriteFromUnixTimeRule implements ExprRewriteRule { return expr; } SlotRef sr = (SlotRef) paramSlot; - if (!sr.getColumn().getType().isIntegerType()) { + if (!sr.getColumn().getType().isBigIntType()) { return new BoolLiteral(false); } Expr right = bp.getChild(1); diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/FoldConstantTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/FoldConstantTest.java index 9b469c98e1..0358b3ea62 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/FoldConstantTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/FoldConstantTest.java @@ -31,6 +31,7 @@ import org.apache.doris.nereids.trees.expressions.SlotReference; import org.apache.doris.nereids.trees.expressions.TimestampArithmetic; import org.apache.doris.nereids.trees.expressions.functions.executable.DateTimeArithmetic; import org.apache.doris.nereids.trees.expressions.functions.executable.DateTimeExtractAndTransform; +import org.apache.doris.nereids.trees.expressions.literal.BigIntLiteral; import org.apache.doris.nereids.trees.expressions.literal.DateLiteral; import org.apache.doris.nereids.trees.expressions.literal.DateTimeLiteral; import org.apache.doris.nereids.trees.expressions.literal.DateTimeV2Literal; @@ -577,10 +578,10 @@ class FoldConstantTest extends ExpressionRewriteTestHelper { new IntegerLiteral(1) ).toSql(), answer[answerIdx++]); Assertions.assertEquals(DateTimeExtractAndTransform.fromUnixTime( - new IntegerLiteral(234179844) + new BigIntLiteral(234179844) ).toSql(), answer[answerIdx++]); Assertions.assertEquals(DateTimeExtractAndTransform.fromUnixTime( - new IntegerLiteral(234179844), + new BigIntLiteral(234179844), new VarcharLiteral("%Y-%m-%d") ).toSql(), answer[answerIdx++]); Assertions.assertEquals(DateTimeExtractAndTransform.unixTimestamp( diff --git a/gensrc/script/doris_builtins_functions.py b/gensrc/script/doris_builtins_functions.py index 23d86eedbd..77cd90ca3e 100644 --- a/gensrc/script/doris_builtins_functions.py +++ b/gensrc/script/doris_builtins_functions.py @@ -869,9 +869,9 @@ visible_functions = { [['unix_timestamp'], 'INT', ['DATEV2'], ''], [['unix_timestamp'], 'INT', ['VARCHAR', 'VARCHAR'], 'ALWAYS_NULLABLE'], [['unix_timestamp'], 'INT', ['STRING', 'STRING'], 'ALWAYS_NULLABLE'], - [['from_unixtime'], 'VARCHAR', ['INT'], 'ALWAYS_NULLABLE'], - [['from_unixtime'], 'VARCHAR', ['INT', 'VARCHAR'], 'ALWAYS_NULLABLE'], - [['from_unixtime'], 'VARCHAR', ['INT', 'STRING'], 'ALWAYS_NULLABLE'], + [['from_unixtime'], 'VARCHAR', ['BIGINT'], 'ALWAYS_NULLABLE'], + [['from_unixtime'], 'VARCHAR', ['BIGINT', 'VARCHAR'], 'ALWAYS_NULLABLE'], + [['from_unixtime'], 'VARCHAR', ['BIGINT', 'STRING'], 'ALWAYS_NULLABLE'], [['from_microsecond'], 'DATETIMEV2', ['BIGINT'], 'ALWAYS_NULLABLE'], [['from_millisecond'], 'DATETIMEV2', ['BIGINT'], 'ALWAYS_NULLABLE'], [['from_second'], 'DATETIMEV2', ['BIGINT'], 'ALWAYS_NULLABLE'], diff --git a/regression-test/data/correctness/test_from_millisecond_microsecond.out b/regression-test/data/correctness/test_from_millisecond_microsecond.out index 50861a9400..7a5867d2c9 100644 --- a/regression-test/data/correctness/test_from_millisecond_microsecond.out +++ b/regression-test/data/correctness/test_from_millisecond_microsecond.out @@ -12,7 +12,7 @@ \N \N -- !select3 -- -2038-01-19 11:14:07 2038-01-19T11:14:07 \N 2038-01-19T11:14:08 \N 2650-07-06T16:21:10 +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 @@ -45,7 +45,7 @@ \N -- !select9 -- -2038-01-19 11:14:07 2038-01-19T11:14:07 \N 2038-01-19T11:14:08 \N 2650-07-06T16:21:10 +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 diff --git a/regression-test/data/datatype_p0/date/test_from_unixtime.out b/regression-test/data/datatype_p0/date/test_from_unixtime.out index c202e0aeea..a78ef107ea 100644 --- a/regression-test/data/datatype_p0/date/test_from_unixtime.out +++ b/regression-test/data/datatype_p0/date/test_from_unixtime.out @@ -5,3 +5,26 @@ -- !sql2 -- 2019-03-21 07:10:55 +-- !sql3 -- +1970-01-01 + +-- !sql4 -- +1970-01-01 00:00:00 + +-- !sql5 -- +\N + +-- !sql6 -- +\N + +-- !sql7 -- +3001-01-18 23:59:59 + +-- !sql8 -- +\N + +-- !sql9 -- +\N + +-- !sql10 -- +\N \ No newline at end of file diff --git a/regression-test/suites/correctness/test_from_millisecond_microsecond.groovy b/regression-test/suites/correctness/test_from_millisecond_microsecond.groovy index 15335cfd68..50fe8fcc5e 100644 --- a/regression-test/suites/correctness/test_from_millisecond_microsecond.groovy +++ b/regression-test/suites/correctness/test_from_millisecond_microsecond.groovy @@ -60,12 +60,12 @@ suite("test_from_millisecond_microsecond") { 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(2147483647),from_second(2147483647), - FROM_UNIXTIME(2147483647 + 1),from_second(2147483647 + 1), - FROM_UNIXTIME(21474836470),from_second(21474836470); + from_unixtime(32536771199), from_second(32536771199), + from_unixtime(32536771199 + 1), from_second(32536771199 + 1), + from_unixtime(21474836470), from_second(21474836470); """ qt_select4 """ diff --git a/regression-test/suites/datatype_p0/date/test_from_unixtime.groovy b/regression-test/suites/datatype_p0/date/test_from_unixtime.groovy index 5cdbcf85af..43d4a58150 100644 --- a/regression-test/suites/datatype_p0/date/test_from_unixtime.groovy +++ b/regression-test/suites/datatype_p0/date/test_from_unixtime.groovy @@ -19,9 +19,29 @@ suite("test_from_unixtime") { sql "set enable_fold_constant_by_be=true" + sql "set time_zone='+08:00'" + qt_sql1 "select from_unixtime(1553152255)" sql "set time_zone='+00:00'" qt_sql2 "select from_unixtime(1553152255)" + + qt_sql3 "select from_unixtime(0, \"%Y-%m-%d\")" + qt_sql4 "select from_unixtime(0);" + + qt_sql5 "select from_unixtime(-1, \"%Y-%m-%d\");" + qt_sql6 "select from_unixtime(-1);" + + // https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_from-unixtime + // 32536771199 is mysql max valid timestamp on 64bit system, return 3001-01-18 23:59:59 + // INT32_MAX(2147483647) < 32536771199 < INT64_MAX + qt_sql7 "select from_unixtime(32536771199)" + + // Return NULL, same with msyql + qt_sql8 "select from_unixtime(32536771199 + 1)" + + qt_sql9 "select from_unixtime(-7629445119491449, \"%Y-%m-%d\");" + qt_sql10 "select from_unixtime(-7629445119491449);" + } diff --git a/regression-test/suites/nereids_p0/expression/fold_constant/fold_constant_by_fe.groovy b/regression-test/suites/nereids_p0/expression/fold_constant/fold_constant_by_fe.groovy index 7e6a42ac60..7e40c55913 100644 --- a/regression-test/suites/nereids_p0/expression/fold_constant/fold_constant_by_fe.groovy +++ b/regression-test/suites/nereids_p0/expression/fold_constant/fold_constant_by_fe.groovy @@ -68,7 +68,7 @@ suite("test_fold_constant_by_fe") { test_year = [2001, 2013, 123, 1969, 2023] for (year in test_year) { for (integer in test_int) { - qt_sql "select makedate(${year}, ${integer}), from_days(${year * integer}), from_unixtime(${year / 10 * year * integer})" + qt_sql "select /*+SET_VAR(time_zone=\"UTC+8\")*/ makedate(${year}, ${integer}), from_days(${year * integer}), from_unixtime(${year / 10 * year * integer})" } } @@ -137,9 +137,13 @@ suite("test_fold_constant_by_fe") { assertFalse(res.contains("day") || res.contains("date")) } + // NOTE: For casts that has precision loss, new planner will not do const fold on fe. + // But we do have some cases like select CAST(419074969.6 AS INT) that can be processed by FE, + // this is actually an unexpected cast. + // So after changing arguments of from_unixtime from int to bigint, we also changed test case to avoid precision loss cast on fe. for (year in test_year) { for (integer in test_int) { - res = sql "explain select makedate(${year}, ${integer}), from_days(${year * integer}), from_unixtime(${year / 10 * year * integer})" + res = sql "explain select /*+SET_VAR(time_zone=\"UTC+8\")*/ makedate(${year}, ${integer}), from_days(${year * integer}), from_unixtime(${year * integer * 10})" res = res.split('VUNION')[1] assertFalse(res.contains("makedate") || res.contains("from")) } diff --git a/regression-test/suites/nereids_p0/sql_functions/datetime_functions/test_date_function.groovy b/regression-test/suites/nereids_p0/sql_functions/datetime_functions/test_date_function.groovy index a66c77a816..51164d2576 100644 --- a/regression-test/suites/nereids_p0/sql_functions/datetime_functions/test_date_function.groovy +++ b/regression-test/suites/nereids_p0/sql_functions/datetime_functions/test_date_function.groovy @@ -289,11 +289,11 @@ suite("test_date_function") { qt_sql """ select from_days(1) """ // FROM_UNIXTIME - qt_sql """ select from_unixtime(1196440219) """ - qt_sql """ select from_unixtime(1196440219, 'yyyy-MM-dd HH:mm:ss') """ - qt_sql """ select from_unixtime(1196440219, '%Y-%m-%d') """ - qt_sql """ select from_unixtime(1196440219, '%Y-%m-%d %H:%i:%s') """ - qt_sql """ select from_unixtime(253402272000, '%Y-%m-%d %H:%i:%s') """ + qt_sql """ select /*+SET_VAR(time_zone="UTC+8")*/ from_unixtime(1196440219) """ + qt_sql """ select /*+SET_VAR(time_zone="UTC+8")*/ from_unixtime(1196440219, 'yyyy-MM-dd HH:mm:ss') """ + qt_sql """ select /*+SET_VAR(time_zone="UTC+8")*/ from_unixtime(1196440219, '%Y-%m-%d') """ + qt_sql """ select /*+SET_VAR(time_zone="UTC+8")*/ from_unixtime(1196440219, '%Y-%m-%d %H:%i:%s') """ + qt_sql """ select /*+SET_VAR(time_zone="UTC+8")*/ from_unixtime(253402272000, '%Y-%m-%d %H:%i:%s') """ // HOUR qt_sql """ select hour('2018-12-31 23:59:59') """ diff --git a/regression-test/suites/query_p0/sql_functions/datetime_functions/test_date_function.groovy b/regression-test/suites/query_p0/sql_functions/datetime_functions/test_date_function.groovy index 2aa3dbb85d..045fa39917 100644 --- a/regression-test/suites/query_p0/sql_functions/datetime_functions/test_date_function.groovy +++ b/regression-test/suites/query_p0/sql_functions/datetime_functions/test_date_function.groovy @@ -288,11 +288,11 @@ suite("test_date_function") { qt_sql """ select from_days(1) """ // FROM_UNIXTIME - qt_sql """ select from_unixtime(1196440219) """ - qt_sql """ select from_unixtime(1196440219, 'yyyy-MM-dd HH:mm:ss') """ - qt_sql """ select from_unixtime(1196440219, '%Y-%m-%d') """ - qt_sql """ select from_unixtime(1196440219, '%Y-%m-%d %H:%i:%s') """ - qt_sql """ select from_unixtime(253402272000, '%Y-%m-%d %H:%i:%s') """ + qt_sql """ select /*+SET_VAR(time_zone="UTC+8")*/ from_unixtime(1196440219) """ + qt_sql """ select /*+SET_VAR(time_zone="UTC+8")*/ from_unixtime(1196440219, 'yyyy-MM-dd HH:mm:ss') """ + qt_sql """ select /*+SET_VAR(time_zone="UTC+8")*/ from_unixtime(1196440219, '%Y-%m-%d') """ + qt_sql """ select /*+SET_VAR(time_zone="UTC+8")*/ from_unixtime(1196440219, '%Y-%m-%d %H:%i:%s') """ + qt_sql """ select /*+SET_VAR(time_zone="UTC+8")*/ from_unixtime(253402272000, '%Y-%m-%d %H:%i:%s') """ // HOUR qt_sql """ select hour('2018-12-31 23:59:59') """