@@ -226,6 +226,9 @@ class JoinHashMapTable : public HashMapTable<Key, Cell, Hash, Grower, Allocator>
226
226
template <int JoinOpType>
227
227
void prepare_build (size_t num_elem, int batch_size, bool has_null_key) {
228
228
_has_null_key = has_null_key;
229
+
230
+ // the first row in build side is not really from build side table
231
+ _empty_build_side = num_elem <= 1 ;
229
232
max_batch_size = batch_size;
230
233
bucket_size = calc_bucket_size (num_elem + 1 );
231
234
first.resize (bucket_size + 1 );
@@ -262,6 +265,14 @@ class JoinHashMapTable : public HashMapTable<Key, Cell, Hash, Grower, Allocator>
262
265
uint32_t * __restrict probe_idxs, bool & probe_visited,
263
266
uint32_t * __restrict build_idxs,
264
267
doris::vectorized::ColumnFilterHelper* mark_column) {
268
+ if constexpr (JoinOpType == doris::TJoinOp::NULL_AWARE_LEFT_ANTI_JOIN) {
269
+ if (_empty_build_side) {
270
+ return _process_null_aware_left_anti_join_for_empty_build_side<
271
+ JoinOpType, with_other_conjuncts, is_mark_join>(
272
+ probe_idx, probe_rows, probe_idxs, build_idxs, mark_column);
273
+ }
274
+ }
275
+
265
276
if constexpr (is_mark_join) {
266
277
return _find_batch_mark<JoinOpType, with_other_conjuncts>(
267
278
keys, build_idx_map, probe_idx, probe_rows, probe_idxs, build_idxs,
@@ -367,6 +378,29 @@ class JoinHashMapTable : public HashMapTable<Key, Cell, Hash, Grower, Allocator>
367
378
return std::tuple {probe_idx, 0U , matched_cnt};
368
379
}
369
380
381
+ template <int JoinOpType, bool with_other_conjuncts, bool is_mark_join>
382
+ auto _process_null_aware_left_anti_join_for_empty_build_side (
383
+ int probe_idx, int probe_rows, uint32_t * __restrict probe_idxs,
384
+ uint32_t * __restrict build_idxs, doris::vectorized::ColumnFilterHelper* mark_column) {
385
+ static_assert (JoinOpType == doris::TJoinOp::NULL_AWARE_LEFT_ANTI_JOIN);
386
+ auto matched_cnt = 0 ;
387
+ const auto batch_size = max_batch_size;
388
+
389
+ while (probe_idx < probe_rows && matched_cnt < batch_size) {
390
+ probe_idxs[matched_cnt] = probe_idx++;
391
+ if constexpr (is_mark_join) {
392
+ build_idxs[matched_cnt] = 0 ;
393
+ }
394
+ ++matched_cnt;
395
+ }
396
+
397
+ if constexpr (is_mark_join && !with_other_conjuncts) {
398
+ mark_column->resize_fill (matched_cnt, 1 );
399
+ }
400
+
401
+ return std::tuple {probe_idx, 0U , matched_cnt};
402
+ }
403
+
370
404
auto _find_batch_right_semi_anti (const Key* __restrict keys,
371
405
const uint32_t * __restrict build_idx_map, int probe_idx,
372
406
int probe_rows) {
@@ -532,6 +566,7 @@ class JoinHashMapTable : public HashMapTable<Key, Cell, Hash, Grower, Allocator>
532
566
Cell cell;
533
567
doris::vectorized::Arena* pool;
534
568
bool _has_null_key = false ;
569
+ bool _empty_build_side = true ;
535
570
};
536
571
537
572
template <typename Key, typename Mapped, typename Hash = DefaultHash<Key>,
0 commit comments