From a33183ee1e12e1d4072054f0908732955683a0e6 Mon Sep 17 00:00:00 2001 From: feng lv Date: Sun, 14 Feb 2021 16:07:20 +0000 Subject: [PATCH] fix transform with floating point key better update test --- src/Functions/transform.cpp | 102 +++++++++++------- .../01704_transform_with_float_key.reference | 30 ++++++ .../01704_transform_with_float_key.sql | 3 + 3 files changed, 94 insertions(+), 41 deletions(-) create mode 100644 tests/queries/0_stateless/01704_transform_with_float_key.reference create mode 100644 tests/queries/0_stateless/01704_transform_with_float_key.sql diff --git a/src/Functions/transform.cpp b/src/Functions/transform.cpp index ab589be9c07..07fbd5a7b96 100644 --- a/src/Functions/transform.cpp +++ b/src/Functions/transform.cpp @@ -1,4 +1,6 @@ #include +#include + #include #include #include @@ -13,6 +15,7 @@ #include #include #include +#include namespace DB @@ -491,7 +494,7 @@ private: dst.resize(size); for (size_t i = 0; i < size; ++i) { - auto it = table.find(src[i]); + const auto * it = table.find(ext::bit_cast(src[i])); if (it) memcpy(&dst[i], &it->getMapped(), sizeof(dst[i])); /// little endian. else @@ -507,7 +510,7 @@ private: dst.resize(size); for (size_t i = 0; i < size; ++i) { - auto it = table.find(src[i]); + const auto * it = table.find(ext::bit_cast(src[i])); if (it) memcpy(&dst[i], &it->getMapped(), sizeof(dst[i])); /// little endian. else @@ -523,7 +526,7 @@ private: dst.resize(size); for (size_t i = 0; i < size; ++i) { - auto it = table.find(src[i]); + const auto * it = table.find(ext::bit_cast(src[i])); if (it) memcpy(&dst[i], &it->getMapped(), sizeof(dst[i])); else @@ -541,7 +544,7 @@ private: ColumnString::Offset current_dst_offset = 0; for (size_t i = 0; i < size; ++i) { - auto it = table.find(src[i]); + const auto * it = table.find(ext::bit_cast(src[i])); StringRef ref = it ? it->getMapped() : dst_default; dst_data.resize(current_dst_offset + ref.size); memcpy(&dst_data[current_dst_offset], ref.data, ref.size); @@ -562,7 +565,8 @@ private: ColumnString::Offset current_dst_default_offset = 0; for (size_t i = 0; i < size; ++i) { - auto it = table.find(src[i]); + Field key = src[i]; + const auto * it = table.find(key.reinterpret()); StringRef ref; if (it) @@ -778,50 +782,66 @@ private: /// Note: Doesn't check the duplicates in the `from` array. - if (from[0].getType() != Field::Types::String && to[0].getType() != Field::Types::String) + const IDataType & from_type = *arguments[0].type; + + if (from[0].getType() != Field::Types::String) { - cache.table_num_to_num = std::make_unique(); - auto & table = *cache.table_num_to_num; - for (size_t i = 0; i < size; ++i) + if (to[0].getType() != Field::Types::String) { - // Field may be of Float type, but for the purpose of bitwise - // equality we can treat them as UInt64, hence the reinterpret(). - table[from[i].reinterpret()] = (*used_to)[i].reinterpret(); + cache.table_num_to_num = std::make_unique(); + auto & table = *cache.table_num_to_num; + for (size_t i = 0; i < size; ++i) + { + Field key = convertFieldToType(from[i], from_type); + if (key.isNull()) + continue; + + // Field may be of Float type, but for the purpose of bitwise + // equality we can treat them as UInt64, hence the reinterpret(). + table[key.reinterpret()] = (*used_to)[i].reinterpret(); + } + } + else + { + cache.table_num_to_string = std::make_unique(); + auto & table = *cache.table_num_to_string; + for (size_t i = 0; i < size; ++i) + { + Field key = convertFieldToType(from[i], from_type); + if (key.isNull()) + continue; + + const String & str_to = to[i].get(); + StringRef ref{cache.string_pool.insert(str_to.data(), str_to.size() + 1), str_to.size() + 1}; + table[key.reinterpret()] = ref; + } } } - else if (from[0].getType() != Field::Types::String && to[0].getType() == Field::Types::String) + else { - cache.table_num_to_string = std::make_unique(); - auto & table = *cache.table_num_to_string; - for (size_t i = 0; i < size; ++i) + if (to[0].getType() != Field::Types::String) { - const String & str_to = to[i].get(); - StringRef ref{cache.string_pool.insert(str_to.data(), str_to.size() + 1), str_to.size() + 1}; - table[from[i].reinterpret()] = ref; + cache.table_string_to_num = std::make_unique(); + auto & table = *cache.table_string_to_num; + for (size_t i = 0; i < size; ++i) + { + const String & str_from = from[i].get(); + StringRef ref{cache.string_pool.insert(str_from.data(), str_from.size() + 1), str_from.size() + 1}; + table[ref] = (*used_to)[i].reinterpret(); + } } - } - else if (from[0].getType() == Field::Types::String && to[0].getType() != Field::Types::String) - { - cache.table_string_to_num = std::make_unique(); - auto & table = *cache.table_string_to_num; - for (size_t i = 0; i < size; ++i) + else { - const String & str_from = from[i].get(); - StringRef ref{cache.string_pool.insert(str_from.data(), str_from.size() + 1), str_from.size() + 1}; - table[ref] = (*used_to)[i].reinterpret(); - } - } - else if (from[0].getType() == Field::Types::String && to[0].getType() == Field::Types::String) - { - cache.table_string_to_string = std::make_unique(); - auto & table = *cache.table_string_to_string; - for (size_t i = 0; i < size; ++i) - { - const String & str_from = from[i].get(); - const String & str_to = to[i].get(); - StringRef ref_from{cache.string_pool.insert(str_from.data(), str_from.size() + 1), str_from.size() + 1}; - StringRef ref_to{cache.string_pool.insert(str_to.data(), str_to.size() + 1), str_to.size() + 1}; - table[ref_from] = ref_to; + cache.table_string_to_string = std::make_unique(); + auto & table = *cache.table_string_to_string; + for (size_t i = 0; i < size; ++i) + { + const String & str_from = from[i].get(); + const String & str_to = to[i].get(); + StringRef ref_from{cache.string_pool.insert(str_from.data(), str_from.size() + 1), str_from.size() + 1}; + StringRef ref_to{cache.string_pool.insert(str_to.data(), str_to.size() + 1), str_to.size() + 1}; + table[ref_from] = ref_to; + } } } diff --git a/tests/queries/0_stateless/01704_transform_with_float_key.reference b/tests/queries/0_stateless/01704_transform_with_float_key.reference new file mode 100644 index 00000000000..761e15c903c --- /dev/null +++ b/tests/queries/0_stateless/01704_transform_with_float_key.reference @@ -0,0 +1,30 @@ +- +Hello +- +World +- +- +- +- +- +- +- +- +Hello +- +World +- +- +- +- +- +- +- +Hello +- +World +- +- +- +- +- diff --git a/tests/queries/0_stateless/01704_transform_with_float_key.sql b/tests/queries/0_stateless/01704_transform_with_float_key.sql new file mode 100644 index 00000000000..690c73ee28a --- /dev/null +++ b/tests/queries/0_stateless/01704_transform_with_float_key.sql @@ -0,0 +1,3 @@ +SELECT transform(number / 2, [0.5, 1.5], ['Hello', 'World'], '-') FROM numbers(10); +SELECT transform(number / 2, [1.0, 2.0], ['Hello', 'World'], '-') FROM numbers(10); +SELECT transform(number / 2, [1, 2], ['Hello', 'World'], '-') FROM numbers(10);