mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-18 21:51:57 +00:00
74 lines
2.2 KiB
C++
74 lines
2.2 KiB
C++
#include <Functions/FunctionArrayMapped.h>
|
|
#include <Functions/FunctionFactory.h>
|
|
|
|
|
|
namespace DB
|
|
{
|
|
|
|
/** Sort arrays, by values of its elements, or by values of corresponding elements of calculated expression (known as "schwartzsort").
|
|
*/
|
|
template <bool positive>
|
|
struct ArraySortImpl
|
|
{
|
|
static bool needBoolean() { return false; }
|
|
static bool needExpression() { return false; }
|
|
static bool needOneArray() { return false; }
|
|
|
|
static DataTypePtr getReturnType(const DataTypePtr & /*expression_return*/, const DataTypePtr & array_element)
|
|
{
|
|
return std::make_shared<DataTypeArray>(array_element);
|
|
}
|
|
|
|
struct Less
|
|
{
|
|
const IColumn & column;
|
|
|
|
Less(const IColumn & column) : column(column) {}
|
|
|
|
bool operator()(size_t lhs, size_t rhs) const
|
|
{
|
|
if (positive)
|
|
return column.compareAt(lhs, rhs, column, 1) < 0;
|
|
else
|
|
return column.compareAt(lhs, rhs, column, -1) > 0;
|
|
}
|
|
};
|
|
|
|
static ColumnPtr execute(const ColumnArray & array, ColumnPtr mapped)
|
|
{
|
|
const ColumnArray::Offsets & offsets = array.getOffsets();
|
|
|
|
size_t size = offsets.size();
|
|
size_t nested_size = array.getData().size();
|
|
IColumn::Permutation permutation(nested_size);
|
|
|
|
for (size_t i = 0; i < nested_size; ++i)
|
|
permutation[i] = i;
|
|
|
|
ColumnArray::Offset current_offset = 0;
|
|
for (size_t i = 0; i < size; ++i)
|
|
{
|
|
auto next_offset = offsets[i];
|
|
std::sort(&permutation[current_offset], &permutation[next_offset], Less(*mapped));
|
|
current_offset = next_offset;
|
|
}
|
|
|
|
return ColumnArray::create(array.getData().permute(permutation, 0), array.getOffsetsPtr());
|
|
}
|
|
};
|
|
|
|
struct NameArraySort { static constexpr auto name = "arraySort"; };
|
|
struct NameArrayReverseSort { static constexpr auto name = "arrayReverseSort"; };
|
|
|
|
using FunctionArraySort = FunctionArrayMapped<ArraySortImpl<true>, NameArraySort>;
|
|
using FunctionArrayReverseSort = FunctionArrayMapped<ArraySortImpl<false>, NameArrayReverseSort>;
|
|
|
|
void registerFunctionsArraySort(FunctionFactory & factory)
|
|
{
|
|
factory.registerFunction<FunctionArraySort>();
|
|
factory.registerFunction<FunctionArrayReverseSort>();
|
|
}
|
|
|
|
}
|
|
|