Added optional length parameter to aggregate function groupArrayInsertAt [#CLICKHOUSE-3003].

This commit is contained in:
Alexey Milovidov 2017-05-12 23:57:24 +03:00
parent 40595ce688
commit cfc4c987c5
3 changed files with 38 additions and 5 deletions

View File

@ -34,7 +34,11 @@ namespace ErrorCodes
* If more than one value was inserted to single position, the any value (first in case of single thread) is stored.
* If no values was inserted to some position, then default value will be substituted.
*
* Default value is optional parameter for aggregate function.
* Aggregate function also accept optional parameters:
* - default value to substitute;
* - length to resize result arrays (if you want to have results of same length for all aggregation keys);
*
* If you want to pass length, default value should be also given.
*/
@ -51,6 +55,7 @@ class AggregateFunctionGroupArrayInsertAtGeneric final
private:
DataTypePtr type;
Field default_value;
size_t length_to_resize = 0; /// zero means - do not do resizing.
public:
String getName() const override { return "groupArrayInsertAt"; }
@ -85,16 +90,26 @@ public:
if (params.empty())
return;
if (params.size() != 1)
throw Exception("Aggregate function " + getName() + " requires at most one parameter.", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
if (params.size() > 2)
throw Exception("Aggregate function " + getName() + " requires at most two parameters.", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
default_value = params.front();
default_value = params[0];
if (params.size() == 2)
{
length_to_resize = applyVisitor(FieldVisitorConvertToNumber<size_t>(), params[1]);
}
}
void addImpl(AggregateDataPtr place, const IColumn & column_value, const IColumn & column_position, size_t row_num, Arena *) const
{
/// TODO Do positions need to be 1-based for this function?
size_t position = column_position.get64(row_num);
/// If position is larger than size to which array will be cutted - simply ignore value.
if (length_to_resize && position >= length_to_resize)
return;
if (position >= AGGREGATE_FUNCTION_GROUP_ARRAY_INSERT_AT_MAX_SIZE)
throw Exception("Too large array size: position argument (" + toString(position) + ")"
" is greater or equals to limit (" + toString(AGGREGATE_FUNCTION_GROUP_ARRAY_INSERT_AT_MAX_SIZE) + ")",
@ -179,7 +194,13 @@ public:
to_data.insert(default_value);
}
to_offsets.push_back((to_offsets.empty() ? 0 : to_offsets.back()) + arr.size());
size_t result_array_size = length_to_resize ? length_to_resize : arr.size();
/// Pad array if need.
for (size_t i = arr.size(); i < result_array_size; ++i)
to_data.insert(default_value);
to_offsets.push_back((to_offsets.empty() ? 0 : to_offsets.back()) + result_array_size);
}
};

View File

@ -12,3 +12,14 @@
8 [0,0,0,0,0,0,0,0,8]
9 [0,0,0,0,0,0,0,0,0,9]
0 0
0 ['0','-','-','-','-','-','-','-','-','-']
1 ['-','1','-','-','-','-','-','-','-','-']
2 ['-','-','2','-','-','-','-','-','-','-']
3 ['-','-','-','3','-','-','-','-','-','-']
4 ['-','-','-','-','4','-','-','-','-','-']
5 ['-','-','-','-','-','5','-','-','-','-']
6 ['-','-','-','-','-','-','6','-','-','-']
7 ['-','-','-','-','-','-','-','7','-','-']
8 ['-','-','-','-','-','-','-','-','8','-']
9 ['-','-','-','-','-','-','-','-','-','9']
10 ['-','-','-','-','-','-','-','-','-','-']

View File

@ -3,3 +3,4 @@ SELECT groupArrayInsertAt('-')(toString(number), number * 2) FROM (SELECT * FROM
SELECT groupArrayInsertAt([123])(range(number), number * 2) FROM (SELECT * FROM system.numbers LIMIT 10);
SELECT number, groupArrayInsertAt(number, number) FROM (SELECT * FROM system.numbers LIMIT 10) GROUP BY number ORDER BY number;
SELECT k, ignore(groupArrayInsertAt(x, x)) FROM (SELECT dummy AS k, randConstant() % 10 AS x FROM remote('127.0.0.{1,1}', system.one)) GROUP BY k ORDER BY k;
SELECT k, groupArrayInsertAt('-', 10)(toString(x), x) FROM (SELECT number AS k, number AS x FROM system.numbers LIMIT 11) GROUP BY k ORDER BY k;