diff --git a/be/src/exec/exec_node.cpp b/be/src/exec/exec_node.cpp index 0a854ba89b..be48218fb6 100644 --- a/be/src/exec/exec_node.cpp +++ b/be/src/exec/exec_node.cpp @@ -213,7 +213,9 @@ Status ExecNode::prepare(RuntimeState* state) { if (_vconjunct_ctx_ptr) { RETURN_IF_ERROR((*_vconjunct_ctx_ptr)->prepare(state, _row_descriptor)); } - RETURN_IF_ERROR(Expr::prepare(_conjunct_ctxs, state, _row_descriptor)); + if (typeid(*this) != typeid(doris::vectorized::VOlapScanNode)) { + RETURN_IF_ERROR(Expr::prepare(_conjunct_ctxs, state, _row_descriptor)); + } // TODO(zc): // AddExprCtxsToFree(_conjunct_ctxs); @@ -229,7 +231,11 @@ Status ExecNode::open(RuntimeState* state) { if (_vconjunct_ctx_ptr) { RETURN_IF_ERROR((*_vconjunct_ctx_ptr)->open(state)); } - return Expr::open(_conjunct_ctxs, state); + if (typeid(*this) != typeid(doris::vectorized::VOlapScanNode)) { + return Expr::open(_conjunct_ctxs, state); + } else { + return Status::OK(); + } } Status ExecNode::reset(RuntimeState* state) { @@ -267,7 +273,9 @@ Status ExecNode::close(RuntimeState* state) { } if (_vconjunct_ctx_ptr) (*_vconjunct_ctx_ptr)->close(state); - Expr::close(_conjunct_ctxs, state); + if (typeid(*this) != typeid(doris::vectorized::VOlapScanNode)) { + Expr::close(_conjunct_ctxs, state); + } if (_buffer_pool_client.is_registered()) { VLOG_FILE << _id << " returning reservation " << _resource_profile.min_reservation; diff --git a/be/src/exec/tablet_info.cpp b/be/src/exec/tablet_info.cpp index 0fd5e24032..c89e03f0be 100644 --- a/be/src/exec/tablet_info.cpp +++ b/be/src/exec/tablet_info.cpp @@ -331,11 +331,33 @@ Status OlapTablePartitionParam::_create_partition_key(const TExprNode& t_expr, T tuple->set_not_null(slot_desc->null_indicator_offset()); switch (t_expr.node_type) { case TExprNodeType::DATE_LITERAL: { - if (!reinterpret_cast(slot)->from_date_str( - t_expr.date_literal.value.c_str(), t_expr.date_literal.value.size())) { - std::stringstream ss; - ss << "invalid date literal in partition column, date=" << t_expr.date_literal; - return Status::InternalError(ss.str()); + if ((t_expr.type.types[0].scalar_type.type == TPrimitiveType::DATE) || + (t_expr.type.types[0].scalar_type.type == TPrimitiveType::DATETIME)) { + if (!reinterpret_cast(slot)->from_date_str( + t_expr.date_literal.value.c_str(), t_expr.date_literal.value.size())) { + std::stringstream ss; + ss << "invalid date literal in partition column, date=" << t_expr.date_literal; + return Status::InternalError(ss.str()); + } + } else if (t_expr.type.types[0].scalar_type.type == TPrimitiveType::DATEV2) { + if (!reinterpret_cast< + doris::vectorized::DateV2Value*>(slot) + ->from_date_str(t_expr.date_literal.value.c_str(), + t_expr.date_literal.value.size())) { + std::stringstream ss; + ss << "invalid date literal in partition column, date=" << t_expr.date_literal; + return Status::InternalError(ss.str()); + } + } else { + if (!reinterpret_cast< + doris::vectorized::DateV2Value*>( + slot) + ->from_date_str(t_expr.date_literal.value.c_str(), + t_expr.date_literal.value.size())) { + std::stringstream ss; + ss << "invalid date literal in partition column, date=" << t_expr.date_literal; + return Status::InternalError(ss.str()); + } } break; } diff --git a/be/src/exprs/hybrid_set.h b/be/src/exprs/hybrid_set.h index 16b740e951..e43b2c29ea 100644 --- a/be/src/exprs/hybrid_set.h +++ b/be/src/exprs/hybrid_set.h @@ -51,6 +51,8 @@ public: virtual Status to_vexpr_list(doris::ObjectPool* pool, std::vector* vexpr_list, int precision, int scale) = 0; + + virtual bool is_date_v2() { return false; } class IteratorBase { public: IteratorBase() {} @@ -73,6 +75,8 @@ public: ~HybridSet() override = default; + bool is_date_v2() override { return T == TYPE_DATEV2; } + Status to_vexpr_list(doris::ObjectPool* pool, std::vector* vexpr_list, int precision, int scale) override { diff --git a/be/src/olap/rowset/segment_v2/bloom_filter_index_writer.cpp b/be/src/olap/rowset/segment_v2/bloom_filter_index_writer.cpp index 62ee2ede53..e6376ad4c1 100644 --- a/be/src/olap/rowset/segment_v2/bloom_filter_index_writer.cpp +++ b/be/src/olap/rowset/segment_v2/bloom_filter_index_writer.cpp @@ -210,6 +210,13 @@ Status BloomFilterIndexWriter::create(const BloomFilterOptions& bf_options, case OLAP_FIELD_TYPE_DECIMAL: res->reset(new BloomFilterIndexWriterImpl(bf_options, type_info)); break; + case OLAP_FIELD_TYPE_DATEV2: + res->reset(new BloomFilterIndexWriterImpl(bf_options, type_info)); + break; + case OLAP_FIELD_TYPE_DATETIMEV2: + res->reset( + new BloomFilterIndexWriterImpl(bf_options, type_info)); + break; default: return Status::NotSupported("unsupported type for bitmap index: {}", std::to_string(type)); } diff --git a/be/src/olap/rowset/segment_v2/segment_iterator.cpp b/be/src/olap/rowset/segment_v2/segment_iterator.cpp index 24035a62fc..3b91bbc024 100644 --- a/be/src/olap/rowset/segment_v2/segment_iterator.cpp +++ b/be/src/olap/rowset/segment_v2/segment_iterator.cpp @@ -908,10 +908,6 @@ void SegmentIterator::_init_current_block( current_columns[cid]->set_date_type(); } else if (column_desc->type() == OLAP_FIELD_TYPE_DATETIME) { current_columns[cid]->set_datetime_type(); - } else if (column_desc->type() == OLAP_FIELD_TYPE_DATEV2) { - current_columns[cid]->set_date_v2_type(); - } else if (column_desc->type() == OLAP_FIELD_TYPE_DATETIMEV2) { - current_columns[cid]->set_datetime_v2_type(); } else if (column_desc->type() == OLAP_FIELD_TYPE_DECIMAL) { current_columns[cid]->set_decimalv2_type(); } diff --git a/be/src/vec/columns/column.h b/be/src/vec/columns/column.h index cdc6fed9bf..002fc8eea3 100644 --- a/be/src/vec/columns/column.h +++ b/be/src/vec/columns/column.h @@ -513,22 +513,16 @@ public: virtual void replace_column_data_default(size_t self_row = 0) = 0; virtual bool is_date_type() const { return is_date; } - virtual bool is_date_v2_type() const { return is_date_v2; } - virtual bool is_datetime_v2_type() const { return is_datetime_v2; } virtual bool is_datetime_type() const { return is_date_time; } virtual bool is_decimalv2_type() const { return is_decimalv2; } virtual void set_date_type() { is_date = true; } - virtual void set_date_v2_type() { is_date_v2 = true; } - virtual void set_datetime_v2_type() { is_datetime_v2 = true; } virtual void set_datetime_type() { is_date_time = true; } virtual void set_decimalv2_type() { is_decimalv2 = true; } // todo(wb): a temporary implemention, need re-abstract here bool is_date = false; bool is_date_time = false; - bool is_date_v2 = false; - bool is_datetime_v2 = false; bool is_decimalv2 = false; protected: diff --git a/be/src/vec/columns/column_nullable.h b/be/src/vec/columns/column_nullable.h index 37249a858a..c9268118df 100644 --- a/be/src/vec/columns/column_nullable.h +++ b/be/src/vec/columns/column_nullable.h @@ -180,12 +180,9 @@ public: } bool is_date_type() const override { return get_nested_column().is_date_type(); } - bool is_date_v2_type() const override { return get_nested_column().is_date_v2_type(); } - bool is_datetime_v2_type() const override { return get_nested_column().is_datetime_v2_type(); } bool is_datetime_type() const override { return get_nested_column().is_datetime_type(); } bool is_decimalv2_type() const override { return get_nested_column().is_decimalv2_type(); } void set_date_type() override { get_nested_column().set_date_type(); } - void set_date_v2_type() override { get_nested_column().set_date_v2_type(); } void set_datetime_type() override { get_nested_column().set_datetime_type(); } void set_decimalv2_type() override { get_nested_column().set_decimalv2_type(); } diff --git a/be/src/vec/data_types/data_type_time_v2.cpp b/be/src/vec/data_types/data_type_time_v2.cpp index a9f1a27098..04e1789a45 100644 --- a/be/src/vec/data_types/data_type_time_v2.cpp +++ b/be/src/vec/data_types/data_type_time_v2.cpp @@ -49,20 +49,18 @@ void DataTypeDateV2::to_string(const IColumn& column, size_t row_num, BufferWrit } MutableColumnPtr DataTypeDateV2::create_column() const { - auto col = DataTypeNumberBase::create_column(); - col->set_date_v2_type(); - return col; + return DataTypeNumberBase::create_column(); } void DataTypeDateV2::cast_to_date_time(const UInt32 from, Int64& to) { - auto& to_value = (doris::vectorized::VecDateTimeValue&)to; - auto& from_value = (doris::vectorized::DateV2Value&)from; + auto& to_value = (VecDateTimeValue&)to; + auto& from_value = (DateV2Value&)from; to_value.create_from_date_v2(from_value, TimeType::TIME_DATETIME); } void DataTypeDateV2::cast_to_date(const UInt32 from, Int64& to) { - auto& to_value = (doris::vectorized::VecDateTimeValue&)(to); - auto& from_value = (doris::vectorized::DateV2Value&)from; + auto& to_value = (VecDateTimeValue&)(to); + auto& from_value = (DateV2Value&)from; to_value.create_from_date_v2(from_value, TimeType::TIME_DATE); } @@ -70,6 +68,18 @@ void DataTypeDateV2::cast_to_date_time_v2(const UInt32 from, UInt64& to) { to = ((UInt64)from) << TIME_PART_LENGTH; } +void DataTypeDateV2::cast_from_date(const Int64 from, UInt32& to) { + auto& to_value = (DateV2Value&)(to); + auto from_value = binary_cast(from); + to_value.set_time(from_value.year(), from_value.month(), from_value.day(), 0, 0, 0, 0); +} + +void DataTypeDateV2::cast_from_date_time(const Int64 from, UInt32& to) { + auto& to_value = (DateV2Value&)(to); + auto from_value = binary_cast(from); + to_value.set_time(from_value.year(), from_value.month(), from_value.day(), 0, 0, 0, 0); +} + bool DataTypeDateTimeV2::equals(const IDataType& rhs) const { return typeid(rhs) == typeid(*this); } @@ -100,23 +110,35 @@ void DataTypeDateTimeV2::to_string(const IColumn& column, size_t row_num, } MutableColumnPtr DataTypeDateTimeV2::create_column() const { - auto col = DataTypeNumberBase::create_column(); - col->set_datetime_v2_type(); - return col; + return DataTypeNumberBase::create_column(); } void DataTypeDateTimeV2::cast_to_date_time(const UInt64 from, Int64& to) { - auto& to_value = (doris::vectorized::VecDateTimeValue&)to; - auto& from_value = (doris::vectorized::DateV2Value&)from; + auto& to_value = (VecDateTimeValue&)to; + auto& from_value = (DateV2Value&)from; to_value.create_from_date_v2(from_value, TimeType::TIME_DATETIME); } void DataTypeDateTimeV2::cast_to_date(const UInt64 from, Int64& to) { - auto& to_value = (doris::vectorized::VecDateTimeValue&)(to); - auto& from_value = (doris::vectorized::DateV2Value&)from; + auto& to_value = (VecDateTimeValue&)(to); + auto& from_value = (DateV2Value&)from; to_value.create_from_date_v2(from_value, TimeType::TIME_DATE); } +void DataTypeDateTimeV2::cast_from_date(const Int64 from, UInt64& to) { + auto& to_value = (DateV2Value&)(to); + auto from_value = binary_cast(from); + to_value.set_time(from_value.year(), from_value.month(), from_value.day(), from_value.hour(), + from_value.minute(), from_value.second(), 0); +} + +void DataTypeDateTimeV2::cast_from_date_time(const Int64 from, UInt64& to) { + auto& to_value = (DateV2Value&)(to); + auto from_value = binary_cast(from); + to_value.set_time(from_value.year(), from_value.month(), from_value.day(), from_value.hour(), + from_value.minute(), from_value.second(), 0); +} + void DataTypeDateTimeV2::cast_to_date_v2(const UInt64 from, UInt32& to) { to = from >> TIME_PART_LENGTH; } diff --git a/be/src/vec/data_types/data_type_time_v2.h b/be/src/vec/data_types/data_type_time_v2.h index 0efff481e6..d2a6cefae6 100644 --- a/be/src/vec/data_types/data_type_time_v2.h +++ b/be/src/vec/data_types/data_type_time_v2.h @@ -43,6 +43,8 @@ public: static void cast_to_date(const UInt32 from, Int64& to); static void cast_to_date_time(const UInt32 from, Int64& to); static void cast_to_date_time_v2(const UInt32 from, UInt64& to); + static void cast_from_date(const Int64 from, UInt32& to); + static void cast_from_date_time(const Int64 from, UInt32& to); }; class DataTypeDateTimeV2 final : public DataTypeNumberBase { @@ -74,6 +76,8 @@ public: static void cast_to_date(const UInt64 from, Int64& to); static void cast_to_date_time(const UInt64 from, Int64& to); static void cast_to_date_v2(const UInt64 from, UInt32& to); + static void cast_from_date(const Int64 from, UInt64& to); + static void cast_from_date_time(const Int64 from, UInt64& to); private: UInt32 scale_; diff --git a/be/src/vec/exec/volap_scan_node.cpp b/be/src/vec/exec/volap_scan_node.cpp index 6d69643bb8..cd4b3bb42d 100644 --- a/be/src/vec/exec/volap_scan_node.cpp +++ b/be/src/vec/exec/volap_scan_node.cpp @@ -811,7 +811,8 @@ static bool ignore_cast(SlotDescriptor* slot, VExpr* expr) { template Status VOlapScanNode::change_value_range(ColumnValueRange& temp_range, void* value, const ChangeFixedValueRangeFunc& func, - const std::string& fn_name, int slot_ref_child) { + const std::string& fn_name, bool cast_date_to_datetime, + int slot_ref_child) { if constexpr (PrimitiveType == TYPE_DATE) { DateTimeValue date_value; reinterpret_cast(value)->convert_vec_dt_to_dt(&date_value); @@ -844,27 +845,39 @@ Status VOlapScanNode::change_value_range(ColumnValueRange& temp_r reinterpret_cast(&date_value))); } } else if constexpr (PrimitiveType == TYPE_DATEV2) { - DateV2Value datetimev2_value = - *reinterpret_cast*>(value); - if constexpr (IsFixed) { - if (datetimev2_value.can_cast_to_date_without_loss_accuracy()) { - DateV2Value date_v2; + if (cast_date_to_datetime) { + DateV2Value datetimev2_value = + *reinterpret_cast*>(value); + if constexpr (IsFixed) { + if (datetimev2_value.can_cast_to_date_without_loss_accuracy()) { + DateV2Value date_v2; + date_v2.set_date_uint32(binary_cast, uint64_t>( + datetimev2_value) >> + TIME_PART_LENGTH); + func(temp_range, &date_v2); + } + } else { + doris::vectorized::DateV2Value date_v2; date_v2.set_date_uint32( binary_cast, uint64_t>(datetimev2_value) >> TIME_PART_LENGTH); - func(temp_range, &date_v2); + if (!datetimev2_value.can_cast_to_date_without_loss_accuracy()) { + if (fn_name == "lt" || fn_name == "ge") { + ++date_v2; + } + } + func(temp_range, to_olap_filter_type(fn_name, slot_ref_child), &date_v2); } } else { - doris::vectorized::DateV2Value date_v2; - date_v2.set_date_uint32( - binary_cast, uint64_t>(datetimev2_value) >> - TIME_PART_LENGTH); - if (!datetimev2_value.can_cast_to_date_without_loss_accuracy()) { - if (fn_name == "lt" || fn_name == "ge") { - ++date_v2; - } + if constexpr (IsFixed) { + func(temp_range, + reinterpret_cast::CppType*>( + value)); + } else { + func(temp_range, to_olap_filter_type(fn_name, slot_ref_child), + reinterpret_cast::CppType*>( + value)); } - func(temp_range, to_olap_filter_type(fn_name, slot_ref_child), &date_v2); } } else if constexpr ((PrimitiveType == TYPE_DECIMALV2) || (PrimitiveType == TYPE_CHAR) || (PrimitiveType == TYPE_VARCHAR) || (PrimitiveType == TYPE_HLL) || @@ -1503,8 +1516,9 @@ Status VOlapScanNode::_normalize_in_and_eq_predicate(VExpr* expr, VExprContext* continue; } auto value = const_cast(iter->get_value()); - RETURN_IF_ERROR(change_value_range( - temp_range, value, ColumnValueRange::add_fixed_value_range, fn_name)); + RETURN_IF_ERROR(change_value_range(temp_range, value, + ColumnValueRange::add_fixed_value_range, + fn_name, !state->hybrid_set->is_date_v2())); iter->next(); } @@ -1577,10 +1591,12 @@ Status VOlapScanNode::_normalize_not_in_and_not_eq_predicate(VExpr* expr, VExprC auto value = const_cast(iter->get_value()); if (is_fixed_range) { RETURN_IF_ERROR(change_value_range( - range, value, ColumnValueRange::remove_fixed_value_range, fn_name)); + range, value, ColumnValueRange::remove_fixed_value_range, fn_name, + !state->hybrid_set->is_date_v2())); } else { RETURN_IF_ERROR(change_value_range( - not_in_range, value, ColumnValueRange::add_fixed_value_range, fn_name)); + not_in_range, value, ColumnValueRange::add_fixed_value_range, fn_name, + !state->hybrid_set->is_date_v2())); } iter->next(); } @@ -1687,11 +1703,11 @@ Status VOlapScanNode::_normalize_noneq_binary_predicate(VExpr* expr, VExprContex auto val = StringValue(value.data, value.size); RETURN_IF_ERROR(change_value_range(range, reinterpret_cast(&val), ColumnValueRange::add_value_range, - fn_name, slot_ref_child)); + fn_name, true, slot_ref_child)); } else { RETURN_IF_ERROR(change_value_range( range, reinterpret_cast(const_cast(value.data)), - ColumnValueRange::add_value_range, fn_name, slot_ref_child)); + ColumnValueRange::add_value_range, fn_name, true, slot_ref_child)); } } } diff --git a/be/src/vec/exec/volap_scan_node.h b/be/src/vec/exec/volap_scan_node.h index fba7fdd24a..7b3f383b62 100644 --- a/be/src/vec/exec/volap_scan_node.h +++ b/be/src/vec/exec/volap_scan_node.h @@ -74,7 +74,8 @@ private: template static Status change_value_range(ColumnValueRange& range, void* value, const ChangeFixedValueRangeFunc& func, - const std::string& fn_name, int slot_ref_child = -1); + const std::string& fn_name, bool cast_date_to_datetime = true, + int slot_ref_child = -1); void transfer_thread(RuntimeState* state); void scanner_thread(VOlapScanner* scanner); diff --git a/be/src/vec/functions/array/function_array_element.h b/be/src/vec/functions/array/function_array_element.h index 53c41b19eb..d04a1b605b 100644 --- a/be/src/vec/functions/array/function_array_element.h +++ b/be/src/vec/functions/array/function_array_element.h @@ -199,18 +199,10 @@ private: if (nested_column->is_date_type()) { res = _execute_number(offsets, *nested_column, src_null_map, *arguments[1].column, nested_null_map, dst_null_map); - } else if (nested_column->is_date_v2_type()) { - res = _execute_number(offsets, *nested_column, src_null_map, - *arguments[1].column, nested_null_map, - dst_null_map); } else if (nested_column->is_datetime_type()) { res = _execute_number(offsets, *nested_column, src_null_map, *arguments[1].column, nested_null_map, dst_null_map); - } else if (nested_column->is_datetime_v2_type()) { - res = _execute_number(offsets, *nested_column, src_null_map, - *arguments[1].column, nested_null_map, - dst_null_map); } else if (check_column(*nested_column)) { res = _execute_number(offsets, *nested_column, src_null_map, *arguments[1].column, nested_null_map, dst_null_map); diff --git a/be/src/vec/functions/array/function_array_index.h b/be/src/vec/functions/array/function_array_index.h index 3bb1df5003..ab81490267 100644 --- a/be/src/vec/functions/array/function_array_index.h +++ b/be/src/vec/functions/array/function_array_index.h @@ -174,12 +174,6 @@ private: } else if (right_column.is_date_type()) { return _execute_number(offsets, nested_null_map, nested_column, right_column); - } else if (right_column.is_date_v2_type()) { - return _execute_number(offsets, nested_null_map, - nested_column, right_column); - } else if (right_column.is_datetime_v2_type()) { - return _execute_number(offsets, nested_null_map, - nested_column, right_column); } else if (right_column.is_datetime_type()) { return _execute_number(offsets, nested_null_map, nested_column, right_column); @@ -257,15 +251,9 @@ private: if (nested_column->is_date_type()) { return_column = _execute_number_expanded(offsets, nested_null_map, *nested_column, *right_column); - } else if (nested_column->is_date_v2_type()) { - return_column = _execute_number_expanded( - offsets, nested_null_map, *nested_column, *right_column); } else if (nested_column->is_datetime_type()) { return_column = _execute_number_expanded( offsets, nested_null_map, *nested_column, *right_column); - } else if (nested_column->is_datetime_v2_type()) { - return_column = _execute_number_expanded( - offsets, nested_null_map, *nested_column, *right_column); } } diff --git a/be/src/vec/functions/function_cast.h b/be/src/vec/functions/function_cast.h index b262ad7a29..11d8d7ed44 100644 --- a/be/src/vec/functions/function_cast.h +++ b/be/src/vec/functions/function_cast.h @@ -145,14 +145,9 @@ struct ConvertImpl { DataTypeDate::cast_to_date(vec_to[i]); } } else if constexpr (IsDateV2Type) { - auto date_v2 = binary_cast>(vec_to[i]); - date_v2.from_date_int64( - reinterpret_cast(vec_from[i]).to_int64()); + DataTypeDateV2::cast_from_date(vec_from[i], vec_to[i]); } else if constexpr (IsDateTimeV2Type) { - auto date_v2 = - binary_cast>(vec_to[i]); - date_v2.from_date_int64( - reinterpret_cast(vec_from[i]).to_int64()); + DataTypeDateTimeV2::cast_from_date(vec_from[i], vec_to[i]); } else { vec_to[i] = reinterpret_cast(vec_from[i]).to_int64(); 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 6bf620e9c4..1d8be77af7 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 @@ -829,7 +829,7 @@ public class FunctionCallExpr extends Expr { */ public void analyzeImplForDefaultValue() throws AnalysisException { fn = getBuiltinFunction(fnName.getFunction(), new Type[0], Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF); - type = fn.getReturnType(); + type = ScalarType.getDefaultDateType(fn.getReturnType()); for (int i = 0; i < children.size(); ++i) { if (getChild(i).getType().isNull()) { uncheckedCastChild(Type.BOOLEAN, i); diff --git a/gensrc/script/doris_builtins_functions.py b/gensrc/script/doris_builtins_functions.py index 92b3bbe7db..fb1b1ddab1 100755 --- a/gensrc/script/doris_builtins_functions.py +++ b/gensrc/script/doris_builtins_functions.py @@ -1826,6 +1826,8 @@ visible_functions = [ [['if'], 'DOUBLE', ['BOOLEAN', 'DOUBLE', 'DOUBLE'], '', '', '', 'vec', 'CUSTOM'], [['if'], 'DATETIME', ['BOOLEAN', 'DATETIME', 'DATETIME'], '', '', '', 'vec', 'CUSTOM'], [['if'], 'DATE', ['BOOLEAN', 'DATE', 'DATE'], '', '', '', 'vec', 'CUSTOM'], + [['if'], 'DATETIMEV2', ['BOOLEAN', 'DATETIMEV2', 'DATETIMEV2'], '', '', '', 'vec', 'CUSTOM'], + [['if'], 'DATEV2', ['BOOLEAN', 'DATEV2', 'DATEV2'], '', '', '', 'vec', 'CUSTOM'], [['if'], 'DECIMALV2', ['BOOLEAN', 'DECIMALV2', 'DECIMALV2'], '', '', '', 'vec', 'CUSTOM'], [['if'], 'BITMAP', ['BOOLEAN', 'BITMAP', 'BITMAP'], '', '', '', 'vec', 'CUSTOM'], # The priority of varchar should be lower than decimal in IS_SUPERTYPE_OF mode.