Fixed error found by M.Filimonov (equality of array sizes are not checked in n-ary version of aggregate functions with -Array combinator) [#CLICKHOUSE-2].

This commit is contained in:
Alexey Milovidov 2017-12-19 00:44:18 +03:00
parent 6c28c72fdc
commit 521b3aee84
3 changed files with 27 additions and 0 deletions

View File

@ -10,6 +10,11 @@
namespace DB namespace DB
{ {
namespace ErrorCodes
{
extern const int SIZES_OF_ARRAYS_DOESNT_MATCH;
}
/** Not an aggregate function, but an adapter of aggregate functions, /** Not an aggregate function, but an adapter of aggregate functions,
* which any aggregate function `agg(x)` makes an aggregate function of the form `aggArray(x)`. * which any aggregate function `agg(x)` makes an aggregate function of the form `aggArray(x)`.
@ -97,6 +102,16 @@ public:
size_t begin = row_num == 0 ? 0 : offsets[row_num - 1]; size_t begin = row_num == 0 ? 0 : offsets[row_num - 1];
size_t end = offsets[row_num]; size_t end = offsets[row_num];
/// Sanity check. NOTE We can implement specialization for a case with single argument, if the check will hurt performance.
for (size_t i = 1; i < num_agruments; ++i)
{
const ColumnArray & ith_column = static_cast<const ColumnArray &>(*columns[i]);
const IColumn::Offsets & ith_offsets = ith_column.getOffsets();
if (ith_offsets[row_num] != end || (row_num != 0 && ith_offsets[row_num - 1] != begin))
throw Exception("Arrays passed to " + getName() + " aggregate function have different sizes", ErrorCodes::SIZES_OF_ARRAYS_DOESNT_MATCH);
}
for (size_t i = begin; i < end; ++i) for (size_t i = begin; i < end; ++i)
nested_func->add(place, nested, i, arena); nested_func->add(place, nested, i, arena);
} }

View File

@ -0,0 +1,6 @@
2
3
2
3
2
3

View File

@ -0,0 +1,6 @@
SELECT uniqArray([0, 1, 1], [0, 1, 1], [0, 1, 1]);
SELECT uniqArray([0, 1, 1], [0, 1, 1], [0, 1, 0]);
SELECT uniqExactArray([0, 1, 1], [0, 1, 1], [0, 1, 1]);
SELECT uniqExactArray([0, 1, 1], [0, 1, 1], [0, 1, 0]);
SELECT uniqUpToArray(10)([0, 1, 1], [0, 1, 1], [0, 1, 1]);
SELECT uniqUpToArray(10)([0, 1, 1], [0, 1, 1], [0, 1, 0]);