Fix UBSan report in arrayDifference

This commit is contained in:
Alexey Milovidov 2021-02-13 03:45:06 +03:00
parent abb7c88b80
commit 1c55be261c
3 changed files with 29 additions and 7 deletions

View File

@ -47,6 +47,29 @@ struct ArrayDifferenceImpl
} }
template <typename Element, typename Result>
static void NO_SANITIZE_UNDEFINED impl(const Element * __restrict src, Result * __restrict dst, size_t begin, size_t end)
{
/// First element is zero, then the differences of ith and i-1th elements.
Element prev{};
for (size_t pos = begin; pos < end; ++pos)
{
if (pos == begin)
{
dst[pos] = 0;
prev = src[pos];
}
else
{
Element curr = src[pos];
dst[pos] = curr - prev;
prev = curr;
}
}
}
template <typename Element, typename Result> template <typename Element, typename Result>
static bool executeType(const ColumnPtr & mapped, const ColumnArray & array, ColumnPtr & res_ptr) static bool executeType(const ColumnPtr & mapped, const ColumnArray & array, ColumnPtr & res_ptr)
{ {
@ -73,14 +96,10 @@ struct ArrayDifferenceImpl
size_t pos = 0; size_t pos = 0;
for (auto offset : offsets) for (auto offset : offsets)
{ {
// skip empty arrays impl(data.data(), res_values.data(), pos, offset);
if (pos < offset) pos = offset;
{
res_values[pos] = 0;
for (++pos; pos < offset; ++pos)
res_values[pos] = static_cast<Result>(data[pos]) - static_cast<Result>(data[pos - 1]);
}
} }
res_ptr = ColumnArray::create(std::move(res_nested), array.getOffsetsPtr()); res_ptr = ColumnArray::create(std::move(res_nested), array.getOffsetsPtr());
return true; return true;
} }

View File

@ -0,0 +1 @@
[0,9223372036854710272]

View File

@ -0,0 +1,2 @@
-- Overflow is Ok and behaves as the CPU does it.
SELECT arrayDifference([65536, -9223372036854775808]);