-
Notifications
You must be signed in to change notification settings - Fork 3.7k
[Schema change] Support More column type in schema change #4938
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -28,6 +28,7 @@ | |
| #include "gen_cpp/segment_v2.pb.h" // for ColumnMetaPB | ||
| #include "olap/collection.h" | ||
| #include "olap/decimal12.h" | ||
|
|
||
| #include "olap/olap_common.h" | ||
| #include "olap/olap_define.h" | ||
| #include "olap/tablet_schema.h" // for TabletColumn | ||
|
|
@@ -495,12 +496,32 @@ struct BaseFieldtypeTraits : public CppTypeTraits<field_type> { | |
| } | ||
| }; | ||
|
|
||
| static void prepare_char_before_convert(const void* src) { | ||
| Slice* slice = const_cast<Slice*>(reinterpret_cast<const Slice*>(src)); | ||
| char* buf = slice->data; | ||
| auto p = slice->size - 1; | ||
| while (p >= 0 && buf[p] == '\0') { | ||
| p--; | ||
| } | ||
| slice->size = p + 1; | ||
| } | ||
|
|
||
| template <typename T> | ||
| OLAPStatus convert_int_from_varchar(void* dest, const void* src) { | ||
| using SrcType = typename CppTypeTraits<OLAP_FIELD_TYPE_VARCHAR>::CppType; | ||
| auto src_value = reinterpret_cast<const SrcType*>(src); | ||
| T convert_from_varchar(const Slice* src_value, StringParser::ParseResult& parse_res, std::true_type) { | ||
| return StringParser::string_to_int<T>(src_value->get_data(), src_value->get_size(), &parse_res); | ||
| } | ||
|
|
||
| template <typename T> | ||
| T convert_from_varchar(const Slice* src_value, StringParser::ParseResult& parse_res, std::false_type) { | ||
| return StringParser::string_to_float<T>(src_value->get_data(), src_value->get_size(), &parse_res); | ||
| } | ||
|
|
||
| template <typename T> | ||
| OLAPStatus arithmetic_convert_from_varchar(void* dest, const void* src) { | ||
| auto src_value = reinterpret_cast<const Slice*>(src); | ||
| StringParser::ParseResult parse_res; | ||
| T result = StringParser::string_to_int<T>(src_value->get_data(), src_value->get_size(), &parse_res); | ||
| //TODO: use C++17 if constexpr to replace label assignment | ||
| auto result = convert_from_varchar<T>(src_value, parse_res, std::is_integral<T>()); | ||
| if (UNLIKELY(parse_res != StringParser::PARSE_SUCCESS)) { | ||
| return OLAPStatus::OLAP_ERR_INVALID_SCHEMA; | ||
| } | ||
|
|
@@ -509,98 +530,55 @@ OLAPStatus convert_int_from_varchar(void* dest, const void* src) { | |
| } | ||
|
|
||
| template <typename T> | ||
| OLAPStatus convert_float_from_varchar(void* dest, const void* src) { | ||
| using SrcType = typename CppTypeTraits<OLAP_FIELD_TYPE_VARCHAR>::CppType; | ||
| auto src_value = reinterpret_cast<const SrcType *>(src); | ||
| StringParser::ParseResult parse_res; | ||
| T result = StringParser::string_to_float<T>(src_value->get_data(), src_value->get_size(), &parse_res); | ||
| if (UNLIKELY(parse_res != StringParser::PARSE_SUCCESS)) { | ||
| return OLAPStatus::OLAP_ERR_INVALID_SCHEMA; | ||
| } | ||
| *reinterpret_cast<T*>(dest) = result; | ||
| return OLAPStatus::OLAP_SUCCESS; | ||
| OLAPStatus numeric_convert_from_char(void *dest, const void *src) { | ||
| prepare_char_before_convert(src); | ||
| return arithmetic_convert_from_varchar<T>(dest, src); | ||
| } | ||
|
|
||
| template<FieldType field_type> | ||
| struct FieldTypeTraits : public BaseFieldtypeTraits<field_type> { }; | ||
| // Using NumericFieldtypeTraits to Derived code for OLAP_FIELD_TYPE_XXXINT, OLAP_FIELD_TYPE_FLOAT, | ||
| // OLAP_FIELD_TYPE_DOUBLE, to reduce redundant code | ||
| template <FieldType fieldType, bool isArithmetic> | ||
| struct NumericFieldtypeTraits : public BaseFieldtypeTraits<fieldType> { | ||
| using CppType = typename CppTypeTraits<fieldType>::CppType; | ||
|
|
||
| template<> | ||
| struct FieldTypeTraits<OLAP_FIELD_TYPE_BOOL> : public BaseFieldtypeTraits<OLAP_FIELD_TYPE_BOOL> { | ||
| static std::string to_string(const void* src) { | ||
| char buf[1024] = {'\0'}; | ||
| snprintf(buf, sizeof(buf), "%d", *reinterpret_cast<const bool*>(src)); | ||
| return std::string(buf); | ||
| return std::to_string(*reinterpret_cast<const CppType*>(src)); | ||
| } | ||
| static void set_to_max(void* buf) { | ||
| (*(bool*)buf) = true; | ||
| } | ||
| static void set_to_min(void* buf) { | ||
| (*(bool*)buf) = false; | ||
| } | ||
| }; | ||
|
|
||
| template<> | ||
| struct FieldTypeTraits<OLAP_FIELD_TYPE_TINYINT> : public BaseFieldtypeTraits<OLAP_FIELD_TYPE_TINYINT> { | ||
| static std::string to_string(const void* src) { | ||
| char buf[1024] = {'\0'}; | ||
| snprintf(buf, sizeof(buf), "%d", *reinterpret_cast<const int8_t*>(src)); | ||
| return std::string(buf); | ||
| } | ||
| static OLAPStatus convert_from(void* dest, const void* src, const TypeInfo* src_type, MemPool* mem_pool) { | ||
| if (src_type->type() == OLAP_FIELD_TYPE_VARCHAR) { | ||
| return convert_int_from_varchar<CppType>(dest, src); | ||
| return arithmetic_convert_from_varchar<CppType>(dest, src); | ||
| } else if (src_type->type() == OLAP_FIELD_TYPE_CHAR) { | ||
| return numeric_convert_from_char<CppType>(dest, src); | ||
| } | ||
| return OLAPStatus::OLAP_ERR_INVALID_SCHEMA; | ||
| } | ||
| }; | ||
|
|
||
| template<> | ||
| struct FieldTypeTraits<OLAP_FIELD_TYPE_SMALLINT> : public BaseFieldtypeTraits<OLAP_FIELD_TYPE_SMALLINT> { | ||
| static std::string to_string(const void* src) { | ||
| char buf[1024] = {'\0'}; | ||
| snprintf(buf, sizeof(buf), "%d", *reinterpret_cast<const int16_t*>(src)); | ||
| return std::string(buf); | ||
| } | ||
| static OLAPStatus convert_from(void* dest, const void* src, const TypeInfo* src_type, MemPool* mem_pool) { | ||
| if (src_type->type() == OLAP_FIELD_TYPE_VARCHAR) { | ||
| return convert_int_from_varchar<CppType>(dest, src); | ||
| } | ||
| return OLAPStatus::OLAP_ERR_INVALID_SCHEMA; | ||
| } | ||
| }; | ||
| template <FieldType fieldType> | ||
| struct NumericFieldtypeTraits<fieldType, false> : public BaseFieldtypeTraits<fieldType> {}; | ||
|
|
||
| template<> | ||
| struct FieldTypeTraits<OLAP_FIELD_TYPE_INT> : public BaseFieldtypeTraits<OLAP_FIELD_TYPE_INT> { | ||
| static std::string to_string(const void* src) { | ||
| char buf[1024] = {'\0'}; | ||
| snprintf(buf, sizeof(buf), "%d", *reinterpret_cast<const int32_t *>(src)); | ||
| return std::string(buf); | ||
| } | ||
| static OLAPStatus convert_from(void* dest, const void* src, const TypeInfo* src_type, MemPool* mem_pool) { | ||
| if (src_type->type() == OLAP_FIELD_TYPE_VARCHAR) { | ||
| return convert_int_from_varchar<CppType>(dest, src); | ||
| } | ||
| return OLAPStatus::OLAP_ERR_INVALID_SCHEMA; | ||
| } | ||
| }; | ||
| template <FieldType fieldType> | ||
| struct FieldTypeTraits : public NumericFieldtypeTraits<fieldType, | ||
| std::is_arithmetic<typename BaseFieldtypeTraits<fieldType>::CppType>::value && std::is_signed<typename BaseFieldtypeTraits<fieldType>::CppType>::value> {}; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use std::is_signed for what?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now, ArithmeticField just to keep the small with old code. |
||
|
|
||
| template<> | ||
| struct FieldTypeTraits<OLAP_FIELD_TYPE_BIGINT> : public BaseFieldtypeTraits<OLAP_FIELD_TYPE_BIGINT> { | ||
| struct FieldTypeTraits<OLAP_FIELD_TYPE_BOOL> : public BaseFieldtypeTraits<OLAP_FIELD_TYPE_BOOL> { | ||
| static std::string to_string(const void* src) { | ||
| char buf[1024] = {'\0'}; | ||
| snprintf(buf, sizeof(buf), "%ld", *reinterpret_cast<const int64_t*>(src)); | ||
| snprintf(buf, sizeof(buf), "%d", *reinterpret_cast<const bool*>(src)); | ||
| return std::string(buf); | ||
| } | ||
| static OLAPStatus convert_from(void* dest, const void* src, const TypeInfo* src_type, MemPool* mem_pool) { | ||
| if (src_type->type() == OLAP_FIELD_TYPE_VARCHAR) { | ||
| return convert_int_from_varchar<CppType>(dest, src); | ||
| } | ||
| return OLAPStatus::OLAP_ERR_INVALID_SCHEMA; | ||
| static void set_to_max(void* buf) { | ||
| (*(bool*)buf) = true; | ||
| } | ||
| static void set_to_min(void* buf) { | ||
| (*(bool*)buf) = false; | ||
| } | ||
| }; | ||
|
|
||
| template<> | ||
| struct FieldTypeTraits<OLAP_FIELD_TYPE_LARGEINT> : public BaseFieldtypeTraits<OLAP_FIELD_TYPE_LARGEINT> { | ||
| struct FieldTypeTraits<OLAP_FIELD_TYPE_LARGEINT> : public NumericFieldtypeTraits<OLAP_FIELD_TYPE_LARGEINT, true> { | ||
| static OLAPStatus from_string(void* buf, const std::string& scan_key) { | ||
| int128_t value = 0; | ||
|
|
||
|
|
@@ -699,16 +677,10 @@ struct FieldTypeTraits<OLAP_FIELD_TYPE_LARGEINT> : public BaseFieldtypeTraits<OL | |
| static void set_to_min(void* buf) { | ||
| *reinterpret_cast<PackedInt128*>(buf) = (int128_t)(1) << 127; | ||
| } | ||
| static OLAPStatus convert_from(void* dest, const void* src, const TypeInfo* src_type, MemPool* mem_pool) { | ||
| if (src_type->type() == OLAP_FIELD_TYPE_VARCHAR) { | ||
| return convert_int_from_varchar<CppType>(dest, src); | ||
| } | ||
| return OLAPStatus::OLAP_ERR_INVALID_SCHEMA; | ||
| } | ||
| }; | ||
|
|
||
| template<> | ||
| struct FieldTypeTraits<OLAP_FIELD_TYPE_FLOAT> : public BaseFieldtypeTraits<OLAP_FIELD_TYPE_FLOAT> { | ||
| struct FieldTypeTraits<OLAP_FIELD_TYPE_FLOAT> : public NumericFieldtypeTraits<OLAP_FIELD_TYPE_FLOAT, true> { | ||
| static OLAPStatus from_string(void* buf, const std::string& scan_key) { | ||
| CppType value = 0.0f; | ||
| if (scan_key.length() > 0) { | ||
|
|
@@ -723,16 +695,10 @@ struct FieldTypeTraits<OLAP_FIELD_TYPE_FLOAT> : public BaseFieldtypeTraits<OLAP_ | |
| DCHECK(length >= 0) << "gcvt float failed, float value=" << *reinterpret_cast<const CppType *>(src); | ||
| return std::string(buf); | ||
| } | ||
| static OLAPStatus convert_from(void* dest, const void* src, const TypeInfo* src_type, MemPool* mem_pool) { | ||
| if (src_type->type() == OLAP_FIELD_TYPE_VARCHAR) { | ||
| return convert_float_from_varchar<CppType>(dest, src); | ||
| } | ||
| return OLAPStatus::OLAP_ERR_INVALID_SCHEMA; | ||
| } | ||
| }; | ||
|
|
||
| template<> | ||
| struct FieldTypeTraits<OLAP_FIELD_TYPE_DOUBLE> : public BaseFieldtypeTraits<OLAP_FIELD_TYPE_DOUBLE> { | ||
| struct FieldTypeTraits<OLAP_FIELD_TYPE_DOUBLE> : public NumericFieldtypeTraits<OLAP_FIELD_TYPE_DOUBLE, true> { | ||
| static OLAPStatus from_string(void* buf, const std::string& scan_key) { | ||
| CppType value = 0.0; | ||
| if (scan_key.length() > 0) { | ||
|
|
@@ -767,10 +733,8 @@ struct FieldTypeTraits<OLAP_FIELD_TYPE_DOUBLE> : public BaseFieldtypeTraits<OLAP | |
| *reinterpret_cast<CppType*>(dest) = strtod(buf,&tg); | ||
| return OLAPStatus::OLAP_SUCCESS; | ||
| } | ||
| if (src_type->type() == OLAP_FIELD_TYPE_VARCHAR) { | ||
| return convert_float_from_varchar<CppType>(dest, src); | ||
| } | ||
| return OLAPStatus::OLAP_ERR_INVALID_SCHEMA; | ||
|
|
||
| return NumericFieldtypeTraits<OLAP_FIELD_TYPE_DOUBLE, true>::convert_from(dest, src, src_type, mem_pool); | ||
| } | ||
| }; | ||
|
|
||
|
|
@@ -844,7 +808,10 @@ struct FieldTypeTraits<OLAP_FIELD_TYPE_DATE> : public BaseFieldtypeTraits<OLAP_F | |
| return OLAPStatus::OLAP_SUCCESS; | ||
| } | ||
|
|
||
| if (src_type->type() == FieldType::OLAP_FIELD_TYPE_VARCHAR) { | ||
| if (src_type->type() == OLAP_FIELD_TYPE_VARCHAR || src_type->type() == OLAP_FIELD_TYPE_CHAR) { | ||
| if (src_type->type() == OLAP_FIELD_TYPE_CHAR) { | ||
| prepare_char_before_convert(src); | ||
| } | ||
| using SrcType = typename CppTypeTraits<OLAP_FIELD_TYPE_VARCHAR>::CppType; | ||
| auto src_value = *reinterpret_cast<const SrcType*>(src); | ||
| DateTimeValue dt; | ||
|
|
@@ -1032,6 +999,9 @@ struct FieldTypeTraits<OLAP_FIELD_TYPE_VARCHAR> : public FieldTypeTraits<OLAP_FI | |
| memcpy(slice->data, result.c_str(), result.size()); | ||
| slice->size = result.size(); | ||
| return OLAP_SUCCESS; | ||
| } else if (src_type->type() == OLAP_FIELD_TYPE_CHAR) { | ||
| prepare_char_before_convert(src); | ||
| deep_copy(dest, src, mem_pool); | ||
| } | ||
| return OLAP_ERR_INVALID_SCHEMA; | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There may use traits ?
Or use if constexpr (std::is_floating_point_v)) to distinguish the two cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi, chaoyli.
if constexpronly support in c++17 andstd::is_floating_point_vsupport in c++14.Now, Doris only support C++11, So I use label assignment to distinguish the float and int.