superdiaodiao commented on code in PR #40293:
URL: https://github.com/apache/doris/pull/40293#discussion_r1741371565
##########
regression-test/suites/nereids_function_p0/scalar_function/T.groovy:
##########
@@ -45,6 +45,10 @@ suite("nereids_scalar_fn_T") {
qt_sql_timestamp_DateTime_notnull "select timestamp(kdtm) from
fn_test_not_nullable order by kdtm"
qt_sql_timestamp_DateTimeV2 "select timestamp(kdtmv2s1) from fn_test
order by kdtmv2s1"
qt_sql_timestamp_DateTimeV2_notnull "select timestamp(kdtmv2s1) from
fn_test_not_nullable order by kdtmv2s1"
+ qt_sql_timestamp_DateTime "select timestamp(kdtm,'Asia/Bangkok') from
fn_test order by kdtm"
+ qt_sql_timestamp_DateTime_notnull "select
timestamp(kdtm,'Asia/Bangkok') from fn_test_not_nullable order by kdtm"
+ qt_sql_timestamp_DateTimeV2 "select timestamp(kdtmv2s1,'Asia/Bangkok')
from fn_test order by kdtmv2s1"
+ qt_sql_timestamp_DateTimeV2_notnull "select
timestamp(kdtmv2s1,'Asia/Bangkok') from fn_test_not_nullable order by kdtmv2s1"
Review Comment:
If the function supports two column arguments, we'd better test this case,
that is, `timestamp(column1, coulumn2)`.
Also, the tag for sentence(like `qt_sql_timestamp_DateTimeV2`) should be
different from the any other's.
##########
be/src/vec/functions/function_convert_tz.h:
##########
@@ -217,4 +219,323 @@ class FunctionConvertTZ : public IFunction {
}
};
+template <typename ArgDateType>
+class FunctionDateTZ : public IFunction {
+ using DateValueType = date_cast::TypeToValueTypeV<ArgDateType>;
+ using ArgColumnType = date_cast::TypeToColumnV<ArgDateType>;
+ using NativeType = date_cast::ValueTypeOfColumnV<ArgColumnType>;
+ constexpr static bool is_v1 = date_cast::IsV1<ArgDateType>();
+ using TempDateType = std::conditional_t<is_v1, DataTypeDateTime,
ArgDateType>;
+ using TempDateValueType = date_cast::TypeToValueTypeV<TempDateType>;
+ using ReturnDateType = std::conditional_t<is_v1, DataTypeDate,
DataTypeDateV2>; //todo
+ using ReturnDateValueType = date_cast::TypeToValueTypeV<ReturnDateType>;
+ using ReturnColumnType = date_cast::TypeToColumnV<ReturnDateType>;
+ using ReturnNativeType = date_cast::ValueTypeOfColumnV<ReturnColumnType>;
+
+public:
+ static constexpr auto name = "date";
+
+ static FunctionPtr create() { return std::make_shared<FunctionDateTZ>(); }
+
+ String get_name() const override { return name; }
+
+ size_t get_number_of_arguments() const override { return 2; }
+
+ DataTypePtr get_return_type_impl(const DataTypes& arguments) const
override {
+ if constexpr (is_v1) {
+ return make_nullable(std::make_shared<DataTypeDate>());
+ } else {
+ return make_nullable(std::make_shared<DataTypeDateV2>());
+ }
+ }
+
+ bool is_variadic() const override { return true; }
+
+ DataTypes get_variadic_argument_types_impl() const override {
+ return {std::make_shared<ArgDateType>(),
std::make_shared<DataTypeString>()};
+ }
+
+ bool use_default_implementation_for_nulls() const override { return false;
}
+
+ Status close(FunctionContext* context, FunctionContext::FunctionStateScope
scope) override {
+ return Status::OK();
+ }
+
+ Status execute_impl(FunctionContext* context, Block& block, const
ColumnNumbers& arguments,
+ size_t result, size_t input_rows_count) const override
{
+ auto result_null_map_column = ColumnUInt8::create(input_rows_count, 0);
+
+ bool col_const[3];
+ ColumnPtr argument_columns[2];
+ for (int i = 0; i < 2; ++i) {
+ col_const[i] =
is_column_const(*block.get_by_position(arguments[i]).column);
+ }
+ argument_columns[0] = col_const[0] ? static_cast<const ColumnConst&>(
+
*block.get_by_position(arguments[0]).column)
+ .convert_to_full_column()
+ :
block.get_by_position(arguments[0]).column;
+
+ default_preprocess_parameter_columns(argument_columns, col_const, {1},
block, arguments);
+
+ for (int i = 0; i < 2; i++) {
+ check_set_nullable(argument_columns[i], result_null_map_column,
col_const[i]);
+ }
+
+ if (col_const[1]) {
+ auto result_column = ReturnColumnType::create();
+ execute_tz_const(context, assert_cast<const
ArgColumnType*>(argument_columns[0].get()),
+ assert_cast<const
ColumnString*>(argument_columns[1].get()),
+
assert_cast<ReturnColumnType*>(result_column.get()),
+
assert_cast<ColumnUInt8*>(result_null_map_column.get())->get_data(),
+ input_rows_count);
+ block.get_by_position(result).column = ColumnNullable::create(
+ std::move(result_column),
std::move(result_null_map_column));
+ } else {
+ auto result_column = ReturnColumnType::create();
+ execute(context, assert_cast<const
ArgColumnType*>(argument_columns[0].get()),
+ assert_cast<const
ColumnString*>(argument_columns[1].get()),
+ assert_cast<ReturnColumnType*>(result_column.get()),
+
assert_cast<ColumnUInt8*>(result_null_map_column.get())->get_data(),
+ input_rows_count);
+ block.get_by_position(result).column = ColumnNullable::create(
+ std::move(result_column),
std::move(result_null_map_column));
+ } //if const
+ return Status::OK();
+ }
+
+private:
+ static void execute(FunctionContext* context, const ArgColumnType*
date_column,
+ const ColumnString* to_tz_column, ReturnColumnType*
result_column,
+ NullMap& result_null_map, size_t input_rows_count) {
Review Comment:
I found that `execute()` as well as `execute_tz_const()` in `class
FunctionDateTZ()` and `class FunctionTimestampTZ()` are almost the same, is
there any chance to simplify them?
##########
be/src/vec/functions/function_convert_tz.h:
##########
@@ -217,4 +219,323 @@ class FunctionConvertTZ : public IFunction {
}
};
+template <typename ArgDateType>
+class FunctionDateTZ : public IFunction {
+ using DateValueType = date_cast::TypeToValueTypeV<ArgDateType>;
+ using ArgColumnType = date_cast::TypeToColumnV<ArgDateType>;
+ using NativeType = date_cast::ValueTypeOfColumnV<ArgColumnType>;
+ constexpr static bool is_v1 = date_cast::IsV1<ArgDateType>();
+ using TempDateType = std::conditional_t<is_v1, DataTypeDateTime,
ArgDateType>;
+ using TempDateValueType = date_cast::TypeToValueTypeV<TempDateType>;
+ using ReturnDateType = std::conditional_t<is_v1, DataTypeDate,
DataTypeDateV2>; //todo
+ using ReturnDateValueType = date_cast::TypeToValueTypeV<ReturnDateType>;
+ using ReturnColumnType = date_cast::TypeToColumnV<ReturnDateType>;
+ using ReturnNativeType = date_cast::ValueTypeOfColumnV<ReturnColumnType>;
+
+public:
+ static constexpr auto name = "date";
+
+ static FunctionPtr create() { return std::make_shared<FunctionDateTZ>(); }
+
+ String get_name() const override { return name; }
+
+ size_t get_number_of_arguments() const override { return 2; }
+
+ DataTypePtr get_return_type_impl(const DataTypes& arguments) const
override {
+ if constexpr (is_v1) {
+ return make_nullable(std::make_shared<DataTypeDate>());
+ } else {
+ return make_nullable(std::make_shared<DataTypeDateV2>());
+ }
+ }
+
+ bool is_variadic() const override { return true; }
+
+ DataTypes get_variadic_argument_types_impl() const override {
+ return {std::make_shared<ArgDateType>(),
std::make_shared<DataTypeString>()};
+ }
+
+ bool use_default_implementation_for_nulls() const override { return false;
}
+
+ Status close(FunctionContext* context, FunctionContext::FunctionStateScope
scope) override {
+ return Status::OK();
+ }
Review Comment:
This function could be deleted.
##########
be/src/vec/functions/function_convert_tz.h:
##########
@@ -217,4 +219,323 @@ class FunctionConvertTZ : public IFunction {
}
};
+template <typename ArgDateType>
+class FunctionDateTZ : public IFunction {
+ using DateValueType = date_cast::TypeToValueTypeV<ArgDateType>;
+ using ArgColumnType = date_cast::TypeToColumnV<ArgDateType>;
+ using NativeType = date_cast::ValueTypeOfColumnV<ArgColumnType>;
+ constexpr static bool is_v1 = date_cast::IsV1<ArgDateType>();
+ using TempDateType = std::conditional_t<is_v1, DataTypeDateTime,
ArgDateType>;
+ using TempDateValueType = date_cast::TypeToValueTypeV<TempDateType>;
+ using ReturnDateType = std::conditional_t<is_v1, DataTypeDate,
DataTypeDateV2>; //todo
+ using ReturnDateValueType = date_cast::TypeToValueTypeV<ReturnDateType>;
+ using ReturnColumnType = date_cast::TypeToColumnV<ReturnDateType>;
+ using ReturnNativeType = date_cast::ValueTypeOfColumnV<ReturnColumnType>;
+
+public:
+ static constexpr auto name = "date";
+
+ static FunctionPtr create() { return std::make_shared<FunctionDateTZ>(); }
+
+ String get_name() const override { return name; }
+
+ size_t get_number_of_arguments() const override { return 2; }
+
+ DataTypePtr get_return_type_impl(const DataTypes& arguments) const
override {
+ if constexpr (is_v1) {
+ return make_nullable(std::make_shared<DataTypeDate>());
+ } else {
+ return make_nullable(std::make_shared<DataTypeDateV2>());
+ }
+ }
+
+ bool is_variadic() const override { return true; }
+
+ DataTypes get_variadic_argument_types_impl() const override {
+ return {std::make_shared<ArgDateType>(),
std::make_shared<DataTypeString>()};
+ }
+
+ bool use_default_implementation_for_nulls() const override { return false;
}
+
+ Status close(FunctionContext* context, FunctionContext::FunctionStateScope
scope) override {
+ return Status::OK();
+ }
+
+ Status execute_impl(FunctionContext* context, Block& block, const
ColumnNumbers& arguments,
+ size_t result, size_t input_rows_count) const override
{
+ auto result_null_map_column = ColumnUInt8::create(input_rows_count, 0);
+
+ bool col_const[3];
+ ColumnPtr argument_columns[2];
+ for (int i = 0; i < 2; ++i) {
+ col_const[i] =
is_column_const(*block.get_by_position(arguments[i]).column);
+ }
+ argument_columns[0] = col_const[0] ? static_cast<const ColumnConst&>(
+
*block.get_by_position(arguments[0]).column)
+ .convert_to_full_column()
+ :
block.get_by_position(arguments[0]).column;
+
+ default_preprocess_parameter_columns(argument_columns, col_const, {1},
block, arguments);
+
+ for (int i = 0; i < 2; i++) {
+ check_set_nullable(argument_columns[i], result_null_map_column,
col_const[i]);
+ }
+
+ if (col_const[1]) {
+ auto result_column = ReturnColumnType::create();
+ execute_tz_const(context, assert_cast<const
ArgColumnType*>(argument_columns[0].get()),
+ assert_cast<const
ColumnString*>(argument_columns[1].get()),
+
assert_cast<ReturnColumnType*>(result_column.get()),
+
assert_cast<ColumnUInt8*>(result_null_map_column.get())->get_data(),
+ input_rows_count);
+ block.get_by_position(result).column = ColumnNullable::create(
+ std::move(result_column),
std::move(result_null_map_column));
+ } else {
+ auto result_column = ReturnColumnType::create();
+ execute(context, assert_cast<const
ArgColumnType*>(argument_columns[0].get()),
+ assert_cast<const
ColumnString*>(argument_columns[1].get()),
+ assert_cast<ReturnColumnType*>(result_column.get()),
+
assert_cast<ColumnUInt8*>(result_null_map_column.get())->get_data(),
+ input_rows_count);
+ block.get_by_position(result).column = ColumnNullable::create(
+ std::move(result_column),
std::move(result_null_map_column));
+ } //if const
Review Comment:
The `result_column` and `block.get_by_position(result).column` could be
moved out of `if-else` part.
##########
be/src/vec/functions/function_convert_tz.h:
##########
@@ -217,4 +219,323 @@ class FunctionConvertTZ : public IFunction {
}
};
+template <typename ArgDateType>
+class FunctionDateTZ : public IFunction {
+ using DateValueType = date_cast::TypeToValueTypeV<ArgDateType>;
+ using ArgColumnType = date_cast::TypeToColumnV<ArgDateType>;
+ using NativeType = date_cast::ValueTypeOfColumnV<ArgColumnType>;
+ constexpr static bool is_v1 = date_cast::IsV1<ArgDateType>();
+ using TempDateType = std::conditional_t<is_v1, DataTypeDateTime,
ArgDateType>;
+ using TempDateValueType = date_cast::TypeToValueTypeV<TempDateType>;
+ using ReturnDateType = std::conditional_t<is_v1, DataTypeDate,
DataTypeDateV2>; //todo
+ using ReturnDateValueType = date_cast::TypeToValueTypeV<ReturnDateType>;
+ using ReturnColumnType = date_cast::TypeToColumnV<ReturnDateType>;
+ using ReturnNativeType = date_cast::ValueTypeOfColumnV<ReturnColumnType>;
+
+public:
+ static constexpr auto name = "date";
+
+ static FunctionPtr create() { return std::make_shared<FunctionDateTZ>(); }
+
+ String get_name() const override { return name; }
+
+ size_t get_number_of_arguments() const override { return 2; }
+
+ DataTypePtr get_return_type_impl(const DataTypes& arguments) const
override {
+ if constexpr (is_v1) {
+ return make_nullable(std::make_shared<DataTypeDate>());
+ } else {
+ return make_nullable(std::make_shared<DataTypeDateV2>());
+ }
+ }
+
+ bool is_variadic() const override { return true; }
+
+ DataTypes get_variadic_argument_types_impl() const override {
+ return {std::make_shared<ArgDateType>(),
std::make_shared<DataTypeString>()};
+ }
+
+ bool use_default_implementation_for_nulls() const override { return false;
}
+
+ Status close(FunctionContext* context, FunctionContext::FunctionStateScope
scope) override {
+ return Status::OK();
+ }
+
+ Status execute_impl(FunctionContext* context, Block& block, const
ColumnNumbers& arguments,
+ size_t result, size_t input_rows_count) const override
{
+ auto result_null_map_column = ColumnUInt8::create(input_rows_count, 0);
+
+ bool col_const[3];
+ ColumnPtr argument_columns[2];
+ for (int i = 0; i < 2; ++i) {
+ col_const[i] =
is_column_const(*block.get_by_position(arguments[i]).column);
+ }
+ argument_columns[0] = col_const[0] ? static_cast<const ColumnConst&>(
+
*block.get_by_position(arguments[0]).column)
+ .convert_to_full_column()
+ :
block.get_by_position(arguments[0]).column;
+
+ default_preprocess_parameter_columns(argument_columns, col_const, {1},
block, arguments);
+
+ for (int i = 0; i < 2; i++) {
+ check_set_nullable(argument_columns[i], result_null_map_column,
col_const[i]);
+ }
+
+ if (col_const[1]) {
+ auto result_column = ReturnColumnType::create();
+ execute_tz_const(context, assert_cast<const
ArgColumnType*>(argument_columns[0].get()),
+ assert_cast<const
ColumnString*>(argument_columns[1].get()),
+
assert_cast<ReturnColumnType*>(result_column.get()),
+
assert_cast<ColumnUInt8*>(result_null_map_column.get())->get_data(),
+ input_rows_count);
+ block.get_by_position(result).column = ColumnNullable::create(
+ std::move(result_column),
std::move(result_null_map_column));
+ } else {
+ auto result_column = ReturnColumnType::create();
+ execute(context, assert_cast<const
ArgColumnType*>(argument_columns[0].get()),
+ assert_cast<const
ColumnString*>(argument_columns[1].get()),
+ assert_cast<ReturnColumnType*>(result_column.get()),
+
assert_cast<ColumnUInt8*>(result_null_map_column.get())->get_data(),
+ input_rows_count);
+ block.get_by_position(result).column = ColumnNullable::create(
+ std::move(result_column),
std::move(result_null_map_column));
+ } //if const
+ return Status::OK();
+ }
+
+private:
+ static void execute(FunctionContext* context, const ArgColumnType*
date_column,
+ const ColumnString* to_tz_column, ReturnColumnType*
result_column,
+ NullMap& result_null_map, size_t input_rows_count) {
+ for (size_t i = 0; i < input_rows_count; i++) {
+ if (result_null_map[i]) {
+ result_column->insert_default();
+ continue;
+ }
+ auto to_tz = to_tz_column->get_data_at(i).to_string();
+ execute_inner_loop(context, date_column, to_tz, result_column,
result_null_map, i);
+ }
+ }
+
+ static void execute_tz_const(FunctionContext* context, const
ArgColumnType* date_column,
+ const ColumnString* to_tz_column,
ReturnColumnType* result_column,
+ NullMap& result_null_map, size_t
input_rows_count) {
+ auto to_tz = to_tz_column->get_data_at(0).to_string();
+ for (size_t i = 0; i < input_rows_count; i++) {
+ if (result_null_map[i]) {
+ result_column->insert_default();
+ continue;
+ }
+ execute_inner_loop(context, date_column, to_tz, result_column,
result_null_map, i);
+ }
+ }
+
+ static void execute_inner_loop(FunctionContext* context, const
ArgColumnType* date_column,
+ const std::string& to_tz_name,
ReturnColumnType* result_column,
+ NullMap& result_null_map, const size_t
index_now) {
+ DateValueType ts_value =
+ binary_cast<NativeType,
DateValueType>(date_column->get_element(index_now));
+ cctz::time_zone from_tz {}, to_tz {};
+ TempDateValueType ts_value2;
+ ReturnDateValueType ts_res;
+
+ from_tz = context->state()->timezone_obj();
+
+ if (!TimezoneUtils::find_cctz_time_zone(to_tz_name, to_tz)) {
+ result_null_map[index_now] = true;
+ result_column->insert_default();
+ return;
+ }
+
+ if constexpr (std::is_same_v<ArgDateType, DataTypeDateTimeV2>) {
+ std::pair<int64_t, int64_t> timestamp;
+ if (!ts_value.unix_timestamp(×tamp, from_tz)) {
+ result_null_map[index_now] = true;
+ result_column->insert_default();
+ return;
+ }
+ ts_value2.from_unixtime(timestamp, to_tz);
+ } else {
+ int64_t timestamp;
+ if (!ts_value.unix_timestamp(×tamp, from_tz)) {
+ result_null_map[index_now] = true;
+ result_column->insert_default();
+ return;
+ }
+ ts_value2.from_unixtime(timestamp, to_tz);
+ }
+
+ if (!ts_value2.is_valid_date()) [[unlikely]] {
+ result_null_map[index_now] = true;
+ result_column->insert_default();
+ return;
+ }
+
+ ts_res = ts_res.create_from_olap_date(ts_value2.to_olap_date());
+
+ result_column->insert(binary_cast<ReturnDateValueType,
ReturnNativeType>(ts_res));
+ }
+};
+
+template <typename ArgDateType>
+class FunctionTimestampTZ : public IFunction {
+ using DateValueType = date_cast::TypeToValueTypeV<ArgDateType>;
+ using ColumnType = date_cast::TypeToColumnV<ArgDateType>;
+ using NativeType = date_cast::ValueTypeOfColumnV<ColumnType>;
+ constexpr static bool is_v1 = date_cast::IsV1<ArgDateType>();
+ using ReturnDateType = std::conditional_t<is_v1, DataTypeDateTime,
ArgDateType>;
+ using ReturnDateValueType = date_cast::TypeToValueTypeV<ReturnDateType>;
+ using ReturnColumnType = date_cast::TypeToColumnV<ReturnDateType>;
+ using ReturnNativeType = date_cast::ValueTypeOfColumnV<ReturnColumnType>;
+
+public:
+ static constexpr auto name = "timestamp";
+
+ static FunctionPtr create() { return
std::make_shared<FunctionTimestampTZ>(); }
+
+ String get_name() const override { return name; }
+
+ size_t get_number_of_arguments() const override { return 2; }
+
+ DataTypePtr get_return_type_impl(const DataTypes& arguments) const
override {
+ if constexpr (is_v1) {
+ return make_nullable(std::make_shared<DataTypeDateTime>());
+ } else {
+ return make_nullable(std::make_shared<DataTypeDateTimeV2>());
+ }
+ }
+
+ bool is_variadic() const override { return true; }
+
+ DataTypes get_variadic_argument_types_impl() const override {
+ return {std::make_shared<ArgDateType>(),
std::make_shared<DataTypeString>()};
+ }
+
+ bool use_default_implementation_for_nulls() const override { return false;
}
+
+ Status close(FunctionContext* context, FunctionContext::FunctionStateScope
scope) override {
+ return Status::OK();
+ }
Review Comment:
ditto
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]