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 72d2feae99 [feature-wip] Support all date functions for 
datev2/datetimev2 (#11265)
72d2feae99 is described below

commit 72d2feae99963ff88aa48eebe6a68ee188ab8fd6
Author: Gabriel <[email protected]>
AuthorDate: Thu Jul 28 08:18:59 2022 +0800

    [feature-wip] Support all date functions for datev2/datetimev2 (#11265)
    
    * [feature-wip] (datetimev2) support convert_tz function
    
    * [feature-wip] Support all date functions for datev2/datetimev2
---
 be/src/exprs/anyval_util.cpp                       |   2 +
 be/src/exprs/anyval_util.h                         |   1 +
 be/src/exprs/expr.cpp                              |   5 +-
 be/src/exprs/expr_context.cpp                      |   1 +
 be/src/exprs/literal.cpp                           |   4 +-
 be/src/exprs/runtime_filter.cpp                    |   1 +
 be/src/exprs/scalar_fn_call.cpp                    |   2 +-
 be/src/runtime/primitive_type.h                    |   5 +
 be/src/vec/data_types/data_type_factory.cpp        |   1 +
 be/src/vec/exprs/vliteral.cpp                      |   2 +
 be/src/vec/functions/function.h                    |  11 +
 be/src/vec/functions/function_convert_tz.cpp       |  10 +-
 be/src/vec/functions/function_convert_tz.h         | 150 +++++--
 .../function_date_or_datetime_computation.h        |  52 ++-
 .../function_date_or_datetime_to_something.h       |   3 -
 .../vec/functions/function_datetime_floor_ceil.cpp | 478 ++++++++++++++++-----
 be/src/vec/functions/function_timestamp.cpp        | 265 +++++++++---
 be/src/vec/runtime/vdatetime_value.cpp             |   3 +-
 be/src/vec/sink/vmysql_result_writer.cpp           |  10 +-
 be/test/vec/function/function_time_test.cpp        |  17 +-
 .../apache/doris/analysis/FunctionCallExpr.java    |  23 +-
 gensrc/script/doris_builtins_functions.py          |  26 +-
 22 files changed, 802 insertions(+), 270 deletions(-)

diff --git a/be/src/exprs/anyval_util.cpp b/be/src/exprs/anyval_util.cpp
index 1099c1297e..9d923bb4a7 100644
--- a/be/src/exprs/anyval_util.cpp
+++ b/be/src/exprs/anyval_util.cpp
@@ -81,6 +81,7 @@ AnyVal* create_any_val(ObjectPool* pool, const 
TypeDescriptor& type) {
         return pool->add(new FloatVal);
 
     case TYPE_TIME:
+    case TYPE_TIMEV2:
     case TYPE_DOUBLE:
         return pool->add(new DoubleVal);
 
@@ -150,6 +151,7 @@ FunctionContext::TypeDesc 
AnyValUtil::column_type_to_type_desc(const TypeDescrip
         out.type = FunctionContext::TYPE_FLOAT;
         break;
     case TYPE_TIME:
+    case TYPE_TIMEV2:
     case TYPE_DOUBLE:
         out.type = FunctionContext::TYPE_DOUBLE;
         break;
diff --git a/be/src/exprs/anyval_util.h b/be/src/exprs/anyval_util.h
index d30565e0b9..742d44214e 100644
--- a/be/src/exprs/anyval_util.h
+++ b/be/src/exprs/anyval_util.h
@@ -405,6 +405,7 @@ public:
                     *reinterpret_cast<const float*>(slot);
             return;
         case TYPE_TIME:
+        case TYPE_TIMEV2:
         case TYPE_DOUBLE:
             reinterpret_cast<doris_udf::DoubleVal*>(dst)->val =
                     *reinterpret_cast<const double*>(slot);
diff --git a/be/src/exprs/expr.cpp b/be/src/exprs/expr.cpp
index f113733597..22684e60aa 100644
--- a/be/src/exprs/expr.cpp
+++ b/be/src/exprs/expr.cpp
@@ -123,6 +123,7 @@ Expr::Expr(const TypeDescriptor& type)
     case TYPE_FLOAT:
     case TYPE_DOUBLE:
     case TYPE_TIME:
+    case TYPE_TIMEV2:
         _node_type = (TExprNodeType::FLOAT_LITERAL);
         break;
 
@@ -185,6 +186,7 @@ Expr::Expr(const TypeDescriptor& type, bool is_slotref)
         case TYPE_FLOAT:
         case TYPE_DOUBLE:
         case TYPE_TIME:
+        case TYPE_TIMEV2:
             _node_type = (TExprNodeType::FLOAT_LITERAL);
             break;
 
@@ -682,7 +684,8 @@ doris_udf::AnyVal* Expr::get_const_val(ExprContext* 
context) {
         break;
     }
     case TYPE_DOUBLE:
-    case TYPE_TIME: {
+    case TYPE_TIME:
+    case TYPE_TIMEV2: {
         _constant_val.reset(new DoubleVal(get_double_val(context, nullptr)));
         break;
     }
diff --git a/be/src/exprs/expr_context.cpp b/be/src/exprs/expr_context.cpp
index a76fbb936e..3f63c93d2c 100644
--- a/be/src/exprs/expr_context.cpp
+++ b/be/src/exprs/expr_context.cpp
@@ -223,6 +223,7 @@ void* ExprContext::get_value(Expr* e, TupleRow* row, int 
precision, int scale) {
         return &_result.float_val;
     }
     case TYPE_TIME:
+    case TYPE_TIMEV2:
     case TYPE_DOUBLE: {
         doris_udf::DoubleVal v = e->get_double_val(this, row);
         if (v.is_null) {
diff --git a/be/src/exprs/literal.cpp b/be/src/exprs/literal.cpp
index e107831739..6d2d381c04 100644
--- a/be/src/exprs/literal.cpp
+++ b/be/src/exprs/literal.cpp
@@ -75,6 +75,7 @@ Literal::Literal(const TExprNode& node) : Expr(node) {
         break;
     case TYPE_DOUBLE:
     case TYPE_TIME:
+    case TYPE_TIMEV2:
         DCHECK_EQ(node.node_type, TExprNodeType::FLOAT_LITERAL);
         DCHECK(node.__isset.float_literal);
         _value.double_val = node.float_literal.value;
@@ -199,7 +200,8 @@ FloatVal Literal::get_float_val(ExprContext* context, 
TupleRow* row) {
 }
 
 DoubleVal Literal::get_double_val(ExprContext* context, TupleRow* row) {
-    DCHECK(_type.type == TYPE_DOUBLE || _type.type == TYPE_TIME) << _type;
+    DCHECK(_type.type == TYPE_DOUBLE || _type.type == TYPE_TIME || _type.type 
== TYPE_TIMEV2)
+            << _type;
     return DoubleVal(_value.double_val);
 }
 
diff --git a/be/src/exprs/runtime_filter.cpp b/be/src/exprs/runtime_filter.cpp
index 2695e31f25..5983b11fcc 100644
--- a/be/src/exprs/runtime_filter.cpp
+++ b/be/src/exprs/runtime_filter.cpp
@@ -65,6 +65,7 @@ TExprNodeType::type get_expr_node_type(PrimitiveType type) {
     case TYPE_FLOAT:
     case TYPE_DOUBLE:
     case TYPE_TIME:
+    case TYPE_TIMEV2:
         return TExprNodeType::FLOAT_LITERAL;
         break;
 
diff --git a/be/src/exprs/scalar_fn_call.cpp b/be/src/exprs/scalar_fn_call.cpp
index bb710b81b7..3eae4e6f41 100644
--- a/be/src/exprs/scalar_fn_call.cpp
+++ b/be/src/exprs/scalar_fn_call.cpp
@@ -435,7 +435,7 @@ FloatVal ScalarFnCall::get_float_val(ExprContext* context, 
TupleRow* row) {
 }
 
 DoubleVal ScalarFnCall::get_double_val(ExprContext* context, TupleRow* row) {
-    DCHECK(_type.type == TYPE_DOUBLE || _type.type == TYPE_TIME);
+    DCHECK(_type.type == TYPE_DOUBLE || _type.type == TYPE_TIME || _type.type 
== TYPE_TIMEV2);
     DCHECK(context != nullptr);
     if (_scalar_fn_wrapper == nullptr) {
         return interpret_eval<DoubleVal>(context, row);
diff --git a/be/src/runtime/primitive_type.h b/be/src/runtime/primitive_type.h
index 973db8f31c..03362acd65 100644
--- a/be/src/runtime/primitive_type.h
+++ b/be/src/runtime/primitive_type.h
@@ -132,6 +132,11 @@ struct PrimitiveTypeTraits<TYPE_TIME> {
     using ColumnType = vectorized::ColumnFloat64;
 };
 template <>
+struct PrimitiveTypeTraits<TYPE_TIMEV2> {
+    using CppType = double;
+    using ColumnType = vectorized::ColumnFloat64;
+};
+template <>
 struct PrimitiveTypeTraits<TYPE_DOUBLE> {
     using CppType = double;
     using ColumnType = vectorized::ColumnFloat64;
diff --git a/be/src/vec/data_types/data_type_factory.cpp 
b/be/src/vec/data_types/data_type_factory.cpp
index 249d008205..e2d1e9d9f3 100644
--- a/be/src/vec/data_types/data_type_factory.cpp
+++ b/be/src/vec/data_types/data_type_factory.cpp
@@ -93,6 +93,7 @@ DataTypePtr DataTypeFactory::create_data_type(const 
TypeDescriptor& col_desc, bo
         nested = std::make_shared<vectorized::DataTypeDateTime>();
         break;
     case TYPE_TIME:
+    case TYPE_TIMEV2:
     case TYPE_DOUBLE:
         nested = std::make_shared<vectorized::DataTypeFloat64>();
         break;
diff --git a/be/src/vec/exprs/vliteral.cpp b/be/src/vec/exprs/vliteral.cpp
index e20597391d..8db2e85df5 100644
--- a/be/src/vec/exprs/vliteral.cpp
+++ b/be/src/vec/exprs/vliteral.cpp
@@ -83,6 +83,7 @@ void VLiteral::init(const TExprNode& node) {
             break;
         }
         case TYPE_TIME:
+        case TYPE_TIMEV2:
         case TYPE_DOUBLE: {
             DCHECK_EQ(node.node_type, TExprNodeType::FLOAT_LITERAL);
             DCHECK(node.__isset.float_literal);
@@ -212,6 +213,7 @@ std::string VLiteral::debug_string() const {
                 break;
             }
             case TYPE_TIME:
+            case TYPE_TIMEV2:
             case TYPE_DOUBLE: {
                 out << *(reinterpret_cast<const double_t*>(ref.data));
                 break;
diff --git a/be/src/vec/functions/function.h b/be/src/vec/functions/function.h
index 24cb18e984..8dd9991f18 100644
--- a/be/src/vec/functions/function.h
+++ b/be/src/vec/functions/function.h
@@ -302,6 +302,17 @@ public:
                                 ? 
((DataTypeNullable*)get_return_type(arguments).get())
                                           ->get_nested_type()
                                 : get_return_type(arguments))) ||
+               // For some date functions such as str_to_date(string, string), 
return_type will
+               // be datetimev2 if users enable datev2 but 
get_return_type(arguments) will still
+               // return datetime. We need keep backward compatibility here.
+               (is_date_v2_or_datetime_v2(
+                        return_type->is_nullable()
+                                ? 
((DataTypeNullable*)return_type.get())->get_nested_type()
+                                : return_type) &&
+                is_date_or_datetime(get_return_type(arguments)->is_nullable()
+                                            ? 
((DataTypeNullable*)get_return_type(arguments).get())
+                                                      ->get_nested_type()
+                                            : get_return_type(arguments))) ||
                (is_decimal(return_type->is_nullable()
                                    ? 
((DataTypeNullable*)return_type.get())->get_nested_type()
                                    : return_type) &&
diff --git a/be/src/vec/functions/function_convert_tz.cpp 
b/be/src/vec/functions/function_convert_tz.cpp
index 7dc2c1762c..00745d1c6d 100644
--- a/be/src/vec/functions/function_convert_tz.cpp
+++ b/be/src/vec/functions/function_convert_tz.cpp
@@ -22,7 +22,15 @@
 namespace doris::vectorized {
 
 void register_function_convert_tz(SimpleFunctionFactory& factory) {
-    factory.register_function<FunctionConvertTZ>();
+    factory.register_function<
+            FunctionConvertTZ<ConvertTZImpl<DateV2Value<DateTimeV2ValueType>, 
DataTypeDateTimeV2>,
+                              DataTypeDateTimeV2>>();
+    
factory.register_function<FunctionConvertTZ<ConvertTZImpl<VecDateTimeValue, 
DataTypeDateTime>,
+                                                DataTypeDateTime>>();
+    factory.register_function<FunctionConvertTZ<
+            ConvertTZImpl<DateV2Value<DateV2ValueType>, DataTypeDateV2>, 
DataTypeDateV2>>();
+    factory.register_function<
+            FunctionConvertTZ<ConvertTZImpl<VecDateTimeValue, DataTypeDate>, 
DataTypeDate>>();
 }
 
 } // namespace doris::vectorized
diff --git a/be/src/vec/functions/function_convert_tz.h 
b/be/src/vec/functions/function_convert_tz.h
index 6a9549188d..fd7c33756c 100644
--- a/be/src/vec/functions/function_convert_tz.h
+++ b/be/src/vec/functions/function_convert_tz.h
@@ -21,10 +21,69 @@
 #include "vec/common/string_ref.h"
 #include "vec/core/types.h"
 #include "vec/data_types/data_type_date_time.h"
+#include "vec/data_types/data_type_string.h"
 #include "vec/utils/util.hpp"
 
 namespace doris::vectorized {
 
+template <typename DateValueType, typename ArgType>
+struct ConvertTZImpl {
+    using ColumnType = std::conditional_t<
+            std::is_same_v<DateV2Value<DateV2ValueType>, DateValueType>, 
ColumnDateV2,
+            
std::conditional_t<std::is_same_v<DateV2Value<DateTimeV2ValueType>, 
DateValueType>,
+                               ColumnDateTimeV2, ColumnDateTime>>;
+    using NativeType = std::conditional_t<
+            std::is_same_v<DateV2Value<DateV2ValueType>, DateValueType>, 
UInt32,
+            
std::conditional_t<std::is_same_v<DateV2Value<DateTimeV2ValueType>, 
DateValueType>,
+                               UInt64, Int64>>;
+    using ReturnDateType = std::conditional_t<std::is_same_v<VecDateTimeValue, 
DateValueType>,
+                                              VecDateTimeValue, 
DateV2Value<DateTimeV2ValueType>>;
+    using ReturnNativeType =
+            std::conditional_t<std::is_same_v<VecDateTimeValue, 
DateValueType>, Int64, UInt64>;
+    using ReturnColumnType = 
std::conditional_t<std::is_same_v<VecDateTimeValue, DateValueType>,
+                                                ColumnDateTime, 
ColumnDateTimeV2>;
+
+    static void execute(FunctionContext* context, const ColumnType* 
date_column,
+                        const ColumnString* from_tz_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;
+            }
+
+            StringRef from_tz = from_tz_column->get_data_at(i);
+            StringRef to_tz = to_tz_column->get_data_at(i);
+
+            DateValueType ts_value =
+                    binary_cast<NativeType, 
DateValueType>(date_column->get_element(i));
+            int64_t timestamp;
+
+            if (!ts_value.unix_timestamp(&timestamp, from_tz.to_string())) {
+                result_null_map[i] = true;
+                result_column->insert_default();
+                continue;
+            }
+
+            ReturnDateType ts_value2;
+            if (!ts_value2.from_unixtime(timestamp, to_tz.to_string())) {
+                result_null_map[i] = true;
+                result_column->insert_default();
+                continue;
+            }
+
+            result_column->insert(binary_cast<ReturnDateType, 
ReturnNativeType>(ts_value2));
+        }
+    }
+
+    static DataTypes get_variadic_argument_types() {
+        return {std::make_shared<ArgType>(), 
std::make_shared<DataTypeString>(),
+                std::make_shared<DataTypeString>()};
+    }
+};
+
+template <typename Transform, typename DateType>
 class FunctionConvertTZ : public IFunction {
 public:
     static constexpr auto name = "convert_tz";
@@ -36,7 +95,18 @@ public:
     size_t get_number_of_arguments() const override { return 3; }
 
     DataTypePtr get_return_type_impl(const DataTypes& arguments) const 
override {
-        return make_nullable(std::make_shared<DataTypeDateTime>());
+        if constexpr (std::is_same_v<DateType, DataTypeDateTime> ||
+                      std::is_same_v<DateType, DataTypeDate>) {
+            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 Transform::get_variadic_argument_types();
     }
 
     bool use_default_implementation_for_constants() const override { return 
true; }
@@ -44,7 +114,6 @@ public:
 
     Status execute_impl(FunctionContext* context, Block& block, const 
ColumnNumbers& arguments,
                         size_t result, size_t input_rows_count) override {
-        auto result_column = ColumnDateTime::create();
         auto result_null_map_column = ColumnUInt8::create(input_rows_count, 0);
 
         ColumnPtr argument_columns[3];
@@ -62,52 +131,43 @@ public:
             }
         }
 
-        execute_straight(context, assert_cast<const 
ColumnDateTime*>(argument_columns[0].get()),
-                         assert_cast<const 
ColumnString*>(argument_columns[1].get()),
-                         assert_cast<const 
ColumnString*>(argument_columns[2].get()),
-                         assert_cast<ColumnDateTime*>(result_column.get()),
-                         
assert_cast<ColumnUInt8*>(result_null_map_column.get())->get_data(),
-                         input_rows_count);
+        if constexpr (std::is_same_v<DateType, DataTypeDateTime> ||
+                      std::is_same_v<DateType, DataTypeDate>) {
+            auto result_column = ColumnDateTime::create();
+            Transform::execute(context,
+                               assert_cast<const 
ColumnDateTime*>(argument_columns[0].get()),
+                               assert_cast<const 
ColumnString*>(argument_columns[1].get()),
+                               assert_cast<const 
ColumnString*>(argument_columns[2].get()),
+                               
assert_cast<ColumnDateTime*>(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 if constexpr (std::is_same_v<DateType, DataTypeDateV2>) {
+            auto result_column = ColumnDateTimeV2::create();
+            Transform::execute(context, assert_cast<const 
ColumnDateV2*>(argument_columns[0].get()),
+                               assert_cast<const 
ColumnString*>(argument_columns[1].get()),
+                               assert_cast<const 
ColumnString*>(argument_columns[2].get()),
+                               
assert_cast<ColumnDateTimeV2*>(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 = ColumnDateTimeV2::create();
+            Transform::execute(context,
+                               assert_cast<const 
ColumnDateTimeV2*>(argument_columns[0].get()),
+                               assert_cast<const 
ColumnString*>(argument_columns[1].get()),
+                               assert_cast<const 
ColumnString*>(argument_columns[2].get()),
+                               
assert_cast<ColumnDateTimeV2*>(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));
+        }
 
-        block.get_by_position(result).column =
-                ColumnNullable::create(std::move(result_column), 
std::move(result_null_map_column));
         return Status::OK();
     }
-
-private:
-    void execute_straight(FunctionContext* context, const ColumnDateTime* 
date_column,
-                          const ColumnString* from_tz_column, const 
ColumnString* to_tz_column,
-                          ColumnDateTime* 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;
-            }
-
-            StringRef from_tz = from_tz_column->get_data_at(i);
-            StringRef to_tz = to_tz_column->get_data_at(i);
-
-            VecDateTimeValue ts_value =
-                    binary_cast<Int64, 
VecDateTimeValue>(date_column->get_element(i));
-            int64_t timestamp;
-
-            if (!ts_value.unix_timestamp(&timestamp, from_tz.to_string())) {
-                result_null_map[i] = true;
-                result_column->insert_default();
-                continue;
-            }
-
-            VecDateTimeValue ts_value2;
-            if (!ts_value2.from_unixtime(timestamp, to_tz.to_string())) {
-                result_null_map[i] = true;
-                result_column->insert_default();
-                continue;
-            }
-
-            result_column->insert(binary_cast<VecDateTimeValue, 
Int64>(ts_value2));
-        }
-    }
 };
 
 } // namespace doris::vectorized
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 8915a8dfaf..48d34e22c7 100644
--- a/be/src/vec/functions/function_date_or_datetime_computation.h
+++ b/be/src/vec/functions/function_date_or_datetime_computation.h
@@ -603,13 +603,29 @@ struct CurrentDateTimeImpl {
     static constexpr auto name = FunctionName::name;
     static Status execute(FunctionContext* context, Block& block, size_t 
result,
                           size_t input_rows_count) {
-        auto col_to = ColumnVector<Int64>::create();
-        VecDateTimeValue dtv;
+        WhichDataType which(block.get_by_position(result).type);
+        if (which.is_date_time_v2()) {
+            return executeImpl<DateV2Value<DateTimeV2ValueType>, 
UInt64>(context, block, result,
+                                                                         
input_rows_count);
+        } else if (which.is_date_v2()) {
+            return executeImpl<DateV2Value<DateV2ValueType>, UInt32>(context, 
block, result,
+                                                                     
input_rows_count);
+        } else {
+            return executeImpl<VecDateTimeValue, Int64>(context, block, 
result, input_rows_count);
+        }
+    }
+
+    template <typename DateValueType, typename NativeType>
+    static Status executeImpl(FunctionContext* context, Block& block, size_t 
result,
+                              size_t input_rows_count) {
+        auto col_to = ColumnVector<NativeType>::create();
+        DateValueType dtv;
         if (dtv.from_unixtime(context->impl()->state()->timestamp_ms() / 1000,
                               context->impl()->state()->timezone_obj())) {
-            reinterpret_cast<VecDateTimeValue*>(&dtv)->set_type(TIME_DATETIME);
-            auto date_packed_int = 
binary_cast<doris::vectorized::VecDateTimeValue, int64_t>(
-                    *reinterpret_cast<VecDateTimeValue*>(&dtv));
+            if constexpr (std::is_same_v<DateValueType, VecDateTimeValue>) {
+                
reinterpret_cast<DateValueType*>(&dtv)->set_type(TIME_DATETIME);
+            }
+            auto date_packed_int = binary_cast<DateValueType, NativeType>(dtv);
             for (int i = 0; i < input_rows_count; i++) {
                 col_to->insert_data(
                         const_cast<const 
char*>(reinterpret_cast<char*>(&date_packed_int)), 0);
@@ -705,12 +721,30 @@ struct UtcTimestampImpl {
     static constexpr auto name = "utc_timestamp";
     static Status execute(FunctionContext* context, Block& block, size_t 
result,
                           size_t input_rows_count) {
+        WhichDataType which(block.get_by_position(result).type);
+        if (which.is_date_time_v2()) {
+            return executeImpl<DateV2Value<DateTimeV2ValueType>, 
UInt64>(context, block, result,
+                                                                         
input_rows_count);
+        } else if (which.is_date_v2()) {
+            return executeImpl<DateV2Value<DateV2ValueType>, UInt32>(context, 
block, result,
+                                                                     
input_rows_count);
+        } else {
+            return executeImpl<VecDateTimeValue, Int64>(context, block, 
result, input_rows_count);
+        }
+    }
+
+    template <typename DateValueType, typename NativeType>
+    static Status executeImpl(FunctionContext* context, Block& block, size_t 
result,
+                              size_t input_rows_count) {
         auto col_to = ColumnVector<Int64>::create();
-        VecDateTimeValue dtv;
+        DateValueType dtv;
         if (dtv.from_unixtime(context->impl()->state()->timestamp_ms() / 1000, 
"+00:00")) {
-            reinterpret_cast<VecDateTimeValue*>(&dtv)->set_type(TIME_DATETIME);
-            auto date_packed_int = 
binary_cast<doris::vectorized::VecDateTimeValue, int64_t>(
-                    *reinterpret_cast<VecDateTimeValue*>(&dtv));
+            if constexpr (std::is_same_v<DateValueType, VecDateTimeValue>) {
+                
reinterpret_cast<DateValueType*>(&dtv)->set_type(TIME_DATETIME);
+            }
+
+            auto date_packed_int =
+                    binary_cast<DateValueType, 
NativeType>(*reinterpret_cast<DateValueType*>(&dtv));
             for (int i = 0; i < input_rows_count; i++) {
                 col_to->insert_data(
                         const_cast<const 
char*>(reinterpret_cast<char*>(&date_packed_int)), 0);
diff --git a/be/src/vec/functions/function_date_or_datetime_to_something.h 
b/be/src/vec/functions/function_date_or_datetime_to_something.h
index 634f6064d1..0762855fb2 100644
--- a/be/src/vec/functions/function_date_or_datetime_to_something.h
+++ b/be/src/vec/functions/function_date_or_datetime_to_something.h
@@ -91,9 +91,6 @@ public:
 
     Status execute_impl(FunctionContext* context, Block& block, const 
ColumnNumbers& arguments,
                         size_t result, size_t input_rows_count) override {
-        const IDataType* from_type = 
block.get_by_position(arguments[0]).type.get();
-        WhichDataType which(from_type);
-
         return DateTimeTransformImpl<typename Transform::ARG_TYPE, typename 
ToDataType::FieldType,
                                      Transform>::execute(block, arguments, 
result,
                                                          input_rows_count);
diff --git a/be/src/vec/functions/function_datetime_floor_ceil.cpp 
b/be/src/vec/functions/function_datetime_floor_ceil.cpp
index 45d1514b49..98519a3e32 100644
--- a/be/src/vec/functions/function_datetime_floor_ceil.cpp
+++ b/be/src/vec/functions/function_datetime_floor_ceil.cpp
@@ -23,9 +23,19 @@
 
 namespace doris::vectorized {
 
-template <typename Impl>
+template <typename Impl, typename DateValueType, typename DeltaValueType, int 
ArgNum, bool UseDelta>
 class FunctionDateTimeFloorCeil : public IFunction {
 public:
+    using ReturnDataType = std::conditional_t<
+            std::is_same_v<DateValueType, VecDateTimeValue>, DataTypeDateTime,
+            std::conditional_t<std::is_same_v<DateValueType, 
DateV2Value<DateV2ValueType>>,
+                               DataTypeDateV2, DataTypeDateTimeV2>>;
+    using NativeType = std::conditional_t<
+            std::is_same_v<DateValueType, VecDateTimeValue>, Int64,
+            std::conditional_t<std::is_same_v<DateValueType, 
DateV2Value<DateV2ValueType>>, UInt32,
+                               UInt64>>;
+    using DeltaDataType =
+            std::conditional_t<std::is_same_v<DeltaValueType, Int32>, 
DataTypeInt32, DataTypeInt64>;
     static constexpr auto name = Impl::name;
 
     static FunctionPtr create() { return 
std::make_shared<FunctionDateTimeFloorCeil>(); }
@@ -39,43 +49,86 @@ public:
     bool is_variadic() const override { return true; }
 
     DataTypePtr get_return_type_impl(const DataTypes& arguments) const 
override {
-        return make_nullable(std::make_shared<DataTypeDateTime>());
+        return make_nullable(std::make_shared<ReturnDataType>());
+    }
+
+    DataTypes get_variadic_argument_types_impl() const override {
+        if constexpr (std::is_same_v<DateValueType, VecDateTimeValue> && 
ArgNum == 1) {
+            return {std::make_shared<DataTypeDateTime>()};
+        } else if constexpr (std::is_same_v<DateValueType, 
DateV2Value<DateV2ValueType>> &&
+                             ArgNum == 1) {
+            return {std::make_shared<DataTypeDateV2>()};
+        } else if constexpr (std::is_same_v<DateValueType, 
DateV2Value<DateTimeV2ValueType>> &&
+                             ArgNum == 1) {
+            return {std::make_shared<DataTypeDateTimeV2>()};
+        } else if constexpr (std::is_same_v<DateValueType, VecDateTimeValue> 
&& ArgNum == 2 &&
+                             UseDelta) {
+            return {std::make_shared<DataTypeDateTime>(), 
std::make_shared<DeltaDataType>()};
+        } else if constexpr (std::is_same_v<DateValueType, 
DateV2Value<DateV2ValueType>> &&
+                             ArgNum == 2 && UseDelta) {
+            return {std::make_shared<DataTypeDateV2>(), 
std::make_shared<DeltaDataType>()};
+        } else if constexpr (std::is_same_v<DateValueType, 
DateV2Value<DateTimeV2ValueType>> &&
+                             ArgNum == 2 && UseDelta) {
+            return {std::make_shared<DataTypeDateTimeV2>(), 
std::make_shared<DeltaDataType>()};
+        } else if constexpr (std::is_same_v<DateValueType, VecDateTimeValue> 
&& ArgNum == 2 &&
+                             !UseDelta) {
+            return {std::make_shared<DataTypeDateTime>(), 
std::make_shared<DataTypeDateTime>()};
+        } else if constexpr (std::is_same_v<DateValueType, 
DateV2Value<DateV2ValueType>> &&
+                             ArgNum == 2 && !UseDelta) {
+            return {std::make_shared<DataTypeDateV2>(), 
std::make_shared<DataTypeDateV2>()};
+        } else if constexpr (std::is_same_v<DateValueType, 
DateV2Value<DateTimeV2ValueType>> &&
+                             ArgNum == 2 && !UseDelta) {
+            return {std::make_shared<DataTypeDateTimeV2>(), 
std::make_shared<DataTypeDateTimeV2>()};
+        } else if constexpr (std::is_same_v<DateValueType, VecDateTimeValue> 
&& ArgNum == 3) {
+            return {std::make_shared<DataTypeDateTime>(), 
std::make_shared<DeltaDataType>(),
+                    std::make_shared<DataTypeDateTime>()};
+        } else if constexpr (std::is_same_v<DateValueType, 
DateV2Value<DateV2ValueType>> &&
+                             ArgNum == 3) {
+            return {std::make_shared<DataTypeDateV2>(), 
std::make_shared<DeltaDataType>(),
+                    std::make_shared<DataTypeDateV2>()};
+        } else {
+            return {std::make_shared<DataTypeDateTimeV2>(), 
std::make_shared<DeltaDataType>(),
+                    std::make_shared<DataTypeDateTimeV2>()};
+        }
     }
 
     Status execute_impl(FunctionContext* context, Block& block, const 
ColumnNumbers& arguments,
                         size_t result, size_t input_rows_count) override {
         const ColumnPtr source_col =
                 
block.get_by_position(arguments[0]).column->convert_to_full_column_if_const();
-        if (const auto* sources = 
check_and_get_column<ColumnVector<Int64>>(source_col.get())) {
-            auto col_to = ColumnVector<Int64>::create();
+        if (const auto* sources =
+                    
check_and_get_column<ColumnVector<NativeType>>(source_col.get())) {
+            auto col_to = ColumnVector<NativeType>::create();
             col_to->resize(input_rows_count);
             auto null_map = ColumnVector<UInt8>::create();
             null_map->get_data().resize_fill(input_rows_count, false);
 
-            if (arguments.size() == 1) {
-                Impl::vector(sources->get_data(), col_to->get_data(), 
null_map->get_data());
-            } else if (arguments.size() == 2) {
+            if constexpr (ArgNum == 1) {
+                Impl::template vector<NativeType>(sources->get_data(), 
col_to->get_data(),
+                                                  null_map->get_data());
+            } else if constexpr (ArgNum == 2) {
                 const IColumn& delta_column = 
*block.get_by_position(arguments[1]).column;
                 if (const auto* delta_const_column =
                             typeid_cast<const ColumnConst*>(&delta_column)) {
                     if 
(block.get_by_position(arguments[1]).type->get_type_id() !=
                         TypeIndex::Int32) {
-                        Impl::vector_constant(sources->get_data(),
-                                              
delta_const_column->get_field().get<Int64>(),
-                                              col_to->get_data(), 
null_map->get_data());
+                        Impl::template vector_constant<NativeType>(
+                                sources->get_data(),
+                                
delta_const_column->get_field().get<NativeType>(),
+                                col_to->get_data(), null_map->get_data());
                     } else {
-                        Impl::vector_constant(sources->get_data(),
-                                              
delta_const_column->get_field().get<Int32>(),
-                                              col_to->get_data(), 
null_map->get_data());
+                        Impl::template vector_constant_delta<NativeType, 
DeltaValueType>(
+                                sources->get_data(), 
delta_const_column->get_field().get<Int32>(),
+                                col_to->get_data(), null_map->get_data());
                     }
                 } else {
                     if (const auto* delta_vec_column0 =
-                                
check_and_get_column<ColumnVector<Int64>>(delta_column)) {
+                                
check_and_get_column<ColumnVector<NativeType>>(delta_column)) {
                         Impl::vector_vector(sources->get_data(), 
delta_vec_column0->get_data(),
                                             col_to->get_data(), 
null_map->get_data());
                     } else {
                         const auto* delta_vec_column1 =
-                                
check_and_get_column<ColumnVector<Int32>>(delta_column);
+                                
check_and_get_column<ColumnVector<DeltaValueType>>(delta_column);
                         DCHECK(delta_vec_column1 != nullptr);
                         Impl::vector_vector(sources->get_data(), 
delta_vec_column1->get_data(),
                                             col_to->get_data(), 
null_map->get_data());
@@ -88,14 +141,14 @@ public:
                                                
.column->convert_to_full_column_if_const();
 
                 const auto arg1_column =
-                        
check_and_get_column<ColumnVector<Int32>>(*arg1_column_ptr);
+                        
check_and_get_column<ColumnVector<DeltaValueType>>(*arg1_column_ptr);
                 const auto arg2_column =
-                        
check_and_get_column<ColumnVector<Int64>>(*arg2_column_ptr);
+                        
check_and_get_column<ColumnVector<NativeType>>(*arg2_column_ptr);
                 DCHECK(arg1_column != nullptr);
                 DCHECK(arg2_column != nullptr);
-                Impl::vector_vector(sources->get_data(), 
arg1_column->get_data(),
-                                    arg2_column->get_data(), 
col_to->get_data(),
-                                    null_map->get_data());
+                Impl::template vector_vector<NativeType, DeltaValueType>(
+                        sources->get_data(), arg1_column->get_data(), 
arg2_column->get_data(),
+                        col_to->get_data(), null_map->get_data());
             }
 
             block.get_by_position(result).column =
@@ -113,47 +166,98 @@ template <typename Impl>
 struct FloorCeilImpl {
     static constexpr auto name = Impl::name;
 
-    static void vector(const PaddedPODArray<Int64>& dates, 
PaddedPODArray<Int64>& res,
+    template <typename NativeType>
+    static void vector(const PaddedPODArray<NativeType>& dates, 
PaddedPODArray<NativeType>& res,
                        NullMap& null_map) {
-        vector_constant(dates, Int32(1), res, null_map);
+        vector_constant_delta<NativeType, Int32>(dates, Int32(1), res, 
null_map);
     }
 
-    static void vector_constant(const PaddedPODArray<Int64>& dates, Int64 
origin_date,
-                                PaddedPODArray<Int64>& res, NullMap& null_map) 
{
+    template <typename NativeType>
+    static void vector_constant(const PaddedPODArray<NativeType>& dates, 
NativeType origin_date,
+                                PaddedPODArray<NativeType>& res, NullMap& 
null_map) {
         for (int i = 0; i < dates.size(); ++i) {
-            Impl::time_round(dates[i], Int32(1), origin_date, res[i], 
null_map[i]);
+            if constexpr (std::is_same_v<NativeType, UInt32>) {
+                Impl::template time_round<UInt32, 
DateV2Value<DateV2ValueType>>(
+                        dates[i], Int32(1), origin_date, res[i], null_map[i]);
+            } else if constexpr (std::is_same_v<NativeType, UInt64>) {
+                Impl::template time_round<UInt64, 
DateV2Value<DateTimeV2ValueType>>(
+                        dates[i], Int32(1), origin_date, res[i], null_map[i]);
+            } else {
+                Impl::template time_round<Int64, VecDateTimeValue>(dates[i], 
Int32(1), origin_date,
+                                                                   res[i], 
null_map[i]);
+            }
         }
     }
 
-    static void vector_constant(const PaddedPODArray<Int64>& dates, Int32 
period,
-                                PaddedPODArray<Int64>& res, NullMap& null_map) 
{
+    template <typename NativeType, typename DeltaType>
+    static void vector_constant_delta(const PaddedPODArray<NativeType>& dates, 
DeltaType period,
+                                      PaddedPODArray<NativeType>& res, 
NullMap& null_map) {
         for (int i = 0; i < dates.size(); ++i) {
-            Impl::time_round(dates[i], period, res[i], null_map[i]);
+            if constexpr (std::is_same_v<NativeType, UInt32>) {
+                Impl::template time_round<UInt32, 
DateV2Value<DateV2ValueType>>(
+                        dates[i], period, res[i], null_map[i]);
+            } else if constexpr (std::is_same_v<NativeType, UInt64>) {
+                Impl::template time_round<UInt64, 
DateV2Value<DateTimeV2ValueType>>(
+                        dates[i], period, res[i], null_map[i]);
+            } else {
+                Impl::template time_round<Int64, VecDateTimeValue>(dates[i], 
period, res[i],
+                                                                   
null_map[i]);
+            }
         }
     }
 
-    static void vector_vector(const PaddedPODArray<Int64>& dates,
-                              const PaddedPODArray<Int64>& origin_dates, 
PaddedPODArray<Int64>& res,
-                              NullMap& null_map) {
+    template <typename NativeType>
+    static void vector_vector(const PaddedPODArray<NativeType>& dates,
+                              const PaddedPODArray<NativeType>& origin_dates,
+                              PaddedPODArray<NativeType>& res, NullMap& 
null_map) {
         for (int i = 0; i < dates.size(); ++i) {
-            Impl::time_round(dates[i], Int32(1), origin_dates[i], res[i], 
null_map[i]);
+            if constexpr (std::is_same_v<NativeType, UInt32>) {
+                Impl::template time_round<UInt32, 
DateV2Value<DateV2ValueType>>(
+                        dates[i], Int32(1), origin_dates[i], res[i], 
null_map[i]);
+            } else if constexpr (std::is_same_v<NativeType, UInt64>) {
+                Impl::template time_round<UInt64, 
DateV2Value<DateTimeV2ValueType>>(
+                        dates[i], Int32(1), origin_dates[i], res[i], 
null_map[i]);
+            } else {
+                Impl::template time_round<Int64, VecDateTimeValue>(
+                        dates[i], Int32(1), origin_dates[i], res[i], 
null_map[i]);
+            }
         }
     }
 
-    static void vector_vector(const PaddedPODArray<Int64>& dates,
-                              const PaddedPODArray<Int32>& periods, 
PaddedPODArray<Int64>& res,
-                              NullMap& null_map) {
+    template <typename NativeType, typename DeltaType>
+    static void vector_vector(const PaddedPODArray<NativeType>& dates,
+                              const PaddedPODArray<DeltaType>& periods,
+                              PaddedPODArray<NativeType>& res, NullMap& 
null_map) {
         for (int i = 0; i < dates.size(); ++i) {
-            Impl::time_round(dates[i], periods[i], res[i], null_map[i]);
+            if constexpr (std::is_same_v<NativeType, UInt32>) {
+                Impl::template time_round<UInt32, 
DateV2Value<DateV2ValueType>>(
+                        dates[i], periods[i], res[i], null_map[i]);
+            } else if constexpr (std::is_same_v<NativeType, UInt64>) {
+                Impl::template time_round<UInt64, 
DateV2Value<DateTimeV2ValueType>>(
+                        dates[i], periods[i], res[i], null_map[i]);
+            } else {
+                Impl::template time_round<Int64, VecDateTimeValue>(dates[i], 
periods[i], res[i],
+                                                                   
null_map[i]);
+            }
         }
     }
 
-    static void vector_vector(const PaddedPODArray<Int64>& dates,
-                              const PaddedPODArray<Int32>& periods,
-                              const PaddedPODArray<Int64>& origin_dates, 
PaddedPODArray<Int64>& res,
-                              NullMap& null_map) {
+    template <typename NativeType, typename DeltaType>
+    static void vector_vector(const PaddedPODArray<NativeType>& dates,
+                              const PaddedPODArray<DeltaType>& periods,
+                              const PaddedPODArray<NativeType>& origin_dates,
+                              PaddedPODArray<NativeType>& res, NullMap& 
null_map) {
         for (int i = 0; i < dates.size(); ++i) {
-            Impl::time_round(dates[i], periods[i], origin_dates[i], res[i], 
null_map[i]);
+            if constexpr (std::is_same_v<NativeType, UInt32>) {
+                Impl::template time_round<UInt32, 
DateV2Value<DateV2ValueType>>(
+                        dates[i], periods[i], origin_dates[i], res[i], 
null_map[i]);
+            } else if constexpr (std::is_same_v<NativeType, UInt64>) {
+                Impl::template time_round<UInt64, 
DateV2Value<DateTimeV2ValueType>>(
+                        dates[i], periods[i], origin_dates[i], res[i], 
null_map[i]);
+            } else {
+                Impl::template time_round<Int64, VecDateTimeValue>(
+                        dates[i], periods[i], origin_dates[i], res[i], 
null_map[i]);
+            }
         }
     }
 };
@@ -166,8 +270,15 @@ struct TimeRound {
     static constexpr int8_t FLOOR = 0;
     static constexpr int8_t CEIL = 1;
 
-    static void time_round(const doris::vectorized::VecDateTimeValue& ts2, 
Int32 period,
-                           doris::vectorized::VecDateTimeValue& ts1, UInt8& 
is_null) {
+    static constexpr uint32_t MASK_YEAR_FOR_DATEV2 = -1 >> 23;
+    static constexpr uint32_t MASK_YEAR_MONTH_FOR_DATEV2 = -1 >> 27;
+
+    static constexpr uint64_t MASK_YEAR_FOR_DATETIMEV2 = -1 >> 18;
+    static constexpr uint64_t MASK_YEAR_MONTH_FOR_DATETIMEV2 = -1 >> 22;
+
+    template <typename NativeType, typename DateValueType>
+    static void time_round(const DateValueType& ts2, Int32 period, 
DateValueType& ts1,
+                           UInt8& is_null) {
         if (period < 1) {
             is_null = true;
             return;
@@ -176,48 +287,123 @@ struct TimeRound {
         int64_t diff;
         int64_t trivial_part_ts1;
         int64_t trivial_part_ts2;
-        if constexpr (Impl::Unit == YEAR) {
-            diff = (ts2.year() - ts1.year());
-            trivial_part_ts2 = ts2.to_int64() % 10000000000;
-            trivial_part_ts1 = ts1.to_int64() % 10000000000;
-        }
-        if constexpr (Impl::Unit == MONTH) {
-            diff = (ts2.year() - ts1.year()) * 12 + (ts2.month() - 
ts1.month());
-            trivial_part_ts2 = ts2.to_int64() % 100000000;
-            trivial_part_ts1 = ts1.to_int64() % 100000000;
-        }
-        if constexpr (Impl::Unit == MONTH) {
-            diff = (ts2.year() - ts1.year()) * 12 + (ts2.month() - 
ts1.month());
-            trivial_part_ts2 = ts2.to_int64() % 100000000;
-            trivial_part_ts1 = ts1.to_int64() % 100000000;
-        }
-        if constexpr (Impl::Unit == WEEK) {
-            diff = ts2.daynr() / 7 - ts1.daynr() / 7;
-            trivial_part_ts2 = ts2.daynr() % 7 * 24 * 3600 + ts2.hour() * 3600 
+ ts2.minute() * 60 +
-                               ts2.second();
-            trivial_part_ts1 = ts1.daynr() % 7 * 24 * 3600 + ts1.hour() * 3600 
+ ts1.minute() * 60 +
-                               ts1.second();
-        }
-        if constexpr (Impl::Unit == DAY) {
-            diff = ts2.daynr() - ts1.daynr();
-            trivial_part_ts2 = ts2.hour() * 3600 + ts2.minute() * 60 + 
ts2.second();
-            trivial_part_ts1 = ts1.hour() * 3600 + ts1.minute() * 60 + 
ts1.second();
-        }
-        if constexpr (Impl::Unit == HOUR) {
-            diff = (ts2.daynr() - ts1.daynr()) * 24 + (ts2.hour() - 
ts1.hour());
-            trivial_part_ts2 = ts2.minute() * 60 + ts2.second();
-            trivial_part_ts1 = ts1.minute() * 60 + ts1.second();
-        }
-        if constexpr (Impl::Unit == MINUTE) {
-            diff = (ts2.daynr() - ts1.daynr()) * 24 * 60 + (ts2.hour() - 
ts1.hour()) * 60 +
-                   (ts2.minute() - ts1.minute());
-            trivial_part_ts2 = ts2.second();
-            trivial_part_ts1 = ts1.second();
-        }
-        if constexpr (Impl::Unit == SECOND) {
-            diff = ts2.second_diff(ts1);
-            trivial_part_ts1 = 0;
-            trivial_part_ts2 = 0;
+        if constexpr (std::is_same_v<DateValueType, VecDateTimeValue>) {
+            if constexpr (Impl::Unit == YEAR) {
+                diff = (ts2.year() - ts1.year());
+                trivial_part_ts2 = ts2.to_int64() % 10000000000;
+                trivial_part_ts1 = ts1.to_int64() % 10000000000;
+            }
+            if constexpr (Impl::Unit == MONTH) {
+                diff = (ts2.year() - ts1.year()) * 12 + (ts2.month() - 
ts1.month());
+                trivial_part_ts2 = ts2.to_int64() % 100000000;
+                trivial_part_ts1 = ts1.to_int64() % 100000000;
+            }
+            if constexpr (Impl::Unit == WEEK) {
+                diff = ts2.daynr() / 7 - ts1.daynr() / 7;
+                trivial_part_ts2 = ts2.daynr() % 7 * 24 * 3600 + ts2.hour() * 
3600 +
+                                   ts2.minute() * 60 + ts2.second();
+                trivial_part_ts1 = ts1.daynr() % 7 * 24 * 3600 + ts1.hour() * 
3600 +
+                                   ts1.minute() * 60 + ts1.second();
+            }
+            if constexpr (Impl::Unit == DAY) {
+                diff = ts2.daynr() - ts1.daynr();
+                trivial_part_ts2 = ts2.hour() * 3600 + ts2.minute() * 60 + 
ts2.second();
+                trivial_part_ts1 = ts1.hour() * 3600 + ts1.minute() * 60 + 
ts1.second();
+            }
+            if constexpr (Impl::Unit == HOUR) {
+                diff = (ts2.daynr() - ts1.daynr()) * 24 + (ts2.hour() - 
ts1.hour());
+                trivial_part_ts2 = ts2.minute() * 60 + ts2.second();
+                trivial_part_ts1 = ts1.minute() * 60 + ts1.second();
+            }
+            if constexpr (Impl::Unit == MINUTE) {
+                diff = (ts2.daynr() - ts1.daynr()) * 24 * 60 + (ts2.hour() - 
ts1.hour()) * 60 +
+                       (ts2.minute() - ts1.minute());
+                trivial_part_ts2 = ts2.second();
+                trivial_part_ts1 = ts1.second();
+            }
+            if constexpr (Impl::Unit == SECOND) {
+                diff = ts2.second_diff(ts1);
+                trivial_part_ts1 = 0;
+                trivial_part_ts2 = 0;
+            }
+        } else if constexpr (std::is_same_v<DateValueType, 
DateV2Value<DateV2ValueType>>) {
+            if constexpr (Impl::Unit == YEAR) {
+                diff = (ts2.year() - ts1.year());
+                trivial_part_ts2 = ts2.to_date_int_val() & 
MASK_YEAR_FOR_DATEV2;
+                trivial_part_ts1 = ts1.to_date_int_val() & 
MASK_YEAR_FOR_DATEV2;
+            }
+            if constexpr (Impl::Unit == MONTH) {
+                diff = (ts2.year() - ts1.year()) * 12 + (ts2.month() - 
ts1.month());
+                trivial_part_ts2 = ts2.to_date_int_val() & 
MASK_YEAR_MONTH_FOR_DATEV2;
+                trivial_part_ts1 = ts1.to_date_int_val() & 
MASK_YEAR_MONTH_FOR_DATEV2;
+            }
+            if constexpr (Impl::Unit == WEEK) {
+                diff = ts2.daynr() / 7 - ts1.daynr() / 7;
+                trivial_part_ts2 = ts2.daynr() % 7 * 24 * 3600 + ts2.hour() * 
3600 +
+                                   ts2.minute() * 60 + ts2.second();
+                trivial_part_ts1 = ts1.daynr() % 7 * 24 * 3600 + ts1.hour() * 
3600 +
+                                   ts1.minute() * 60 + ts1.second();
+            }
+            if constexpr (Impl::Unit == DAY) {
+                diff = ts2.daynr() - ts1.daynr();
+                trivial_part_ts2 = ts2.hour() * 3600 + ts2.minute() * 60 + 
ts2.second();
+                trivial_part_ts1 = ts1.hour() * 3600 + ts1.minute() * 60 + 
ts1.second();
+            }
+            if constexpr (Impl::Unit == HOUR) {
+                diff = (ts2.daynr() - ts1.daynr()) * 24 + (ts2.hour() - 
ts1.hour());
+                trivial_part_ts2 = ts2.minute() * 60 + ts2.second();
+                trivial_part_ts1 = ts1.minute() * 60 + ts1.second();
+            }
+            if constexpr (Impl::Unit == MINUTE) {
+                diff = (ts2.daynr() - ts1.daynr()) * 24 * 60 + (ts2.hour() - 
ts1.hour()) * 60 +
+                       (ts2.minute() - ts1.minute());
+                trivial_part_ts2 = ts2.second();
+                trivial_part_ts1 = ts1.second();
+            }
+            if constexpr (Impl::Unit == SECOND) {
+                diff = ts2.second_diff(ts1);
+                trivial_part_ts1 = 0;
+                trivial_part_ts2 = 0;
+            }
+        } else if constexpr (std::is_same_v<DateValueType, 
DateV2Value<DateTimeV2ValueType>>) {
+            if constexpr (Impl::Unit == YEAR) {
+                diff = (ts2.year() - ts1.year());
+                trivial_part_ts2 = ts2.to_date_int_val() & 
MASK_YEAR_FOR_DATETIMEV2;
+                trivial_part_ts1 = ts1.to_date_int_val() & 
MASK_YEAR_FOR_DATETIMEV2;
+            }
+            if constexpr (Impl::Unit == MONTH) {
+                diff = (ts2.year() - ts1.year()) * 12 + (ts2.month() - 
ts1.month());
+                trivial_part_ts2 = ts2.to_date_int_val() & 
MASK_YEAR_MONTH_FOR_DATETIMEV2;
+                trivial_part_ts1 = ts1.to_date_int_val() & 
MASK_YEAR_MONTH_FOR_DATETIMEV2;
+            }
+            if constexpr (Impl::Unit == WEEK) {
+                diff = ts2.daynr() / 7 - ts1.daynr() / 7;
+                trivial_part_ts2 = ts2.daynr() % 7 * 24 * 3600 + ts2.hour() * 
3600 +
+                                   ts2.minute() * 60 + ts2.second();
+                trivial_part_ts1 = ts1.daynr() % 7 * 24 * 3600 + ts1.hour() * 
3600 +
+                                   ts1.minute() * 60 + ts1.second();
+            }
+            if constexpr (Impl::Unit == DAY) {
+                diff = ts2.daynr() - ts1.daynr();
+                trivial_part_ts2 = ts2.hour() * 3600 + ts2.minute() * 60 + 
ts2.second();
+                trivial_part_ts1 = ts1.hour() * 3600 + ts1.minute() * 60 + 
ts1.second();
+            }
+            if constexpr (Impl::Unit == HOUR) {
+                diff = (ts2.daynr() - ts1.daynr()) * 24 + (ts2.hour() - 
ts1.hour());
+                trivial_part_ts2 = ts2.minute() * 60 + ts2.second();
+                trivial_part_ts1 = ts1.minute() * 60 + ts1.second();
+            }
+            if constexpr (Impl::Unit == MINUTE) {
+                diff = (ts2.daynr() - ts1.daynr()) * 24 * 60 + (ts2.hour() - 
ts1.hour()) * 60 +
+                       (ts2.minute() - ts1.minute());
+                trivial_part_ts2 = ts2.second();
+                trivial_part_ts1 = ts1.second();
+            }
+            if constexpr (Impl::Unit == SECOND) {
+                diff = ts2.second_diff(ts1);
+                trivial_part_ts1 = 0;
+                trivial_part_ts2 = 0;
+            }
         }
 
         //round down/up to specific time-unit(HOUR/DAY/MONTH...) by 
increase/decrease diff variable
@@ -239,22 +425,24 @@ struct TimeRound {
                                                    : count);
         bool is_neg = step < 0;
         TimeInterval interval(Impl::Unit, is_neg ? -step : step, is_neg);
-        is_null = !ts1.date_add_interval<Impl::Unit>(interval);
+        is_null = !ts1.template date_add_interval<Impl::Unit>(interval);
         return;
     }
 
-    static void time_round(Int64 date, Int32 period, Int64 origin_date, Int64& 
res,
+    template <typename NativeType, typename DateValueType>
+    static void time_round(NativeType date, Int32 period, NativeType 
origin_date, NativeType& res,
                            UInt8& is_null) {
         res = origin_date;
-        auto ts2 = binary_cast<Int64, VecDateTimeValue>(date);
-        auto& ts1 = (doris::vectorized::VecDateTimeValue&)(res);
+        auto ts2 = binary_cast<NativeType, DateValueType>(date);
+        auto& ts1 = (DateValueType&)(res);
 
-        time_round(ts2, period, ts1, is_null);
+        TimeRound<Impl>::template time_round<NativeType, DateValueType>(ts2, 
period, ts1, is_null);
     }
 
-    static void time_round(Int64 date, Int32 period, Int64& res, UInt8& 
is_null) {
-        auto ts2 = binary_cast<Int64, VecDateTimeValue>(date);
-        auto& ts1 = (doris::vectorized::VecDateTimeValue&)(res);
+    template <typename NativeType, typename DateValueType>
+    static void time_round(NativeType date, Int32 period, NativeType& res, 
UInt8& is_null) {
+        auto ts2 = binary_cast<NativeType, DateValueType>(date);
+        auto& ts1 = (DateValueType&)(res);
         if constexpr (Impl::Unit != WEEK) {
             ts1.from_olap_datetime(FIRST_DAY);
         } else {
@@ -262,17 +450,57 @@ struct TimeRound {
             ts1.from_olap_datetime(FIRST_SUNDAY);
         }
 
-        time_round(ts2, period, ts1, is_null);
+        TimeRound<Impl>::template time_round<NativeType, DateValueType>(ts2, 
period, ts1, is_null);
     }
 };
 
-#define TIME_ROUND(CLASS, NAME, UNIT, TYPE)    \
-    struct CLASS {                             \
-        static constexpr auto name = #NAME;    \
-        static constexpr TimeUnit Unit = UNIT; \
-        static constexpr auto Type = TYPE;     \
-    };                                         \
-    using Function##CLASS = 
FunctionDateTimeFloorCeil<FloorCeilImpl<TimeRound<CLASS>>>;
+#define TIME_ROUND_WITH_DELTA_TYPE(CLASS, NAME, UNIT, TYPE, DELTA)             
                    \
+    using FunctionOneArg##CLASS##DELTA =                                       
                    \
+            FunctionDateTimeFloorCeil<FloorCeilImpl<TimeRound<CLASS>>, 
VecDateTimeValue, DELTA, 1, \
+                                      false>;                                  
                    \
+    using FunctionTwoArg##CLASS##DELTA =                                       
                    \
+            FunctionDateTimeFloorCeil<FloorCeilImpl<TimeRound<CLASS>>, 
VecDateTimeValue, DELTA, 2, \
+                                      false>;                                  
                    \
+    using FunctionThreeArg##CLASS##DELTA =                                     
                    \
+            FunctionDateTimeFloorCeil<FloorCeilImpl<TimeRound<CLASS>>, 
VecDateTimeValue, DELTA, 3, \
+                                      false>;                                  
                    \
+    using FunctionDateV2OneArg##CLASS##DELTA =                                 
                    \
+            FunctionDateTimeFloorCeil<FloorCeilImpl<TimeRound<CLASS>>,         
                    \
+                                      DateV2Value<DateV2ValueType>, DELTA, 1, 
false>;              \
+    using FunctionDateV2TwoArg##CLASS##DELTA =                                 
                    \
+            FunctionDateTimeFloorCeil<FloorCeilImpl<TimeRound<CLASS>>,         
                    \
+                                      DateV2Value<DateV2ValueType>, DELTA, 2, 
false>;              \
+    using FunctionDateV2ThreeArg##CLASS##DELTA =                               
                    \
+            FunctionDateTimeFloorCeil<FloorCeilImpl<TimeRound<CLASS>>,         
                    \
+                                      DateV2Value<DateV2ValueType>, DELTA, 3, 
false>;              \
+    using FunctionDateTimeV2OneArg##CLASS##DELTA =                             
                    \
+            FunctionDateTimeFloorCeil<FloorCeilImpl<TimeRound<CLASS>>,         
                    \
+                                      DateV2Value<DateTimeV2ValueType>, DELTA, 
1, false>;          \
+    using FunctionDateTimeV2TwoArg##CLASS##DELTA =                             
                    \
+            FunctionDateTimeFloorCeil<FloorCeilImpl<TimeRound<CLASS>>,         
                    \
+                                      DateV2Value<DateTimeV2ValueType>, DELTA, 
2, false>;          \
+    using FunctionDateTimeV2ThreeArg##CLASS##DELTA =                           
                    \
+            FunctionDateTimeFloorCeil<FloorCeilImpl<TimeRound<CLASS>>,         
                    \
+                                      DateV2Value<DateTimeV2ValueType>, DELTA, 
3, false>;
+
+#define TIME_ROUND(CLASS, NAME, UNIT, TYPE)                                    
                    \
+    struct CLASS {                                                             
                    \
+        static constexpr auto name = #NAME;                                    
                    \
+        static constexpr TimeUnit Unit = UNIT;                                 
                    \
+        static constexpr auto Type = TYPE;                                     
                    \
+    };                                                                         
                    \
+                                                                               
                    \
+    TIME_ROUND_WITH_DELTA_TYPE(CLASS, NAME, UNIT, TYPE, Int32)                 
                    \
+    TIME_ROUND_WITH_DELTA_TYPE(CLASS, NAME, UNIT, TYPE, Int64)                 
                    \
+    using FunctionDateTimeV2TwoArg##CLASS =                                    
                    \
+            FunctionDateTimeFloorCeil<FloorCeilImpl<TimeRound<CLASS>>,         
                    \
+                                      DateV2Value<DateTimeV2ValueType>, Int32, 
2, true>;           \
+    using FunctionDateV2TwoArg##CLASS =                                        
                    \
+            FunctionDateTimeFloorCeil<FloorCeilImpl<TimeRound<CLASS>>,         
                    \
+                                      DateV2Value<DateV2ValueType>, Int32, 2, 
true>;               \
+    using FunctionDateTimeTwoArg##CLASS =                                      
                    \
+            FunctionDateTimeFloorCeil<FloorCeilImpl<TimeRound<CLASS>>, 
VecDateTimeValue, Int32, 2, \
+                                      true>;
 
 TIME_ROUND(YearFloor, year_floor, YEAR, false);
 TIME_ROUND(MonthFloor, month_floor, MONTH, false);
@@ -291,20 +519,38 @@ TIME_ROUND(MinuteCeil, minute_ceil, MINUTE, true);
 TIME_ROUND(SecondCeil, second_ceil, SECOND, true);
 
 void register_function_datetime_floor_ceil(SimpleFunctionFactory& factory) {
-    factory.register_function<FunctionYearFloor>();
-    factory.register_function<FunctionMonthFloor>();
-    factory.register_function<FunctionWeekFloor>();
-    factory.register_function<FunctionDayFloor>();
-    factory.register_function<FunctionHourFloor>();
-    factory.register_function<FunctionMinuteFloor>();
-    factory.register_function<FunctionSecondFloor>();
-
-    factory.register_function<FunctionYearCeil>();
-    factory.register_function<FunctionMonthCeil>();
-    factory.register_function<FunctionWeekCeil>();
-    factory.register_function<FunctionDayCeil>();
-    factory.register_function<FunctionHourCeil>();
-    factory.register_function<FunctionMinuteCeil>();
-    factory.register_function<FunctionSecondCeil>();
+#define REGISTER_FUNC_WITH_DELTA_TYPE(CLASS, DELTA)                        \
+    factory.register_function<FunctionOneArg##CLASS##DELTA>();             \
+    factory.register_function<FunctionTwoArg##CLASS##DELTA>();             \
+    factory.register_function<FunctionThreeArg##CLASS##DELTA>();           \
+    factory.register_function<FunctionDateV2OneArg##CLASS##DELTA>();       \
+    factory.register_function<FunctionDateV2TwoArg##CLASS##DELTA>();       \
+    factory.register_function<FunctionDateV2ThreeArg##CLASS##DELTA>();     \
+    factory.register_function<FunctionDateTimeV2OneArg##CLASS##DELTA>();   \
+    factory.register_function<FunctionDateTimeV2TwoArg##CLASS##DELTA>();   \
+    factory.register_function<FunctionDateTimeV2ThreeArg##CLASS##DELTA>(); \
+    factory.register_function<FunctionDateTimeV2TwoArg##CLASS>();          \
+    factory.register_function<FunctionDateTimeTwoArg##CLASS>();            \
+    factory.register_function<FunctionDateV2TwoArg##CLASS>();
+
+#define REGISTER_FUNC(CLASS)                    \
+    REGISTER_FUNC_WITH_DELTA_TYPE(CLASS, Int32) \
+    REGISTER_FUNC_WITH_DELTA_TYPE(CLASS, Int64)
+
+    REGISTER_FUNC(YearFloor);
+    REGISTER_FUNC(MonthFloor);
+    REGISTER_FUNC(WeekFloor);
+    REGISTER_FUNC(DayFloor);
+    REGISTER_FUNC(HourFloor);
+    REGISTER_FUNC(MinuteFloor);
+    REGISTER_FUNC(SecondFloor);
+
+    REGISTER_FUNC(YearCeil);
+    REGISTER_FUNC(MonthCeil);
+    REGISTER_FUNC(WeekCeil);
+    REGISTER_FUNC(DayCeil);
+    REGISTER_FUNC(HourCeil);
+    REGISTER_FUNC(MinuteCeil);
+    REGISTER_FUNC(SecondCeil);
 }
 } // namespace doris::vectorized
diff --git a/be/src/vec/functions/function_timestamp.cpp 
b/be/src/vec/functions/function_timestamp.cpp
index ea6defb0dd..de06f993d9 100644
--- a/be/src/vec/functions/function_timestamp.cpp
+++ b/be/src/vec/functions/function_timestamp.cpp
@@ -29,17 +29,70 @@
 
 namespace doris::vectorized {
 
-template <typename DateType, typename NativeType>
 struct StrToDate {
     static constexpr auto name = "str_to_date";
-    using ReturnType = DateType;
-    using ColumnType = ColumnVector<NativeType>;
-
-    static void vector_vector(FunctionContext* context, const 
ColumnString::Chars& ldata,
-                              const ColumnString::Offsets& loffsets,
-                              const ColumnString::Chars& rdata,
-                              const ColumnString::Offsets& roffsets,
-                              PaddedPODArray<NativeType>& res, NullMap& 
null_map) {
+
+    static Status execute(FunctionContext* context, Block& block, const 
ColumnNumbers& arguments,
+                          size_t result, size_t input_rows_count) {
+        auto null_map = ColumnUInt8::create(input_rows_count, 0);
+        ColumnPtr argument_columns[2];
+
+        // focus convert const to full column to simply execute logic
+        // handle
+        for (int i = 0; i < 2; ++i) {
+            argument_columns[i] =
+                    
block.get_by_position(arguments[i]).column->convert_to_full_column_if_const();
+            if (auto* nullable = 
check_and_get_column<ColumnNullable>(*argument_columns[i])) {
+                // Danger: Here must dispose the null map data first! Because
+                // argument_columns[i]=nullable->get_nested_column_ptr(); will 
release the mem
+                // of column nullable mem of null map
+                VectorizedUtils::update_null_map(null_map->get_data(),
+                                                 
nullable->get_null_map_data());
+                argument_columns[i] = nullable->get_nested_column_ptr();
+            }
+        }
+
+        auto specific_str_column = assert_cast<const 
ColumnString*>(argument_columns[0].get());
+        auto specific_char_column = assert_cast<const 
ColumnString*>(argument_columns[1].get());
+
+        auto& ldata = specific_str_column->get_chars();
+        auto& loffsets = specific_str_column->get_offsets();
+
+        auto& rdata = specific_char_column->get_chars();
+        auto& roffsets = specific_char_column->get_offsets();
+
+        ColumnPtr res = nullptr;
+        WhichDataType 
which(remove_nullable(block.get_by_position(result).type));
+        if (which.is_date_time_v2()) {
+            res = ColumnVector<UInt64>::create();
+            executeImpl<DateV2Value<DateTimeV2ValueType>, UInt64>(
+                    context, ldata, loffsets, rdata, roffsets,
+                    
static_cast<ColumnVector<UInt64>*>(res->assume_mutable().get())->get_data(),
+                    null_map->get_data());
+        } else if (which.is_date_v2()) {
+            res = ColumnVector<UInt32>::create();
+            executeImpl<DateV2Value<DateV2ValueType>, UInt32>(
+                    context, ldata, loffsets, rdata, roffsets,
+                    
static_cast<ColumnVector<UInt32>*>(res->assume_mutable().get())->get_data(),
+                    null_map->get_data());
+        } else {
+            res = ColumnVector<Int64>::create();
+            executeImpl<VecDateTimeValue, Int64>(
+                    context, ldata, loffsets, rdata, roffsets,
+                    
static_cast<ColumnVector<Int64>*>(res->assume_mutable().get())->get_data(),
+                    null_map->get_data());
+        }
+
+        block.get_by_position(result).column =
+                ColumnNullable::create(std::move(res), std::move(null_map));
+        return Status::OK();
+    }
+
+    template <typename DateValueType, typename NativeType>
+    static void executeImpl(FunctionContext* context, const 
ColumnString::Chars& ldata,
+                            const ColumnString::Offsets& loffsets, const 
ColumnString::Chars& rdata,
+                            const ColumnString::Offsets& roffsets, 
PaddedPODArray<NativeType>& res,
+                            NullMap& null_map) {
         size_t size = loffsets.size();
         res.resize(size);
         for (size_t i = 0; i < size; ++i) {
@@ -49,43 +102,76 @@ struct StrToDate {
             const char* r_raw_str = reinterpret_cast<const 
char*>(&rdata[roffsets[i - 1]]);
             int r_str_size = roffsets[i] - roffsets[i - 1] - 1;
 
-            if constexpr (std::is_same_v<DateType, DataTypeDateTime> ||
-                          std::is_same_v<DateType, DataTypeDate>) {
-                auto& ts_val = *reinterpret_cast<VecDateTimeValue*>(&res[i]);
-                if (!ts_val.from_date_format_str(r_raw_str, r_str_size, 
l_raw_str, l_str_size)) {
-                    null_map[i] = 1;
-                }
+            auto& ts_val = *reinterpret_cast<DateValueType*>(&res[i]);
+            if (!ts_val.from_date_format_str(r_raw_str, r_str_size, l_raw_str, 
l_str_size)) {
+                null_map[i] = 1;
+            }
+            if constexpr (std::is_same_v<DateValueType, VecDateTimeValue>) {
                 if (context->impl()->get_return_type().type ==
                     doris_udf::FunctionContext::Type::TYPE_DATETIME) {
                     ts_val.to_datetime();
                 } else {
                     ts_val.cast_to_date();
                 }
-            } else {
-                auto& ts_val = 
*reinterpret_cast<DateV2Value<DateV2ValueType>*>(&res[i]);
-                if (!ts_val.from_date_format_str(r_raw_str, r_str_size, 
l_raw_str, l_str_size)) {
-                    null_map[i] = 1;
-                }
             }
         }
     }
 };
 
-struct NameMakeDate {
+struct MakeDateImpl {
     static constexpr auto name = "makedate";
-};
 
-template <typename LeftDataType, typename RightDataType, typename 
ResultDateType,
-          typename ReturnType>
-struct MakeDateImpl {
-    using ResultDataType = ResultDateType;
-    using LeftDataColumnType = ColumnVector<typename LeftDataType::FieldType>;
-    using RightDataColumnType = ColumnVector<typename 
RightDataType::FieldType>;
-    using ColumnType = ColumnVector<ReturnType>;
-
-    static void vector_vector(const PaddedPODArray<typename 
LeftDataType::FieldType>& ldata,
-                              const PaddedPODArray<typename 
RightDataType::FieldType>& rdata,
-                              PaddedPODArray<ReturnType>& res, NullMap& 
null_map) {
+    static Status execute(FunctionContext* context, Block& block, const 
ColumnNumbers& arguments,
+                          size_t result, size_t input_rows_count) {
+        auto null_map = ColumnUInt8::create(input_rows_count, 0);
+        DCHECK_EQ(arguments.size(), 2);
+        ColumnPtr argument_columns[2];
+        for (int i = 0; i < 2; ++i) {
+            argument_columns[i] =
+                    
block.get_by_position(arguments[i]).column->convert_to_full_column_if_const();
+            if (auto* nullable = 
check_and_get_column<ColumnNullable>(*argument_columns[i])) {
+                // Danger: Here must dispose the null map data first! Because
+                // argument_columns[i]=nullable->get_nested_column_ptr(); will 
release the mem
+                // of column nullable mem of null map
+                VectorizedUtils::update_null_map(null_map->get_data(),
+                                                 
nullable->get_null_map_data());
+                argument_columns[i] = nullable->get_nested_column_ptr();
+            }
+        }
+
+        ColumnPtr res = nullptr;
+        WhichDataType 
which(remove_nullable(block.get_by_position(result).type));
+        if (which.is_date_v2()) {
+            res = ColumnVector<UInt32>::create();
+            executeImpl<DateV2Value<DateV2ValueType>, UInt32>(
+                    static_cast<const 
ColumnVector<Int32>*>(argument_columns[0].get())->get_data(),
+                    static_cast<const 
ColumnVector<Int32>*>(argument_columns[1].get())->get_data(),
+                    
static_cast<ColumnVector<UInt32>*>(res->assume_mutable().get())->get_data(),
+                    null_map->get_data());
+        } else if (which.is_date_time_v2()) {
+            res = ColumnVector<UInt64>::create();
+            executeImpl<DateV2Value<DateTimeV2ValueType>, UInt64>(
+                    static_cast<const 
ColumnVector<Int32>*>(argument_columns[0].get())->get_data(),
+                    static_cast<const 
ColumnVector<Int32>*>(argument_columns[1].get())->get_data(),
+                    
static_cast<ColumnVector<UInt64>*>(res->assume_mutable().get())->get_data(),
+                    null_map->get_data());
+        } else {
+            res = ColumnVector<Int64>::create();
+            executeImpl<VecDateTimeValue, Int64>(
+                    static_cast<const 
ColumnVector<Int32>*>(argument_columns[0].get())->get_data(),
+                    static_cast<const 
ColumnVector<Int32>*>(argument_columns[1].get())->get_data(),
+                    
static_cast<ColumnVector<Int64>*>(res->assume_mutable().get())->get_data(),
+                    null_map->get_data());
+        }
+
+        block.get_by_position(result).column =
+                ColumnNullable::create(std::move(res), std::move(null_map));
+        return Status::OK();
+    }
+
+    template <typename DateValueType, typename ReturnType>
+    static void executeImpl(const PaddedPODArray<Int32>& ldata, const 
PaddedPODArray<Int32>& rdata,
+                            PaddedPODArray<ReturnType>& res, NullMap& 
null_map) {
         auto len = ldata.size();
         res.resize(len);
 
@@ -97,10 +183,8 @@ struct MakeDateImpl {
                 continue;
             }
 
-            if constexpr (std::is_same_v<ResultDataType, DataTypeDateTime> ||
-                          std::is_same_v<ResultDataType, DataTypeDate>) {
-                auto& res_val = *reinterpret_cast<VecDateTimeValue*>(&res[i]);
-
+            auto& res_val = *reinterpret_cast<DateValueType*>(&res[i]);
+            if constexpr (std::is_same_v<DateValueType, VecDateTimeValue>) {
                 VecDateTimeValue ts_value = VecDateTimeValue();
                 ts_value.set_time(l, 1, 1, 0, 0, 0);
 
@@ -113,16 +197,15 @@ struct MakeDateImpl {
 
                 TimeInterval interval(DAY, r - 1, false);
                 res_val = VecDateTimeValue::from_datetime_val(ts_val);
-                if (!res_val.date_add_interval<DAY>(interval)) {
+                if (!res_val.template date_add_interval<DAY>(interval)) {
                     null_map[i] = 1;
                     continue;
                 }
                 res_val.cast_to_date();
             } else {
-                DateV2Value<DateV2ValueType>* value = new (&res[i]) 
DateV2Value<DateV2ValueType>();
-                value->set_time(l, 1, 1);
+                res_val.set_time(l, 1, 1, 0, 0, 0, 0);
                 TimeInterval interval(DAY, r - 1, false);
-                if (!value->date_add_interval<DAY>(interval, *value)) {
+                if (!res_val.template date_add_interval<DAY>(interval)) {
                     null_map[i] = 1;
                 }
             }
@@ -130,7 +213,6 @@ struct MakeDateImpl {
     }
 };
 
-template <typename DateType>
 class FromDays : public IFunction {
 public:
     static constexpr auto name = "from_days";
@@ -146,48 +228,65 @@ public:
     bool use_default_implementation_for_nulls() const override { return true; }
 
     DataTypePtr get_return_type_impl(const DataTypes& arguments) const 
override {
-        return make_nullable(std::make_shared<DateType>());
+        return make_nullable(std::make_shared<DataTypeDate>());
     }
 
     Status execute_impl(FunctionContext* context, Block& block, const 
ColumnNumbers& arguments,
                         size_t result, size_t input_rows_count) override {
         auto null_map = ColumnUInt8::create(input_rows_count, 0);
-        auto res_column = ColumnInt64::create(input_rows_count);
-        auto& res_data = assert_cast<ColumnInt64&>(*res_column).get_data();
+
         ColumnPtr argument_column =
                 
block.get_by_position(arguments[0]).column->convert_to_full_column_if_const();
-
         auto data_col = assert_cast<const 
ColumnVector<Int32>*>(argument_column.get());
+
+        ColumnPtr res_column;
+        WhichDataType 
which(remove_nullable(block.get_by_position(result).type));
+        if (which.is_date()) {
+            res_column = ColumnInt64::create(input_rows_count);
+            execute_straight<VecDateTimeValue, Int64>(
+                    input_rows_count, null_map->get_data(), 
data_col->get_data(),
+                    
static_cast<ColumnVector<Int64>*>(res_column->assume_mutable().get())
+                            ->get_data());
+        } else {
+            res_column = ColumnVector<UInt32>::create(input_rows_count);
+            execute_straight<DateV2Value<DateV2ValueType>, UInt32>(
+                    input_rows_count, null_map->get_data(), 
data_col->get_data(),
+                    
static_cast<ColumnVector<UInt32>*>(res_column->assume_mutable().get())
+                            ->get_data());
+        }
+
+        block.replace_by_position(
+                result, ColumnNullable::create(std::move(res_column), 
std::move(null_map)));
+        return Status::OK();
+    }
+
+private:
+    template <typename DateValueType, typename ReturnType>
+    void execute_straight(size_t input_rows_count, NullMap& null_map,
+                          const PaddedPODArray<Int32>& data_col,
+                          PaddedPODArray<ReturnType>& res_data) {
         for (int i = 0; i < input_rows_count; i++) {
-            if constexpr (std::is_same_v<DateType, DataTypeDate>) {
-                const auto& cur_data = data_col->get_data()[i];
-                auto& ts_value = 
*reinterpret_cast<VecDateTimeValue*>(&res_data[i]);
+            if constexpr (std::is_same_v<DateValueType, VecDateTimeValue>) {
+                const auto& cur_data = data_col[i];
+                auto& ts_value = 
*reinterpret_cast<DateValueType*>(&res_data[i]);
                 if (!ts_value.from_date_daynr(cur_data)) {
-                    null_map->get_data()[i] = 1;
+                    null_map[i] = 1;
                     continue;
                 }
                 DateTimeVal ts_val;
                 ts_value.to_datetime_val(&ts_val);
                 ts_value = VecDateTimeValue::from_datetime_val(ts_val);
             } else {
-                const auto& cur_data = data_col->get_data()[i];
-                auto& ts_value = 
*reinterpret_cast<DateV2Value<DateV2ValueType>*>(&res_data[i]);
+                const auto& cur_data = data_col[i];
+                auto& ts_value = 
*reinterpret_cast<DateValueType*>(&res_data[i]);
                 if (!ts_value.get_date_from_daynr(cur_data)) {
-                    null_map->get_data()[i] = 1;
+                    null_map[i] = 1;
                 }
             }
         }
-        block.replace_by_position(
-                result, ColumnNullable::create(std::move(res_column), 
std::move(null_map)));
-        return Status::OK();
     }
 };
 
-using FunctionStrToDate = 
FunctionBinaryStringOperateToNullType<StrToDate<DataTypeDateTime, Int64>>;
-
-using FunctionMakeDate = FunctionBinaryToNullType<DataTypeInt32, 
DataTypeInt32, DataTypeDateTime,
-                                                  Int64, MakeDateImpl, 
NameMakeDate>;
-
 struct UnixTimeStampImpl {
     static Int32 trim_timestamp(Int64 timestamp) {
         if (timestamp < 0 || timestamp > INT_MAX) {
@@ -258,7 +357,7 @@ struct UnixTimeStampDateImpl {
                     null_map_data[i] = false;
                     col_result_data[i] = 
UnixTimeStampImpl::trim_timestamp(timestamp);
                 }
-            } else {
+            } else if constexpr (std::is_same_v<DateType, DataTypeDateV2>) {
                 const DateV2Value<DateV2ValueType>& ts_value =
                         reinterpret_cast<const 
DateV2Value<DateV2ValueType>&>(*source.data);
                 int64_t timestamp;
@@ -269,6 +368,17 @@ struct UnixTimeStampDateImpl {
                     null_map_data[i] = false;
                     col_result_data[i] = 
UnixTimeStampImpl::trim_timestamp(timestamp);
                 }
+            } else {
+                const DateV2Value<DateTimeV2ValueType>& ts_value =
+                        reinterpret_cast<const 
DateV2Value<DateTimeV2ValueType>&>(*source.data);
+                int64_t timestamp;
+                if (!ts_value.unix_timestamp(&timestamp,
+                                             
context->impl()->state()->timezone_obj())) {
+                    null_map_data[i] = true;
+                } else {
+                    null_map_data[i] = false;
+                    col_result_data[i] = 
UnixTimeStampImpl::trim_timestamp(timestamp);
+                }
             }
         }
 
@@ -367,16 +477,45 @@ public:
     }
 };
 
+template <typename Impl>
+class FunctionOtherTypesToDateType : public IFunction {
+public:
+    static constexpr auto name = Impl::name;
+    static FunctionPtr create() { return 
std::make_shared<FunctionOtherTypesToDateType>(); }
+
+    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 {
+        return make_nullable(std::make_shared<DataTypeDateTime>());
+    }
+
+    bool use_default_implementation_for_constants() const override { return 
true; }
+
+    Status execute_impl(FunctionContext* context, Block& block, const 
ColumnNumbers& arguments,
+                        size_t result, size_t input_rows_count) override {
+        return Impl::execute(context, block, arguments, result, 
input_rows_count);
+    }
+};
+
+using FunctionStrToDate = FunctionOtherTypesToDateType<StrToDate>;
+
+using FunctionMakeDate = FunctionOtherTypesToDateType<MakeDateImpl>;
+
 void register_function_timestamp(SimpleFunctionFactory& factory) {
     factory.register_function<FunctionStrToDate>();
     factory.register_function<FunctionMakeDate>();
-    factory.register_function<FromDays<DataTypeDate>>();
+    factory.register_function<FromDays>();
 
     factory.register_function<FunctionUnixTimestamp<UnixTimeStampImpl>>();
     
factory.register_function<FunctionUnixTimestamp<UnixTimeStampDateImpl<DataTypeDate>>>();
     
factory.register_function<FunctionUnixTimestamp<UnixTimeStampDateImpl<DataTypeDateV2>>>();
+    
factory.register_function<FunctionUnixTimestamp<UnixTimeStampDateImpl<DataTypeDateTimeV2>>>();
     
factory.register_function<FunctionUnixTimestamp<UnixTimeStampDatetimeImpl<DataTypeDate>>>();
     
factory.register_function<FunctionUnixTimestamp<UnixTimeStampDatetimeImpl<DataTypeDateV2>>>();
+    factory.register_function<
+            
FunctionUnixTimestamp<UnixTimeStampDatetimeImpl<DataTypeDateTimeV2>>>();
     factory.register_function<FunctionUnixTimestamp<UnixTimeStampStrImpl>>();
 }
 
diff --git a/be/src/vec/runtime/vdatetime_value.cpp 
b/be/src/vec/runtime/vdatetime_value.cpp
index 9056e44c46..c9d5ff9d1c 100644
--- a/be/src/vec/runtime/vdatetime_value.cpp
+++ b/be/src/vec/runtime/vdatetime_value.cpp
@@ -2333,7 +2333,8 @@ template <typename T>
 uint32_t DateV2Value<T>::year_week(uint8_t mode) const {
     uint16_t year = 0;
     // The range of the week in the year_week is 1-53, so the mode WEEK_YEAR 
is always true.
-    uint8_t week = calc_week(this->daynr(), this->year(), this->month(), 
this->day(), mode, &year);
+    uint8_t week =
+            calc_week(this->daynr(), this->year(), this->month(), this->day(), 
mode | 2, &year);
     // When the mode WEEK_FIRST_WEEKDAY is not set,
     // the week in which the last three days of the year fall may belong to 
the following year.
     if (week == 53 && day() >= 29 && !(mode & 4)) {
diff --git a/be/src/vec/sink/vmysql_result_writer.cpp 
b/be/src/vec/sink/vmysql_result_writer.cpp
index a0c7dbb02a..04436dcd68 100644
--- a/be/src/vec/sink/vmysql_result_writer.cpp
+++ b/be/src/vec/sink/vmysql_result_writer.cpp
@@ -214,7 +214,7 @@ Status VMysqlResultWriter::_add_one_column(const ColumnPtr& 
column_ptr,
             if constexpr (type == TYPE_DOUBLE) {
                 buf_ret = _buffer.push_double(data[i]);
             }
-            if constexpr (type == TYPE_TIME) {
+            if constexpr (type == TYPE_TIME || type == TYPE_TIMEV2) {
                 buf_ret = _buffer.push_time(data[i]);
             }
             if constexpr (type == TYPE_DATETIME) {
@@ -502,6 +502,14 @@ Status VMysqlResultWriter::append_block(Block& 
input_block) {
             }
             break;
         }
+        case TYPE_TIMEV2: {
+            if (type_ptr->is_nullable()) {
+                status = _add_one_column<PrimitiveType::TYPE_TIMEV2, 
true>(column_ptr, result);
+            } else {
+                status = _add_one_column<PrimitiveType::TYPE_TIMEV2, 
false>(column_ptr, result);
+            }
+            break;
+        }
         case TYPE_STRING:
         case TYPE_CHAR:
         case TYPE_VARCHAR: {
diff --git a/be/test/vec/function/function_time_test.cpp 
b/be/test/vec/function/function_time_test.cpp
index 40bcd4fb5f..021965e2b0 100644
--- a/be/test/vec/function/function_time_test.cpp
+++ b/be/test/vec/function/function_time_test.cpp
@@ -539,7 +539,7 @@ TEST(VTimestampFunctionsTest, convert_tz_test) {
             {{DATETIME("2019-08-01 13:21:03"), STRING("+08:00"), 
STRING("America/Los_Angeles")},
              str_to_date_time("2019-07-31 22:21:03", true)}};
 
-    check_function<DataTypeDate, true>(func_name, input_types, data_set);
+    check_function<DataTypeDateTime, true>(func_name, input_types, data_set);
 }
 
 TEST(VTimestampFunctionsTest, weekday_test) {
@@ -1817,4 +1817,19 @@ TEST(VTimestampFunctionsTest, seconds_sub_v2_test) {
     }
 }
 
+TEST(VTimestampFunctionsTest, convert_tz_v2_test) {
+    std::string func_name = "convert_tz";
+
+    InputTypeSet input_types = {TypeIndex::DateTimeV2, TypeIndex::String, 
TypeIndex::String};
+
+    DataSet data_set = {
+            {{DATETIME("2019-08-01 13:21:03"), STRING("Asia/Shanghai"),
+              STRING("America/Los_Angeles")},
+             str_to_datetime_v2("2019-07-31 22:21:03", "%Y-%m-%d 
%H:%i:%s.%f")},
+            {{DATETIME("2019-08-01 13:21:03"), STRING("+08:00"), 
STRING("America/Los_Angeles")},
+             str_to_datetime_v2("2019-07-31 22:21:03", "%Y-%m-%d 
%H:%i:%s.%f")}};
+
+    check_function<DataTypeDateTimeV2, true>(func_name, input_types, data_set);
+}
+
 } // namespace doris::vectorized
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java
index ae70ca3297..ee65f35469 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java
@@ -32,6 +32,7 @@ import org.apache.doris.catalog.ScalarFunction;
 import org.apache.doris.catalog.ScalarType;
 import org.apache.doris.catalog.Type;
 import org.apache.doris.common.AnalysisException;
+import org.apache.doris.common.Config;
 import org.apache.doris.common.ErrorCode;
 import org.apache.doris.common.ErrorReport;
 import org.apache.doris.common.util.VectorizedUtil;
@@ -1026,10 +1027,12 @@ public class FunctionCallExpr extends Expr {
                 for (int i = 0; i < argTypes.length; ++i) {
                     // For varargs, we must compare with the last type in 
callArgs.argTypes.
                     int ix = Math.min(args.length - 1, i);
-                    if (!argTypes[i].matchesType(args[ix]) && !(
+                    if (!argTypes[i].matchesType(args[ix]) && 
Config.use_date_v2_by_default
+                            && !argTypes[i].isDateType() && (args[ix].isDate() 
|| args[ix].isDatetime())) {
+                        
uncheckedCastChild(DateLiteral.getDefaultDateType(args[ix]), i);
+                    } else if (!argTypes[i].matchesType(args[ix]) && !(
                             argTypes[i].isDateType() && 
args[ix].isDateType())) {
                         uncheckedCastChild(args[ix], i);
-                        //if (argTypes[i] != args[ix]) castChild(args[ix], i);
                     }
                 }
             }
@@ -1075,6 +1078,22 @@ public class FunctionCallExpr extends Expr {
             this.type = fn.getReturnType();
         }
 
+        Type[] childTypes = collectChildReturnTypes();
+        if ((this.type.isDate() || this.type.isDatetime()) && 
Config.use_date_v2_by_default
+                && fn.getArgs().length == childTypes.length) {
+            boolean implicitCastToDate = false;
+            for (int i = 0; i < fn.getArgs().length; i++) {
+                implicitCastToDate = Type.canCastTo(childTypes[i], 
fn.getArgs()[i]);
+                if (implicitCastToDate) {
+                    break;
+                }
+            }
+            if (implicitCastToDate) {
+                this.type = DateLiteral.getDefaultDateType(fn.getReturnType());
+                
fn.setReturnType(DateLiteral.getDefaultDateType(fn.getReturnType()));
+            }
+        }
+
         if (this.type.isDecimalV3()) {
             // DECIMAL need to pass precision and scale to be
             if 
(DECIMAL_FUNCTION_SET.contains(fn.getFunctionName().getFunction())
diff --git a/gensrc/script/doris_builtins_functions.py 
b/gensrc/script/doris_builtins_functions.py
index 63a4cb4a6f..136c97a822 100755
--- a/gensrc/script/doris_builtins_functions.py
+++ b/gensrc/script/doris_builtins_functions.py
@@ -367,9 +367,6 @@ visible_functions = [
     [['now', 'current_timestamp', 'localtime', 'localtimestamp'], 'DATETIME', 
[],
         '_ZN5doris18TimestampFunctions3nowEPN9doris_udf15FunctionContextE',
         '', '', 'vec', 'ALWAYS_NOT_NULLABLE'],
-    [['now', 'current_timestamp', 'localtime', 'localtimestamp'], 
'DATETIMEV2', [],
-     '_ZN5doris18TimestampFunctions3nowEPN9doris_udf15FunctionContextE',
-     '', '', 'vec', 'ALWAYS_NOT_NULLABLE'],
     [['curtime', 'current_time'], 'TIME', [],
         '_ZN5doris18TimestampFunctions7curtimeEPN9doris_udf15FunctionContextE',
         '', '', 'vec', 'ALWAYS_NOT_NULLABLE'],
@@ -436,7 +433,7 @@ visible_functions = [
         
'_ZN5doris18TimestampFunctions6secondEPN9doris_udf15FunctionContextERKNS1_11DateTimeValE',
         '', '', 'vec', 'ALWAYS_NULLABLE'],
 
-    [['makedate'], 'DATETIME', ['INT', 'INT'],
+    [['makedate'], 'DATE', ['INT', 'INT'],
         
'_ZN5doris18TimestampFunctions9make_dateEPN9doris_udf15FunctionContextERKNS1_6IntValES6_',
         '', '', 'vec', 'ALWAYS_NULLABLE'],
     [['years_add'], 'DATETIME', ['DATETIME', 'INT'],
@@ -739,19 +736,10 @@ visible_functions = [
             
'_ZN5doris18TimestampFunctions11second_ceilEPN9doris_udf15FunctionContextERKNS1_11DateTimeValERKNS1_6IntValES6_',
             '', '', 'vec', 'ALWAYS_NULLABLE'],
 
-    [['curdate', 'current_date'], 'DATEV2', [],
-     '_ZN5doris18TimestampFunctions7curdateEPN9doris_udf15FunctionContextE',
-     '', '', 'vec', 'ALWAYS_NOT_NULLABLE'],
-    [['utc_timestamp'], 'DATETIMEV2', [],
-     
'_ZN5doris18TimestampFunctions13utc_timestampEPN9doris_udf15FunctionContextE',
-     '', '', 'vec', 'ALWAYS_NOT_NULLABLE'],
     [['timestamp'], 'DATETIMEV2', ['DATETIMEV2'],
      
'_ZN5doris18TimestampFunctions9timestampEPN9doris_udf15FunctionContextERKNS1_11DateTimeV2ValE',
      '', '', 'vec', 'ALWAYS_NULLABLE'],
 
-    [['from_days'], 'DATEV2', ['INT'],
-     
'_ZN5doris18TimestampFunctions9from_daysEPN9doris_udf15FunctionContextERKNS1_6IntValE',
-     '', '', 'vec', 'ALWAYS_NULLABLE'],
     [['to_days'], 'INT', ['DATEV2'],
      
'_ZN5doris18TimestampFunctions7to_daysEPN9doris_udf15FunctionContextERKNS1_11DateTimeV2ValE',
      '', '', 'vec', 'ALWAYS_NULLABLE'],
@@ -848,9 +836,6 @@ visible_functions = [
      
'_ZN5doris18TimestampFunctions6secondEPN9doris_udf15FunctionContextERKNS1_11DateV2ValE',
      '', '', 'vec', 'ALWAYS_NULLABLE'],
 
-    [['makedate'], 'DATETIMEV2', ['INT', 'INT'],
-     
'_ZN5doris18TimestampFunctions9make_dateEPN9doris_udf15FunctionContextERKNS1_6IntValES6_',
-     '', '', 'vec', 'ALWAYS_NULLABLE'],
     [['years_add'], 'DATETIMEV2', ['DATETIMEV2', 'INT'],
      '_ZN5doris18TimestampFunctions9years_addEPN9doris_udf'
      '15FunctionContextERKNS1_11DateTimeV2ValERKNS1_6IntValE',
@@ -916,9 +901,6 @@ visible_functions = [
      '15FunctionContextERKNS1_11DateTimeV2ValERKNS1_6IntValE',
      '', '', '', ''],
 
-    [['makedate'], 'DATEV2', ['INT', 'INT'],
-     
'_ZN5doris18TimestampFunctions9make_dateEPN9doris_udf15FunctionContextERKNS1_6IntValES6_',
-     '', '', 'vec', 'ALWAYS_NULLABLE'],
     [['years_add'], 'DATEV2', ['DATEV2', 'INT'],
      '_ZN5doris18TimestampFunctions9years_addEPN9doris_udf'
      '15FunctionContextERKNS1_11DateTimeV2ValERKNS1_6IntValE',
@@ -1026,12 +1008,6 @@ visible_functions = [
      '_ZN5doris18TimestampFunctions9time_diffEPN9doris_udf'
      '15FunctionContextERKNS1_11DateTimeV2ValES6_', '', '', 'vec', 
'ALWAYS_NULLABLE'],
 
-    [['str_to_date'], 'DATETIMEV2', ['VARCHAR', 'VARCHAR'],
-     '_ZN5doris18TimestampFunctions11str_to_dateEPN9doris_udf'
-     '15FunctionContextERKNS1_9StringValES6_', '', '', 'vec', 
'ALWAYS_NULLABLE'],
-    [['str_to_date'], 'DATETIMEV2', ['STRING', 'STRING'],
-     '_ZN5doris18TimestampFunctions11str_to_dateEPN9doris_udf'
-     '15FunctionContextERKNS1_9StringValES6_', '', '', 'vec', 
'ALWAYS_NULLABLE'],
     [['date_format'], 'VARCHAR', ['DATETIMEV2', 'VARCHAR'],
      '_ZN5doris18TimestampFunctions11date_formatEPN9doris_udf'
      '15FunctionContextERKNS1_11DateTimeV2ValERKNS1_9StringValE',


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to