1#include "FunctionArrayMapped.h"
2#include <Functions/FunctionFactory.h>
3
4
5namespace DB
6{
7
8/** Sort arrays, by values of its elements, or by values of corresponding elements of calculated expression (known as "schwartzsort").
9 */
10template <bool positive>
11struct ArraySortImpl
12{
13 static bool needBoolean() { return false; }
14 static bool needExpression() { return false; }
15 static bool needOneArray() { return false; }
16
17 static DataTypePtr getReturnType(const DataTypePtr & /*expression_return*/, const DataTypePtr & array_element)
18 {
19 return std::make_shared<DataTypeArray>(array_element);
20 }
21
22 struct Less
23 {
24 const IColumn & column;
25
26 Less(const IColumn & column_) : column(column_) {}
27
28 bool operator()(size_t lhs, size_t rhs) const
29 {
30 if (positive)
31 return column.compareAt(lhs, rhs, column, 1) < 0;
32 else
33 return column.compareAt(lhs, rhs, column, -1) > 0;
34 }
35 };
36
37 static ColumnPtr execute(const ColumnArray & array, ColumnPtr mapped)
38 {
39 const ColumnArray::Offsets & offsets = array.getOffsets();
40
41 size_t size = offsets.size();
42 size_t nested_size = array.getData().size();
43 IColumn::Permutation permutation(nested_size);
44
45 for (size_t i = 0; i < nested_size; ++i)
46 permutation[i] = i;
47
48 ColumnArray::Offset current_offset = 0;
49 for (size_t i = 0; i < size; ++i)
50 {
51 auto next_offset = offsets[i];
52 std::sort(&permutation[current_offset], &permutation[next_offset], Less(*mapped));
53 current_offset = next_offset;
54 }
55
56 return ColumnArray::create(array.getData().permute(permutation, 0), array.getOffsetsPtr());
57 }
58};
59
60struct NameArraySort { static constexpr auto name = "arraySort"; };
61struct NameArrayReverseSort { static constexpr auto name = "arrayReverseSort"; };
62
63using FunctionArraySort = FunctionArrayMapped<ArraySortImpl<true>, NameArraySort>;
64using FunctionArrayReverseSort = FunctionArrayMapped<ArraySortImpl<false>, NameArrayReverseSort>;
65
66void registerFunctionsArraySort(FunctionFactory & factory)
67{
68 factory.registerFunction<FunctionArraySort>();
69 factory.registerFunction<FunctionArrayReverseSort>();
70}
71
72}
73
74