[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

@ -45,7 +45,9 @@ namespace doris::vectorized {
VTableFunctionNode::VTableFunctionNode(doris::ObjectPool* pool, const TPlanNode& tnode,
const DescriptorTbl& descs)
: ExecNode(pool, tnode, descs) {}
: ExecNode(pool, tnode, descs) {
_child_block = Block::create_shared();
}
Status VTableFunctionNode::init(const TPlanNode& tnode, RuntimeState* state) {
RETURN_IF_ERROR(ExecNode::init(tnode, state));
@ -144,12 +146,12 @@ Status VTableFunctionNode::get_next(RuntimeState* state, Block* block, bool* eos
// if child_block is empty, get data from child.
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*, Block*, bool*)) & ExecNode::get_next,
_children[0], std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3)));
RETURN_IF_ERROR(push(state, &_child_block, _child_eos));
RETURN_IF_ERROR(push(state, _child_block.get(), _child_eos));
}
return pull(state, block, eos);
@ -170,7 +172,7 @@ Status VTableFunctionNode::_get_expanded_block(RuntimeState* state, Block* outpu
RETURN_IF_CANCELLED(state);
RETURN_IF_ERROR(state->check_query_state("VTableFunctionNode, while getting next batch."));
if (_child_block.rows() == 0) {
if (_child_block->rows() == 0) {
break;
}
@ -227,13 +229,13 @@ Status VTableFunctionNode::_get_expanded_block(RuntimeState* state, Block* outpu
Status VTableFunctionNode::_process_next_child_row() {
_cur_child_offset++;
if (_cur_child_offset >= _child_block.rows()) {
if (_cur_child_offset >= _child_block->rows()) {
// release block use count.
for (TableFunction* fn : _fns) {
RETURN_IF_ERROR(fn->process_close());
}
release_block_memory(_child_block);
release_block_memory(*_child_block);
_cur_child_offset = -1;
return Status::OK();
}