31
31
namespace doris ::vectorized {
32
32
33
33
ColumnNullable::ColumnNullable (MutableColumnPtr&& nested_column_, MutableColumnPtr&& null_map_)
34
- : nested_column (std::move(nested_column_ )), null_map (std::move(null_map_ )) {
34
+ : NullMapProvider (std::move(null_map_ )), nested_column (std::move(nested_column_ )) {
35
35
// / ColumnNullable cannot have constant nested column. But constant argument could be passed. Materialize it.
36
36
nested_column = get_nested_column ().convert_to_full_column_if_const ();
37
37
38
38
// after convert const column to full column, it may be a nullable column
39
39
if (nested_column->is_nullable ()) {
40
- assert_cast<ColumnNullable&>(*nested_column).apply_null_map ((const ColumnUInt8&)*null_map);
41
- null_map = assert_cast<ColumnNullable&>(*nested_column).get_null_map_column_ptr ();
40
+ assert_cast<ColumnNullable&>(*nested_column)
41
+ .apply_null_map (static_cast <const ColumnUInt8&>(get_null_map_column ()));
42
+ reset_null_map (assert_cast<ColumnNullable&>(*nested_column).get_null_map_column_ptr ());
42
43
nested_column = assert_cast<ColumnNullable&>(*nested_column).get_nested_column_ptr ();
43
44
}
44
45
45
- if (is_column_const (*null_map)) {
46
+ if (is_column_const (get_null_map_column ())) [[unlikely]] {
46
47
throw doris::Exception (ErrorCode::INTERNAL_ERROR,
47
48
" ColumnNullable cannot have constant null map" );
48
49
__builtin_unreachable ();
@@ -69,7 +70,7 @@ void ColumnNullable::update_xxHash_with_value(size_t start, size_t end, uint64_t
69
70
nested_column->update_xxHash_with_value (start, end, hash, nullptr );
70
71
} else {
71
72
const auto * __restrict real_null_data =
72
- assert_cast<const ColumnUInt8&>(*null_map ).get_data ().data ();
73
+ assert_cast<const ColumnUInt8&>(get_null_map_column () ).get_data ().data ();
73
74
for (int i = start; i < end; ++i) {
74
75
if (real_null_data[i] != 0 ) {
75
76
hash = HashUtil::xxHash64NullWithSeed (hash);
@@ -85,7 +86,7 @@ void ColumnNullable::update_crc_with_value(size_t start, size_t end, uint32_t& h
85
86
nested_column->update_crc_with_value (start, end, hash, nullptr );
86
87
} else {
87
88
const auto * __restrict real_null_data =
88
- assert_cast<const ColumnUInt8&>(*null_map ).get_data ().data ();
89
+ assert_cast<const ColumnUInt8&>(get_null_map_column () ).get_data ().data ();
89
90
for (int i = start; i < end; ++i) {
90
91
if (real_null_data[i] != 0 ) {
91
92
hash = HashUtil::zlib_crc_hash_null (hash);
@@ -110,7 +111,7 @@ void ColumnNullable::update_crcs_with_value(uint32_t* __restrict hashes, doris::
110
111
auto s = rows;
111
112
DCHECK (s == size ());
112
113
const auto * __restrict real_null_data =
113
- assert_cast<const ColumnUInt8&>(*null_map ).get_data ().data ();
114
+ assert_cast<const ColumnUInt8&>(get_null_map_column () ).get_data ().data ();
114
115
if (!has_null ()) {
115
116
nested_column->update_crcs_with_value (hashes, type, rows, offset, nullptr );
116
117
} else {
@@ -128,7 +129,7 @@ void ColumnNullable::update_hashes_with_value(uint64_t* __restrict hashes,
128
129
DCHECK (null_data == nullptr );
129
130
auto s = size ();
130
131
const auto * __restrict real_null_data =
131
- assert_cast<const ColumnUInt8&>(*null_map ).get_data ().data ();
132
+ assert_cast<const ColumnUInt8&>(get_null_map_column () ).get_data ().data ();
132
133
if (!has_null ()) {
133
134
nested_column->update_hashes_with_value (hashes, nullptr );
134
135
} else {
@@ -183,24 +184,24 @@ StringRef ColumnNullable::get_data_at(size_t n) const {
183
184
void ColumnNullable::insert_data (const char * pos, size_t length) {
184
185
if (pos == nullptr ) {
185
186
get_nested_column ().insert_default ();
186
- _get_null_map_data ().push_back (1 );
187
+ get_null_map_data ().push_back (1 );
187
188
_has_null = true ;
189
+ _need_update_has_null = false ;
188
190
} else {
189
191
get_nested_column ().insert_data (pos, length);
190
- _get_null_map_data (). push_back ( 0 );
192
+ _push_false_to_nullmap ( 1 );
191
193
}
192
194
}
193
195
194
196
void ColumnNullable::insert_many_strings (const StringRef* strings, size_t num) {
195
- auto & null_map_data = _get_null_map_data ();
196
197
for (size_t i = 0 ; i != num; ++i) {
197
198
if (strings[i].data == nullptr ) {
198
199
nested_column->insert_default ();
199
- null_map_data .push_back (1 );
200
+ get_null_map_data () .push_back (1 );
200
201
_has_null = true ;
201
202
} else {
202
203
nested_column->insert_data (strings[i].data , strings[i].size );
203
- null_map_data. push_back ( 0 );
204
+ _push_false_to_nullmap ( 1 );
204
205
}
205
206
}
206
207
}
@@ -227,13 +228,14 @@ const char* ColumnNullable::deserialize_and_insert_from_arena(const char* pos) {
227
228
UInt8 val = *reinterpret_cast <const UInt8 *>(pos);
228
229
pos += sizeof (val);
229
230
230
- _get_null_map_data ().push_back (val);
231
+ get_null_map_data ().push_back (val);
231
232
232
233
if (val == 0 ) {
233
234
pos = get_nested_column ().deserialize_and_insert_from_arena (pos);
234
235
} else {
235
236
get_nested_column ().insert_default ();
236
237
_has_null = true ;
238
+ _need_update_has_null = false ;
237
239
}
238
240
239
241
return pos;
@@ -265,7 +267,7 @@ void ColumnNullable::serialize_vec(std::vector<StringRef>& keys, size_t num_rows
265
267
}
266
268
267
269
void ColumnNullable::deserialize_vec (std::vector<StringRef>& keys, const size_t num_rows) {
268
- auto & arr = _get_null_map_data ();
270
+ auto & arr = get_null_map_data ();
269
271
const size_t old_size = arr.size ();
270
272
arr.resize (old_size + num_rows);
271
273
@@ -288,31 +290,24 @@ void ColumnNullable::deserialize_vec(std::vector<StringRef>& keys, const size_t
288
290
void ColumnNullable::insert_range_from_ignore_overflow (const doris::vectorized::IColumn& src,
289
291
size_t start, size_t length) {
290
292
const auto & nullable_col = assert_cast<const ColumnNullable&>(src);
291
- _get_null_map_column ().insert_range_from (* nullable_col.null_map , start, length);
293
+ get_null_map_column ().insert_range_from (nullable_col.get_null_map_column () , start, length);
292
294
get_nested_column ().insert_range_from_ignore_overflow (*nullable_col.nested_column , start,
293
295
length);
294
- const auto & src_null_map_data = nullable_col.get_null_map_data ();
295
- _has_null = has_null ();
296
- _has_null |= simd::contain_byte (src_null_map_data.data () + start, length, 1 );
297
296
}
298
297
299
298
void ColumnNullable::insert_range_from (const IColumn& src, size_t start, size_t length) {
300
299
const auto & nullable_col = assert_cast<const ColumnNullable&>(src);
301
- _get_null_map_column ().insert_range_from (* nullable_col.null_map , start, length);
300
+ get_null_map_column ().insert_range_from (nullable_col.get_null_map_column () , start, length);
302
301
get_nested_column ().insert_range_from (*nullable_col.nested_column , start, length);
303
- const auto & src_null_map_data = nullable_col.get_null_map_data ();
304
- _has_null = has_null ();
305
- _has_null |= simd::contain_byte (src_null_map_data.data () + start, length, 1 );
306
302
}
307
303
308
304
void ColumnNullable::insert_indices_from (const IColumn& src, const uint32_t * indices_begin,
309
305
const uint32_t * indices_end) {
310
306
const auto & src_concrete = assert_cast<const ColumnNullable&>(src);
311
307
get_nested_column ().insert_indices_from (src_concrete.get_nested_column (), indices_begin,
312
308
indices_end);
313
- _get_null_map_column ().insert_indices_from (src_concrete.get_null_map_column (), indices_begin,
314
- indices_end);
315
- _need_update_has_null = true ;
309
+ get_null_map_column ().insert_indices_from (src_concrete.get_null_map_column (), indices_begin,
310
+ indices_end);
316
311
}
317
312
318
313
void ColumnNullable::insert_indices_from_not_has_null (const IColumn& src,
@@ -321,37 +316,37 @@ void ColumnNullable::insert_indices_from_not_has_null(const IColumn& src,
321
316
const auto & src_concrete = assert_cast<const ColumnNullable&>(src);
322
317
get_nested_column ().insert_indices_from (src_concrete.get_nested_column (), indices_begin,
323
318
indices_end);
324
- _get_null_map_column (). insert_many_defaults (indices_end - indices_begin);
319
+ _push_false_to_nullmap (indices_end - indices_begin);
325
320
}
326
321
327
322
void ColumnNullable::insert (const Field& x) {
328
323
if (x.is_null ()) {
329
324
get_nested_column ().insert_default ();
330
- _get_null_map_data ().push_back (1 );
325
+ get_null_map_data ().push_back (1 );
331
326
_has_null = true ;
327
+ _need_update_has_null = false ;
332
328
} else {
333
329
get_nested_column ().insert (x);
334
- _get_null_map_data (). push_back ( 0 );
330
+ _push_false_to_nullmap ( 1 );
335
331
}
336
332
}
337
333
338
334
void ColumnNullable::insert_from (const IColumn& src, size_t n) {
339
335
const auto & src_concrete = assert_cast<const ColumnNullable&>(src);
340
336
get_nested_column ().insert_from (src_concrete.get_nested_column (), n);
341
337
auto is_null = src_concrete.get_null_map_data ()[n];
342
- _has_null |= is_null;
343
- _get_null_map_data ().push_back (is_null);
338
+ get_null_map_data ().push_back (is_null);
344
339
}
345
340
346
341
void ColumnNullable::insert_from_not_nullable (const IColumn& src, size_t n) {
347
342
get_nested_column ().insert_from (src, n);
348
- _get_null_map_data (). push_back ( 0 );
343
+ _push_false_to_nullmap ( 1 );
349
344
}
350
345
351
346
void ColumnNullable::insert_range_from_not_nullable (const IColumn& src, size_t start,
352
347
size_t length) {
353
348
get_nested_column ().insert_range_from (src, start, length);
354
- _get_null_map_data (). resize_fill ( _get_null_map_data (). size () + length, 0 );
349
+ _push_false_to_nullmap ( length);
355
350
}
356
351
357
352
void ColumnNullable::insert_many_from_not_nullable (const IColumn& src, size_t position,
@@ -380,15 +375,14 @@ size_t ColumnNullable::filter(const Filter& filter) {
380
375
}
381
376
382
377
Status ColumnNullable::filter_by_selector (const uint16_t * sel, size_t sel_size, IColumn* col_ptr) {
383
- const auto * nullable_col_ptr = reinterpret_cast < const ColumnNullable*>(col_ptr);
378
+ auto * nullable_col_ptr = assert_cast< ColumnNullable*>(col_ptr);
384
379
ColumnPtr nest_col_ptr = nullable_col_ptr->nested_column ;
385
- ColumnPtr null_map_ptr = nullable_col_ptr->null_map ;
380
+
381
+ // / `get_null_map_data` will set `_need_update_has_null` to true
382
+ auto & res_nullmap = nullable_col_ptr->get_null_map_data ();
383
+
386
384
RETURN_IF_ERROR (get_nested_column ().filter_by_selector (
387
385
sel, sel_size, const_cast <doris::vectorized::IColumn*>(nest_col_ptr.get ())));
388
- // insert cur nullmap into result nullmap which is empty
389
- auto & res_nullmap = reinterpret_cast <vectorized::ColumnVector<UInt8 >*>(
390
- const_cast <doris::vectorized::IColumn*>(null_map_ptr.get ()))
391
- ->get_data ();
392
386
DCHECK (res_nullmap.empty ());
393
387
res_nullmap.resize (sel_size);
394
388
auto & cur_nullmap = get_null_map_column ().get_data ();
@@ -535,15 +529,10 @@ void ColumnNullable::get_permutation(bool reverse, size_t limit, int null_direct
535
529
}
536
530
}
537
531
}
538
- //
539
- // void ColumnNullable::gather(ColumnGathererStream & gatherer)
540
- // {
541
- // gatherer.gather(*this);
542
- // }
543
532
544
533
void ColumnNullable::reserve (size_t n) {
545
534
get_nested_column ().reserve (n);
546
- _get_null_map_data ( ).reserve (n);
535
+ get_null_map_data ( false ).reserve (n);
547
536
}
548
537
549
538
void ColumnNullable::resize (size_t n) {
@@ -595,7 +584,7 @@ void ColumnNullable::apply_null_map(const ColumnNullable& other) {
595
584
}
596
585
597
586
void ColumnNullable::check_consistency () const {
598
- if (null_map-> size () != get_nested_column ().size ()) {
587
+ if (get_null_map_column (). size () != get_nested_column ().size ()) {
599
588
throw Exception (ErrorCode::INTERNAL_ERROR,
600
589
" Sizes of nested column and null map of Nullable column are not equal" );
601
590
}
@@ -609,8 +598,8 @@ void ColumnNullable::sort_column(const ColumnSorter* sorter, EqualFlags& flags,
609
598
}
610
599
611
600
void ColumnNullable::_update_has_null () {
612
- const UInt8 * null_pos = _get_null_map_data ().data ();
613
- _has_null = simd::contain_byte (null_pos, _get_null_map_data ().size (), 1 );
601
+ const UInt8 * null_pos = get_null_map_data ().data ();
602
+ _has_null = simd::contain_byte (null_pos, get_null_map_data ().size (), 1 );
614
603
_need_update_has_null = false ;
615
604
}
616
605
0 commit comments