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 b2371c1246 [Refact](Literal)refact literal get field and value (#19351) b2371c1246 is described below commit b2371c12464c615d6548805896f431ef25c6f437 Author: amory <wangqian...@selectdb.com> AuthorDate: Wed May 10 09:01:17 2023 +0800 [Refact](Literal)refact literal get field and value (#19351) --- be/src/vec/data_types/data_type.h | 2 + be/src/vec/data_types/data_type_array.h | 4 + be/src/vec/data_types/data_type_bitmap.h | 4 + be/src/vec/data_types/data_type_date.h | 10 + be/src/vec/data_types/data_type_date_time.h | 11 + be/src/vec/data_types/data_type_decimal.h | 26 ++ .../vec/data_types/data_type_fixed_length_object.h | 4 + be/src/vec/data_types/data_type_hll.h | 4 + be/src/vec/data_types/data_type_jsonb.h | 7 + be/src/vec/data_types/data_type_map.h | 5 + be/src/vec/data_types/data_type_nothing.h | 4 + be/src/vec/data_types/data_type_nullable.h | 7 + be/src/vec/data_types/data_type_number_base.cpp | 38 +++ be/src/vec/data_types/data_type_number_base.h | 2 + be/src/vec/data_types/data_type_object.h | 5 + be/src/vec/data_types/data_type_quantilestate.h | 4 + be/src/vec/data_types/data_type_string.h | 6 + be/src/vec/data_types/data_type_struct.h | 5 + be/src/vec/data_types/data_type_time_v2.h | 19 ++ be/src/vec/exprs/vexpr.cpp | 4 + be/src/vec/exprs/vliteral.cpp | 270 +-------------------- be/test/vec/exprs/vexpr_test.cpp | 153 +++++++++++- 22 files changed, 321 insertions(+), 273 deletions(-) diff --git a/be/src/vec/data_types/data_type.h b/be/src/vec/data_types/data_type.h index 9af716c5ca..a088d6af25 100644 --- a/be/src/vec/data_types/data_type.h +++ b/be/src/vec/data_types/data_type.h @@ -20,6 +20,7 @@ #pragma once +#include <gen_cpp/Exprs_types.h> #include <gen_cpp/Types_types.h> #include <stddef.h> #include <stdint.h> @@ -103,6 +104,7 @@ public: */ virtual Field get_default() const = 0; + virtual Field get_field(const TExprNode& node) const = 0; /** The data type can be promoted in order to try to avoid overflows. * Data types which can be promoted are typically Number or Decimal data types. */ diff --git a/be/src/vec/data_types/data_type_array.h b/be/src/vec/data_types/data_type_array.h index 9409102ee1..c33d976b53 100644 --- a/be/src/vec/data_types/data_type_array.h +++ b/be/src/vec/data_types/data_type_array.h @@ -74,6 +74,10 @@ public: Field get_default() const override; + [[noreturn]] Field get_field(const TExprNode& node) const override { + LOG(FATAL) << "Unimplemented get_field for array"; + } + bool equals(const IDataType& rhs) const override; bool get_is_parametric() const override { return true; } diff --git a/be/src/vec/data_types/data_type_bitmap.h b/be/src/vec/data_types/data_type_bitmap.h index 082b7ff2d3..b3197b946b 100644 --- a/be/src/vec/data_types/data_type_bitmap.h +++ b/be/src/vec/data_types/data_type_bitmap.h @@ -103,6 +103,10 @@ public: __builtin_unreachable(); } + [[noreturn]] Field get_field(const TExprNode& node) const override { + LOG(FATAL) << "Unimplemented get_field for BitMap"; + } + static void serialize_as_stream(const BitmapValue& value, BufferWritable& buf); static void deserialize_as_stream(BitmapValue& value, BufferReadable& buf); diff --git a/be/src/vec/data_types/data_type_date.h b/be/src/vec/data_types/data_type_date.h index 54e45e63d3..dadab0dc8a 100644 --- a/be/src/vec/data_types/data_type_date.h +++ b/be/src/vec/data_types/data_type_date.h @@ -63,6 +63,16 @@ public: Status from_string(ReadBuffer& rb, IColumn* column) const override; static void cast_to_date(Int64& x); + Field get_field(const TExprNode& node) const override { + VecDateTimeValue value; + if (value.from_date_str(node.date_literal.value.c_str(), node.date_literal.value.size())) { + value.cast_to_date(); + return Int64(*reinterpret_cast<__int64_t*>(&value)); + } else { + throw doris::Exception(doris::ErrorCode::INVALID_ARGUMENT, + "Invalid value: {} for type Date", node.date_literal.value); + } + } MutableColumnPtr create_column() const override; diff --git a/be/src/vec/data_types/data_type_date_time.h b/be/src/vec/data_types/data_type_date_time.h index 98aa4b26be..cc280c9751 100644 --- a/be/src/vec/data_types/data_type_date_time.h +++ b/be/src/vec/data_types/data_type_date_time.h @@ -87,6 +87,17 @@ public: DataTypeSerDeSPtr get_serde() const override { return std::make_shared<DataTypeDate64SerDe>(); } + Field get_field(const TExprNode& node) const override { + VecDateTimeValue value; + if (value.from_date_str(node.date_literal.value.c_str(), node.date_literal.value.size())) { + value.to_datetime(); + return Int64(*reinterpret_cast<__int64_t*>(&value)); + } else { + throw doris::Exception(doris::ErrorCode::INVALID_ARGUMENT, + "Invalid value: {} for type DateTime", node.date_literal.value); + } + } + void to_string(const IColumn& column, size_t row_num, BufferWritable& ostr) const override; Status from_string(ReadBuffer& rb, IColumn* column) const override; diff --git a/be/src/vec/data_types/data_type_decimal.h b/be/src/vec/data_types/data_type_decimal.h index a3672b05df..8a0fdc186d 100644 --- a/be/src/vec/data_types/data_type_decimal.h +++ b/be/src/vec/data_types/data_type_decimal.h @@ -206,6 +206,32 @@ public: void to_pb_column_meta(PColumnMeta* col_meta) const override; Field get_default() const override; + + Field get_field(const TExprNode& node) const override { + DCHECK_EQ(node.node_type, TExprNodeType::DECIMAL_LITERAL); + DCHECK(node.__isset.decimal_literal); + // decimalv2 + if constexpr (std::is_same_v<TypeId<T>, TypeId<Decimal128>>) { + DecimalV2Value value; + if (value.parse_from_str(node.decimal_literal.value.c_str(), + node.decimal_literal.value.size()) == E_DEC_OK) { + return DecimalField<Decimal128>(value.value(), value.scale()); + } else { + throw doris::Exception(doris::ErrorCode::INVALID_ARGUMENT, + "Invalid decimal(scale: {}) value: {}", value.scale(), + node.decimal_literal.value); + } + } + // decimal + T val; + if (!parse_from_string(node.decimal_literal.value, &val)) { + throw doris::Exception(doris::ErrorCode::INVALID_ARGUMENT, + "Invalid value: {} for type {}", node.decimal_literal.value, + do_get_name()); + }; + return DecimalField<T>(val, scale); + } + bool can_be_promoted() const override { return true; } DataTypePtr promote_numeric_type() const override; MutableColumnPtr create_column() const override; diff --git a/be/src/vec/data_types/data_type_fixed_length_object.h b/be/src/vec/data_types/data_type_fixed_length_object.h index 92c502df61..f81d1dc6fa 100644 --- a/be/src/vec/data_types/data_type_fixed_length_object.h +++ b/be/src/vec/data_types/data_type_fixed_length_object.h @@ -60,6 +60,10 @@ public: Field get_default() const override { return String(); } + [[noreturn]] Field get_field(const TExprNode& node) const override { + LOG(FATAL) << "Unimplemented get_field for DataTypeFixedLengthObject"; + } + bool equals(const IDataType& rhs) const override { return typeid(rhs) == typeid(*this); } int64_t get_uncompressed_serialized_bytes(const IColumn& column, diff --git a/be/src/vec/data_types/data_type_hll.h b/be/src/vec/data_types/data_type_hll.h index 2a597a7a18..769d5a8036 100644 --- a/be/src/vec/data_types/data_type_hll.h +++ b/be/src/vec/data_types/data_type_hll.h @@ -100,6 +100,10 @@ public: return String(); } + [[noreturn]] Field get_field(const TExprNode& node) const override { + LOG(FATAL) << "Unimplemented get_field for HLL"; + } + static void serialize_as_stream(const HyperLogLog& value, BufferWritable& buf); static void deserialize_as_stream(HyperLogLog& value, BufferReadable& buf); diff --git a/be/src/vec/data_types/data_type_jsonb.h b/be/src/vec/data_types/data_type_jsonb.h index defe1a9879..e228b43fb4 100644 --- a/be/src/vec/data_types/data_type_jsonb.h +++ b/be/src/vec/data_types/data_type_jsonb.h @@ -70,6 +70,13 @@ public: return JsonbField(binary_val.value(), binary_val.size()); } + Field get_field(const TExprNode& node) const override { + DCHECK_EQ(node.node_type, TExprNodeType::JSON_LITERAL); + DCHECK(node.__isset.json_literal); + JsonBinaryValue value(node.json_literal.value); + return String(value.value(), value.size()); + } + bool equals(const IDataType& rhs) const override; bool get_is_parametric() const override { return false; } diff --git a/be/src/vec/data_types/data_type_map.h b/be/src/vec/data_types/data_type_map.h index e01ac90805..017c5a184c 100644 --- a/be/src/vec/data_types/data_type_map.h +++ b/be/src/vec/data_types/data_type_map.h @@ -71,6 +71,11 @@ public: bool can_be_inside_nullable() const override { return true; } MutableColumnPtr create_column() const override; Field get_default() const override; + + [[noreturn]] Field get_field(const TExprNode& node) const override { + LOG(FATAL) << "Unimplemented get_field for map"; + } + bool equals(const IDataType& rhs) const override; bool get_is_parametric() const override { return true; } bool have_subtypes() const override { return true; } diff --git a/be/src/vec/data_types/data_type_nothing.h b/be/src/vec/data_types/data_type_nothing.h index 450aa2802f..039e4d5b30 100644 --- a/be/src/vec/data_types/data_type_nothing.h +++ b/be/src/vec/data_types/data_type_nothing.h @@ -78,6 +78,10 @@ public: LOG(FATAL) << "Method get_default() is not implemented for data type " << get_name(); } + [[noreturn]] Field get_field(const TExprNode& node) const override { + LOG(FATAL) << "Unimplemented get_field for Nothing"; + } + void insert_default_into(IColumn&) const override { LOG(FATAL) << "Method insert_default_into() is not implemented for data type " << get_name(); diff --git a/be/src/vec/data_types/data_type_nullable.h b/be/src/vec/data_types/data_type_nullable.h index 80948bdb9d..734b31588b 100644 --- a/be/src/vec/data_types/data_type_nullable.h +++ b/be/src/vec/data_types/data_type_nullable.h @@ -76,6 +76,13 @@ public: Field get_default() const override; + Field get_field(const TExprNode& node) const override { + if (node.node_type == TExprNodeType::NULL_LITERAL) { + return Null(); + } + return nested_data_type->get_field(node); + } + bool equals(const IDataType& rhs) const override; bool is_value_unambiguously_represented_in_contiguous_memory_region() const override { diff --git a/be/src/vec/data_types/data_type_number_base.cpp b/be/src/vec/data_types/data_type_number_base.cpp index 5994a7aa4c..5e226b6c89 100644 --- a/be/src/vec/data_types/data_type_number_base.cpp +++ b/be/src/vec/data_types/data_type_number_base.cpp @@ -29,7 +29,9 @@ #include <utility> #include "gutil/strings/numbers.h" +#include "runtime/large_int_value.h" #include "util/mysql_global.h" +#include "util/string_parser.hpp" #include "vec/columns/column.h" #include "vec/columns/column_const.h" #include "vec/columns/column_vector.h" @@ -101,6 +103,42 @@ Field DataTypeNumberBase<T>::get_default() const { return NearestFieldType<FieldType>(); } +template <typename T> +Field DataTypeNumberBase<T>::get_field(const TExprNode& node) const { + if constexpr (std::is_same_v<TypeId<T>, TypeId<UInt8>>) { + return UInt8(node.bool_literal.value); + } + if constexpr (std::is_same_v<TypeId<T>, TypeId<Int8>>) { + return Int8(node.int_literal.value); + } + if constexpr (std::is_same_v<TypeId<T>, TypeId<Int16>>) { + return Int16(node.int_literal.value); + } + if constexpr (std::is_same_v<TypeId<T>, TypeId<Int32>>) { + return Int32(node.int_literal.value); + } + if constexpr (std::is_same_v<TypeId<T>, TypeId<Int64>>) { + return Int64(node.int_literal.value); + } + if constexpr (std::is_same_v<TypeId<T>, TypeId<Int128>>) { + StringParser::ParseResult parse_result = StringParser::PARSE_SUCCESS; + __int128_t value = StringParser::string_to_int<__int128>( + node.large_int_literal.value.c_str(), node.large_int_literal.value.size(), + &parse_result); + if (parse_result != StringParser::PARSE_SUCCESS) { + value = MAX_INT128; + } + return Int128(value); + } + if constexpr (std::is_same_v<TypeId<T>, TypeId<Float32>>) { + return Float32(node.float_literal.value); + } + if constexpr (std::is_same_v<TypeId<T>, TypeId<Float64>>) { + return Float64(node.float_literal.value); + } + __builtin_unreachable(); +} + template <typename T> std::string DataTypeNumberBase<T>::to_string(const IColumn& column, size_t row_num) const { auto result = check_column_const_set_readability(column, row_num); diff --git a/be/src/vec/data_types/data_type_number_base.h b/be/src/vec/data_types/data_type_number_base.h index b7f4f6bef0..14780542ba 100644 --- a/be/src/vec/data_types/data_type_number_base.h +++ b/be/src/vec/data_types/data_type_number_base.h @@ -115,6 +115,8 @@ public: } Field get_default() const override; + Field get_field(const TExprNode& node) const override; + int64_t get_uncompressed_serialized_bytes(const IColumn& column, int be_exec_version) const override; char* serialize(const IColumn& column, char* buf, int be_exec_version) const override; diff --git a/be/src/vec/data_types/data_type_object.h b/be/src/vec/data_types/data_type_object.h index f68c64196f..106e8cf973 100644 --- a/be/src/vec/data_types/data_type_object.h +++ b/be/src/vec/data_types/data_type_object.h @@ -75,6 +75,11 @@ public: [[noreturn]] Field get_default() const override { LOG(FATAL) << "Method getDefault() is not implemented for data type " << get_name(); } + + [[noreturn]] Field get_field(const TExprNode& node) const override { + LOG(FATAL) << "Unimplemented get_field for object"; + } + DataTypeSerDeSPtr get_serde() const override { return std::make_shared<DataTypeObjectSerDe>(); }; diff --git a/be/src/vec/data_types/data_type_quantilestate.h b/be/src/vec/data_types/data_type_quantilestate.h index 71968b7f88..4a779c1414 100644 --- a/be/src/vec/data_types/data_type_quantilestate.h +++ b/be/src/vec/data_types/data_type_quantilestate.h @@ -102,6 +102,10 @@ public: __builtin_unreachable(); } + [[noreturn]] Field get_field(const TExprNode& node) const override { + LOG(FATAL) << "Unimplemented get_field for quantilestate"; + } + static void serialize_as_stream(const QuantileState<T>& value, BufferWritable& buf); static void deserialize_as_stream(QuantileState<T>& value, BufferReadable& buf); diff --git a/be/src/vec/data_types/data_type_string.h b/be/src/vec/data_types/data_type_string.h index d222a13418..301b85bf11 100644 --- a/be/src/vec/data_types/data_type_string.h +++ b/be/src/vec/data_types/data_type_string.h @@ -70,6 +70,12 @@ public: Field get_default() const override; + Field get_field(const TExprNode& node) const override { + DCHECK_EQ(node.node_type, TExprNodeType::STRING_LITERAL); + DCHECK(node.__isset.string_literal); + return node.string_literal.value; + } + bool equals(const IDataType& rhs) const override; bool get_is_parametric() const override { return false; } diff --git a/be/src/vec/data_types/data_type_struct.h b/be/src/vec/data_types/data_type_struct.h index 8b09a7cc88..90fc1b8dba 100644 --- a/be/src/vec/data_types/data_type_struct.h +++ b/be/src/vec/data_types/data_type_struct.h @@ -85,6 +85,11 @@ public: MutableColumnPtr create_column() const override; Field get_default() const override; + + Field get_field(const TExprNode& node) const override { + LOG(FATAL) << "Unimplemented get_field for struct"; + } + void insert_default_into(IColumn& column) const override; bool equals(const IDataType& rhs) const override; 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 336048b39a..645b23bca2 100644 --- a/be/src/vec/data_types/data_type_time_v2.h +++ b/be/src/vec/data_types/data_type_time_v2.h @@ -70,6 +70,15 @@ public: DataTypeSerDeSPtr get_serde() const override { return std::make_shared<DataTypeDateV2SerDe>(); } + Field get_field(const TExprNode& node) const override { + DateV2Value<DateV2ValueType> value; + if (value.from_date_str(node.date_literal.value.c_str(), node.date_literal.value.size())) { + return value.to_date_int_val(); + } else { + throw doris::Exception(doris::ErrorCode::INVALID_ARGUMENT, + "Invalid value: {} for type DateV2", node.date_literal.value); + } + } bool equals(const IDataType& rhs) const override; std::string to_string(const IColumn& column, size_t row_num) const override; void to_string(const IColumn& column, size_t row_num, BufferWritable& ostr) const override; @@ -120,6 +129,16 @@ public: return std::make_shared<DataTypeDateTimeV2SerDe>(); }; + Field get_field(const TExprNode& node) const override { + DateV2Value<DateTimeV2ValueType> value; + if (value.from_date_str(node.date_literal.value.c_str(), node.date_literal.value.size())) { + return value.to_date_int_val(); + } else { + throw doris::Exception(doris::ErrorCode::INVALID_ARGUMENT, + "Invalid value: {} for type DateTimeV2", + node.date_literal.value); + } + } MutableColumnPtr create_column() const override; UInt32 get_scale() const { return _scale; } diff --git a/be/src/vec/exprs/vexpr.cpp b/be/src/vec/exprs/vexpr.cpp index df3705c53c..f6b08c5fd1 100644 --- a/be/src/vec/exprs/vexpr.cpp +++ b/be/src/vec/exprs/vexpr.cpp @@ -75,6 +75,10 @@ VExpr::VExpr(const doris::TExprNode& node) if (node.__isset.is_nullable) { is_nullable = node.is_nullable; } + // If we define null literal ,should make nullable data type to get correct field instead of undefined ptr + if (node.node_type == TExprNodeType::NULL_LITERAL) { + CHECK(is_nullable); + } _data_type = DataTypeFactory::instance().create_data_type(_type, is_nullable); } diff --git a/be/src/vec/exprs/vliteral.cpp b/be/src/vec/exprs/vliteral.cpp index 8025134c51..3d39a844dc 100644 --- a/be/src/vec/exprs/vliteral.cpp +++ b/be/src/vec/exprs/vliteral.cpp @@ -54,187 +54,7 @@ class VExprContext; void VLiteral::init(const TExprNode& node) { Field field; - if (node.node_type != TExprNodeType::NULL_LITERAL) { - switch (_type.type) { - case TYPE_BOOLEAN: { - DCHECK_EQ(node.node_type, TExprNodeType::BOOL_LITERAL); - DCHECK(node.__isset.bool_literal); - field = Int8(node.bool_literal.value); - break; - } - case TYPE_TINYINT: { - DCHECK_EQ(node.node_type, TExprNodeType::INT_LITERAL); - DCHECK(node.__isset.int_literal); - field = Int8(node.int_literal.value); - break; - } - case TYPE_SMALLINT: { - DCHECK_EQ(node.node_type, TExprNodeType::INT_LITERAL); - DCHECK(node.__isset.int_literal); - field = Int16(node.int_literal.value); - break; - } - case TYPE_INT: { - DCHECK_EQ(node.node_type, TExprNodeType::INT_LITERAL); - DCHECK(node.__isset.int_literal); - field = Int32(node.int_literal.value); - break; - } - case TYPE_BIGINT: { - DCHECK_EQ(node.node_type, TExprNodeType::INT_LITERAL); - DCHECK(node.__isset.int_literal); - field = Int64(node.int_literal.value); - break; - } - case TYPE_LARGEINT: { - StringParser::ParseResult parse_result = StringParser::PARSE_SUCCESS; - DCHECK_EQ(node.node_type, TExprNodeType::LARGE_INT_LITERAL); - __int128_t value = StringParser::string_to_int<__int128>( - node.large_int_literal.value.c_str(), node.large_int_literal.value.size(), - &parse_result); - if (parse_result != StringParser::PARSE_SUCCESS) { - value = MAX_INT128; - } - field = Int128(value); - break; - } - case TYPE_FLOAT: { - DCHECK_EQ(node.node_type, TExprNodeType::FLOAT_LITERAL); - DCHECK(node.__isset.float_literal); - field = Float32(node.float_literal.value); - break; - } - case TYPE_TIME: - case TYPE_TIMEV2: - case TYPE_DOUBLE: { - DCHECK_EQ(node.node_type, TExprNodeType::FLOAT_LITERAL); - DCHECK(node.__isset.float_literal); - field = Float64(node.float_literal.value); - break; - } - case TYPE_DATE: { - VecDateTimeValue value; - if (value.from_date_str(node.date_literal.value.c_str(), - node.date_literal.value.size())) { - value.cast_to_date(); - field = Int64(*reinterpret_cast<__int64_t*>(&value)); - } - break; - } - case TYPE_DATEV2: { - DateV2Value<DateV2ValueType> value; - if (value.from_date_str(node.date_literal.value.c_str(), - node.date_literal.value.size())) { - field = value.to_date_int_val(); - } - break; - } - case TYPE_DATETIMEV2: { - DateV2Value<DateTimeV2ValueType> value; - if (value.from_date_str(node.date_literal.value.c_str(), - node.date_literal.value.size())) { - field = value.to_date_int_val(); - } - break; - } - case TYPE_DATETIME: { - VecDateTimeValue value; - if (value.from_date_str(node.date_literal.value.c_str(), - node.date_literal.value.size())) { - value.to_datetime(); - field = Int64(*reinterpret_cast<__int64_t*>(&value)); - } - break; - } - case TYPE_STRING: - case TYPE_CHAR: - case TYPE_VARCHAR: { - DCHECK_EQ(node.node_type, TExprNodeType::STRING_LITERAL); - DCHECK(node.__isset.string_literal); - field = node.string_literal.value; - break; - } - case TYPE_JSONB: { - DCHECK_EQ(node.node_type, TExprNodeType::JSON_LITERAL); - DCHECK(node.__isset.json_literal); - JsonBinaryValue value(node.json_literal.value); - field = String(value.value(), value.size()); - break; - } - case TYPE_DECIMALV2: { - DCHECK_EQ(node.node_type, TExprNodeType::DECIMAL_LITERAL); - DCHECK(node.__isset.decimal_literal); - DecimalV2Value value; - if (value.parse_from_str(node.decimal_literal.value.c_str(), - node.decimal_literal.value.size()) == E_DEC_OK) { - field = DecimalField<Decimal128>(value.value(), value.scale()); - } else { - throw doris::Exception(doris::ErrorCode::INVALID_ARGUMENT, - "Invalid decimal(scale: {}) value: {}", value.scale(), - node.decimal_literal.value); - } - break; - } - case TYPE_DECIMAL32: { - DCHECK_EQ(node.node_type, TExprNodeType::DECIMAL_LITERAL); - DCHECK(node.__isset.decimal_literal); - DataTypePtr type_ptr = create_decimal(node.type.types[0].scalar_type.precision, - node.type.types[0].scalar_type.scale, false); - Decimal32 val; - if (typeid_cast<const DataTypeDecimal<Decimal32>*>(type_ptr.get()) - ->parse_from_string(node.decimal_literal.value, &val)) { - auto scale = - typeid_cast<const DataTypeDecimal<Decimal32>*>(type_ptr.get())->get_scale(); - field = DecimalField<Decimal32>(val, scale); - } else { - throw doris::Exception(doris::ErrorCode::INVALID_ARGUMENT, - "Invalid value: {} for type {}", node.decimal_literal.value, - type_ptr->get_name()); - } - break; - } - case TYPE_DECIMAL64: { - DCHECK_EQ(node.node_type, TExprNodeType::DECIMAL_LITERAL); - DCHECK(node.__isset.decimal_literal); - DataTypePtr type_ptr = create_decimal(node.type.types[0].scalar_type.precision, - node.type.types[0].scalar_type.scale, false); - Decimal64 val; - if (typeid_cast<const DataTypeDecimal<Decimal64>*>(type_ptr.get()) - ->parse_from_string(node.decimal_literal.value, &val)) { - auto scale = - typeid_cast<const DataTypeDecimal<Decimal64>*>(type_ptr.get())->get_scale(); - field = DecimalField<Decimal64>(val, scale); - } else { - throw doris::Exception(doris::ErrorCode::INVALID_ARGUMENT, - "Invalid value: {} for type {}", node.decimal_literal.value, - type_ptr->get_name()); - } - break; - } - case TYPE_DECIMAL128I: { - DCHECK_EQ(node.node_type, TExprNodeType::DECIMAL_LITERAL); - DCHECK(node.__isset.decimal_literal); - DataTypePtr type_ptr = create_decimal(node.type.types[0].scalar_type.precision, - node.type.types[0].scalar_type.scale, false); - Decimal128I val; - if (typeid_cast<const DataTypeDecimal<Decimal128I>*>(type_ptr.get()) - ->parse_from_string(node.decimal_literal.value, &val)) { - auto scale = typeid_cast<const DataTypeDecimal<Decimal128I>*>(type_ptr.get()) - ->get_scale(); - field = DecimalField<Decimal128I>(val, scale); - } else { - throw doris::Exception(doris::ErrorCode::INVALID_ARGUMENT, - "Invalid value: {} for type {}", node.decimal_literal.value, - type_ptr->get_name()); - } - break; - } - default: { - DCHECK(false) << "Invalid type: " << _type.type; - break; - } - } - } + field = _data_type->get_field(node); _column_ptr = _data_type->create_column_const(1, field); } @@ -251,93 +71,7 @@ std::string VLiteral::value() const { if (i != 0) { out << ", "; } - StringRef ref = _column_ptr->get_data_at(i); - if (ref.data == nullptr) { - out << "null"; - } else { - switch (_type.type) { - case TYPE_BOOLEAN: - case TYPE_TINYINT: - out << *(reinterpret_cast<const int8_t*>(ref.data)); - break; - case TYPE_SMALLINT: - out << *(reinterpret_cast<const int16_t*>(ref.data)); - break; - case TYPE_INT: { - out << *(reinterpret_cast<const int32_t*>(ref.data)); - break; - } - case TYPE_BIGINT: { - out << *(reinterpret_cast<const int64_t*>(ref.data)); - break; - } - case TYPE_LARGEINT: { - out << fmt::format("{}", *(reinterpret_cast<const __int128_t*>(ref.data))); - break; - } - case TYPE_FLOAT: { - out << *(reinterpret_cast<const float*>(ref.data)); - break; - } - case TYPE_TIME: - case TYPE_TIMEV2: - case TYPE_DOUBLE: { - out << *(reinterpret_cast<const double_t*>(ref.data)); - break; - } - case TYPE_DATE: - case TYPE_DATETIME: { - auto value = *(reinterpret_cast<const int64_t*>(ref.data)); - auto date_value = (VecDateTimeValue*)&value; - out << *date_value; - break; - } - case TYPE_DATEV2: { - auto* value = (DateV2Value<DateV2ValueType>*)ref.data; - out << *value; - break; - } - case TYPE_DATETIMEV2: { - auto* value = (DateV2Value<DateTimeV2ValueType>*)ref.data; - out << *value; - break; - } - case TYPE_STRING: - case TYPE_CHAR: - case TYPE_VARCHAR: - case TYPE_JSONB: { - out << ref; - break; - } - case TYPE_DECIMALV2: { - DecimalV2Value value(*(reinterpret_cast<const int128_t*>(ref.data))); - out << value; - break; - } - case TYPE_DECIMAL32: { - auto str = - reinterpret_cast<const Decimal<int32_t>*>(ref.data)->to_string(_type.scale); - out << str; - break; - } - case TYPE_DECIMAL64: { - auto str = - reinterpret_cast<const Decimal<int64_t>*>(ref.data)->to_string(_type.scale); - out << str; - break; - } - case TYPE_DECIMAL128I: { - auto str = reinterpret_cast<const Decimal<int128_t>*>(ref.data)->to_string( - _type.scale); - out << str; - break; - } - default: { - out << "UNKNOWN TYPE: " << int(_type.type); - break; - } - } - } + out << _data_type->to_string(*_column_ptr, i); } return out.str(); } diff --git a/be/test/vec/exprs/vexpr_test.cpp b/be/test/vec/exprs/vexpr_test.cpp index a1971f2502..a97206741d 100644 --- a/be/test/vec/exprs/vexpr_test.cpp +++ b/be/test/vec/exprs/vexpr_test.cpp @@ -36,6 +36,7 @@ #include "gen_cpp/Types_types.h" #include "gtest/gtest_pred_impl.h" #include "runtime/descriptors.h" +#include "runtime/jsonb_value.h" #include "runtime/large_int_value.h" #include "runtime/memory/chunk_allocator.h" #include "runtime/runtime_state.h" @@ -225,14 +226,39 @@ struct literal_traits<TYPE_DOUBLE> { template <> struct literal_traits<TYPE_DATETIME> { + const static TPrimitiveType::type ttype = TPrimitiveType::DATETIME; + const static TExprNodeType::type tnode_type = TExprNodeType::DATE_LITERAL; + using CXXType = std::string; +}; +template <> +struct literal_traits<TYPE_DATETIMEV2> { + const static TPrimitiveType::type ttype = TPrimitiveType::DATETIMEV2; + const static TExprNodeType::type tnode_type = TExprNodeType::DATE_LITERAL; + using CXXType = std::string; +}; +template <> +struct literal_traits<TYPE_DATE> { const static TPrimitiveType::type ttype = TPrimitiveType::DATE; - const static TExprNodeType::type tnode_type = TExprNodeType::STRING_LITERAL; + const static TExprNodeType::type tnode_type = TExprNodeType::DATE_LITERAL; using CXXType = std::string; }; - template <> struct literal_traits<TYPE_DATEV2> { const static TPrimitiveType::type ttype = TPrimitiveType::DATEV2; + const static TExprNodeType::type tnode_type = TExprNodeType::DATE_LITERAL; + using CXXType = std::string; +}; + +template <> +struct literal_traits<TYPE_JSONB> { + const static TPrimitiveType::type ttype = TPrimitiveType::JSONB; + const static TExprNodeType::type tnode_type = TExprNodeType::JSON_LITERAL; + using CXXType = std::string; +}; + +template <> +struct literal_traits<TYPE_STRING> { + const static TPrimitiveType::type ttype = TPrimitiveType::STRING; const static TExprNodeType::type tnode_type = TExprNodeType::STRING_LITERAL; using CXXType = std::string; }; @@ -244,6 +270,7 @@ struct literal_traits<TYPE_DECIMALV2> { using CXXType = std::string; }; +//======================== set literal =================================== template <PrimitiveType T, class U = typename literal_traits<T>::CXXType, std::enable_if_t<std::is_integral<U>::value, bool> = true> void set_literal(TExprNode& node, const U& value) { @@ -274,6 +301,22 @@ void set_literal(TExprNode& node, const U& value) { node.__set_date_literal(date_literal); } +template <PrimitiveType T, class U = typename literal_traits<T>::CXXType, + std::enable_if_t<T == TYPE_DATETIMEV2, bool> = true> +void set_literal(TExprNode& node, const U& value) { + TDateLiteral date_literal; + date_literal.__set_value(value); + node.__set_date_literal(date_literal); +} + +template <PrimitiveType T, class U = typename literal_traits<T>::CXXType, + std::enable_if_t<T == TYPE_DATE, bool> = true> +void set_literal(TExprNode& node, const U& value) { + TDateLiteral date_literal; + date_literal.__set_value(value); + node.__set_date_literal(date_literal); +} + template <PrimitiveType T, class U = typename literal_traits<T>::CXXType, std::enable_if_t<T == TYPE_DATEV2, bool> = true> void set_literal(TExprNode& node, const U& value) { @@ -282,6 +325,22 @@ void set_literal(TExprNode& node, const U& value) { node.__set_date_literal(date_literal); } +template <PrimitiveType T, class U = typename literal_traits<T>::CXXType, + std::enable_if_t<T == TYPE_JSONB, bool> = true> +void set_literal(TExprNode& node, const U& value) { + TJsonLiteral jsonb_literal; + jsonb_literal.__set_value(value); + node.__set_json_literal(jsonb_literal); +} + +template <PrimitiveType T, class U = typename literal_traits<T>::CXXType, + std::enable_if_t<T == TYPE_STRING, bool> = true> +void set_literal(TExprNode& node, const U& value) { + TStringLiteral string_literal; + string_literal.__set_value(value); + node.__set_string_literal(string_literal); +} + template <PrimitiveType T, class U = typename literal_traits<T>::CXXType, std::enable_if_t<std::numeric_limits<U>::is_iec559, bool> = true> void set_literal(TExprNode& node, const U& value) { @@ -299,7 +358,7 @@ void set_literal(TExprNode& node, const U& value) { } template <PrimitiveType T, class U = typename literal_traits<T>::CXXType> -doris::TExprNode create_literal(const U& value) { +doris::TExprNode create_literal(const U& value, int scale = 9) { TExprNode node; TTypeDesc type_desc; TTypeNode type_node; @@ -307,7 +366,7 @@ doris::TExprNode create_literal(const U& value) { type_nodes.emplace_back(); TScalarType scalar_type; scalar_type.__set_precision(27); - scalar_type.__set_scale(9); + scalar_type.__set_scale(scale); scalar_type.__set_len(20); scalar_type.__set_type(literal_traits<T>::ttype); type_nodes[0].__set_scalar_type(scalar_type); @@ -322,15 +381,19 @@ doris::TExprNode create_literal(const U& value) { TEST(TEST_VEXPR, LITERALTEST) { using namespace doris; using namespace doris::vectorized; + // bool { VLiteral literal(create_literal<TYPE_BOOLEAN>(true)); + std::cout << "data type: " << literal.data_type().get()->get_name() << std::endl; Block block; int ret = -1; literal.execute(nullptr, &block, &ret); auto ctn = block.safe_get_by_position(ret); bool v = ctn.column->get_bool(0); EXPECT_EQ(v, true); + EXPECT_EQ("1", literal.value()); } + // smallint { VLiteral literal(create_literal<TYPE_SMALLINT>(1024)); Block block; @@ -339,7 +402,9 @@ TEST(TEST_VEXPR, LITERALTEST) { auto ctn = block.safe_get_by_position(ret); auto v = ctn.column->get64(0); EXPECT_EQ(v, 1024); + EXPECT_EQ("1024", literal.value()); } + // int { VLiteral literal(create_literal<TYPE_INT>(1024)); Block block; @@ -348,7 +413,9 @@ TEST(TEST_VEXPR, LITERALTEST) { auto ctn = block.safe_get_by_position(ret); auto v = ctn.column->get64(0); EXPECT_EQ(v, 1024); + EXPECT_EQ("1024", literal.value()); } + // bigint { VLiteral literal(create_literal<TYPE_BIGINT>(1024)); Block block; @@ -357,7 +424,9 @@ TEST(TEST_VEXPR, LITERALTEST) { auto ctn = block.safe_get_by_position(ret); auto v = ctn.column->get64(0); EXPECT_EQ(v, 1024); + EXPECT_EQ("1024", literal.value()); } + // large int { VLiteral literal(create_literal<TYPE_LARGEINT, __int128_t>(1024)); Block block; @@ -366,7 +435,9 @@ TEST(TEST_VEXPR, LITERALTEST) { auto ctn = block.safe_get_by_position(ret); auto v = (*ctn.column)[0].get<__int128_t>(); EXPECT_EQ(v, 1024); + EXPECT_EQ("1024", literal.value()); } + // float { VLiteral literal(create_literal<TYPE_FLOAT, float>(1024.0f)); Block block; @@ -375,7 +446,9 @@ TEST(TEST_VEXPR, LITERALTEST) { auto ctn = block.safe_get_by_position(ret); auto v = (*ctn.column)[0].get<double>(); EXPECT_FLOAT_EQ(v, 1024.0f); + EXPECT_EQ("1024", literal.value()); } + // double { VLiteral literal(create_literal<TYPE_DOUBLE, double>(1024.0)); Block block; @@ -384,11 +457,14 @@ TEST(TEST_VEXPR, LITERALTEST) { auto ctn = block.safe_get_by_position(ret); auto v = (*ctn.column)[0].get<double>(); EXPECT_FLOAT_EQ(v, 1024.0); + EXPECT_EQ("1024", literal.value()); } + // datetime { vectorized::VecDateTimeValue data_time_value; - const char* date = "20210407"; + const char* date = "20210407000000"; data_time_value.from_date_str(date, strlen(date)); + std::cout << data_time_value.type() << std::endl; __int64_t dt; memcpy(&dt, &data_time_value, sizeof(__int64_t)); VLiteral literal(create_literal<TYPE_DATETIME, std::string>(std::string(date))); @@ -398,7 +474,49 @@ TEST(TEST_VEXPR, LITERALTEST) { auto ctn = block.safe_get_by_position(ret); auto v = (*ctn.column)[0].get<__int64_t>(); EXPECT_EQ(v, dt); + EXPECT_EQ("2021-04-07 00:00:00", literal.value()); + } + // datetimev2 + { + uint16_t year = 1997; + uint8_t month = 11; + uint8_t day = 18; + uint8_t hour = 9; + uint8_t minute = 12; + uint8_t second = 46; + uint32_t microsecond = 999999; + DateV2Value<DateTimeV2ValueType> datetime_v2; + datetime_v2.set_time(year, month, day, hour, minute, second, microsecond); + std::string date = datetime_v2.debug_string(); + + __uint64_t dt; + memcpy(&dt, &datetime_v2, sizeof(__uint64_t)); + VLiteral literal(create_literal<TYPE_DATETIMEV2, std::string>(date, 4)); + Block block; + int ret = -1; + literal.execute(nullptr, &block, &ret); + auto ctn = block.safe_get_by_position(ret); + auto v = (*ctn.column)[0].get<__uint64_t>(); + EXPECT_EQ(v, dt); + EXPECT_EQ("1997-11-18 09:12:46.9999", literal.value()); } + // date + { + vectorized::VecDateTimeValue data_time_value; + const char* date = "20210407"; + data_time_value.from_date_str(date, strlen(date)); + __int64_t dt; + memcpy(&dt, &data_time_value, sizeof(__int64_t)); + VLiteral literal(create_literal<TYPE_DATE, std::string>(std::string(date))); + Block block; + int ret = -1; + literal.execute(nullptr, &block, &ret); + auto ctn = block.safe_get_by_position(ret); + auto v = (*ctn.column)[0].get<__int64_t>(); + EXPECT_EQ(v, dt); + EXPECT_EQ("2021-04-07", literal.value()); + } + // datev2 { vectorized::DateV2Value<doris::vectorized::DateV2ValueType> data_time_value; const char* date = "20210407"; @@ -412,7 +530,31 @@ TEST(TEST_VEXPR, LITERALTEST) { auto ctn = block.safe_get_by_position(ret); auto v = (*ctn.column)[0].get<uint32_t>(); EXPECT_EQ(v, dt); + EXPECT_EQ("2021-04-07", literal.value()); + } + // jsonb + { + std::string j = R"([null,true,false,100,6.18,"abc"])"; + VLiteral literal(create_literal<TYPE_JSONB, std::string>(j)); + Block block; + int ret = -1; + literal.execute(nullptr, &block, &ret); + auto ctn = block.safe_get_by_position(ret); + EXPECT_EQ(j, literal.value()); + } + // string + { + std::string s = "I am Amory, 24"; + VLiteral literal(create_literal<TYPE_STRING, std::string>(std::string("I am Amory, 24"))); + Block block; + int ret = -1; + literal.execute(nullptr, &block, &ret); + auto ctn = block.safe_get_by_position(ret); + auto v = (*ctn.column)[0].get<String>(); + EXPECT_EQ(v, s); + EXPECT_EQ(s, literal.value()); } + // decimalv2 { VLiteral literal(create_literal<TYPE_DECIMALV2, std::string>(std::string("1234.56"))); Block block; @@ -421,5 +563,6 @@ TEST(TEST_VEXPR, LITERALTEST) { auto ctn = block.safe_get_by_position(ret); auto v = (*ctn.column)[0].get<DecimalField<Decimal128>>(); EXPECT_FLOAT_EQ(((double)v.get_value()) / (std::pow(10, v.get_scale())), 1234.56); + EXPECT_EQ("1234.560000000", literal.value()); } } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org