From a459b2c2984b0de51209aba7793cba1cdce1a067 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Fri, 15 Mar 2019 02:10:51 +0300 Subject: [PATCH 1/2] Fixed insufficient type checking in hasAll, hasAny functions --- .../AggregateFunctionGroupArray.cpp | 1 + dbms/src/Columns/ColumnArray.h | 16 +++++++++------- dbms/src/Columns/ColumnConst.h | 8 ++++++++ dbms/src/Columns/ColumnDecimal.h | 8 ++++++++ dbms/src/Columns/ColumnFixedString.h | 7 +++++++ dbms/src/Columns/ColumnLowCardinality.h | 9 +++++++++ dbms/src/Columns/ColumnNothing.h | 5 +++++ dbms/src/Columns/ColumnNullable.h | 9 +++++++++ dbms/src/Columns/ColumnString.h | 5 +++++ dbms/src/Columns/ColumnTuple.cpp | 18 ++++++++++++++++++ dbms/src/Columns/ColumnTuple.h | 1 + dbms/src/Columns/ColumnUnique.h | 7 +++++++ dbms/src/Columns/ColumnVector.h | 6 ++++++ dbms/src/Columns/IColumn.h | 7 +++++++ dbms/src/Functions/FunctionsCoding.h | 5 +++-- .../Functions/FunctionsEmbeddedDictionaries.h | 1 + .../Functions/FunctionsExternalDictionaries.h | 2 ++ dbms/src/Functions/FunctionsFindCluster.h | 1 + dbms/src/Functions/FunctionsHashing.h | 1 + dbms/src/Functions/FunctionsStringArray.h | 1 + dbms/src/Functions/FunctionsVisitParam.h | 5 +++++ dbms/src/Functions/GatherUtils/Algorithms.h | 6 +++--- dbms/src/Functions/GatherUtils/Sources.h | 12 +++++++++++- dbms/src/Functions/arrayEnumerateRanked.cpp | 5 +++++ dbms/src/Functions/arrayReduce.cpp | 1 + dbms/src/Functions/flatten.cpp | 5 +++++ dbms/src/Functions/hasAllAny.h | 7 ++++--- dbms/src/Functions/replicate.cpp | 5 +++++ dbms/src/Functions/timeSlots.cpp | 1 + .../MergeTree/MergedBlockOutputStream.cpp | 5 +++++ ...00918_has_unsufficient_type_check.reference | 3 +++ .../00918_has_unsufficient_type_check.sql | 3 +++ 32 files changed, 160 insertions(+), 16 deletions(-) create mode 100644 dbms/tests/queries/0_stateless/00918_has_unsufficient_type_check.reference create mode 100644 dbms/tests/queries/0_stateless/00918_has_unsufficient_type_check.sql diff --git a/dbms/src/AggregateFunctions/AggregateFunctionGroupArray.cpp b/dbms/src/AggregateFunctions/AggregateFunctionGroupArray.cpp index 51bc04ea39c..1efb1a82475 100644 --- a/dbms/src/AggregateFunctions/AggregateFunctionGroupArray.cpp +++ b/dbms/src/AggregateFunctions/AggregateFunctionGroupArray.cpp @@ -12,6 +12,7 @@ namespace DB namespace ErrorCodes { extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH; + extern const int BAD_ARGUMENTS; } namespace diff --git a/dbms/src/Columns/ColumnArray.h b/dbms/src/Columns/ColumnArray.h index d58dfba025a..41e38953cf1 100644 --- a/dbms/src/Columns/ColumnArray.h +++ b/dbms/src/Columns/ColumnArray.h @@ -3,17 +3,12 @@ #include #include #include +#include + namespace DB { -namespace ErrorCodes -{ - extern const int ILLEGAL_COLUMN; - extern const int NOT_IMPLEMENTED; - extern const int BAD_ARGUMENTS; -} - /** A column of array values. * In memory, it is represented as one column of a nested type, whose size is equal to the sum of the sizes of all arrays, * and as an array of offsets in it, which allows you to get each element. @@ -121,6 +116,13 @@ public: callback(data); } + bool structureEquals(const IColumn & rhs) const override + { + if (auto rhs_concrete = typeid_cast(&rhs)) + return data->structureEquals(*rhs_concrete->data); + return false; + } + private: ColumnPtr data; ColumnPtr offsets; diff --git a/dbms/src/Columns/ColumnConst.h b/dbms/src/Columns/ColumnConst.h index 248bb04a186..53ac5b24220 100644 --- a/dbms/src/Columns/ColumnConst.h +++ b/dbms/src/Columns/ColumnConst.h @@ -3,6 +3,7 @@ #include #include #include +#include namespace DB @@ -190,6 +191,13 @@ public: callback(data); } + bool structureEquals(const IColumn & rhs) const override + { + if (auto rhs_concrete = typeid_cast(&rhs)) + return data->structureEquals(*rhs_concrete->data); + return false; + } + bool onlyNull() const override { return data->isNullAt(0); } bool isColumnConst() const override { return true; } bool isNumeric() const override { return data->isNumeric(); } diff --git a/dbms/src/Columns/ColumnDecimal.h b/dbms/src/Columns/ColumnDecimal.h index 372b0c245c0..4a3c6153947 100644 --- a/dbms/src/Columns/ColumnDecimal.h +++ b/dbms/src/Columns/ColumnDecimal.h @@ -2,6 +2,7 @@ #include +#include #include #include @@ -133,6 +134,13 @@ public: void gather(ColumnGathererStream & gatherer_stream) override; + bool structureEquals(const IColumn & rhs) const override + { + if (auto rhs_concrete = typeid_cast *>(&rhs)) + return scale == rhs_concrete->scale; + return false; + } + void insert(const T value) { data.push_back(value); } Container & getData() { return data; } diff --git a/dbms/src/Columns/ColumnFixedString.h b/dbms/src/Columns/ColumnFixedString.h index b773d7c8eb4..1f79594b459 100644 --- a/dbms/src/Columns/ColumnFixedString.h +++ b/dbms/src/Columns/ColumnFixedString.h @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -134,6 +135,12 @@ public: void getExtremes(Field & min, Field & max) const override; + bool structureEquals(const IColumn & rhs) const override + { + if (auto rhs_concrete = typeid_cast(&rhs)) + return n == rhs_concrete->n; + return false; + } bool canBeInsideNullable() const override { return true; } diff --git a/dbms/src/Columns/ColumnLowCardinality.h b/dbms/src/Columns/ColumnLowCardinality.h index 0e9cbbadebe..3b816b2449c 100644 --- a/dbms/src/Columns/ColumnLowCardinality.h +++ b/dbms/src/Columns/ColumnLowCardinality.h @@ -5,6 +5,7 @@ #include #include "ColumnsNumber.h" + namespace DB { @@ -132,6 +133,14 @@ public: callback(dictionary.getColumnUniquePtr()); } + bool structureEquals(const IColumn & rhs) const override + { + if (auto rhs_low_cardinality = typeid_cast(&rhs)) + return idx.getPositions()->structureEquals(*rhs_low_cardinality->idx.getPositions()) + && dictionary.getColumnUnique().structureEquals(rhs_low_cardinality->dictionary.getColumnUnique()); + return false; + } + bool valuesHaveFixedSize() const override { return getDictionary().valuesHaveFixedSize(); } bool isFixedAndContiguous() const override { return false; } size_t sizeOfValueIfFixed() const override { return getDictionary().sizeOfValueIfFixed(); } diff --git a/dbms/src/Columns/ColumnNothing.h b/dbms/src/Columns/ColumnNothing.h index c9cde4f26ec..0c9f843a454 100644 --- a/dbms/src/Columns/ColumnNothing.h +++ b/dbms/src/Columns/ColumnNothing.h @@ -23,6 +23,11 @@ public: MutableColumnPtr cloneDummy(size_t s_) const override { return ColumnNothing::create(s_); } bool canBeInsideNullable() const override { return true; } + + bool structureEquals(const IColumn & rhs) const override + { + return typeid(rhs) == typeid(ColumnNothing); + } }; } diff --git a/dbms/src/Columns/ColumnNullable.h b/dbms/src/Columns/ColumnNullable.h index 8012d03b0e8..8a3651b378b 100644 --- a/dbms/src/Columns/ColumnNullable.h +++ b/dbms/src/Columns/ColumnNullable.h @@ -2,6 +2,8 @@ #include #include +#include + namespace DB { @@ -89,6 +91,13 @@ public: callback(null_map); } + bool structureEquals(const IColumn & rhs) const override + { + if (auto rhs_nullable = typeid_cast(&rhs)) + return nested_column->structureEquals(*rhs_nullable->nested_column); + return false; + } + bool isColumnNullable() const override { return true; } bool isFixedAndContiguous() const override { return false; } bool valuesHaveFixedSize() const override { return nested_column->valuesHaveFixedSize(); } diff --git a/dbms/src/Columns/ColumnString.h b/dbms/src/Columns/ColumnString.h index d2d9bf2fb61..9ae32c41fd9 100644 --- a/dbms/src/Columns/ColumnString.h +++ b/dbms/src/Columns/ColumnString.h @@ -231,6 +231,11 @@ public: bool canBeInsideNullable() const override { return true; } + bool structureEquals(const IColumn & rhs) const override + { + return typeid(rhs) == typeid(ColumnString); + } + Chars & getChars() { return chars; } const Chars & getChars() const { return chars; } diff --git a/dbms/src/Columns/ColumnTuple.cpp b/dbms/src/Columns/ColumnTuple.cpp index ec0bcc1f5b5..caed6c5d6f1 100644 --- a/dbms/src/Columns/ColumnTuple.cpp +++ b/dbms/src/Columns/ColumnTuple.cpp @@ -4,6 +4,7 @@ #include #include #include +#include namespace DB @@ -341,6 +342,23 @@ void ColumnTuple::forEachSubcolumn(ColumnCallback callback) callback(column); } +bool ColumnTuple::structureEquals(const IColumn & rhs) const +{ + if (auto rhs_tuple = typeid_cast(&rhs)) + { + const size_t tuple_size = columns.size(); + if (tuple_size != rhs_tuple->columns.size()) + return false; + + for (const auto i : ext::range(0, tuple_size)) + if (!columns[i]->structureEquals(*rhs_tuple->columns[i])) + return false; + + return true; + } + else + return false; +} } diff --git a/dbms/src/Columns/ColumnTuple.h b/dbms/src/Columns/ColumnTuple.h index c39a92e3c8c..d0a65a03d37 100644 --- a/dbms/src/Columns/ColumnTuple.h +++ b/dbms/src/Columns/ColumnTuple.h @@ -73,6 +73,7 @@ public: size_t allocatedBytes() const override; void protect() override; void forEachSubcolumn(ColumnCallback callback) override; + bool structureEquals(const IColumn & rhs) const override; size_t tupleSize() const { return columns.size(); } diff --git a/dbms/src/Columns/ColumnUnique.h b/dbms/src/Columns/ColumnUnique.h index 5eee80dc9d8..a06863858ae 100644 --- a/dbms/src/Columns/ColumnUnique.h +++ b/dbms/src/Columns/ColumnUnique.h @@ -95,6 +95,13 @@ public: nested_column_nullable = ColumnNullable::create(column_holder, nested_null_mask); } + bool structureEquals(const IColumn & rhs) const override + { + if (auto rhs_concrete = typeid_cast(&rhs)) + return column_holder->structureEquals(*rhs_concrete->column_holder); + return false; + } + const UInt64 * tryGetSavedHash() const override { return index.tryGetSavedHash(); } UInt128 getHash() const override { return hash.getHash(*getRawColumnPtr()); } diff --git a/dbms/src/Columns/ColumnVector.h b/dbms/src/Columns/ColumnVector.h index 9de84f95b4a..43f6b0a3d52 100644 --- a/dbms/src/Columns/ColumnVector.h +++ b/dbms/src/Columns/ColumnVector.h @@ -251,6 +251,12 @@ public: size_t sizeOfValueIfFixed() const override { return sizeof(T); } StringRef getRawData() const override { return StringRef(reinterpret_cast(data.data()), data.size()); } + + bool structureEquals(const IColumn & rhs) const override + { + return typeid(rhs) == typeid(ColumnVector); + } + /** More efficient methods of manipulation - to manipulate with data directly. */ Container & getData() { diff --git a/dbms/src/Columns/IColumn.h b/dbms/src/Columns/IColumn.h index 86a1097d368..b7df53ed148 100644 --- a/dbms/src/Columns/IColumn.h +++ b/dbms/src/Columns/IColumn.h @@ -262,6 +262,13 @@ public: using ColumnCallback = std::function; virtual void forEachSubcolumn(ColumnCallback) {} + /// Columns have equal structure. + /// If true - you can use "compareAt", "insertFrom", etc. methods. + virtual bool structureEquals(const IColumn &) const + { + throw Exception("Method structureEquals is not supported for " + getName(), ErrorCodes::NOT_IMPLEMENTED); + } + MutablePtr mutate() const && { diff --git a/dbms/src/Functions/FunctionsCoding.h b/dbms/src/Functions/FunctionsCoding.h index 6192102b529..1f88482aa49 100644 --- a/dbms/src/Functions/FunctionsCoding.h +++ b/dbms/src/Functions/FunctionsCoding.h @@ -33,6 +33,7 @@ namespace ErrorCodes { extern const int TOO_FEW_ARGUMENTS_FOR_FUNCTION; extern const int LOGICAL_ERROR; + extern const int ILLEGAL_COLUMN; } @@ -123,8 +124,8 @@ public: } else throw Exception("Illegal column " + block.getByPosition(arguments[0]).column->getName() - + " of argument of function " + getName(), - ErrorCodes::ILLEGAL_COLUMN); + + " of argument of function " + getName(), + ErrorCodes::ILLEGAL_COLUMN); } }; diff --git a/dbms/src/Functions/FunctionsEmbeddedDictionaries.h b/dbms/src/Functions/FunctionsEmbeddedDictionaries.h index 7e5093d1ce8..e51b847f47d 100644 --- a/dbms/src/Functions/FunctionsEmbeddedDictionaries.h +++ b/dbms/src/Functions/FunctionsEmbeddedDictionaries.h @@ -36,6 +36,7 @@ namespace ErrorCodes { extern const int DICTIONARIES_WAS_NOT_LOADED; extern const int BAD_ARGUMENTS; + extern const int ILLEGAL_COLUMN; extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH; } diff --git a/dbms/src/Functions/FunctionsExternalDictionaries.h b/dbms/src/Functions/FunctionsExternalDictionaries.h index 85a5c9cc6a5..e9e0f94bb40 100644 --- a/dbms/src/Functions/FunctionsExternalDictionaries.h +++ b/dbms/src/Functions/FunctionsExternalDictionaries.h @@ -44,6 +44,8 @@ namespace ErrorCodes extern const int UNKNOWN_TYPE; extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH; extern const int TYPE_MISMATCH; + extern const int ILLEGAL_COLUMN; + extern const int BAD_ARGUMENTS; } /** Functions that use plug-ins (external) dictionaries. diff --git a/dbms/src/Functions/FunctionsFindCluster.h b/dbms/src/Functions/FunctionsFindCluster.h index 5b8db96d1ba..1b2bde45d29 100644 --- a/dbms/src/Functions/FunctionsFindCluster.h +++ b/dbms/src/Functions/FunctionsFindCluster.h @@ -20,6 +20,7 @@ namespace DB namespace ErrorCodes { extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH; + extern const int ILLEGAL_COLUMN; } enum ClusterOperation diff --git a/dbms/src/Functions/FunctionsHashing.h b/dbms/src/Functions/FunctionsHashing.h index f14a91d422e..e756e8b79e7 100644 --- a/dbms/src/Functions/FunctionsHashing.h +++ b/dbms/src/Functions/FunctionsHashing.h @@ -48,6 +48,7 @@ namespace ErrorCodes extern const int LOGICAL_ERROR; extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH; extern const int NOT_IMPLEMENTED; + extern const int ILLEGAL_COLUMN; } diff --git a/dbms/src/Functions/FunctionsStringArray.h b/dbms/src/Functions/FunctionsStringArray.h index 641a23e225c..fb89dfceda2 100644 --- a/dbms/src/Functions/FunctionsStringArray.h +++ b/dbms/src/Functions/FunctionsStringArray.h @@ -21,6 +21,7 @@ namespace ErrorCodes { extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH; extern const int BAD_ARGUMENTS; + extern const int ILLEGAL_COLUMN; } diff --git a/dbms/src/Functions/FunctionsVisitParam.h b/dbms/src/Functions/FunctionsVisitParam.h index 5b20a53135d..09cc3106719 100644 --- a/dbms/src/Functions/FunctionsVisitParam.h +++ b/dbms/src/Functions/FunctionsVisitParam.h @@ -38,6 +38,11 @@ namespace DB { +namespace ErrorCodes +{ + extern const int ILLEGAL_COLUMN; +} + struct HasParam { using ResultType = UInt8; diff --git a/dbms/src/Functions/GatherUtils/Algorithms.h b/dbms/src/Functions/GatherUtils/Algorithms.h index aaf1828f47d..9cc2d8ba21a 100644 --- a/dbms/src/Functions/GatherUtils/Algorithms.h +++ b/dbms/src/Functions/GatherUtils/Algorithms.h @@ -53,7 +53,7 @@ inline ALWAYS_INLINE void writeSlice(const StringSource::Slice & slice, FixedStr /// Assuming same types of underlying columns for slice and sink if (ArraySlice, ArraySink) is (GenericArraySlice, GenericArraySink). inline ALWAYS_INLINE void writeSlice(const GenericArraySlice & slice, GenericArraySink & sink) { - if (typeid(slice.elements) == typeid(static_cast(&sink.elements))) + if (slice.elements->structureEquals(sink.elements)) { sink.elements.insertRangeFrom(*slice.elements, slice.begin, slice.size); sink.current_offset += slice.size; @@ -125,7 +125,7 @@ void writeSlice(const NumericValueSlice & slice, NumericArraySink & sink) /// Assuming same types of underlying columns for slice and sink if (ArraySlice, ArraySink) is (GenericValueSlice, GenericArraySink). inline ALWAYS_INLINE void writeSlice(const GenericValueSlice & slice, GenericArraySink & sink) { - if (typeid(slice.elements) == typeid(static_cast(&sink.elements))) + if (slice.elements->structureEquals(sink.elements)) { sink.elements.insertFrom(*slice.elements, slice.position); ++sink.current_offset; @@ -457,7 +457,7 @@ template bool sliceHas(const GenericArraySlice & first, const GenericArraySlice & second) { /// Generic arrays should have the same type in order to use column.compareAt(...) - if (typeid(*first.elements) != typeid(*second.elements)) + if (!first.elements->structureEquals(*second.elements)) return false; auto impl = sliceHasImpl; diff --git a/dbms/src/Functions/GatherUtils/Sources.h b/dbms/src/Functions/GatherUtils/Sources.h index 40115a5a240..a70e06c98e2 100644 --- a/dbms/src/Functions/GatherUtils/Sources.h +++ b/dbms/src/Functions/GatherUtils/Sources.h @@ -14,7 +14,15 @@ #include #include -namespace DB::GatherUtils +namespace DB +{ + +namespace ErrorCodes +{ + extern const int ILLEGAL_COLUMN; +} + +namespace GatherUtils { template @@ -660,3 +668,5 @@ struct NullableValueSource : public ValueSource }; } + +} diff --git a/dbms/src/Functions/arrayEnumerateRanked.cpp b/dbms/src/Functions/arrayEnumerateRanked.cpp index 705d92ecd19..a559d64c9a0 100644 --- a/dbms/src/Functions/arrayEnumerateRanked.cpp +++ b/dbms/src/Functions/arrayEnumerateRanked.cpp @@ -6,6 +6,11 @@ namespace DB { +namespace ErrorCodes +{ + extern const int BAD_ARGUMENTS; +} + ArraysDepths getArraysDepths(const ColumnsWithTypeAndName & arguments) { const size_t num_arguments = arguments.size(); diff --git a/dbms/src/Functions/arrayReduce.cpp b/dbms/src/Functions/arrayReduce.cpp index 1bee774412d..ffab005e949 100644 --- a/dbms/src/Functions/arrayReduce.cpp +++ b/dbms/src/Functions/arrayReduce.cpp @@ -22,6 +22,7 @@ namespace ErrorCodes extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH; extern const int ILLEGAL_COLUMN; extern const int ILLEGAL_TYPE_OF_ARGUMENT; + extern const int BAD_ARGUMENTS; } diff --git a/dbms/src/Functions/flatten.cpp b/dbms/src/Functions/flatten.cpp index eb1ff7212e6..8fe743db8ea 100644 --- a/dbms/src/Functions/flatten.cpp +++ b/dbms/src/Functions/flatten.cpp @@ -7,6 +7,11 @@ namespace DB { +namespace ErrorCodes +{ + extern const int ILLEGAL_COLUMN; +} + /// flatten([[1, 2, 3], [4, 5]]) = [1, 2, 3, 4, 5] - flatten array. class FunctionFlatten : public IFunction { diff --git a/dbms/src/Functions/hasAllAny.h b/dbms/src/Functions/hasAllAny.h index 45780d0aa3c..e5f45083b8d 100644 --- a/dbms/src/Functions/hasAllAny.h +++ b/dbms/src/Functions/hasAllAny.h @@ -53,10 +53,8 @@ public: size_t rows = input_rows_count; size_t num_args = arguments.size(); - auto result_column = ColumnUInt8::create(rows); - DataTypePtr common_type = nullptr; - auto commonType = [& common_type, & block, & arguments]() + auto commonType = [&common_type, &block, &arguments]() { if (common_type == nullptr) { @@ -92,6 +90,8 @@ public: for (auto & argument_column : preprocessed_columns) { + std::cerr << argument_column->getName() << "\n"; + bool is_const = false; if (auto argument_column_const = typeid_cast(argument_column.get())) @@ -106,6 +106,7 @@ public: throw Exception{"Arguments for function " + getName() + " must be arrays.", ErrorCodes::LOGICAL_ERROR}; } + auto result_column = ColumnUInt8::create(rows); auto result_column_ptr = typeid_cast(result_column.get()); GatherUtils::sliceHas(*sources[0], *sources[1], all, *result_column_ptr); diff --git a/dbms/src/Functions/replicate.cpp b/dbms/src/Functions/replicate.cpp index 054106cfd5a..10b82953a57 100644 --- a/dbms/src/Functions/replicate.cpp +++ b/dbms/src/Functions/replicate.cpp @@ -8,6 +8,11 @@ namespace DB { +namespace ErrorCodes +{ + extern const int ILLEGAL_COLUMN; +} + /** Creates an array, multiplying the column (the first argument) by the number of elements in the array (the second argument). */ class FunctionReplicate : public IFunction diff --git a/dbms/src/Functions/timeSlots.cpp b/dbms/src/Functions/timeSlots.cpp index 7ee0d1a1b2f..ce10d96043e 100644 --- a/dbms/src/Functions/timeSlots.cpp +++ b/dbms/src/Functions/timeSlots.cpp @@ -17,6 +17,7 @@ namespace ErrorCodes { extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH; extern const int ILLEGAL_TYPE_OF_ARGUMENT; + extern const int ILLEGAL_COLUMN; } /** timeSlots(StartTime, Duration) diff --git a/dbms/src/Storages/MergeTree/MergedBlockOutputStream.cpp b/dbms/src/Storages/MergeTree/MergedBlockOutputStream.cpp index 18a5ee81923..49fa5da2afa 100644 --- a/dbms/src/Storages/MergeTree/MergedBlockOutputStream.cpp +++ b/dbms/src/Storages/MergeTree/MergedBlockOutputStream.cpp @@ -11,6 +11,11 @@ namespace DB { +namespace ErrorCodes +{ + extern const int BAD_ARGUMENTS; +} + namespace { diff --git a/dbms/tests/queries/0_stateless/00918_has_unsufficient_type_check.reference b/dbms/tests/queries/0_stateless/00918_has_unsufficient_type_check.reference new file mode 100644 index 00000000000..7938dcdde86 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00918_has_unsufficient_type_check.reference @@ -0,0 +1,3 @@ +0 +1 +0 diff --git a/dbms/tests/queries/0_stateless/00918_has_unsufficient_type_check.sql b/dbms/tests/queries/0_stateless/00918_has_unsufficient_type_check.sql new file mode 100644 index 00000000000..f76fd446a8e --- /dev/null +++ b/dbms/tests/queries/0_stateless/00918_has_unsufficient_type_check.sql @@ -0,0 +1,3 @@ +SELECT hasAny([['Hello, world']], [[[]]]); +SELECT hasAny([['Hello, world']], [['Hello', 'world'], ['Hello, world']]); +SELECT hasAll([['Hello, world']], [['Hello', 'world'], ['Hello, world']]); From f7bdc657d34a7bfca336874d5f1e076515c294f8 Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Fri, 15 Mar 2019 02:12:30 +0300 Subject: [PATCH 2/2] Update hasAllAny.h --- dbms/src/Functions/hasAllAny.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/dbms/src/Functions/hasAllAny.h b/dbms/src/Functions/hasAllAny.h index e5f45083b8d..b688406fd91 100644 --- a/dbms/src/Functions/hasAllAny.h +++ b/dbms/src/Functions/hasAllAny.h @@ -90,8 +90,6 @@ public: for (auto & argument_column : preprocessed_columns) { - std::cerr << argument_column->getName() << "\n"; - bool is_const = false; if (auto argument_column_const = typeid_cast(argument_column.get()))