From 12b62de3744ff895a43a4b58b50e2acbfe37c9a0 Mon Sep 17 00:00:00 2001 From: kssenii Date: Fri, 3 Feb 2023 17:07:02 +0100 Subject: [PATCH] Add field CustomType --- src/Common/FieldVisitorConvertToNumber.h | 5 +++ src/Common/FieldVisitorDump.h | 2 +- src/Common/FieldVisitorHash.h | 1 + src/Common/FieldVisitorSum.h | 1 + src/Common/FieldVisitorToString.cpp | 1 + src/Common/FieldVisitorToString.h | 1 + src/Common/FieldVisitorWriteBinary.h | 2 +- src/Core/Field.cpp | 1 + src/Core/Field.h | 54 +++++++++++++++++++++++- src/DataTypes/FieldToDataType.cpp | 6 +++ src/DataTypes/FieldToDataType.h | 1 + 11 files changed, 72 insertions(+), 3 deletions(-) diff --git a/src/Common/FieldVisitorConvertToNumber.h b/src/Common/FieldVisitorConvertToNumber.h index ed73cd38cda..2e11b3173d7 100644 --- a/src/Common/FieldVisitorConvertToNumber.h +++ b/src/Common/FieldVisitorConvertToNumber.h @@ -106,6 +106,11 @@ public: throw Exception(ErrorCodes::CANNOT_CONVERT_TYPE, "Cannot convert AggregateFunctionStateData to {}", demangle(typeid(T).name())); } + T operator() (const CustomType &) const + { + throw Exception(ErrorCodes::CANNOT_CONVERT_TYPE, "Cannot convert CustomType to {}", demangle(typeid(T).name())); + } + template requires is_big_int_v T operator() (const U & x) const diff --git a/src/Common/FieldVisitorDump.h b/src/Common/FieldVisitorDump.h index 6ffd91bb400..5f5ecc35a8e 100644 --- a/src/Common/FieldVisitorDump.h +++ b/src/Common/FieldVisitorDump.h @@ -30,8 +30,8 @@ public: String operator() (const DecimalField & x) const; String operator() (const DecimalField & x) const; String operator() (const AggregateFunctionStateData & x) const; + String operator() (const CustomType & x) const; String operator() (const bool & x) const; }; } - diff --git a/src/Common/FieldVisitorHash.h b/src/Common/FieldVisitorHash.h index 1350956146b..47699e96998 100644 --- a/src/Common/FieldVisitorHash.h +++ b/src/Common/FieldVisitorHash.h @@ -36,6 +36,7 @@ public: void operator() (const DecimalField & x) const; void operator() (const DecimalField & x) const; void operator() (const AggregateFunctionStateData & x) const; + void operator() (const CustomType & x) const; void operator() (const bool & x) const; }; diff --git a/src/Common/FieldVisitorSum.h b/src/Common/FieldVisitorSum.h index 5b9c83d1dd1..cbb4c4a1de3 100644 --- a/src/Common/FieldVisitorSum.h +++ b/src/Common/FieldVisitorSum.h @@ -31,6 +31,7 @@ public: bool operator() (IPv4 &) const; bool operator() (IPv6 &) const; bool operator() (AggregateFunctionStateData &) const; + bool operator() (CustomType &) const; bool operator() (bool &) const; template diff --git a/src/Common/FieldVisitorToString.cpp b/src/Common/FieldVisitorToString.cpp index ef21a13b700..e0ec6b7a335 100644 --- a/src/Common/FieldVisitorToString.cpp +++ b/src/Common/FieldVisitorToString.cpp @@ -69,6 +69,7 @@ String FieldVisitorToString::operator() (const IPv4 & x) const { return formatQu String FieldVisitorToString::operator() (const IPv6 & x) const { return formatQuoted(x); } String FieldVisitorToString::operator() (const AggregateFunctionStateData & x) const { return formatQuoted(x.data); } String FieldVisitorToString::operator() (const bool & x) const { return x ? "true" : "false"; } +String FieldVisitorToString::operator() (const CustomType & x) const { return x.toString(); } String FieldVisitorToString::operator() (const Array & x) const { diff --git a/src/Common/FieldVisitorToString.h b/src/Common/FieldVisitorToString.h index 6a10de12ff9..ea4b43ead08 100644 --- a/src/Common/FieldVisitorToString.h +++ b/src/Common/FieldVisitorToString.h @@ -30,6 +30,7 @@ public: String operator() (const DecimalField & x) const; String operator() (const DecimalField & x) const; String operator() (const AggregateFunctionStateData & x) const; + String operator() (const CustomType & x) const; String operator() (const bool & x) const; }; diff --git a/src/Common/FieldVisitorWriteBinary.h b/src/Common/FieldVisitorWriteBinary.h index bc75150bed2..915e75fbbdd 100644 --- a/src/Common/FieldVisitorWriteBinary.h +++ b/src/Common/FieldVisitorWriteBinary.h @@ -29,8 +29,8 @@ public: void operator() (const DecimalField & x, WriteBuffer & buf) const; void operator() (const DecimalField & x, WriteBuffer & buf) const; void operator() (const AggregateFunctionStateData & x, WriteBuffer & buf) const; + void operator() (const CustomType & x, WriteBuffer & buf) const; void operator() (const bool & x, WriteBuffer & buf) const; }; } - diff --git a/src/Core/Field.cpp b/src/Core/Field.cpp index 9ada9c719fa..976f47cdbe3 100644 --- a/src/Core/Field.cpp +++ b/src/Core/Field.cpp @@ -597,6 +597,7 @@ String fieldTypeToString(Field::Types::Which type) case Field::Types::Which::UUID: return "UUID"; case Field::Types::Which::IPv4: return "IPv4"; case Field::Types::Which::IPv6: return "IPv6"; + case Field::Types::Which::CustomType: return "CustomType"; } } diff --git a/src/Core/Field.h b/src/Core/Field.h index d98ff61c9ea..bfb5cc1f324 100644 --- a/src/Core/Field.h +++ b/src/Core/Field.h @@ -102,6 +102,43 @@ struct AggregateFunctionStateData } }; +struct CustomType +{ + struct CustomTypeImpl + { + virtual ~CustomTypeImpl() = default; + virtual const char * getTypeName() const = 0; + virtual String toString() const = 0; + + // virtual std::unique_ptr clone() const; + // virtual std::optional getBaseTypeIfConvertible() const; + // virtual std::optional tryConvertToBaseType(Types::Which dest_type) const + + bool operator < (const CustomTypeImpl &) const { throwNotImpleneted("<"); } + bool operator <= (const CustomTypeImpl &) const { throwNotImpleneted("<="); } + bool operator > (const CustomTypeImpl &) const { throwNotImpleneted(">"); } + bool operator >= (const CustomTypeImpl &) const { throwNotImpleneted(">="); } + bool operator == (const CustomTypeImpl &) const { throwNotImpleneted("=="); } + + [[noreturn]] void throwNotImpleneted(const std::string & op) const + { + throw Exception( + ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Operation {} is not implemented for custom type {}", op, getTypeName()); + } + }; + + String toString() const { return impl->toString(); } + + bool operator < (const CustomType & rhs) const { return *impl < *rhs.impl; } + bool operator <= (const CustomType & rhs) const { return *impl <= *rhs.impl; } + bool operator > (const CustomType & rhs) const { return *impl > *rhs.impl; } + bool operator >= (const CustomType & rhs) const { return *impl >= *rhs.impl; } + bool operator == (const CustomType & rhs) const { return *impl == *rhs.impl; } + + std::shared_ptr impl; + +}; + template bool decimalEqual(T x, T y, UInt32 x_scale, UInt32 y_scale); template bool decimalLess(T x, T y, UInt32 x_scale, UInt32 y_scale); template bool decimalLessOrEqual(T x, T y, UInt32 x_scale, UInt32 y_scale); @@ -233,6 +270,7 @@ template <> struct NearestFieldTypeImpl { using Type = UInt64; }; template <> struct NearestFieldTypeImpl { using Type = Null; }; template <> struct NearestFieldTypeImpl { using Type = AggregateFunctionStateData; }; +template <> struct NearestFieldTypeImpl { using Type = CustomType; }; // For enum types, use the field type that corresponds to their underlying type. template @@ -297,6 +335,7 @@ public: Object = 29, IPv4 = 30, IPv6 = 31, + CustomType = 32, }; }; @@ -486,6 +525,7 @@ public: case Types::Decimal128: return get>() < rhs.get>(); case Types::Decimal256: return get>() < rhs.get>(); case Types::AggregateFunctionState: return get() < rhs.get(); + case Types::CustomType: return get() < rhs.get(); } throw Exception(ErrorCodes::BAD_TYPE_OF_FIELD, "Bad type of Field"); @@ -527,6 +567,7 @@ public: case Types::Decimal128: return get>() <= rhs.get>(); case Types::Decimal256: return get>() <= rhs.get>(); case Types::AggregateFunctionState: return get() <= rhs.get(); + case Types::CustomType: return get() <= rhs.get(); } throw Exception(ErrorCodes::BAD_TYPE_OF_FIELD, "Bad type of Field"); @@ -572,6 +613,7 @@ public: case Types::Decimal128: return get>() == rhs.get>(); case Types::Decimal256: return get>() == rhs.get>(); case Types::AggregateFunctionState: return get() == rhs.get(); + case Types::CustomType: return get() == rhs.get(); } throw Exception(ErrorCodes::BAD_TYPE_OF_FIELD, "Bad type of Field"); @@ -615,6 +657,7 @@ public: case Types::Decimal128: return f(field.template get>()); case Types::Decimal256: return f(field.template get>()); case Types::AggregateFunctionState: return f(field.template get()); + case Types::CustomType: return f(field.template get()); } UNREACHABLE(); @@ -627,7 +670,7 @@ private: std::aligned_union_t, DecimalField, DecimalField, DecimalField, - AggregateFunctionStateData + AggregateFunctionStateData, CustomType > storage; Types::Which which; @@ -731,6 +774,9 @@ private: case Types::AggregateFunctionState: destroy(); break; + case Types::CustomType: + destroy(); + break; default: break; } @@ -774,6 +820,7 @@ template <> struct Field::TypeToEnum>{ static constexpr template <> struct Field::TypeToEnum>{ static constexpr Types::Which value = Types::Decimal256; }; template <> struct Field::TypeToEnum>{ static constexpr Types::Which value = Types::Decimal64; }; template <> struct Field::TypeToEnum{ static constexpr Types::Which value = Types::AggregateFunctionState; }; +template <> struct Field::TypeToEnum{ static constexpr Types::Which value = Types::CustomType; }; template <> struct Field::TypeToEnum{ static constexpr Types::Which value = Types::Bool; }; template <> struct Field::EnumToType { using Type = Null; }; @@ -797,6 +844,7 @@ template <> struct Field::EnumToType { using Type = Dec template <> struct Field::EnumToType { using Type = DecimalField; }; template <> struct Field::EnumToType { using Type = DecimalField; }; template <> struct Field::EnumToType { using Type = DecimalField; }; +template <> struct Field::EnumToType { using Type = CustomType; }; template <> struct Field::EnumToType { using Type = UInt64; }; inline constexpr bool isInt64OrUInt64FieldType(Field::Types::Which t) @@ -935,6 +983,10 @@ void readBinary(Object & x, ReadBuffer & buf); void writeBinary(const Object & x, WriteBuffer & buf); void writeText(const Object & x, WriteBuffer & buf); + +void writeBinary(const CustomType & x, WriteBuffer & buf); +void writeText(const CustomType & x, WriteBuffer & buf); + [[noreturn]] inline void writeQuoted(const Object &, WriteBuffer &) { throw Exception(ErrorCodes::NOT_IMPLEMENTED, "Cannot write Object quoted."); } __attribute__ ((noreturn)) inline void writeText(const AggregateFunctionStateData &, WriteBuffer &) diff --git a/src/DataTypes/FieldToDataType.cpp b/src/DataTypes/FieldToDataType.cpp index 2841ccee12f..0a70761a64e 100644 --- a/src/DataTypes/FieldToDataType.cpp +++ b/src/DataTypes/FieldToDataType.cpp @@ -191,6 +191,12 @@ DataTypePtr FieldToDataType::operator() (const AggregateFunctionStateD return DataTypeFactory::instance().get(name); } +template +DataTypePtr FieldToDataType::operator() (const CustomType &) const +{ + throw Exception(ErrorCodes::NOT_IMPLEMENTED, "Not implemented"); +} + template DataTypePtr FieldToDataType::operator()(const bool &) const { diff --git a/src/DataTypes/FieldToDataType.h b/src/DataTypes/FieldToDataType.h index bd7d5b1af85..8febadc1a0d 100644 --- a/src/DataTypes/FieldToDataType.h +++ b/src/DataTypes/FieldToDataType.h @@ -41,6 +41,7 @@ public: DataTypePtr operator() (const DecimalField & x) const; DataTypePtr operator() (const DecimalField & x) const; DataTypePtr operator() (const AggregateFunctionStateData & x) const; + DataTypePtr operator() (const CustomType & x) const; DataTypePtr operator() (const UInt256 & x) const; DataTypePtr operator() (const Int256 & x) const; DataTypePtr operator() (const bool & x) const;