1#include <Common/assert_cast.h>
2#include <Interpreters/NullableUtils.h>
3
4
5namespace DB
6{
7
8ColumnPtr extractNestedColumnsAndNullMap(ColumnRawPtrs & key_columns, ConstNullMapPtr & null_map)
9{
10 ColumnPtr null_map_holder;
11
12 if (key_columns.size() == 1)
13 {
14 auto & column = key_columns[0];
15 if (auto * column_nullable = checkAndGetColumn<ColumnNullable>(*column))
16 {
17 null_map_holder = column_nullable->getNullMapColumnPtr();
18 null_map = &column_nullable->getNullMapData();
19 column = &column_nullable->getNestedColumn();
20 }
21 }
22 else
23 {
24 for (auto & column : key_columns)
25 {
26 if (auto * column_nullable = checkAndGetColumn<ColumnNullable>(*column))
27 {
28 column = &column_nullable->getNestedColumn();
29
30 if (!null_map_holder)
31 {
32 null_map_holder = column_nullable->getNullMapColumnPtr();
33 }
34 else
35 {
36 MutableColumnPtr mutable_null_map_holder = (*std::move(null_map_holder)).mutate();
37
38 PaddedPODArray<UInt8> & mutable_null_map = assert_cast<ColumnUInt8 &>(*mutable_null_map_holder).getData();
39 const PaddedPODArray<UInt8> & other_null_map = column_nullable->getNullMapData();
40 for (size_t i = 0, size = mutable_null_map.size(); i < size; ++i)
41 mutable_null_map[i] |= other_null_map[i];
42
43 null_map_holder = std::move(mutable_null_map_holder);
44 }
45 }
46 }
47
48 null_map = null_map_holder ? &assert_cast<const ColumnUInt8 &>(*null_map_holder).getData() : nullptr;
49 }
50
51 return null_map_holder;
52}
53
54}
55