[FEAT MERGE]4_1_sql_feature
Co-authored-by: leslieyuchen <leslieyuchen@gmail.com> Co-authored-by: Charles0429 <xiezhenjiang@gmail.com> Co-authored-by: raywill <hustos@gmail.com>
This commit is contained in:
@ -28,6 +28,8 @@ int ObRecursiveInnerDataOp::init(const ObExpr *search_expr, const ObExpr *cycle_
|
||||
cycle_expr_ = cycle_expr;
|
||||
if (OB_FAIL(dfs_pump_.init())) {
|
||||
LOG_WARN("Failed to init depth first search pump", K(ret));
|
||||
} else if (OB_FAIL(ctx_.get_my_session()->get_sys_variable(share::SYS_VAR_CTE_MAX_RECURSION_DEPTH, max_recursion_depth_))) {
|
||||
LOG_WARN("Get sys variable error", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -388,7 +390,9 @@ int ObRecursiveInnerDataOp::get_next_row()
|
||||
LOG_WARN("Format output row failed", K(ret));
|
||||
} else { }
|
||||
} else if (RecursiveUnionState::R_UNION_READ_LEFT == state_) {
|
||||
if (OB_FAIL(try_get_left_rows())) {
|
||||
if (is_mysql_mode() && OB_FAIL(check_recursive_depth())) {
|
||||
LOG_WARN("Recursive query abort", K(ret));
|
||||
} else if (OB_FAIL(try_get_left_rows())) {
|
||||
if (ret != OB_ITER_END) {
|
||||
LOG_WARN("Get left rows failed", K(ret));
|
||||
} else {
|
||||
@ -398,7 +402,9 @@ int ObRecursiveInnerDataOp::get_next_row()
|
||||
state_ = R_UNION_READ_RIGHT;
|
||||
}
|
||||
} else if (RecursiveUnionState::R_UNION_READ_RIGHT == state_) {
|
||||
if (OB_FAIL(try_get_right_rows())) {
|
||||
if (is_mysql_mode() && OB_FAIL(check_recursive_depth())) {
|
||||
LOG_WARN("Recursive query abort", K(ret));
|
||||
} else if (OB_FAIL(try_get_right_rows())) {
|
||||
if (ret != OB_ITER_END) {
|
||||
LOG_WARN("Get right rows failed", K(ret));
|
||||
} else {
|
||||
@ -432,7 +438,9 @@ int ObRecursiveInnerDataOp::get_next_batch(const int64_t max_row_cnt,
|
||||
LOG_WARN("Format output row failed", K(ret));
|
||||
}// else { } do nothing
|
||||
} else if (RecursiveUnionState::R_UNION_READ_LEFT == state_) {
|
||||
if (OB_FAIL(try_get_left_rows(true))) {
|
||||
if (is_mysql_mode() && OB_FAIL(check_recursive_depth())) {
|
||||
LOG_WARN("Recursive query abort", K(ret));
|
||||
} else if (OB_FAIL(try_get_left_rows(true))) {
|
||||
if (ret != OB_ITER_END) {
|
||||
LOG_WARN("Get left rows failed", K(ret));
|
||||
} else {
|
||||
@ -442,7 +450,9 @@ int ObRecursiveInnerDataOp::get_next_batch(const int64_t max_row_cnt,
|
||||
state_ = R_UNION_READ_RIGHT;
|
||||
}
|
||||
} else if (RecursiveUnionState::R_UNION_READ_RIGHT == state_) {
|
||||
if (OB_FAIL(try_get_right_rows(true))) {
|
||||
if (is_mysql_mode() && OB_FAIL(check_recursive_depth())) {
|
||||
LOG_WARN("Recursive query abort", K(ret));
|
||||
} else if (OB_FAIL(try_get_right_rows(true))) {
|
||||
if (ret != OB_ITER_END) {
|
||||
LOG_WARN("Get right rows failed", K(ret));
|
||||
} else {
|
||||
@ -549,5 +559,22 @@ int ObRecursiveInnerDataOp::assign_to_cur_row(ObChunkDatumStore::StoredRow *stor
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRecursiveInnerDataOp::check_recursive_depth() {
|
||||
int ret = OB_SUCCESS;
|
||||
ObSearchMethodOp *pump = NULL;
|
||||
if (OB_ISNULL(pump = get_search_method_bump())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected null", K(ret));
|
||||
} else {
|
||||
uint64_t level = pump->get_last_node_level();
|
||||
if (level != UINT64_MAX && level > max_recursion_depth_) {
|
||||
ret = OB_ERR_CTE_MAX_RECURSION_DEPTH;
|
||||
LOG_USER_ERROR(OB_ERR_CTE_MAX_RECURSION_DEPTH, level);
|
||||
LOG_WARN("Recursive query aborted after too many iterations.", K(ret), K(level));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
|
||||
@ -67,7 +67,8 @@ public:
|
||||
bfs_pump_(stored_row_buf_, left_output, sort_collations, cycle_by_col_lists),
|
||||
eval_ctx_(eval_ctx),
|
||||
ctx_(exec_ctx),
|
||||
output_union_exprs_(output_union_exprs)
|
||||
output_union_exprs_(output_union_exprs),
|
||||
max_recursion_depth_(0)
|
||||
{
|
||||
}
|
||||
~ObRecursiveInnerDataOp() = default;
|
||||
@ -121,6 +122,7 @@ private:
|
||||
return &dfs_pump_;
|
||||
}
|
||||
}
|
||||
int check_recursive_depth();
|
||||
// disallow copy
|
||||
DISALLOW_COPY_AND_ASSIGN(ObRecursiveInnerDataOp);
|
||||
private:
|
||||
@ -162,6 +164,7 @@ private:
|
||||
ObExecContext &ctx_;
|
||||
const common::ObIArray<ObExpr *> &output_union_exprs_;
|
||||
int64_t batch_size_ = 1;
|
||||
uint64_t max_recursion_depth_;
|
||||
};
|
||||
} // end namespace sql
|
||||
} // end namespace oceanbase
|
||||
|
||||
@ -345,6 +345,7 @@ int ObBreadthFisrtSearchOp::reuse()
|
||||
{
|
||||
ObSearchMethodOp::reuse();
|
||||
current_parent_node_ = &bst_root_;
|
||||
last_node_level_ = 0;
|
||||
bst_root_.child_num_ = 0;
|
||||
bst_root_.children_ = nullptr;
|
||||
bst_root_.parent_ = nullptr;
|
||||
@ -435,6 +436,7 @@ int ObBreadthFisrtSearchOp::update_parent_node(ObTreeNode &node)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
current_parent_node_ = node.in_bstree_node_;
|
||||
last_node_level_ = node.tree_level_;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -459,6 +461,7 @@ int ObBreadthFisrtSearchOp::add_result_rows()
|
||||
tmp->parent_ = current_parent_node_;
|
||||
current_parent_node_->children_[i] = tmp;
|
||||
node.in_bstree_node_ = tmp;
|
||||
node.tree_level_ = last_node_level_ + 1;
|
||||
if (OB_FAIL(is_breadth_cycle_node(node))) {
|
||||
LOG_WARN("Find cycle failed", K(ret));
|
||||
} else if (OB_FAIL(search_results_.push_back(node))) {
|
||||
@ -490,4 +493,4 @@ int ObBreadthFisrtSearchOp::finish_add_row(bool sort)
|
||||
}
|
||||
search_results_.reuse();
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@ -176,7 +176,7 @@ public:
|
||||
const common::ObIArray<uint64_t> &cycle_by_columns)
|
||||
: allocator_(allocator), input_rows_(),
|
||||
sort_collations_(sort_collations), cycle_by_columns_(cycle_by_columns),
|
||||
left_output_(left_output) {};
|
||||
left_output_(left_output), last_node_level_(UINT64_MAX) {};
|
||||
virtual ~ObSearchMethodOp() = default;
|
||||
|
||||
virtual int finish_add_row(bool sort) = 0;
|
||||
@ -193,6 +193,7 @@ public:
|
||||
int is_same_row(ObChunkDatumStore::StoredRow &row_1st, ObChunkDatumStore::StoredRow &row_2nd,
|
||||
bool &is_cycle);
|
||||
int64_t count() { return input_rows_.count(); }
|
||||
virtual uint64_t get_last_node_level() { return last_node_level_; }
|
||||
const static int64_t ROW_EXTRA_SIZE = 0;
|
||||
protected:
|
||||
// hard code seed, 24bit max prime number
|
||||
@ -203,6 +204,8 @@ protected:
|
||||
const common::ObIArray<uint64_t> &cycle_by_columns_;
|
||||
common::ObArray<ObChunkDatumStore::StoredRow*> recycle_rows_;
|
||||
const ExprFixedArray &left_output_;
|
||||
// 记录当前查询行在树中的level
|
||||
uint64_t last_node_level_;
|
||||
};
|
||||
|
||||
class ObDepthFisrtSearchOp : public ObSearchMethodOp
|
||||
@ -213,7 +216,7 @@ public:
|
||||
const common::ObIArray<ObSortFieldCollation> &sort_collations,
|
||||
const common::ObIArray<uint64_t> &cycle_by_columns) :
|
||||
ObSearchMethodOp(allocator, left_output, sort_collations, cycle_by_columns),
|
||||
hash_filter_rows_(), hash_col_idx_(), last_node_level_(UINT64_MAX),
|
||||
hash_filter_rows_(), hash_col_idx_(),
|
||||
current_search_path_(), search_stack_(allocator_)
|
||||
{ }
|
||||
virtual ~ObDepthFisrtSearchOp() {
|
||||
@ -238,8 +241,6 @@ private:
|
||||
private:
|
||||
RowMap hash_filter_rows_;
|
||||
common::ObSEArray<uint64_t, 32> hash_col_idx_;
|
||||
// 记录当前查询行在树中的level
|
||||
uint64_t last_node_level_;
|
||||
/**
|
||||
* level
|
||||
* A 0
|
||||
@ -265,7 +266,9 @@ public:
|
||||
const common::ObIArray<ObSortFieldCollation> &sort_collations,
|
||||
const common::ObIArray<uint64_t> &cycle_by_columns) :
|
||||
ObSearchMethodOp(allocator, left_output, sort_collations, cycle_by_columns), bst_root_(),
|
||||
current_parent_node_(&bst_root_), search_queue_(allocator), search_results_() {}
|
||||
current_parent_node_(&bst_root_), search_queue_(allocator), search_results_() {
|
||||
last_node_level_ = 0;
|
||||
}
|
||||
virtual ~ObBreadthFisrtSearchOp() = default;
|
||||
|
||||
virtual int finish_add_row(bool sort) override;
|
||||
|
||||
Reference in New Issue
Block a user