2015-11-21 03:19:43 +00:00
|
|
|
#pragma once
|
|
|
|
|
2017-04-01 09:19:00 +00:00
|
|
|
#include <Columns/IColumn.h>
|
2015-11-21 03:19:43 +00:00
|
|
|
|
|
|
|
|
2017-03-09 00:56:38 +00:00
|
|
|
/// Common helper methods for implementation of different columns.
|
2015-11-21 03:19:43 +00:00
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
2018-04-18 21:00:47 +00:00
|
|
|
namespace ErrorCodes
|
|
|
|
{
|
2020-02-25 18:02:41 +00:00
|
|
|
extern const int SIZES_OF_COLUMNS_DOESNT_MATCH;
|
2018-04-18 21:00:47 +00:00
|
|
|
extern const int LOGICAL_ERROR;
|
|
|
|
}
|
|
|
|
|
2017-03-09 00:56:38 +00:00
|
|
|
/// Counts how many bytes of `filt` are greater than zero.
|
2020-11-15 10:05:52 +00:00
|
|
|
size_t countBytesInFilter(const UInt8 * filt, size_t sz);
|
2015-11-21 03:19:43 +00:00
|
|
|
size_t countBytesInFilter(const IColumn::Filter & filt);
|
2020-11-15 10:05:52 +00:00
|
|
|
size_t countBytesInFilterWithNull(const IColumn::Filter & filt, const UInt8 * null_map);
|
2015-11-21 03:19:43 +00:00
|
|
|
|
2018-02-09 15:09:33 +00:00
|
|
|
/// Returns vector with num_columns elements. vector[i] is the count of i values in selector.
|
2018-02-06 19:34:53 +00:00
|
|
|
/// Selector must contain values from 0 to num_columns - 1. NOTE: this is not checked.
|
|
|
|
std::vector<size_t> countColumnsSizeInSelector(IColumn::ColumnIndex num_columns, const IColumn::Selector & selector);
|
|
|
|
|
2017-06-23 06:45:48 +00:00
|
|
|
/// Returns true, if the memory contains only zeros.
|
|
|
|
bool memoryIsZero(const void * data, size_t size);
|
2019-06-05 08:05:46 +00:00
|
|
|
bool memoryIsByte(const void * data, size_t size, uint8_t byte);
|
2015-11-21 03:19:43 +00:00
|
|
|
|
2017-03-09 00:56:38 +00:00
|
|
|
/// The general implementation of `filter` function for ColumnArray and ColumnString.
|
2015-11-21 03:19:43 +00:00
|
|
|
template <typename T>
|
|
|
|
void filterArraysImpl(
|
2017-12-15 21:32:25 +00:00
|
|
|
const PaddedPODArray<T> & src_elems, const IColumn::Offsets & src_offsets,
|
|
|
|
PaddedPODArray<T> & res_elems, IColumn::Offsets & res_offsets,
|
2017-04-01 07:20:54 +00:00
|
|
|
const IColumn::Filter & filt, ssize_t result_size_hint);
|
2015-11-21 03:19:43 +00:00
|
|
|
|
2017-04-18 03:03:39 +00:00
|
|
|
/// Same as above, but not fills res_offsets.
|
|
|
|
template <typename T>
|
|
|
|
void filterArraysImplOnlyData(
|
2017-12-15 21:32:25 +00:00
|
|
|
const PaddedPODArray<T> & src_elems, const IColumn::Offsets & src_offsets,
|
2017-04-18 03:03:39 +00:00
|
|
|
PaddedPODArray<T> & res_elems,
|
|
|
|
const IColumn::Filter & filt, ssize_t result_size_hint);
|
|
|
|
|
2018-04-18 21:00:47 +00:00
|
|
|
namespace detail
|
|
|
|
{
|
|
|
|
template <typename T>
|
2018-06-07 18:14:37 +00:00
|
|
|
const PaddedPODArray<T> * getIndexesData(const IColumn & indexes);
|
2018-04-18 21:00:47 +00:00
|
|
|
}
|
|
|
|
|
2019-02-10 15:17:45 +00:00
|
|
|
/// Check limit <= indexes->size() and call column.indexImpl(const PaddedPodArray<Type> & indexes, UInt64 limit).
|
2018-04-18 21:00:47 +00:00
|
|
|
template <typename Column>
|
2019-02-18 17:28:53 +00:00
|
|
|
ColumnPtr selectIndexImpl(const Column & column, const IColumn & indexes, size_t limit)
|
2018-04-18 21:00:47 +00:00
|
|
|
{
|
|
|
|
if (limit == 0)
|
2018-06-07 18:14:37 +00:00
|
|
|
limit = indexes.size();
|
2018-04-18 21:00:47 +00:00
|
|
|
|
2018-06-07 18:14:37 +00:00
|
|
|
if (indexes.size() < limit)
|
2018-04-18 21:00:47 +00:00
|
|
|
throw Exception("Size of indexes is less than required.", ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH);
|
|
|
|
|
|
|
|
if (auto * data_uint8 = detail::getIndexesData<UInt8>(indexes))
|
2018-04-23 16:51:27 +00:00
|
|
|
return column.template indexImpl<UInt8>(*data_uint8, limit);
|
2018-04-18 21:00:47 +00:00
|
|
|
else if (auto * data_uint16 = detail::getIndexesData<UInt16>(indexes))
|
2018-04-23 16:51:27 +00:00
|
|
|
return column.template indexImpl<UInt16>(*data_uint16, limit);
|
2018-04-18 21:00:47 +00:00
|
|
|
else if (auto * data_uint32 = detail::getIndexesData<UInt32>(indexes))
|
2018-04-23 16:51:27 +00:00
|
|
|
return column.template indexImpl<UInt32>(*data_uint32, limit);
|
2018-04-18 21:00:47 +00:00
|
|
|
else if (auto * data_uint64 = detail::getIndexesData<UInt64>(indexes))
|
2018-04-23 16:51:27 +00:00
|
|
|
return column.template indexImpl<UInt64>(*data_uint64, limit);
|
2018-04-18 21:00:47 +00:00
|
|
|
else
|
2018-06-07 18:14:37 +00:00
|
|
|
throw Exception("Indexes column for IColumn::select must be ColumnUInt, got" + indexes.getName(),
|
2018-04-18 21:00:47 +00:00
|
|
|
ErrorCodes::LOGICAL_ERROR);
|
|
|
|
}
|
|
|
|
|
|
|
|
#define INSTANTIATE_INDEX_IMPL(Column) \
|
2019-02-18 17:28:53 +00:00
|
|
|
template ColumnPtr Column::indexImpl<UInt8>(const PaddedPODArray<UInt8> & indexes, size_t limit) const; \
|
|
|
|
template ColumnPtr Column::indexImpl<UInt16>(const PaddedPODArray<UInt16> & indexes, size_t limit) const; \
|
|
|
|
template ColumnPtr Column::indexImpl<UInt32>(const PaddedPODArray<UInt32> & indexes, size_t limit) const; \
|
|
|
|
template ColumnPtr Column::indexImpl<UInt64>(const PaddedPODArray<UInt64> & indexes, size_t limit) const;
|
2015-11-21 03:19:43 +00:00
|
|
|
}
|