1#pragma once
2
3#include <Columns/IColumn.h>
4
5
6/// Common helper methods for implementation of different columns.
7
8namespace DB
9{
10
11namespace ErrorCodes
12{
13 extern const int LOGICAL_ERROR;
14}
15
16/// Counts how many bytes of `filt` are greater than zero.
17size_t countBytesInFilter(const IColumn::Filter & filt);
18
19/// Returns vector with num_columns elements. vector[i] is the count of i values in selector.
20/// Selector must contain values from 0 to num_columns - 1. NOTE: this is not checked.
21std::vector<size_t> countColumnsSizeInSelector(IColumn::ColumnIndex num_columns, const IColumn::Selector & selector);
22
23/// Returns true, if the memory contains only zeros.
24bool memoryIsZero(const void * data, size_t size);
25bool memoryIsByte(const void * data, size_t size, uint8_t byte);
26
27/// The general implementation of `filter` function for ColumnArray and ColumnString.
28template <typename T>
29void filterArraysImpl(
30 const PaddedPODArray<T> & src_elems, const IColumn::Offsets & src_offsets,
31 PaddedPODArray<T> & res_elems, IColumn::Offsets & res_offsets,
32 const IColumn::Filter & filt, ssize_t result_size_hint);
33
34/// Same as above, but not fills res_offsets.
35template <typename T>
36void filterArraysImplOnlyData(
37 const PaddedPODArray<T> & src_elems, const IColumn::Offsets & src_offsets,
38 PaddedPODArray<T> & res_elems,
39 const IColumn::Filter & filt, ssize_t result_size_hint);
40
41namespace detail
42{
43 template <typename T>
44 const PaddedPODArray<T> * getIndexesData(const IColumn & indexes);
45}
46
47/// Check limit <= indexes->size() and call column.indexImpl(const PaddedPodArray<Type> & indexes, UInt64 limit).
48template <typename Column>
49ColumnPtr selectIndexImpl(const Column & column, const IColumn & indexes, size_t limit)
50{
51 if (limit == 0)
52 limit = indexes.size();
53
54 if (indexes.size() < limit)
55 throw Exception("Size of indexes is less than required.", ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH);
56
57 if (auto * data_uint8 = detail::getIndexesData<UInt8>(indexes))
58 return column.template indexImpl<UInt8>(*data_uint8, limit);
59 else if (auto * data_uint16 = detail::getIndexesData<UInt16>(indexes))
60 return column.template indexImpl<UInt16>(*data_uint16, limit);
61 else if (auto * data_uint32 = detail::getIndexesData<UInt32>(indexes))
62 return column.template indexImpl<UInt32>(*data_uint32, limit);
63 else if (auto * data_uint64 = detail::getIndexesData<UInt64>(indexes))
64 return column.template indexImpl<UInt64>(*data_uint64, limit);
65 else
66 throw Exception("Indexes column for IColumn::select must be ColumnUInt, got" + indexes.getName(),
67 ErrorCodes::LOGICAL_ERROR);
68}
69
70#define INSTANTIATE_INDEX_IMPL(Column) \
71 template ColumnPtr Column::indexImpl<UInt8>(const PaddedPODArray<UInt8> & indexes, size_t limit) const; \
72 template ColumnPtr Column::indexImpl<UInt16>(const PaddedPODArray<UInt16> & indexes, size_t limit) const; \
73 template ColumnPtr Column::indexImpl<UInt32>(const PaddedPODArray<UInt32> & indexes, size_t limit) const; \
74 template ColumnPtr Column::indexImpl<UInt64>(const PaddedPODArray<UInt64> & indexes, size_t limit) const;
75}
76