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(×tamp, 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(×tamp, 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(×tamp,
+
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]