Merge pull request #5559 from proller/fix28

CLICKHOUSE-4179 Fix of function arrayEnumerateUniqRanked for arguments with empty arrays
This commit is contained in:
alexey-milovidov 2019-06-13 13:14:51 +03:00 committed by GitHub
commit be51de0903
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 118 additions and 4 deletions

View File

@ -234,8 +234,8 @@ void FunctionArrayEnumerateRankedExtended<Derived>::executeImpl(
{
throw Exception(
getName() + ": Passed array number " + std::to_string(array_num) + " depth ("
+ std::to_string(arrays_depths.depths[array_num]) + ") is more than the actual array depth (" + std::to_string(col_depth)
+ ").",
+ std::to_string(arrays_depths.depths[array_num]) + ") is more than the actual array depth ("
+ std::to_string(col_depth) + ").",
ErrorCodes::SIZES_OF_ARRAYS_DOESNT_MATCH);
}
@ -255,7 +255,7 @@ void FunctionArrayEnumerateRankedExtended<Derived>::executeImpl(
executeMethodImpl(offsets_by_depth, data_columns, arrays_depths, res_values);
ColumnPtr result_nested_array = std::move(res_nested);
for (int depth = arrays_depths.max_array_depth - 1; depth >= 0; --depth)
for (ssize_t depth = arrays_depths.max_array_depth - 1; depth >= 0; --depth)
result_nested_array = ColumnArray::create(std::move(result_nested_array), offsetsptr_by_depth[depth]);
block.getByPosition(result).column = result_nested_array;
@ -321,6 +321,7 @@ void FunctionArrayEnumerateRankedExtended<Derived>::executeMethodImpl(
std::vector<size_t> indices_by_depth(arrays_depths.max_array_depth);
std::vector<size_t> current_offset_n_by_depth(arrays_depths.max_array_depth);
std::vector<size_t> last_offset_by_depth(arrays_depths.max_array_depth, 0); // For skipping empty arrays
UInt32 rank = 0;
@ -330,6 +331,24 @@ void FunctionArrayEnumerateRankedExtended<Derived>::executeMethodImpl(
{
bool want_clear = false;
/// Skipping offsets if no data in this array
if (prev_off == off)
{
want_clear = true;
++indices_by_depth[0];
for (ssize_t depth = current_offset_depth - 1; depth >= 0; --depth)
{
const auto offsets_by_depth_size = offsets_by_depth[depth]->size();
while (last_offset_by_depth[depth] == (*offsets_by_depth[depth])[current_offset_n_by_depth[depth]])
{
if (current_offset_n_by_depth[depth] + 1 >= offsets_by_depth_size)
break; // only one empty array: SELECT arrayEnumerateUniqRanked([]);
++current_offset_n_by_depth[depth];
}
}
}
/// For each element at the depth we want to look.
for (size_t j = prev_off; j < off; ++j)
{
@ -356,14 +375,21 @@ void FunctionArrayEnumerateRankedExtended<Derived>::executeMethodImpl(
// Debug: DUMP(off, prev_off, j, columns_indices, res_values[j], columns);
for (int depth = current_offset_depth - 1; depth >= 0; --depth)
for (ssize_t depth = current_offset_depth - 1; depth >= 0; --depth)
{
/// Skipping offsets for empty arrays
while (last_offset_by_depth[depth] == (*offsets_by_depth[depth])[current_offset_n_by_depth[depth]])
{
++current_offset_n_by_depth[depth];
}
++indices_by_depth[depth];
if (indices_by_depth[depth] == (*offsets_by_depth[depth])[current_offset_n_by_depth[depth]])
{
if (static_cast<int>(arrays_depths.clear_depth) == depth + 1)
want_clear = true;
last_offset_by_depth[depth] = (*offsets_by_depth[depth])[current_offset_n_by_depth[depth]];
++current_offset_n_by_depth[depth];
}
else

View File

@ -178,3 +178,50 @@ arrayEnumerateUniq(a1, a2) =
[1,2]
[1,1]
[[[[[[[[[[1]]]]]]]]]]
[[1],[1]]
[[],[1],[1]]
[[],[],[],[1],[],[1]]
[[],[],[],[],[1],[1]]
[[1],[],[1]]
[[1],[],[],[1]]
[[1],[],[],[1],[1]]
-- no order
[[],[1,2,3,4]] [[],[1,1,1,1]]
[[3,4,5]] [[1,1,1]]
-- order no arr
[[1,2,3,4]] [[1,1,1,1]]
[[3,4,5]] [[1,1,1]]
-- order two arr
[[],[1,2,3,4]] [[],[1,1,1,1]]
[[],[3,4,5]] [[],[1,1,1]]
-- order non empt
[[3,4,5]] [[1,1,1]]
[[6],[1,2,3,4]] [[1],[1,1,1,1]]
-- order
[[],[1,2,3,4]] [[],[1,1,1,1]]
[[3,4,5]] [[1,1,1]]
--
[[1,1,1,1],[1,1,1,1]]
[[],[1,1,1,1],[1,1,1,1]]
[[],[1,1,1,1],[],[],[1,1,1,1]]
[[1,1,1,1],[],[],[1,1,1,1]]
[[1],[1]]
[[],[1],[1]]
[[],[4]] [[],[1]]
[[4]] [[1]]
--
[[],[1,2,3,4]] [[],[1,1,1,1]]
[[],[3,4,5]] [[],[1,1,1]]
--
[[],[1,2,3,4]] [[],[1,1,1,1]]
[[3,4,5]] [[1,1,1]]
--
[[],[],[1,2,3,4]] [[],[],[1,1,1,1]]
[[3,4,5]] [[1,1,1]]
--
[[],[],[1,2,3,4]] [[],[],[1,1,1,1]]
[[],[],[3,4,5]] [[],[],[1,1,1]]
--
[[],[],[1,2,1,4]] [[],[],[1,1,2,1]]
[[],[],[3,4,5,4]] [[],[],[1,1,1,2]]
--

View File

@ -180,3 +180,44 @@ SELECT arrayEnumerateDenseRanked(1.1, [10,20,10,30]); -- { serverError 170 }
SELECT arrayEnumerateDenseRanked([10,20,10,30], 0.4); -- { serverError 170 }
SELECT arrayEnumerateDenseRanked([10,20,10,30], 1.8); -- { serverError 170 }
SELECT arrayEnumerateUniqRanked(1, [], 1000000000); -- { serverError 36 }
-- skipping empty arrays
SELECT arrayEnumerateUniqRanked(2, [[3], [3]]);
SELECT arrayEnumerateUniqRanked(2, [[], [3], [3]]);
SELECT arrayEnumerateUniqRanked(2, [[], [], [], [3], [], [3]]);
SELECT arrayEnumerateUniqRanked(2, [[], [], [], [], [3], [3]]);
SELECT arrayEnumerateUniqRanked(2, [[3], [], [3]]);
SELECT arrayEnumerateUniqRanked(2, [[3], [], [], [3]]);
SELECT arrayEnumerateUniqRanked(2, [[3], [], [], [3], [3]]);
select '-- no order';
SELECT * FROM (SELECT a, arrayEnumerateUniqRanked(a) FROM ( SELECT * FROM ( SELECT [[], [1, 2, 3, 4]] AS a UNION ALL SELECT [[3, 4, 5]] AS a ) ) ) ORDER BY a ASC;
select '-- order no arr';
SELECT a, arrayEnumerateUniqRanked(a) FROM ( SELECT * FROM ( SELECT [[1, 2, 3, 4]] AS a UNION ALL SELECT [[3, 4, 5]] AS a ) ORDER BY a ASC );
select '-- order two arr';
SELECT a, arrayEnumerateUniqRanked(a) FROM ( SELECT * FROM ( SELECT [[], [1, 2, 3, 4]] AS a UNION ALL SELECT [[], [3, 4, 5]] AS a ) ORDER BY a ASC );
select '-- order non empt';
SELECT a, arrayEnumerateUniqRanked(a) FROM ( SELECT * FROM ( SELECT [[6], [1, 2, 3, 4]] AS a UNION ALL SELECT [[3, 4, 5]] AS a ) ORDER BY a ASC );
select '-- order';
SELECT a, arrayEnumerateUniqRanked(a) FROM ( SELECT * FROM ( SELECT [[], [1, 2, 3, 4]] AS a UNION ALL SELECT [[3, 4, 5]] AS a ) ORDER BY a ASC );
select '-- ';
SELECT arrayEnumerateUniqRanked(2,[[1, 2, 3, 4], [3, 4, 5, 6]]);
SELECT arrayEnumerateUniqRanked(2, [[], [1, 2, 3, 4], [3, 4, 5, 6]]);
SELECT arrayEnumerateUniqRanked(2, [[], [1, 2, 3, 4], [], [], [3, 4, 5, 6]]);
SELECT arrayEnumerateUniqRanked(2, [[1, 2, 3, 4], [], [], [3, 4, 5, 6]]);
SELECT arrayEnumerateUniqRanked(2,[[1], [1]]);
SELECT arrayEnumerateUniqRanked(2, [[], [1], [1]]);
SELECT a, arrayEnumerateUniqRanked(a) FROM ( SELECT * FROM ( SELECT [[], [4]] AS a UNION ALL SELECT [[4]] AS a ) ORDER BY a ASC );
select '-- ';
SELECT a, arrayEnumerateUniqRanked(a) FROM ( SELECT * FROM ( SELECT [[], [1, 2, 3, 4]] AS a UNION ALL SELECT [[], [3, 4, 5]] AS a ) ORDER BY a ASC );
select '-- ';
SELECT a, arrayEnumerateUniqRanked(a) FROM ( SELECT * FROM ( SELECT [[], [1, 2, 3, 4]] AS a UNION ALL SELECT [[3, 4, 5]] AS a ) ORDER BY a ASC );
select '-- ';
SELECT a, arrayEnumerateUniqRanked(a) FROM ( SELECT * FROM ( SELECT [[], [], [1, 2, 3, 4]] AS a UNION ALL SELECT [[3, 4, 5]] AS a ) ORDER BY a ASC );
select '-- ';
SELECT a, arrayEnumerateUniqRanked(a) FROM ( SELECT * FROM ( SELECT [[], [], [1, 2, 3, 4]] AS a UNION ALL SELECT [[], [], [3, 4, 5]] AS a ) ORDER BY a ASC );
select '-- ';
SELECT a, arrayEnumerateUniqRanked(a) FROM ( SELECT * FROM ( SELECT [[], [], [1, 2, 1, 4]] AS a UNION ALL SELECT [[], [], [3, 4, 5, 4]] AS a ) ORDER BY a ASC );
select '-- ';