#pragma once #include #include #include #include #include #include #include #include namespace DB { struct Settings; namespace ErrorCodes { extern const int INCORRECT_DATA; } /// Returns the same type as the first argument struct NameAggregateFunctionNothing { static constexpr auto name = "nothing"; }; /// Always returns Nullable(Nothing) struct NameAggregateFunctionNothingNull { static constexpr auto name = "nothingNull"; }; /// Always returns UInt64 struct NameAggregateFunctionNothingUInt64 { static constexpr auto name = "nothingUInt64"; }; template class AggregateFunctionNothingImpl; using AggregateFunctionNothing = AggregateFunctionNothingImpl; using AggregateFunctionNothingNull = AggregateFunctionNothingImpl; using AggregateFunctionNothingUInt64 = AggregateFunctionNothingImpl; /** Aggregate function that takes arbitrary number of arbitrary arguments and does nothing. */ template class AggregateFunctionNothingImpl final : public IAggregateFunctionHelper> { static DataTypePtr getReturnType(const DataTypes & arguments [[maybe_unused]]) { if constexpr (std::is_same_v) return std::make_shared(); else if constexpr (std::is_same_v) return std::make_shared(std::make_shared()); return arguments.empty() ? std::make_shared(std::make_shared()) : arguments.front(); } public: AggregateFunctionNothingImpl(const DataTypes & arguments, const Array & params) : IAggregateFunctionHelper>(arguments, params, getReturnType(arguments)) { } String getName() const override { return Name::name; } bool allocatesMemoryInArena() const override { return false; } void create(AggregateDataPtr __restrict) const override { } void destroy(AggregateDataPtr __restrict) const noexcept override { } bool hasTrivialDestructor() const override { return true; } size_t sizeOfData() const override { return 0; } size_t alignOfData() const override { return 1; } void add(AggregateDataPtr __restrict, const IColumn **, size_t, Arena *) const override { } void merge(AggregateDataPtr __restrict, ConstAggregateDataPtr, Arena *) const override { } void serialize(ConstAggregateDataPtr __restrict, WriteBuffer & buf, std::optional) const override { writeChar('\0', buf); } void deserialize(AggregateDataPtr __restrict, ReadBuffer & buf, std::optional, Arena *) const override { [[maybe_unused]] char symbol; readChar(symbol, buf); if (symbol != '\0') throw Exception(ErrorCodes::INCORRECT_DATA, "Incorrect state of aggregate function '{}', it should contain exactly one zero byte, while it is {}", getName(), static_cast(symbol)); } void insertResultInto(AggregateDataPtr __restrict, IColumn & to, Arena *) const override { to.insertDefault(); } }; }