22
22
#include " exprs/bloom_filter_func.h"
23
23
#include " pipeline/exec/hashjoin_probe_operator.h"
24
24
#include " pipeline/exec/operator.h"
25
+ #include " pipeline/pipeline_x/pipeline_x_task.h"
25
26
#include " vec/data_types/data_type_nullable.h"
26
27
#include " vec/exec/join/vhash_join_node.h"
27
28
#include " vec/utils/template_helpers.hpp"
@@ -122,6 +123,9 @@ Status HashJoinBuildSinkLocalState::open(RuntimeState* state) {
122
123
}
123
124
124
125
Status HashJoinBuildSinkLocalState::close (RuntimeState* state, Status exec_status) {
126
+ if (_closed) {
127
+ return Status::OK ();
128
+ }
125
129
auto p = _parent->cast <HashJoinBuildSinkOperatorX>();
126
130
Defer defer {[&]() {
127
131
if (_should_build_hash_table && p._shared_hashtable_controller ) {
@@ -130,25 +134,30 @@ Status HashJoinBuildSinkLocalState::close(RuntimeState* state, Status exec_statu
130
134
}};
131
135
132
136
if (!_runtime_filter_slots || _runtime_filters.empty () || state->is_cancelled ()) {
133
- return Status::OK ( );
137
+ return Base::close (state, exec_status );
134
138
}
135
- auto * block = _shared_state->build_block .get ();
136
- uint64_t hash_table_size = block ? block->rows () : 0 ;
137
- {
138
- SCOPED_TIMER (_runtime_filter_init_timer);
139
- if (_should_build_hash_table) {
140
- RETURN_IF_ERROR (_runtime_filter_slots->init_filters (state, hash_table_size));
139
+
140
+ if (state->get_task ()->wake_up_by_downstream ()) {
141
+ RETURN_IF_ERROR (_runtime_filter_slots->send_filter_size (state, 0 , _finish_dependency));
142
+ RETURN_IF_ERROR (_runtime_filter_slots->ignore_all_filters ());
143
+ } else {
144
+ auto * block = _shared_state->build_block .get ();
145
+ uint64_t hash_table_size = block ? block->rows () : 0 ;
146
+ {
147
+ SCOPED_TIMER (_runtime_filter_init_timer);
148
+ if (_should_build_hash_table) {
149
+ RETURN_IF_ERROR (_runtime_filter_slots->init_filters (state, hash_table_size));
150
+ }
151
+ RETURN_IF_ERROR (_runtime_filter_slots->ignore_filters (state));
152
+ }
153
+ if (_should_build_hash_table && hash_table_size > 1 ) {
154
+ SCOPED_TIMER (_runtime_filter_compute_timer);
155
+ _runtime_filter_slots->insert (block);
141
156
}
142
- RETURN_IF_ERROR (_runtime_filter_slots->ignore_filters (state));
143
- }
144
- if (_should_build_hash_table && hash_table_size > 1 ) {
145
- SCOPED_TIMER (_runtime_filter_compute_timer);
146
- _runtime_filter_slots->insert (block);
147
157
}
148
-
149
158
SCOPED_TIMER (_publish_runtime_filter_timer);
150
159
RETURN_IF_ERROR (_runtime_filter_slots->publish (!_should_build_hash_table));
151
- return Status::OK ( );
160
+ return Base::close (state, exec_status );
152
161
}
153
162
154
163
bool HashJoinBuildSinkLocalState::build_unique () const {
@@ -519,6 +528,7 @@ Status HashJoinBuildSinkOperatorX::sink(RuntimeState* state, vectorized::Block*
519
528
SCOPED_TIMER (local_state.exec_time_counter ());
520
529
COUNTER_UPDATE (local_state.rows_input_counter (), (int64_t )in_block->rows ());
521
530
531
+ local_state._eos = eos;
522
532
if (local_state._should_build_hash_table ) {
523
533
// If eos or have already met a null value using short-circuit strategy, we do not need to pull
524
534
// data from probe side.
@@ -582,6 +592,7 @@ Status HashJoinBuildSinkOperatorX::sink(RuntimeState* state, vectorized::Block*
582
592
local_state.process_build_block (state, (*local_state._shared_state ->build_block )));
583
593
if (_shared_hashtable_controller) {
584
594
_shared_hash_table_context->status = Status::OK ();
595
+ _shared_hash_table_context->complete_build_stage = true ;
585
596
// arena will be shared with other instances.
586
597
_shared_hash_table_context->arena = local_state._shared_state ->arena ;
587
598
_shared_hash_table_context->hash_table_variants =
@@ -594,7 +605,8 @@ Status HashJoinBuildSinkOperatorX::sink(RuntimeState* state, vectorized::Block*
594
605
local_state._runtime_filter_slots ->copy_to_shared_context (_shared_hash_table_context);
595
606
_shared_hashtable_controller->signal (node_id ());
596
607
}
597
- } else if (!local_state._should_build_hash_table ) {
608
+ } else if (!local_state._should_build_hash_table &&
609
+ _shared_hash_table_context->complete_build_stage ) {
598
610
DCHECK (_shared_hashtable_controller != nullptr );
599
611
DCHECK (_shared_hash_table_context != nullptr );
600
612
// the instance which is not build hash table, it's should wait the signal of hash table build finished.
0 commit comments