#pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace DB { namespace ErrorCodes { extern const int LOGICAL_ERROR; extern const int ILLEGAL_TYPE_OF_ARGUMENT; } class FunctionArrayHasAllAny : public IFunction { public: FunctionArrayHasAllAny(GatherUtils::ArraySearchType search_type_, const char * name_) : search_type(search_type_), name(name_) {} String getName() const override { return name; } bool isVariadic() const override { return false; } size_t getNumberOfArguments() const override { return 2; } DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override { for (auto i : ext::range(0, arguments.size())) { auto array_type = typeid_cast(arguments[i].get()); if (!array_type) throw Exception("Argument " + std::to_string(i) + " for function " + getName() + " must be an array but it has type " + arguments[i]->getName() + ".", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); } return std::make_shared(); } ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override { size_t num_args = arguments.size(); DataTypePtr common_type = getLeastSupertype(ext::map(arguments, [](auto & arg) { return arg.type; })); Columns preprocessed_columns(num_args); for (size_t i = 0; i < num_args; ++i) preprocessed_columns[i] = castColumn(arguments[i], common_type); std::vector> sources; for (auto & argument_column : preprocessed_columns) { bool is_const = false; if (const auto * argument_column_const = typeid_cast(argument_column.get())) { is_const = true; argument_column = argument_column_const->getDataColumnPtr(); } if (const auto * argument_column_array = typeid_cast(argument_column.get())) sources.emplace_back(GatherUtils::createArraySource(*argument_column_array, is_const, input_rows_count)); else throw Exception{"Arguments for function " + getName() + " must be arrays.", ErrorCodes::LOGICAL_ERROR}; } auto result_column = ColumnUInt8::create(input_rows_count); auto * result_column_ptr = typeid_cast(result_column.get()); GatherUtils::sliceHas(*sources[0], *sources[1], search_type, *result_column_ptr); return result_column; } bool useDefaultImplementationForConstants() const override { return true; } private: GatherUtils::ArraySearchType search_type; const char * name; }; }