| 1 | #pragma once |
| 2 | |
| 3 | #include <Columns/IColumn.h> |
| 4 | |
| 5 | |
| 6 | /// Common helper methods for implementation of different columns. |
| 7 | |
| 8 | namespace DB |
| 9 | { |
| 10 | |
| 11 | namespace ErrorCodes |
| 12 | { |
| 13 | extern const int LOGICAL_ERROR; |
| 14 | } |
| 15 | |
| 16 | /// Counts how many bytes of `filt` are greater than zero. |
| 17 | size_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. |
| 21 | std::vector<size_t> countColumnsSizeInSelector(IColumn::ColumnIndex num_columns, const IColumn::Selector & selector); |
| 22 | |
| 23 | /// Returns true, if the memory contains only zeros. |
| 24 | bool memoryIsZero(const void * data, size_t size); |
| 25 | bool memoryIsByte(const void * data, size_t size, uint8_t byte); |
| 26 | |
| 27 | /// The general implementation of `filter` function for ColumnArray and ColumnString. |
| 28 | template <typename T> |
| 29 | void 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. |
| 35 | template <typename T> |
| 36 | void 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 | |
| 41 | namespace 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). |
| 48 | template <typename Column> |
| 49 | ColumnPtr 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 | |