[bugfix](core) child block is shared between operator and node, it should be shared ptr (#28106)

_child_block in nest loop join , table value function, repeat node will be shared between ExecNode and related operator, but it should not be a unique ptr in operator, it belongs to exec node.

It will double free the block, if operator's close method is not called correctly.

It should be a shared ptr, then it will not core even if the opeartor's close method is not called.
This commit is contained in:
yiguolei
2023-12-09 00:18:14 +08:00
committed by GitHub
parent 8eed760704
commit abc802b5ba
10 changed files with 48 additions and 45 deletions

View File

@ -53,7 +53,9 @@ VRepeatNode::VRepeatNode(ObjectPool* pool, const TPlanNode& tnode, const Descrip
_grouping_list(tnode.repeat_node.grouping_list),
_output_tuple_id(tnode.repeat_node.output_tuple_id),
_child_eos(false),
_repeat_id_idx(0) {}
_repeat_id_idx(0) {
_child_block = Block::create_shared();
}
Status VRepeatNode::init(const TPlanNode& tnode, RuntimeState* state) {
RETURN_IF_ERROR(ExecNode::init(tnode, state));
@ -189,12 +191,12 @@ Status VRepeatNode::pull(doris::RuntimeState* state, vectorized::Block* output_b
int size = _repeat_id_list.size();
if (_repeat_id_idx >= size) {
_intermediate_block->clear();
release_block_memory(_child_block);
release_block_memory(*_child_block);
_repeat_id_idx = 0;
}
}
RETURN_IF_ERROR(VExprContext::filter_block(_conjuncts, output_block, output_block->columns()));
*eos = _child_eos && _child_block.rows() == 0;
*eos = _child_eos && _child_block->rows() == 0;
reached_limit(output_block, eos);
COUNTER_SET(_rows_returned_counter, _num_rows_returned);
return Status::OK();
@ -225,7 +227,7 @@ Status VRepeatNode::push(RuntimeState* state, vectorized::Block* input_block, bo
}
bool VRepeatNode::need_more_input_data() const {
return !_child_block.rows() && !_child_eos;
return !_child_block->rows() && !_child_eos;
}
Status VRepeatNode::get_next(RuntimeState* state, Block* block, bool* eos) {
@ -243,13 +245,13 @@ Status VRepeatNode::get_next(RuntimeState* state, Block* block, bool* eos) {
DCHECK(block->rows() == 0);
while (need_more_input_data()) {
RETURN_IF_ERROR(child(0)->get_next_after_projects(
state, &_child_block, &_child_eos,
state, _child_block.get(), &_child_eos,
std::bind((Status(ExecNode::*)(RuntimeState*, vectorized::Block*, bool*)) &
ExecNode::get_next,
_children[0], std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3)));
static_cast<void>(push(state, &_child_block, _child_eos));
static_cast<void>(push(state, _child_block.get(), _child_eos));
}
return pull(state, block, eos);