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 ad4751972c [feature-wip] Support in predicate for datev2 type (#10810) ad4751972c is described below commit ad4751972cfa345834aa92425477e4fbdf14986c Author: Gabriel <gabrielleeb...@gmail.com> AuthorDate: Fri Jul 15 14:32:40 2022 +0800 [feature-wip] Support in predicate for datev2 type (#10810) --- be/src/exprs/anyval_util.cpp | 6 ++ be/src/exprs/anyval_util.h | 16 +++++ be/src/exprs/cast_functions.cpp | 81 ++++++++++++++++++++++ be/src/exprs/cast_functions.h | 18 +++++ be/src/exprs/create_predicate_function.h | 2 + be/src/exprs/expr.cpp | 17 ++++- be/src/exprs/expr.h | 1 + be/src/exprs/expr_context.cpp | 13 +++- be/src/exprs/expr_context.h | 1 + be/src/exprs/expr_value.h | 1 + be/src/exprs/literal.cpp | 11 ++- be/src/exprs/literal.h | 1 + be/src/exprs/scalar_fn_call.cpp | 13 +++- be/src/exprs/scalar_fn_call.h | 1 + be/src/exprs/slot_ref.cpp | 13 ++++ be/src/exprs/slot_ref.h | 1 + be/src/runtime/primitive_type.h | 5 ++ be/src/udf/udf.h | 27 ++++++++ be/src/util/symbols_util.cpp | 4 ++ be/src/vec/exprs/vliteral.cpp | 3 +- be/src/vec/runtime/vdatetime_value.h | 10 +++ .../java/org/apache/doris/analysis/CastExpr.java | 6 +- .../org/apache/doris/analysis/DateLiteral.java | 7 +- .../java/org/apache/doris/catalog/Function.java | 6 +- .../java/org/apache/doris/catalog/FunctionSet.java | 25 ++++++- .../java/org/apache/doris/catalog/ScalarType.java | 13 ++-- .../org/apache/doris/catalog/ColumnTypeTest.java | 6 +- 27 files changed, 283 insertions(+), 25 deletions(-) diff --git a/be/src/exprs/anyval_util.cpp b/be/src/exprs/anyval_util.cpp index 4c8a96e498..f92419123f 100644 --- a/be/src/exprs/anyval_util.cpp +++ b/be/src/exprs/anyval_util.cpp @@ -37,6 +37,7 @@ using doris_udf::DecimalV2Val; using doris_udf::DateTimeVal; using doris_udf::StringVal; using doris_udf::AnyVal; +using doris_udf::DateV2Val; Status allocate_any_val(RuntimeState* state, MemPool* pool, const TypeDescriptor& type, const std::string& mem_limit_exceeded_msg, AnyVal** result) { @@ -105,7 +106,11 @@ AnyVal* create_any_val(ObjectPool* pool, const TypeDescriptor& type) { case TYPE_DATE: return pool->add(new DateTimeVal); + case TYPE_DATEV2: + return pool->add(new DateV2Val); + case TYPE_DATETIME: + case TYPE_DATETIMEV2: return pool->add(new DateTimeVal); case TYPE_ARRAY: @@ -149,6 +154,7 @@ FunctionContext::TypeDesc AnyValUtil::column_type_to_type_desc(const TypeDescrip out.type = FunctionContext::TYPE_DATE; break; case TYPE_DATETIME: + case TYPE_DATETIMEV2: out.type = FunctionContext::TYPE_DATETIME; break; case TYPE_DATEV2: diff --git a/be/src/exprs/anyval_util.h b/be/src/exprs/anyval_util.h index a6b8063be3..207d610f25 100644 --- a/be/src/exprs/anyval_util.h +++ b/be/src/exprs/anyval_util.h @@ -183,6 +183,10 @@ public: DecimalV2Val val; type_limit<DecimalV2Value>::min().to_decimal_val(&val); return val; + } else if constexpr (std::is_same_v<Val, DateV2Val>) { + DateV2Val val; + type_limit<doris::vectorized::DateV2Value>::min().to_datev2_val(&val); + return val; } else { return Val(type_limit<decltype(std::declval<Val>().val)>::min()); } @@ -206,6 +210,10 @@ public: DecimalV2Val val; type_limit<DecimalV2Value>::max().to_decimal_val(&val); return val; + } else if constexpr (std::is_same_v<Val, DateV2Val>) { + DateV2Val val; + type_limit<doris::vectorized::DateV2Value>::max().to_datev2_val(&val); + return val; } else { return Val(type_limit<decltype(std::declval<Val>().val)>::max()); } @@ -246,6 +254,8 @@ public: case TYPE_STRING: return sizeof(doris_udf::StringVal); + case TYPE_DATEV2: + return sizeof(doris_udf::DateV2Val); case TYPE_DATE: case TYPE_DATETIME: return sizeof(doris_udf::DateTimeVal); @@ -291,6 +301,8 @@ public: case TYPE_DATETIME: case TYPE_DATE: return alignof(DateTimeVal); + case TYPE_DATEV2: + return alignof(DateV2Val); case TYPE_DECIMALV2: return alignof(DecimalV2Val); case TYPE_ARRAY: @@ -411,6 +423,10 @@ public: case TYPE_DATETIME: reinterpret_cast<const DateTimeValue*>(slot)->to_datetime_val( reinterpret_cast<doris_udf::DateTimeVal*>(dst)); + + case TYPE_DATEV2: + reinterpret_cast<const doris::vectorized::DateV2Value*>(slot)->to_datev2_val( + reinterpret_cast<doris_udf::DateV2Val*>(dst)); return; case TYPE_ARRAY: reinterpret_cast<const CollectionValue*>(slot)->to_collection_val( diff --git a/be/src/exprs/cast_functions.cpp b/be/src/exprs/cast_functions.cpp index 65cf27d6d4..16a2b47a6a 100644 --- a/be/src/exprs/cast_functions.cpp +++ b/be/src/exprs/cast_functions.cpp @@ -32,6 +32,7 @@ #include "util/mysql_global.h" #include "util/string_parser.hpp" #include "vec/data_types/data_type_decimal.h" +#include "vec/runtime/vdatetime_value.h" namespace doris { @@ -609,6 +610,86 @@ Decimal64Val CastFunctions::cast_to_decimal64_val(FunctionContext* ctx, const De } } +DateTimeVal CastFunctions::cast_to_date_val(FunctionContext* ctx, const DateV2Val& val) { + if (val.is_null) { + return DateTimeVal::null(); + } + vectorized::DateV2Value datev2_val = vectorized::DateV2Value::from_datev2_val(val); + DateTimeValue datetime_value; + datev2_val.convert_date_v2_to_dt(&datetime_value); + DateTimeVal result; + datetime_value.to_datetime_val(&result); + return result; +} + +DateTimeVal CastFunctions::cast_to_datetime_val(FunctionContext* ctx, const DateV2Val& val) { + if (val.is_null) { + return DateTimeVal::null(); + } + vectorized::DateV2Value datev2_val = vectorized::DateV2Value::from_datev2_val(val); + DateTimeValue datetime_value; + datev2_val.convert_date_v2_to_dt(&datetime_value); + datetime_value.set_type(TYPE_DATETIME); + DateTimeVal result; + datetime_value.to_datetime_val(&result); + return result; +} + +#define CAST_TO_DATEV2(from_type) \ + DateV2Val CastFunctions::cast_to_datev2_val(FunctionContext* ctx, const from_type& val) { \ + if (val.is_null) return DateV2Val::null(); \ + doris::vectorized::DateV2Value date_value; \ + if (!date_value.from_date_int64(val.val)) return DateV2Val::null(); \ + DateV2Val result; \ + date_value.to_datev2_val(&result); \ + return result; \ + } + +#define CAST_NUMERIC_TYPES_TO_DATEV2() \ + CAST_TO_DATEV2(TinyIntVal); \ + CAST_TO_DATEV2(SmallIntVal); \ + CAST_TO_DATEV2(IntVal); \ + CAST_TO_DATEV2(BigIntVal); \ + CAST_TO_DATEV2(LargeIntVal); \ + CAST_TO_DATEV2(FloatVal); \ + CAST_TO_DATEV2(DoubleVal); + +CAST_NUMERIC_TYPES_TO_DATEV2(); + +DateV2Val CastFunctions::cast_to_datev2_val(FunctionContext* ctx, const DateV2Val& val) { + if (val.is_null) { + return DateV2Val::null(); + } + return val; +} + +DateV2Val CastFunctions::cast_to_datev2_val(FunctionContext* ctx, const StringVal& val) { + if (val.is_null) { + return DateV2Val::null(); + } + doris::vectorized::DateV2Value date_value; + if (!date_value.from_date_str((char*)val.ptr, val.len)) { + return DateV2Val::null(); + } + // Return null if 'val' did not parse + DateV2Val result; + date_value.to_datev2_val(&result); + return result; +} + +DateV2Val CastFunctions::cast_to_datev2_val(FunctionContext* ctx, const DateTimeVal& val) { + if (val.is_null) { + return DateV2Val::null(); + } + vectorized::VecDateTimeValue date_value = vectorized::VecDateTimeValue::from_datetime_val(val); + + doris::vectorized::DateV2Value datev2_val; + datev2_val.from_date(date_value.to_date_v2()); + DateV2Val result; + datev2_val.to_datev2_val(&result); + return result; +} + CollectionVal CastFunctions::cast_to_array_val(FunctionContext* context, const StringVal& val) { CollectionVal array_val; Status status = ArrayParser::parse(array_val, context, val); diff --git a/be/src/exprs/cast_functions.h b/be/src/exprs/cast_functions.h index 497f49bf80..5beecf8e62 100644 --- a/be/src/exprs/cast_functions.h +++ b/be/src/exprs/cast_functions.h @@ -128,6 +128,8 @@ public: static DateTimeVal cast_to_datetime_val(FunctionContext* context, const DoubleVal& val); static DateTimeVal cast_to_datetime_val(FunctionContext* context, const DateTimeVal& val); static DateTimeVal cast_to_datetime_val(FunctionContext* context, const StringVal& val); + static DateTimeVal cast_to_datetime_val(FunctionContext* context, + const doris_udf::DateV2Val& val); static DateTimeVal cast_to_date_val(FunctionContext* context, const TinyIntVal& val); static DateTimeVal cast_to_date_val(FunctionContext* context, const SmallIntVal& val); @@ -138,6 +140,22 @@ public: static DateTimeVal cast_to_date_val(FunctionContext* context, const DoubleVal& val); static DateTimeVal cast_to_date_val(FunctionContext* context, const DateTimeVal& val); static DateTimeVal cast_to_date_val(FunctionContext* context, const StringVal& val); + static DateTimeVal cast_to_date_val(FunctionContext* context, const doris_udf::DateV2Val& val); + + static doris_udf::DateV2Val cast_to_datev2_val(FunctionContext* context, const TinyIntVal& val); + static doris_udf::DateV2Val cast_to_datev2_val(FunctionContext* context, + const SmallIntVal& val); + static doris_udf::DateV2Val cast_to_datev2_val(FunctionContext* context, const IntVal& val); + static doris_udf::DateV2Val cast_to_datev2_val(FunctionContext* context, const BigIntVal& val); + static doris_udf::DateV2Val cast_to_datev2_val(FunctionContext* context, + const LargeIntVal& val); + static doris_udf::DateV2Val cast_to_datev2_val(FunctionContext* context, const FloatVal& val); + static doris_udf::DateV2Val cast_to_datev2_val(FunctionContext* context, const DoubleVal& val); + static doris_udf::DateV2Val cast_to_datev2_val(FunctionContext* context, + const doris_udf::DateV2Val& val); + static doris_udf::DateV2Val cast_to_datev2_val(FunctionContext* context, const StringVal& val); + static doris_udf::DateV2Val cast_to_datev2_val(FunctionContext* context, + const DateTimeVal& val); #define DECLARE_CAST_TO_DECIMAL(width) \ static Decimal##width##Val cast_to_decimal##width##_val(FunctionContext*, const TinyIntVal&); \ diff --git a/be/src/exprs/create_predicate_function.h b/be/src/exprs/create_predicate_function.h index 36fed51383..6795777cc6 100644 --- a/be/src/exprs/create_predicate_function.h +++ b/be/src/exprs/create_predicate_function.h @@ -95,6 +95,8 @@ typename Traits::BasePtr create_predicate_function(PrimitiveType type) { return Creator::template create<TYPE_DATETIME>(); case TYPE_DATEV2: return Creator::template create<TYPE_DATEV2>(); + case TYPE_DATETIMEV2: + return Creator::template create<TYPE_DATETIMEV2>(); case TYPE_CHAR: return Creator::template create<TYPE_CHAR>(); diff --git a/be/src/exprs/expr.cpp b/be/src/exprs/expr.cpp index 1cbacf3445..283eb81fca 100644 --- a/be/src/exprs/expr.cpp +++ b/be/src/exprs/expr.cpp @@ -132,6 +132,8 @@ Expr::Expr(const TypeDescriptor& type) case TYPE_DATE: case TYPE_DATETIME: + case TYPE_DATEV2: + case TYPE_DATETIMEV2: _node_type = (TExprNodeType::DATE_LITERAL); break; @@ -191,6 +193,8 @@ Expr::Expr(const TypeDescriptor& type, bool is_slotref) break; case TYPE_DATETIME: + case TYPE_DATEV2: + case TYPE_DATETIMEV2: _node_type = (TExprNodeType::DATE_LITERAL); break; @@ -692,11 +696,17 @@ doris_udf::AnyVal* Expr::get_const_val(ExprContext* context) { break; } case TYPE_DATE: - case TYPE_DATETIME: { + case TYPE_DATETIME: + case TYPE_DATETIMEV2: { _constant_val.reset(new DateTimeVal(get_datetime_val(context, nullptr))); break; } + case TYPE_DATEV2: { + _constant_val.reset(new DateV2Val(get_datev2_val(context, nullptr))); + break; + } + case TYPE_DECIMALV2: { _constant_val.reset(new DecimalV2Val(get_decimalv2_val(context, nullptr))); break; @@ -806,6 +816,11 @@ DateTimeVal Expr::get_datetime_val(ExprContext* context, TupleRow* row) { return val; } +DateV2Val Expr::get_datev2_val(ExprContext* context, TupleRow* row) { + DateV2Val val; + return val; +} + DecimalV2Val Expr::get_decimalv2_val(ExprContext* context, TupleRow* row) { DecimalV2Val val; return val; diff --git a/be/src/exprs/expr.h b/be/src/exprs/expr.h index 9b114b664b..6d65910b7f 100644 --- a/be/src/exprs/expr.h +++ b/be/src/exprs/expr.h @@ -105,6 +105,7 @@ public: // virtual ArrayVal GetArrayVal(ExprContext* context, TupleRow*); virtual DateTimeVal get_datetime_val(ExprContext* context, TupleRow*); virtual DecimalV2Val get_decimalv2_val(ExprContext* context, TupleRow*); + virtual DateV2Val get_datev2_val(ExprContext* context, TupleRow*); virtual CollectionVal get_array_val(ExprContext* context, TupleRow*); virtual Decimal32Val get_decimal32_val(ExprContext* context, TupleRow*); diff --git a/be/src/exprs/expr_context.cpp b/be/src/exprs/expr_context.cpp index 139127b5c8..007372d786 100644 --- a/be/src/exprs/expr_context.cpp +++ b/be/src/exprs/expr_context.cpp @@ -257,7 +257,6 @@ void* ExprContext::get_value(Expr* e, TupleRow* row, int precision, int scale) { } case TYPE_DATE: case TYPE_DATETIME: - case TYPE_DATEV2: case TYPE_DATETIMEV2: { doris_udf::DateTimeVal v = e->get_datetime_val(this, row); if (v.is_null) { @@ -266,6 +265,14 @@ void* ExprContext::get_value(Expr* e, TupleRow* row, int precision, int scale) { _result.datetime_val = DateTimeValue::from_datetime_val(v); return &_result.datetime_val; } + case TYPE_DATEV2: { + doris_udf::DateV2Val v = e->get_datev2_val(this, row); + if (v.is_null) { + return nullptr; + } + _result.datev2_val = doris::vectorized::DateV2Value::from_datev2_val(v); + return &_result.datev2_val; + } case TYPE_DECIMALV2: { DecimalV2Val v = e->get_decimalv2_val(this, row); if (v.is_null) { @@ -370,6 +377,10 @@ DateTimeVal ExprContext::get_datetime_val(TupleRow* row) { return _root->get_datetime_val(this, row); } +DateV2Val ExprContext::get_datev2_val(TupleRow* row) { + return _root->get_datev2_val(this, row); +} + DecimalV2Val ExprContext::get_decimalv2_val(TupleRow* row) { return _root->get_decimalv2_val(this, row); } diff --git a/be/src/exprs/expr_context.h b/be/src/exprs/expr_context.h index 14cfa86df2..b8bda8fa48 100644 --- a/be/src/exprs/expr_context.h +++ b/be/src/exprs/expr_context.h @@ -126,6 +126,7 @@ public: // TODO(zc): // ArrayVal GetArrayVal(TupleRow* row); DateTimeVal get_datetime_val(TupleRow* row); + DateV2Val get_datev2_val(TupleRow* row); DecimalV2Val get_decimalv2_val(TupleRow* row); /// Frees all local allocations made by fn_contexts_. This can be called when result diff --git a/be/src/exprs/expr_value.h b/be/src/exprs/expr_value.h index ede221147e..12cc1dba6f 100644 --- a/be/src/exprs/expr_value.h +++ b/be/src/exprs/expr_value.h @@ -45,6 +45,7 @@ struct ExprValue { std::string string_data; StringValue string_val; DateTimeValue datetime_val; + doris::vectorized::DateV2Value datev2_val; DecimalV2Value decimalv2_val; CollectionValue array_val; diff --git a/be/src/exprs/literal.cpp b/be/src/exprs/literal.cpp index de0e214bfe..83db5f6ae0 100644 --- a/be/src/exprs/literal.cpp +++ b/be/src/exprs/literal.cpp @@ -81,11 +81,14 @@ Literal::Literal(const TExprNode& node) : Expr(node) { break; case TYPE_DATE: case TYPE_DATETIME: - case TYPE_DATEV2: case TYPE_DATETIMEV2: _value.datetime_val.from_date_str(node.date_literal.value.c_str(), node.date_literal.value.size()); break; + case TYPE_DATEV2: + _value.datev2_val.from_date_str(node.date_literal.value.c_str(), + node.date_literal.value.size()); + break; case TYPE_CHAR: case TYPE_VARCHAR: case TYPE_STRING: @@ -210,6 +213,12 @@ DateTimeVal Literal::get_datetime_val(ExprContext* context, TupleRow* row) { return dt_val; } +DateV2Val Literal::get_datev2_val(ExprContext* context, TupleRow* row) { + DateV2Val dt_val; + _value.datev2_val.to_datev2_val(&dt_val); + return dt_val; +} + StringVal Literal::get_string_val(ExprContext* context, TupleRow* row) { DCHECK(_type.is_string_type()) << _type; StringVal str_val; diff --git a/be/src/exprs/literal.h b/be/src/exprs/literal.h index 87372b1590..9637b3038c 100644 --- a/be/src/exprs/literal.h +++ b/be/src/exprs/literal.h @@ -44,6 +44,7 @@ public: virtual DoubleVal get_double_val(ExprContext* context, TupleRow*) override; virtual DecimalV2Val get_decimalv2_val(ExprContext* context, TupleRow*) override; virtual DateTimeVal get_datetime_val(ExprContext* context, TupleRow*) override; + virtual DateV2Val get_datev2_val(ExprContext* context, TupleRow*) override; virtual StringVal get_string_val(ExprContext* context, TupleRow* row) override; virtual CollectionVal get_array_val(ExprContext* context, TupleRow*) override; virtual Decimal32Val get_decimal32_val(ExprContext* context, TupleRow*) override; diff --git a/be/src/exprs/scalar_fn_call.cpp b/be/src/exprs/scalar_fn_call.cpp index c5e2b61b0f..86140761d4 100644 --- a/be/src/exprs/scalar_fn_call.cpp +++ b/be/src/exprs/scalar_fn_call.cpp @@ -355,6 +355,7 @@ typedef FloatVal (*FloatWrapper)(ExprContext*, TupleRow*); typedef DoubleVal (*DoubleWrapper)(ExprContext*, TupleRow*); typedef StringVal (*StringWrapper)(ExprContext*, TupleRow*); typedef DateTimeVal (*DatetimeWrapper)(ExprContext*, TupleRow*); +typedef DateV2Val (*DateV2Wrapper)(ExprContext*, TupleRow*); typedef DecimalV2Val (*DecimalV2Wrapper)(ExprContext*, TupleRow*); typedef Decimal32Val (*Decimal32Wrapper)(ExprContext*, TupleRow*); typedef Decimal64Val (*Decimal64Wrapper)(ExprContext*, TupleRow*); @@ -454,7 +455,7 @@ StringVal ScalarFnCall::get_string_val(ExprContext* context, TupleRow* row) { } DateTimeVal ScalarFnCall::get_datetime_val(ExprContext* context, TupleRow* row) { - DCHECK(_type.is_date_type()); + DCHECK(_type.is_date_type() || _type.is_date_v2_type()); DCHECK(context != nullptr); if (_scalar_fn_wrapper == nullptr) { return interpret_eval<DateTimeVal>(context, row); @@ -463,6 +464,16 @@ DateTimeVal ScalarFnCall::get_datetime_val(ExprContext* context, TupleRow* row) return fn(context, row); } +DateV2Val ScalarFnCall::get_datev2_val(ExprContext* context, TupleRow* row) { + DCHECK(_type.is_date_v2_type()); + DCHECK(context != nullptr); + if (_scalar_fn_wrapper == nullptr) { + return interpret_eval<DateV2Val>(context, row); + } + DateV2Wrapper fn = reinterpret_cast<DateV2Wrapper>(_scalar_fn_wrapper); + return fn(context, row); +} + DecimalV2Val ScalarFnCall::get_decimalv2_val(ExprContext* context, TupleRow* row) { DCHECK_EQ(_type.type, TYPE_DECIMALV2); DCHECK(context != nullptr); diff --git a/be/src/exprs/scalar_fn_call.h b/be/src/exprs/scalar_fn_call.h index 97287c37c7..0e4f297c57 100644 --- a/be/src/exprs/scalar_fn_call.h +++ b/be/src/exprs/scalar_fn_call.h @@ -84,6 +84,7 @@ protected: virtual doris_udf::DoubleVal get_double_val(ExprContext* context, TupleRow*) override; virtual doris_udf::StringVal get_string_val(ExprContext* context, TupleRow*) override; virtual doris_udf::DateTimeVal get_datetime_val(ExprContext* context, TupleRow*) override; + virtual doris_udf::DateV2Val get_datev2_val(ExprContext* context, TupleRow*) override; virtual doris_udf::DecimalV2Val get_decimalv2_val(ExprContext* context, TupleRow*) override; virtual CollectionVal get_array_val(ExprContext* context, TupleRow*) override; diff --git a/be/src/exprs/slot_ref.cpp b/be/src/exprs/slot_ref.cpp index 666b427565..d6893eedce 100644 --- a/be/src/exprs/slot_ref.cpp +++ b/be/src/exprs/slot_ref.cpp @@ -225,6 +225,19 @@ DateTimeVal SlotRef::get_datetime_val(ExprContext* context, TupleRow* row) { return result; } +DateV2Val SlotRef::get_datev2_val(ExprContext* context, TupleRow* row) { + DCHECK(_type.is_date_type()); + Tuple* t = row->get_tuple(_tuple_idx); + if (t == nullptr || t->is_null(_null_indicator_offset)) { + return DateV2Val::null(); + } + doris::vectorized::DateV2Value* tv = + reinterpret_cast<doris::vectorized::DateV2Value*>(t->get_slot(_slot_offset)); + DateV2Val result; + tv->to_datev2_val(&result); + return result; +} + DecimalV2Val SlotRef::get_decimalv2_val(ExprContext* context, TupleRow* row) { DCHECK_EQ(_type.type, TYPE_DECIMALV2); Tuple* t = row->get_tuple(_tuple_idx); diff --git a/be/src/exprs/slot_ref.h b/be/src/exprs/slot_ref.h index 0e916dff9f..009b841e56 100644 --- a/be/src/exprs/slot_ref.h +++ b/be/src/exprs/slot_ref.h @@ -69,6 +69,7 @@ public: virtual doris_udf::DoubleVal get_double_val(ExprContext* context, TupleRow* row) override; virtual doris_udf::StringVal get_string_val(ExprContext* context, TupleRow*) override; virtual doris_udf::DateTimeVal get_datetime_val(ExprContext* context, TupleRow*) override; + virtual doris_udf::DateV2Val get_datev2_val(ExprContext* context, TupleRow*) override; virtual doris_udf::DecimalV2Val get_decimalv2_val(ExprContext* context, TupleRow*) override; virtual doris_udf::CollectionVal get_array_val(ExprContext* context, TupleRow*) override; virtual Decimal32Val get_decimal32_val(ExprContext* context, TupleRow*) override; diff --git a/be/src/runtime/primitive_type.h b/be/src/runtime/primitive_type.h index bbe473e212..adf1acadd4 100644 --- a/be/src/runtime/primitive_type.h +++ b/be/src/runtime/primitive_type.h @@ -147,6 +147,11 @@ struct PrimitiveTypeTraits<TYPE_DATETIME> { using ColumnType = vectorized::ColumnVector<vectorized::DateTime>; }; template <> +struct PrimitiveTypeTraits<TYPE_DATETIMEV2> { + using CppType = doris::DateTimeValue; + using ColumnType = vectorized::ColumnVector<vectorized::DateTime>; +}; +template <> struct PrimitiveTypeTraits<TYPE_DATEV2> { using CppType = doris::vectorized::DateV2Value; using ColumnType = vectorized::ColumnVector<vectorized::DateV2>; diff --git a/be/src/udf/udf.h b/be/src/udf/udf.h index c74d566d42..d0ce5eb264 100644 --- a/be/src/udf/udf.h +++ b/be/src/udf/udf.h @@ -52,6 +52,7 @@ struct IntVal; struct BigIntVal; struct StringVal; struct DateTimeVal; +struct DateV2Val; struct DecimalV2Val; struct HllVal; struct CollectionVal; @@ -680,6 +681,32 @@ struct DateTimeVal : public AnyVal { bool operator!=(const DateTimeVal& other) const { return !(*this == other); } }; +struct DateV2Val : public AnyVal { + uint32_t datev2_value; + + DateV2Val() {} + DateV2Val(uint32_t val) : datev2_value(val) {} + + static DateV2Val null() { + DateV2Val result; + result.is_null = true; + return result; + } + + bool operator==(const DateV2Val& other) const { + if (is_null && other.is_null) { + return true; + } + + if (is_null || other.is_null) { + return false; + } + + return datev2_value == other.datev2_value; + } + bool operator!=(const DateV2Val& other) const { return !(*this == other); } +}; + // Note: there is a difference between a nullptr string (is_null == true) and an // empty string (len == 0). struct StringVal : public AnyVal { diff --git a/be/src/util/symbols_util.cpp b/be/src/util/symbols_util.cpp index c5ff9b8b37..d60de4224b 100644 --- a/be/src/util/symbols_util.cpp +++ b/be/src/util/symbols_util.cpp @@ -159,8 +159,12 @@ static void append_any_val_type(int namespace_id, const TypeDescriptor& type, break; case TYPE_DATE: case TYPE_DATETIME: + case TYPE_DATETIMEV2: append_mangled_token("DateTimeVal", s); break; + case TYPE_DATEV2: + append_mangled_token("DateV2Val", s); + break; case TYPE_DECIMALV2: append_mangled_token("DecimalV2Val", s); break; diff --git a/be/src/vec/exprs/vliteral.cpp b/be/src/vec/exprs/vliteral.cpp index 9936733c5c..514f6df070 100644 --- a/be/src/vec/exprs/vliteral.cpp +++ b/be/src/vec/exprs/vliteral.cpp @@ -102,7 +102,8 @@ void VLiteral::init(const TExprNode& node) { field = value.to_date_uint32(); break; } - case TYPE_DATETIME: { + case TYPE_DATETIME: + case TYPE_DATETIMEV2: { VecDateTimeValue value; value.from_date_str(node.date_literal.value.c_str(), node.date_literal.value.size()); value.to_datetime(); diff --git a/be/src/vec/runtime/vdatetime_value.h b/be/src/vec/runtime/vdatetime_value.h index b437d409c5..9d0c58d70c 100644 --- a/be/src/vec/runtime/vdatetime_value.h +++ b/be/src/vec/runtime/vdatetime_value.h @@ -934,6 +934,16 @@ public: bool get_date_from_daynr(uint64_t); + void to_datev2_val(doris_udf::DateV2Val* tv) const { + tv->datev2_value = this->to_date_uint32(); + } + + static DateV2Value from_datev2_val(const doris_udf::DateV2Val& tv) { + DateV2Value value; + value.from_date(tv.datev2_value); + return value; + } + private: static uint8_t calc_week(const uint32_t& day_nr, const uint16_t& year, const uint8_t& month, const uint8_t& day, uint8_t mode, uint16_t* to_year); diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/CastExpr.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/CastExpr.java index 1ada8c8e4c..26c2b473e9 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/CastExpr.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/CastExpr.java @@ -167,10 +167,12 @@ public class CastExpr extends Expr { } String typeName = Function.getUdfTypeName(toType.getPrimitiveType()); // only refactor date/datetime for vectorized engine. - if (toType.getPrimitiveType() == PrimitiveType.DATE - || toType.getPrimitiveType() == PrimitiveType.DATEV2) { + if (toType.getPrimitiveType() == PrimitiveType.DATE) { typeName = "date_val"; } + if (toType.getPrimitiveType() == PrimitiveType.DATEV2) { + typeName = "datev2_val"; + } String beSymbol = "doris::" + beClass + "::cast_to_" + typeName; functionSet.addBuiltinBothScalaAndVectorized(ScalarFunction.createBuiltin(getFnName(toType), diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/DateLiteral.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/DateLiteral.java index fffa15adf4..b3ddb4a692 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/DateLiteral.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/DateLiteral.java @@ -175,7 +175,7 @@ public class DateLiteral extends LiteralExpr { public DateLiteral(Type type, boolean isMax) throws AnalysisException { super(); this.type = type; - if (type.equals(Type.DATE)) { + if (type.equals(Type.DATE) || type.equals(Type.DATEV2)) { if (isMax) { copy(MAX_DATE); } else { @@ -479,9 +479,10 @@ public class DateLiteral extends LiteralExpr { return this; } if (targetType.equals(Type.DATE) || targetType.equals(Type.DATEV2)) { - return new DateLiteral(this.year, this.month, this.day); + return new DateLiteral(this.year, this.month, this.day, targetType); } else if (targetType.equals(Type.DATETIME)) { - return new DateLiteral(this.year, this.month, this.day, this.hour, this.minute, this.second); + return new DateLiteral(this.year, this.month, this.day, this.hour, this.minute, this.second, + targetType); } else if (targetType.isDatetimeV2()) { return new DateLiteral(this.year, this.month, this.day, this.hour, this.minute, this.microsecond, targetType); diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/Function.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/Function.java index 652b81519c..3d01355ca0 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/Function.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/Function.java @@ -519,9 +519,10 @@ public class Function implements Writable { return "string_val"; case DATE: case DATETIME: - case DATEV2: case DATETIMEV2: return "datetime_val"; + case DATEV2: + return "datev2_val"; case DECIMALV2: return "decimalv2_val"; case DECIMAL32: @@ -567,9 +568,10 @@ public class Function implements Writable { return "StringVal"; case DATE: case DATETIME: - case DATEV2: case DATETIMEV2: return "DateTimeVal"; + case DATEV2: + return "DateV2Val"; case DECIMALV2: return "DecimalV2Val"; case DECIMAL32: diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java index 8a1a4b0c81..ed895641bb 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java @@ -1388,6 +1388,19 @@ public class FunctionSet<T> { "", "", true, false, true, true)); + addBuiltin(AggregateFunction.createBuiltin(FunctionSet.WINDOW_FUNNEL, + Lists.newArrayList(Type.BIGINT, Type.STRING, Type.DATEV2, Type.BOOLEAN), + Type.INT, + Type.VARCHAR, + true, + "", + "", + "", + "", + "", + "", + "", + true, false, true, true)); for (Type t : Type.getSupportedTypes()) { if (t.isNull()) { @@ -2328,7 +2341,7 @@ public class FunctionSet<T> { // collect_list Type[] arraySubTypes = {Type.BOOLEAN, Type.SMALLINT, Type.TINYINT, Type.INT, Type.BIGINT, Type.LARGEINT, Type.FLOAT, Type.DOUBLE, Type.DATE, Type.DATETIME, Type.DECIMALV2, Type.DECIMAL32, Type.DECIMAL64, - Type.DECIMAL128, Type.VARCHAR, Type.STRING}; + Type.DECIMAL128, Type.VARCHAR, Type.STRING, Type.DATEV2}; for (Type t : arraySubTypes) { addBuiltin(AggregateFunction.createBuiltin(COLLECT_LIST, Lists.newArrayList(t), new ArrayType(t), t, "", "", "", "", "", true, false, true, true)); @@ -2462,6 +2475,16 @@ public class FunctionSet<T> { prefix + "20timestamp_avg_removeEPN9doris_udf15FunctionContextERKNS1_11DateTimeValEPNS1_9StringValE", prefix + "22timestamp_avg_finalizeEPN9doris_udf15FunctionContextERKNS1_9StringValE", false, true, false, true)); + addBuiltin(AggregateFunction.createBuiltin("avg", + Lists.<Type>newArrayList(Type.DATEV2), Type.DATEV2, Type.DATEV2, + prefix + "8avg_initEPN9doris_udf15FunctionContextEPNS1_9StringValE", + prefix + "20timestamp_avg_updateEPN9doris_udf15FunctionContextERKNS1_11DateTimeValEPNS1_9StringValE", + prefix + "9avg_mergeEPN9doris_udf15FunctionContextERKNS1_9StringValEPS4_", + stringValSerializeOrFinalize, + prefix + "23timestamp_avg_get_valueEPN9doris_udf15FunctionContextERKNS1_9StringValE", + prefix + "20timestamp_avg_removeEPN9doris_udf15FunctionContextERKNS1_11DateTimeValEPNS1_9StringValE", + prefix + "22timestamp_avg_finalizeEPN9doris_udf15FunctionContextERKNS1_9StringValE", + false, true, false, true)); // Group_concat(string) addBuiltin(AggregateFunction.createBuiltin("group_concat", Lists.<Type>newArrayList(Type.VARCHAR), Type.VARCHAR, diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/ScalarType.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/ScalarType.java index 1bf64eb011..88231ba22d 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/ScalarType.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/ScalarType.java @@ -730,15 +730,6 @@ public class ScalarType extends Type { return false; } ScalarType other = (ScalarType) o; - if ((this.isDate() && other.isDateV2()) || (this.isDateV2() && other.isDate())) { - return true; - } - if ((this.isDatetime() && other.isDatetimeV2()) || (this.isTime() && other.isTimeV2())) { - return other.decimalScale() == 0; - } - if ((this.isDatetimeV2() && other.isDatetime()) || (this.isTimeV2() && other.isTime())) { - return this.decimalScale() == 0; - } if ((this.isDatetimeV2() && other.isDatetimeV2()) || (this.isTimeV2() && other.isTimeV2())) { return this.decimalScale() == other.decimalScale(); } @@ -757,6 +748,10 @@ public class ScalarType extends Type { if (type.isDecimalV2Type() || type == PrimitiveType.DATETIMEV2 || type == PrimitiveType.TIMEV2) { return precision == other.precision && scale == other.scale; } + if (type == PrimitiveType.DATETIMEV2 || type == PrimitiveType.TIMEV2) { + return precision == other.precision && scale == other.scale + && type == ((ScalarType) o).getPrimitiveType(); + } return true; } diff --git a/fe/fe-core/src/test/java/org/apache/doris/catalog/ColumnTypeTest.java b/fe/fe-core/src/test/java/org/apache/doris/catalog/ColumnTypeTest.java index 98cb7b3b92..1e267a3258 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/catalog/ColumnTypeTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/catalog/ColumnTypeTest.java @@ -141,7 +141,7 @@ public class ColumnTypeTest { TypeDef type5 = TypeDef.createDatetimeV2(0); TypeDef type6 = TypeDef.create(PrimitiveType.DATETIME); - Assert.assertEquals(type5.getType(), type6.getType()); + Assert.assertNotEquals(type5.getType(), type6.getType()); Assert.assertNotEquals(type.getType(), type6.getType()); } @@ -150,7 +150,7 @@ public class ColumnTypeTest { TypeDef type = TypeDef.create(PrimitiveType.DATE); TypeDef type2 = TypeDef.create(PrimitiveType.DATEV2); type.analyze(null); - Assert.assertEquals(type.getType(), type2.getType()); + Assert.assertNotEquals(type.getType(), type2.getType()); // different type TypeDef type3 = TypeDef.createDatetimeV2(6); @@ -182,7 +182,7 @@ public class ColumnTypeTest { TypeDef type5 = TypeDef.createTimeV2(0); TypeDef type6 = TypeDef.create(PrimitiveType.TIME); - Assert.assertEquals(type5.getType(), type6.getType()); + Assert.assertNotEquals(type5.getType(), type6.getType()); Assert.assertNotEquals(type.getType(), type6.getType()); } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org