1#pragma once
2
3#include <Columns/IColumn.h>
4
5
6namespace DB
7{
8
9/** Allows to access internal array of ColumnVector or ColumnFixedString without cast to concrete type.
10 * We will inherit ColumnVector and ColumnFixedString from this class instead of IColumn.
11 * Assumes data layout of ColumnVector, ColumnFixedString and PODArray.
12 *
13 * Why it is needed?
14 *
15 * There are some algorithms that specialize on the size of data type but doesn't care about concrete type.
16 * The same specialization may work for UInt64, Int64, Float64, FixedString(8), if it only does byte moving and hashing.
17 * To avoid code bloat and compile time increase, we can use single template instantiation for these cases
18 * and just static_cast pointer to some single column type (e. g. ColumnUInt64) assuming that all types have identical memory layout.
19 *
20 * But this static_cast (downcast to unrelated type) is illegal according to the C++ standard and UBSan warns about it.
21 * To allow functional tests to work under UBSan we have to separate some base class that will present the memory layout in explicit way,
22 * and we will do static_cast to this class.
23 */
24class ColumnVectorHelper : public IColumn
25{
26public:
27 template <size_t ELEMENT_SIZE>
28 const char * getRawDataBegin() const
29 {
30 return reinterpret_cast<const PODArrayBase<ELEMENT_SIZE, 4096, Allocator<false>, 15, 16> *>(reinterpret_cast<const char *>(this) + sizeof(*this))->raw_data();
31 }
32
33 template <size_t ELEMENT_SIZE>
34 void insertRawData(const char * ptr)
35 {
36 return reinterpret_cast<PODArrayBase<ELEMENT_SIZE, 4096, Allocator<false>, 15, 16> *>(reinterpret_cast<char *>(this) + sizeof(*this))->push_back_raw(ptr);
37 }
38};
39
40}
41