| 1 | #pragma once | 
|---|
| 2 |  | 
|---|
| 3 | #include <Columns/IColumn.h> | 
|---|
| 4 |  | 
|---|
| 5 |  | 
|---|
| 6 | namespace 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 | */ | 
|---|
| 24 | class ColumnVectorHelper : public IColumn | 
|---|
| 25 | { | 
|---|
| 26 | public: | 
|---|
| 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 |  | 
|---|