Merge pull request #70651 from ClickHouse/backport/24.8/70631

Backport #70631 to 24.8: Fix creation of stateful window functions on misaligned memory
This commit is contained in:
Raúl Marín 2024-10-15 18:29:05 +08:00 committed by GitHub
commit 185337a8e2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 38 additions and 30 deletions

View File

@ -78,11 +78,6 @@ struct WindowFunction : public IAggregateFunctionHelper<WindowFunction>, public
}
String getName() const override { return name; }
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 { fail(); }
void merge(AggregateDataPtr __restrict, ConstAggregateDataPtr, Arena *) const override { fail(); }
void serialize(ConstAggregateDataPtr __restrict, WriteBuffer &, std::optional<size_t>) const override { fail(); }
@ -90,6 +85,22 @@ struct WindowFunction : public IAggregateFunctionHelper<WindowFunction>, public
void insertResultInto(AggregateDataPtr __restrict, IColumn &, Arena *) const override { fail(); }
};
struct StatelessWindowFunction : public WindowFunction
{
StatelessWindowFunction(
const std::string & name_, const DataTypes & argument_types_, const Array & parameters_, const DataTypePtr & result_type_)
: WindowFunction(name_, argument_types_, parameters_, result_type_)
{
}
size_t sizeOfData() const override { return 0; }
size_t alignOfData() const override { return 1; }
void create(AggregateDataPtr __restrict) const override { }
void destroy(AggregateDataPtr __restrict) const noexcept override { }
bool hasTrivialDestructor() const override { return true; }
};
template <typename State>
struct StatefulWindowFunction : public WindowFunction
{
@ -100,7 +111,7 @@ struct StatefulWindowFunction : public WindowFunction
}
size_t sizeOfData() const override { return sizeof(State); }
size_t alignOfData() const override { return 1; }
size_t alignOfData() const override { return alignof(State); }
void create(AggregateDataPtr __restrict place) const override { new (place) State(); }

View File

@ -1500,11 +1500,10 @@ void WindowTransform::work()
}
}
struct WindowFunctionRank final : public WindowFunction
struct WindowFunctionRank final : public StatelessWindowFunction
{
WindowFunctionRank(const std::string & name_,
const DataTypes & argument_types_, const Array & parameters_)
: WindowFunction(name_, argument_types_, parameters_, std::make_shared<DataTypeUInt64>())
WindowFunctionRank(const std::string & name_, const DataTypes & argument_types_, const Array & parameters_)
: StatelessWindowFunction(name_, argument_types_, parameters_, std::make_shared<DataTypeUInt64>())
{}
bool allocatesMemoryInArena() const override { return false; }
@ -1519,11 +1518,10 @@ struct WindowFunctionRank final : public WindowFunction
}
};
struct WindowFunctionDenseRank final : public WindowFunction
struct WindowFunctionDenseRank final : public StatelessWindowFunction
{
WindowFunctionDenseRank(const std::string & name_,
const DataTypes & argument_types_, const Array & parameters_)
: WindowFunction(name_, argument_types_, parameters_, std::make_shared<DataTypeUInt64>())
WindowFunctionDenseRank(const std::string & name_, const DataTypes & argument_types_, const Array & parameters_)
: StatelessWindowFunction(name_, argument_types_, parameters_, std::make_shared<DataTypeUInt64>())
{}
bool allocatesMemoryInArena() const override { return false; }
@ -1721,7 +1719,7 @@ struct WindowFunctionExponentialTimeDecayedSum final : public StatefulWindowFunc
const Float64 decay_length;
};
struct WindowFunctionExponentialTimeDecayedMax final : public WindowFunction
struct WindowFunctionExponentialTimeDecayedMax final : public StatelessWindowFunction
{
static constexpr size_t ARGUMENT_VALUE = 0;
static constexpr size_t ARGUMENT_TIME = 1;
@ -1736,9 +1734,8 @@ struct WindowFunctionExponentialTimeDecayedMax final : public WindowFunction
return applyVisitor(FieldVisitorConvertToNumber<Float64>(), parameters_[0]);
}
WindowFunctionExponentialTimeDecayedMax(const std::string & name_,
const DataTypes & argument_types_, const Array & parameters_)
: WindowFunction(name_, argument_types_, parameters_, std::make_shared<DataTypeFloat64>())
WindowFunctionExponentialTimeDecayedMax(const std::string & name_, const DataTypes & argument_types_, const Array & parameters_)
: StatelessWindowFunction(name_, argument_types_, parameters_, std::make_shared<DataTypeFloat64>())
, decay_length(getDecayLength(parameters_, name_))
{
if (argument_types.size() != 2)
@ -1996,11 +1993,10 @@ struct WindowFunctionExponentialTimeDecayedAvg final : public StatefulWindowFunc
const Float64 decay_length;
};
struct WindowFunctionRowNumber final : public WindowFunction
struct WindowFunctionRowNumber final : public StatelessWindowFunction
{
WindowFunctionRowNumber(const std::string & name_,
const DataTypes & argument_types_, const Array & parameters_)
: WindowFunction(name_, argument_types_, parameters_, std::make_shared<DataTypeUInt64>())
WindowFunctionRowNumber(const std::string & name_, const DataTypes & argument_types_, const Array & parameters_)
: StatelessWindowFunction(name_, argument_types_, parameters_, std::make_shared<DataTypeUInt64>())
{}
bool allocatesMemoryInArena() const override { return false; }
@ -2278,13 +2274,12 @@ public:
// ClickHouse-specific variant of lag/lead that respects the window frame.
template <bool is_lead>
struct WindowFunctionLagLeadInFrame final : public WindowFunction
struct WindowFunctionLagLeadInFrame final : public StatelessWindowFunction
{
FunctionBasePtr func_cast = nullptr;
WindowFunctionLagLeadInFrame(const std::string & name_,
const DataTypes & argument_types_, const Array & parameters_)
: WindowFunction(name_, argument_types_, parameters_, createResultType(argument_types_, name_))
WindowFunctionLagLeadInFrame(const std::string & name_, const DataTypes & argument_types_, const Array & parameters_)
: StatelessWindowFunction(name_, argument_types_, parameters_, createResultType(argument_types_, name_))
{
if (!parameters.empty())
{
@ -2432,11 +2427,10 @@ struct WindowFunctionLagLeadInFrame final : public WindowFunction
}
};
struct WindowFunctionNthValue final : public WindowFunction
struct WindowFunctionNthValue final : public StatelessWindowFunction
{
WindowFunctionNthValue(const std::string & name_,
const DataTypes & argument_types_, const Array & parameters_)
: WindowFunction(name_, argument_types_, parameters_, createResultType(name_, argument_types_))
WindowFunctionNthValue(const std::string & name_, const DataTypes & argument_types_, const Array & parameters_)
: StatelessWindowFunction(name_, argument_types_, parameters_, createResultType(name_, argument_types_))
{
if (!parameters.empty())
{

View File

@ -0,0 +1,3 @@
-- https://github.com/ClickHouse/ClickHouse/issues/70569
-- Reproduces UBSAN alert about misaligned address
SELECT anyLast(id), anyLast(time), exponentialTimeDecayedAvg(10)(id, time) FROM values('id Int8, time DateTime', (1,1),(1,2),(2,3),(3,3),(3,5)); -- { serverError BAD_ARGUMENTS }