From 7f6c48d5dea2f22a050c9327c632a58e22069d4c Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sat, 9 Dec 2017 10:32:32 +0300 Subject: [PATCH] Cleanup semantics of data types [#CLICKHOUSE-2]. --- .../AggregateFunctionNull.h | 12 +---- dbms/src/Columns/ColumnVector.h | 4 +- dbms/src/Columns/IColumn.h | 46 +++++++++-------- dbms/src/Common/UInt128.h | 2 +- dbms/src/Core/Types.h | 50 +++++++------------ .../AddingDefaultBlockOutputStream.cpp | 2 +- dbms/src/DataStreams/isConvertableTypes.cpp | 7 --- dbms/src/DataTypes/DataTypeNullable.cpp | 15 ++++++ dbms/src/DataTypes/DataTypeNullable.h | 4 ++ dbms/src/DataTypes/DataTypeTraits.cpp | 17 ------- dbms/src/DataTypes/DataTypeTraits.h | 18 ------- dbms/src/Functions/CMakeLists.txt | 4 +- dbms/src/Functions/FunctionsArithmetic.h | 9 ---- dbms/src/Functions/FunctionsArray.h | 5 +- dbms/src/Functions/FunctionsConditional.cpp | 2 +- dbms/src/Functions/FunctionsConditional.h | 27 ++-------- dbms/src/Functions/FunctionsNull.cpp | 22 +++----- dbms/src/Functions/GatherUtils.h | 2 - dbms/src/Interpreters/Join.cpp | 10 +--- dbms/src/Interpreters/Set.cpp | 5 +- dbms/src/Interpreters/convertFieldToType.cpp | 5 +- 21 files changed, 91 insertions(+), 177 deletions(-) delete mode 100644 dbms/src/DataTypes/DataTypeTraits.cpp delete mode 100644 dbms/src/DataTypes/DataTypeTraits.h diff --git a/dbms/src/AggregateFunctions/AggregateFunctionNull.h b/dbms/src/AggregateFunctions/AggregateFunctionNull.h index 763097fb7c8..e8bba9a23fc 100644 --- a/dbms/src/AggregateFunctions/AggregateFunctionNull.h +++ b/dbms/src/AggregateFunctions/AggregateFunctionNull.h @@ -196,7 +196,7 @@ public: if (!arguments.front()->isNullable()) throw Exception("Logical error: not nullable data type is passed to AggregateFunctionNullUnary", ErrorCodes::LOGICAL_ERROR); - this->nested_function->setArguments({static_cast(*arguments.front()).getNestedType()}); + this->nested_function->setArguments({removeNullable(arguments.front())}); } void add(AggregateDataPtr place, const IColumn ** columns, size_t row_num, Arena * arena) const override @@ -246,15 +246,7 @@ public: for (size_t i = 0; i < number_of_arguments; ++i) { is_nullable[i] = arguments[i]->isNullable(); - - if (is_nullable[i]) - { - const DataTypeNullable & nullable_type = static_cast(*arguments[i]); - const DataTypePtr & nested_type = nullable_type.getNestedType(); - nested_args[i] = nested_type; - } - else - nested_args[i] = arguments[i]; + nested_args[i] = removeNullable(arguments[i]); } this->nested_function->setArguments(nested_args); diff --git a/dbms/src/Columns/ColumnVector.h b/dbms/src/Columns/ColumnVector.h index 8cbab646b31..0e360a7c1da 100644 --- a/dbms/src/Columns/ColumnVector.h +++ b/dbms/src/Columns/ColumnVector.h @@ -136,8 +136,8 @@ public: ColumnVector(const size_t n) : data{n} {} ColumnVector(const size_t n, const value_type x) : data{n, x} {} - bool isNumeric() const override { return IsNumber::value; } - bool isFixed() const override { return IsNumber::value; } + bool isNumeric() const override { return IsNumber; } + bool isFixed() const override { return IsNumber; } size_t sizeOfField() const override { return sizeof(T); } diff --git a/dbms/src/Columns/IColumn.h b/dbms/src/Columns/IColumn.h index 77e93cbe002..2b751c23193 100644 --- a/dbms/src/Columns/IColumn.h +++ b/dbms/src/Columns/IColumn.h @@ -42,21 +42,6 @@ public: /// Name of a Column kind, without parameters (example: FixedString, Array). virtual const char * getFamilyName() const = 0; - /// Column is vector of numbers or numeric constant. - virtual bool isNumeric() const { return false; } - - /// Is this column numeric and not nullable? - virtual bool isNumericNotNullable() const { return isNumeric(); } - - /// Column stores a constant value. - virtual bool isConst() const { return false; } - - /// Is this column a container for nullable values? - virtual bool isNullable() const { return false; } - - /// Is this a null column? - virtual bool isNull() const { return false; } - /** If column isn't constant, returns nullptr (or itself). * If column is constant, transforms constant to full column (if column type allows such tranform) and return it. * Special case: @@ -65,12 +50,6 @@ public: */ virtual ColumnPtr convertToFullColumnIfConst() const { return {}; } - /// Values in column have equal size in memory. - virtual bool isFixed() const { return false; } - - /// If column isFixed(), returns size of value. - virtual size_t sizeOfField() const { throw Exception("Cannot get sizeOfField() for column " + getName(), ErrorCodes::CANNOT_GET_SIZE_OF_FIELD); } - /// Creates the same column with the same data. virtual ColumnPtr clone() const { return cut(0, size()); } @@ -271,6 +250,31 @@ public: using ColumnCallback = std::function; virtual void forEachSubcolumn(ColumnCallback) {} + + /// Various properties on behaviour of column type. + + /// Column is vector of numbers or numeric constant. + virtual bool isNumeric() const { return false; } + + /// Is this column numeric and not nullable? + virtual bool isNumericNotNullable() const { return isNumeric(); } + + /// Column stores a constant value. + virtual bool isConst() const { return false; } + + /// Is this column a container for nullable values? + virtual bool isNullable() const { return false; } + + /// Is this a null column? + virtual bool isNull() const { return false; } + + /// Values in column have equal size in memory. + virtual bool isFixed() const { return false; } + + /// If column isFixed(), returns size of value. + virtual size_t sizeOfField() const { throw Exception("Cannot get sizeOfField() for column " + getName(), ErrorCodes::CANNOT_GET_SIZE_OF_FIELD); } + + virtual ~IColumn() {} String dumpStructure() const; diff --git a/dbms/src/Common/UInt128.h b/dbms/src/Common/UInt128.h index 134ede4e68a..7b574508844 100644 --- a/dbms/src/Common/UInt128.h +++ b/dbms/src/Common/UInt128.h @@ -66,7 +66,7 @@ template bool inline operator> (T a, const UInt128 b) { return UIn template bool inline operator<= (T a, const UInt128 b) { return UInt128(a) <= b; } template bool inline operator< (T a, const UInt128 b) { return UInt128(a) < b; } -template <> struct IsNumber { static constexpr bool value = true; }; +template <> bool IsNumber = true; template <> struct TypeName { static const char * get() { return "UInt128"; } }; struct UInt128Hash diff --git a/dbms/src/Core/Types.h b/dbms/src/Core/Types.h index 21fc58304e8..8b9cfcbc5f6 100644 --- a/dbms/src/Core/Types.h +++ b/dbms/src/Core/Types.h @@ -3,16 +3,14 @@ #include #include #include -#include namespace DB { -/** Data types for representing values from a database in RAM. - */ +/// Data types for representing elementary values from a database in RAM. -STRONG_TYPEDEF(char, Null); +struct Null {}; using UInt8 = Poco::UInt8; using UInt16 = Poco::UInt16; @@ -28,39 +26,24 @@ using Float32 = float; using Float64 = double; using String = std::string; -using Strings = std::vector; -/// Ordinary types with nullability. -template struct Nullable { using Type = T; }; -/// Get a non-nullable type. -template struct RemoveNullable { using Type = T; }; -template struct RemoveNullable> { using Type = T; }; - -/// Check if a type is nullable. -template struct IsNullable { static constexpr bool value = false; }; -template struct IsNullable> { static constexpr bool value = true; }; - -template struct IsNumber { static constexpr bool value = false; }; -template struct IsNumber> { static constexpr bool value = IsNumber::value; }; - -template <> struct IsNumber { static constexpr bool value = true; }; -template <> struct IsNumber { static constexpr bool value = true; }; -template <> struct IsNumber { static constexpr bool value = true; }; -template <> struct IsNumber { static constexpr bool value = true; }; -template <> struct IsNumber { static constexpr bool value = true; }; -template <> struct IsNumber { static constexpr bool value = true; }; -template <> struct IsNumber { static constexpr bool value = true; }; -template <> struct IsNumber { static constexpr bool value = true; }; -template <> struct IsNumber { static constexpr bool value = true; }; -template <> struct IsNumber { static constexpr bool value = true; }; +/** Note that for types not used in DB, IsNumber is false. + */ +template bool IsNumber = false; +template <> bool IsNumber = true; +template <> bool IsNumber = true; +template <> bool IsNumber = true; +template <> bool IsNumber = true; +template <> bool IsNumber = true; +template <> bool IsNumber = true; +template <> bool IsNumber = true; +template <> bool IsNumber = true; +template <> bool IsNumber = true; +template <> bool IsNumber = true; template struct TypeName; -template struct TypeName> { static const char * get() { return "Nullable"; } }; - -template <> struct TypeName { static const char * get() { return "Null"; } }; -template <> struct TypeName> : TypeName {}; template <> struct TypeName { static const char * get() { return "UInt8"; } }; template <> struct TypeName { static const char * get() { return "UInt16"; } }; @@ -75,4 +58,7 @@ template <> struct TypeName { static const char * get() { return "Float template <> struct TypeName { static const char * get() { return "String"; } }; +/// Not a data type in database, defined just for convenience. +using Strings = std::vector; + } diff --git a/dbms/src/DataStreams/AddingDefaultBlockOutputStream.cpp b/dbms/src/DataStreams/AddingDefaultBlockOutputStream.cpp index 6c8b4d2b96c..4a4beb12f13 100644 --- a/dbms/src/DataStreams/AddingDefaultBlockOutputStream.cpp +++ b/dbms/src/DataStreams/AddingDefaultBlockOutputStream.cpp @@ -58,7 +58,7 @@ void AddingDefaultBlockOutputStream::write(const DB::Block & block) if (offset_columns.count(offsets_name)) { ColumnPtr offsets_column = offset_columns[offsets_name]; - DataTypePtr nested_type = typeid_cast(*column_to_add.type).getNestedType(); + DataTypePtr nested_type = typeid_cast(*column_to_add.type).getNestedType(); UInt64 nested_rows = rows ? get((*offsets_column)[rows - 1]) : 0; ColumnPtr nested_column = nested_type->createConstColumn(nested_rows, nested_type->getDefault())->convertToFullColumnIfConst(); diff --git a/dbms/src/DataStreams/isConvertableTypes.cpp b/dbms/src/DataStreams/isConvertableTypes.cpp index d01aedc7a61..23120c4abe6 100644 --- a/dbms/src/DataStreams/isConvertableTypes.cpp +++ b/dbms/src/DataStreams/isConvertableTypes.cpp @@ -8,13 +8,6 @@ namespace DB { -static DataTypePtr removeNullable(const DataTypePtr & type) -{ - if (type->isNullable()) - return typeid_cast(type.get())->getNestedType(); - return type; -} - bool isConvertableTypes(const DataTypePtr & from, const DataTypePtr & to) { auto from_nn = removeNullable(from); diff --git a/dbms/src/DataTypes/DataTypeNullable.cpp b/dbms/src/DataTypes/DataTypeNullable.cpp index d27ba2352d9..1f2fd1c8e05 100644 --- a/dbms/src/DataTypes/DataTypeNullable.cpp +++ b/dbms/src/DataTypes/DataTypeNullable.cpp @@ -303,4 +303,19 @@ void registerDataTypeNullable(DataTypeFactory & factory) factory.registerDataType("Nullable", create); } + +DataTypePtr makeNullable(const DataTypePtr & type) +{ + if (type->isNullable()) + return type; + return std::make_shared(type); +} + +DataTypePtr removeNullable(const DataTypePtr & type) +{ + if (type->isNullable()) + return static_cast(*type).getNestedType(); + return type; +} + } diff --git a/dbms/src/DataTypes/DataTypeNullable.h b/dbms/src/DataTypes/DataTypeNullable.h index f0877c0ee5c..660d40a9b3f 100644 --- a/dbms/src/DataTypes/DataTypeNullable.h +++ b/dbms/src/DataTypes/DataTypeNullable.h @@ -86,4 +86,8 @@ private: DataTypePtr nested_data_type; }; + +DataTypePtr makeNullable(const DataTypePtr & type); +DataTypePtr removeNullable(const DataTypePtr & type); + } diff --git a/dbms/src/DataTypes/DataTypeTraits.cpp b/dbms/src/DataTypes/DataTypeTraits.cpp deleted file mode 100644 index 20db89fdfe5..00000000000 --- a/dbms/src/DataTypes/DataTypeTraits.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include -#include - -namespace DB { namespace DataTypeTraits { - -const DataTypePtr & removeNullable(const DataTypePtr & type) -{ - if (type->isNullable()) - { - const auto & nullable_type = static_cast(*type); - return nullable_type.getNestedType(); - } - else - return type; -} - -}} diff --git a/dbms/src/DataTypes/DataTypeTraits.h b/dbms/src/DataTypes/DataTypeTraits.h deleted file mode 100644 index 37c5c810b86..00000000000 --- a/dbms/src/DataTypes/DataTypeTraits.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include - - -namespace DB -{ - -namespace DataTypeTraits -{ - -/// If the input type is nullable, return its nested type. -/// Otherwise it is an identity mapping. -const DataTypePtr & removeNullable(const DataTypePtr & type); - -} - -} diff --git a/dbms/src/Functions/CMakeLists.txt b/dbms/src/Functions/CMakeLists.txt index 0ecb0091192..cf93b880276 100644 --- a/dbms/src/Functions/CMakeLists.txt +++ b/dbms/src/Functions/CMakeLists.txt @@ -67,8 +67,8 @@ add_headers_and_sources(clickhouse_functions .) add_headers_and_sources(clickhouse_functions ./Conditional) add_headers_and_sources(clickhouse_functions ${ClickHouse_BINARY_DIR}/dbms/src/Functions) -list(REMOVE_ITEM clickhouse_functions_sources IFunction.cpp FunctionFactory.cpp DataTypeTraits.cpp FunctionHelpers.cpp) -list(REMOVE_ITEM clickhouse_functions_headers IFunction.h FunctionFactory.h DataTypeTraits.h FunctionHelpers.h) +list(REMOVE_ITEM clickhouse_functions_sources IFunction.cpp FunctionFactory.cpp FunctionHelpers.cpp) +list(REMOVE_ITEM clickhouse_functions_headers IFunction.h FunctionFactory.h FunctionHelpers.h) add_library(clickhouse_functions ${clickhouse_functions_sources}) target_link_libraries(clickhouse_functions dbms) diff --git a/dbms/src/Functions/FunctionsArithmetic.h b/dbms/src/Functions/FunctionsArithmetic.h index ac2c0d6158b..b7f07a3d02f 100644 --- a/dbms/src/Functions/FunctionsArithmetic.h +++ b/dbms/src/Functions/FunctionsArithmetic.h @@ -484,15 +484,6 @@ template <> struct IsIntegral { static constexpr auto value = tru template <> struct IsIntegral { static constexpr auto value = true; }; template <> struct IsIntegral { static constexpr auto value = true; }; -template struct IsFloating { static constexpr auto value = false; }; -template <> struct IsFloating { static constexpr auto value = true; }; -template <> struct IsFloating { static constexpr auto value = true; }; - -template struct IsNumeric -{ - static constexpr auto value = IsIntegral::value || IsFloating::value; -}; - template struct IsDateOrDateTime { static constexpr auto value = false; }; template <> struct IsDateOrDateTime { static constexpr auto value = true; }; template <> struct IsDateOrDateTime { static constexpr auto value = true; }; diff --git a/dbms/src/Functions/FunctionsArray.h b/dbms/src/Functions/FunctionsArray.h index 605289b8375..e37e662f98c 100644 --- a/dbms/src/Functions/FunctionsArray.h +++ b/dbms/src/Functions/FunctionsArray.h @@ -15,7 +15,6 @@ #include #include -#include #include #include #include @@ -1024,8 +1023,8 @@ public: if (!arguments[1]->onlyNull()) { - const IDataType * observed_type0 = DataTypeTraits::removeNullable(array_type->getNestedType()).get(); - const IDataType * observed_type1 = DataTypeTraits::removeNullable(arguments[1]).get(); + DataTypePtr observed_type0 = removeNullable(array_type->getNestedType()); + DataTypePtr observed_type1 = removeNullable(arguments[1]); if (!(observed_type0->isNumber() && observed_type1->isNumber()) && !observed_type0->equals(*observed_type1)) diff --git a/dbms/src/Functions/FunctionsConditional.cpp b/dbms/src/Functions/FunctionsConditional.cpp index e8977fbb33c..6520ded2213 100644 --- a/dbms/src/Functions/FunctionsConditional.cpp +++ b/dbms/src/Functions/FunctionsConditional.cpp @@ -216,7 +216,7 @@ DataTypePtr FunctionMultiIf::getReturnTypeImpl(const DataTypes & args) const DataTypePtr common_type_of_branches = getLeastCommonType(types_of_branches); return have_nullable_condition - ? makeNullableDataTypeIfNot(common_type_of_branches) + ? makeNullable(common_type_of_branches) : common_type_of_branches; } diff --git a/dbms/src/Functions/FunctionsConditional.h b/dbms/src/Functions/FunctionsConditional.h index 2212f14ecaf..13e40baa526 100644 --- a/dbms/src/Functions/FunctionsConditional.h +++ b/dbms/src/Functions/FunctionsConditional.h @@ -110,15 +110,6 @@ public: }; -inline const DataTypePtr makeNullableDataTypeIfNot(const DataTypePtr & type) -{ - if (type->isNullable()) - return type; - - return std::make_shared(type); -} - - class FunctionIf : public IFunction { public: @@ -636,14 +627,6 @@ private: return column; } - static const DataTypePtr getNestedDataType(const DataTypePtr & type) - { - if (type->isNullable()) - return static_cast(*type).getNestedType(); - - return type; - } - bool executeForNullableThenElse(Block & block, const ColumnNumbers & arguments, size_t result) { const ColumnWithTypeAndName & arg_cond = block.getByPosition(arguments[0]); @@ -698,17 +681,17 @@ private: arg_cond, { getNestedColumn(arg_then.column), - getNestedDataType(arg_then.type), + removeNullable(arg_then.type), "" }, { getNestedColumn(arg_else.column), - getNestedDataType(arg_else.type), + removeNullable(arg_else.type), "" }, { nullptr, - getNestedDataType(block.getByPosition(result).type), + removeNullable(block.getByPosition(result).type), "" } }); @@ -834,8 +817,8 @@ public: return arguments[0]; if (arguments[0]->isNullable()) - return makeNullableDataTypeIfNot(getReturnTypeImpl({ - getNestedDataType(arguments[0]), arguments[1], arguments[2]})); + return makeNullable(getReturnTypeImpl({ + removeNullable(arguments[0]), arguments[1], arguments[2]})); if (!checkDataType(arguments[0].get())) throw Exception("Illegal type " + arguments[0]->getName() + " of first argument (condition) of function if. Must be UInt8.", diff --git a/dbms/src/Functions/FunctionsNull.cpp b/dbms/src/Functions/FunctionsNull.cpp index 18c718f235a..158f33f6c93 100644 --- a/dbms/src/Functions/FunctionsNull.cpp +++ b/dbms/src/Functions/FunctionsNull.cpp @@ -98,14 +98,6 @@ void FunctionIsNotNull::executeImpl(Block & block, const ColumnNumbers & argumen /// Implementation of coalesce. -static const DataTypePtr getNestedDataType(const DataTypePtr & type) -{ - if (type->isNullable()) - return static_cast(*type).getNestedType(); - - return type; -} - FunctionPtr FunctionCoalesce::create(const Context & context) { return std::make_shared(context); @@ -144,7 +136,7 @@ DataTypePtr FunctionCoalesce::getReturnTypeImpl(const DataTypes & arguments) con else { new_args.push_back(std::make_shared()); - new_args.push_back(getNestedDataType(filtered_args[i])); + new_args.push_back(removeNullable(filtered_args[i])); } } @@ -157,7 +149,7 @@ DataTypePtr FunctionCoalesce::getReturnTypeImpl(const DataTypes & arguments) con /// if last argument is not nullable, result should be also not nullable if (!new_args.back()->isNullable() && res->isNullable()) - res = getNestedDataType(res); + res = removeNullable(res); return res; } @@ -202,7 +194,7 @@ void FunctionCoalesce::executeImpl(Block & block, const ColumnNumbers & argument { temp_block.insert({nullptr, std::make_shared(), ""}); is_not_null.execute(temp_block, {filtered_args[i]}, res_pos); - temp_block.insert({nullptr, getNestedDataType(block.getByPosition(filtered_args[i]).type), ""}); + temp_block.insert({nullptr, removeNullable(block.getByPosition(filtered_args[i]).type), ""}); assume_not_null.execute(temp_block, {filtered_args[i]}, res_pos + 1); multi_if_args.push_back(res_pos); @@ -254,7 +246,7 @@ DataTypePtr FunctionIfNull::getReturnTypeImpl(const DataTypes & arguments) const if (!arguments[0]->isNullable()) return arguments[0]; - return FunctionIf{}.getReturnTypeImpl({std::make_shared(), getNestedDataType(arguments[0]), arguments[1]}); + return FunctionIf{}.getReturnTypeImpl({std::make_shared(), removeNullable(arguments[0]), arguments[1]}); } void FunctionIfNull::executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) @@ -280,7 +272,7 @@ void FunctionIfNull::executeImpl(Block & block, const ColumnNumbers & arguments, size_t is_not_null_pos = temp_block.columns(); temp_block.insert({nullptr, std::make_shared(), ""}); size_t assume_not_null_pos = temp_block.columns(); - temp_block.insert({nullptr, getNestedDataType(block.getByPosition(arguments[0]).type), ""}); + temp_block.insert({nullptr, removeNullable(block.getByPosition(arguments[0]).type), ""}); FunctionIsNotNull{}.execute(temp_block, {arguments[0]}, is_not_null_pos); FunctionAssumeNotNull{}.execute(temp_block, {arguments[0]}, assume_not_null_pos); @@ -308,7 +300,7 @@ std::string FunctionNullIf::getName() const DataTypePtr FunctionNullIf::getReturnTypeImpl(const DataTypes & arguments) const { - return FunctionIf{}.getReturnTypeImpl({std::make_shared(), makeNullableDataTypeIfNot(arguments[0]), arguments[0]}); + return FunctionIf{}.getReturnTypeImpl({std::make_shared(), makeNullable(arguments[0]), arguments[0]}); } void FunctionNullIf::executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) @@ -352,7 +344,7 @@ std::string FunctionAssumeNotNull::getName() const DataTypePtr FunctionAssumeNotNull::getReturnTypeImpl(const DataTypes & arguments) const { - return getNestedDataType(arguments[0]); + return removeNullable(arguments[0]); } void FunctionAssumeNotNull::executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) diff --git a/dbms/src/Functions/GatherUtils.h b/dbms/src/Functions/GatherUtils.h index 5ef29cc8add..d7d781344bf 100644 --- a/dbms/src/Functions/GatherUtils.h +++ b/dbms/src/Functions/GatherUtils.h @@ -18,8 +18,6 @@ #include #include -#include - /** These methods are intended for implementation of functions, that * copy ranges from one or more columns to another column. * diff --git a/dbms/src/Interpreters/Join.cpp b/dbms/src/Interpreters/Join.cpp index 4d9032d14f3..521a64d3c75 100644 --- a/dbms/src/Interpreters/Join.cpp +++ b/dbms/src/Interpreters/Join.cpp @@ -862,14 +862,8 @@ void Join::checkTypesOfKeys(const Block & block_left, const Block & block_right) { /// Compare up to Nullability. - IDataType * left_type = block_left.getByName(key_names_left[i]).type.get(); - IDataType * right_type = block_right.getByName(key_names_right[i]).type.get(); - - if (left_type->isNullable()) - left_type = static_cast(*left_type).getNestedType().get(); - - if (right_type->isNullable()) - right_type = static_cast(*right_type).getNestedType().get(); + DataTypePtr left_type = removeNullable(block_left.getByName(key_names_left[i]).type); + DataTypePtr right_type = removeNullable(block_right.getByName(key_names_right[i]).type); if (!left_type->equals(*right_type)) throw Exception("Type mismatch of columns to JOIN by: " diff --git a/dbms/src/Interpreters/Set.cpp b/dbms/src/Interpreters/Set.cpp index 2c11cdd423f..35bd26fcedb 100644 --- a/dbms/src/Interpreters/Set.cpp +++ b/dbms/src/Interpreters/Set.cpp @@ -11,7 +11,7 @@ #include #include -#include +#include #include #include @@ -367,8 +367,7 @@ ColumnPtr Set::execute(const Block & block, bool negative) const { key_columns.push_back(block.safeGetByPosition(i).column.get()); - if (DataTypeTraits::removeNullable(data_types[i])->getName() != - DataTypeTraits::removeNullable(block.safeGetByPosition(i).type)->getName()) + if (removeNullable(data_types[i])->equals(*removeNullable(block.safeGetByPosition(i).type))) throw Exception("Types of column " + toString(i + 1) + " in section IN don't match: " + data_types[i]->getName() + " on the right, " + block.safeGetByPosition(i).type->getName() + " on the left.", ErrorCodes::TYPE_MISMATCH); diff --git a/dbms/src/Interpreters/convertFieldToType.cpp b/dbms/src/Interpreters/convertFieldToType.cpp index 1f53deeb003..7110c418011 100644 --- a/dbms/src/Interpreters/convertFieldToType.cpp +++ b/dbms/src/Interpreters/convertFieldToType.cpp @@ -12,7 +12,6 @@ #include #include #include -#include #include #include @@ -166,14 +165,14 @@ Field convertFieldToTypeImpl(const Field & src, const IDataType & type) { if (src.getType() == Field::Types::Array) { - const IDataType & nested_type = *DataTypeTraits::removeNullable(type_array->getNestedType()); + const DataTypePtr nested_type = removeNullable(type_array->getNestedType()); const Array & src_arr = src.get(); size_t src_arr_size = src_arr.size(); Array res(src_arr_size); for (size_t i = 0; i < src_arr_size; ++i) - res[i] = convertFieldToType(src_arr[i], nested_type); + res[i] = convertFieldToType(src_arr[i], *nested_type); return res; }