1#include <Functions/IFunctionImpl.h>
2#include <Functions/FunctionFactory.h>
3#include <DataTypes/DataTypesNumber.h>
4#include <DataTypes/DataTypeLowCardinality.h>
5#include <Columns/ColumnsNumber.h>
6#include <Columns/ColumnLowCardinality.h>
7#include <Common/typeid_cast.h>
8
9
10namespace DB
11{
12
13namespace ErrorCodes
14{
15 extern const int ILLEGAL_TYPE_OF_ARGUMENT;
16}
17
18class FunctionLowCardinalityIndices: public IFunction
19{
20public:
21 static constexpr auto name = "lowCardinalityIndices";
22 static FunctionPtr create(const Context &) { return std::make_shared<FunctionLowCardinalityIndices>(); }
23
24 String getName() const override { return name; }
25
26 size_t getNumberOfArguments() const override { return 1; }
27
28 bool useDefaultImplementationForNulls() const override { return false; }
29 bool useDefaultImplementationForConstants() const override { return true; }
30 bool useDefaultImplementationForLowCardinalityColumns() const override { return false; }
31
32 DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
33 {
34 auto * type = typeid_cast<const DataTypeLowCardinality *>(arguments[0].get());
35 if (!type)
36 throw Exception("First first argument of function lowCardinalityIndexes must be ColumnLowCardinality, but got"
37 + arguments[0]->getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
38
39 return std::make_shared<DataTypeUInt64>();
40 }
41
42 void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result, size_t /*input_rows_count*/) override
43 {
44 auto arg_num = arguments[0];
45 const auto & arg = block.getByPosition(arg_num);
46 auto & res = block.getByPosition(result);
47 auto indexes_col = typeid_cast<const ColumnLowCardinality *>(arg.column.get())->getIndexesPtr();
48 auto new_indexes_col = ColumnUInt64::create(indexes_col->size());
49 auto & data = new_indexes_col->getData();
50 for (size_t i = 0; i < data.size(); ++i)
51 data[i] = indexes_col->getUInt(i);
52
53 res.column = std::move(new_indexes_col);
54 }
55};
56
57
58void registerFunctionLowCardinalityIndices(FunctionFactory & factory)
59{
60 factory.registerFunction<FunctionLowCardinalityIndices>();
61}
62
63}
64