提交 25b02ac3 编写于 作者: L Larry955 提交者: ob-robot

fix parallel var assign bug

上级 30421352
......@@ -9074,7 +9074,8 @@ int ObJoinOrder::get_valid_path_info(const ObJoinOrder &left_tree,
if (OB_FAIL(ret)) {
/*do nothing*/
} else {
if (get_cnt_rownum()) {
if (get_cnt_rownum() ||
(!opt_ctx.is_var_assign_only_in_root_stmt() && opt_ctx.has_var_assign())) {
path_info.distributed_methods_ &= DIST_PULL_TO_LOCAL | DIST_BASIC_METHOD;
}
if (IS_LEFT_STYLE_JOIN(path_info.join_type_)) {
......
......@@ -201,39 +201,6 @@ enum class WinDistAlgo
LIST = 3 // range + random distribute
};
#define ADD_DIST_METHOD_WITHOUT_BC2HOST(method) \
do {add_join_dist_flag(method, DIST_PULL_TO_LOCAL); \
add_join_dist_flag(method, DIST_HASH_HASH); \
add_join_dist_flag(method, DIST_BROADCAST_NONE); \
add_join_dist_flag(method, DIST_NONE_BROADCAST); \
add_join_dist_flag(method, DIST_PARTITION_NONE); \
add_join_dist_flag(method, DIST_NONE_PARTITION); \
add_join_dist_flag(method, DIST_PARTITION_WISE); \
} while(0);
#define REMOVE_PX_SPECIFIC_DIST_METHOD(method) \
do {remove_join_dist_flag(method, DIST_HASH_HASH); \
remove_join_dist_flag(method, DIST_BROADCAST_NONE); \
remove_join_dist_flag(method, DIST_NONE_BROADCAST); \
remove_join_dist_flag(method, DIST_BC2HOST_NONE); \
remove_join_dist_flag(method, DIST_NONE_RANDOM); \
remove_join_dist_flag(method, DIST_RANDOM_NONE); \
} while(0);
#define UPDATE_CURRENT_JOIN_DIST_METHOD(method, cost, v_method, v_cost) \
do { if ((DIST_INVALID_METHOD == method || cost > v_cost) && 0 != v_method) { \
method = v_method; \
cost = v_cost;} \
} while(0);
#define REMOVE_PX_PARALLEL_DFO_DIST_METHOD(method) \
do {remove_join_dist_flag(method, DIST_HASH_HASH); \
remove_join_dist_flag(method, DIST_BROADCAST_NONE); \
remove_join_dist_flag(method, DIST_NONE_BROADCAST); \
remove_join_dist_flag(method, DIST_NONE_RANDOM); \
remove_join_dist_flag(method, DIST_RANDOM_NONE); \
} while(0);
class ObLogPlan;
class ObLogOperatorFactory
{
......
......@@ -8670,6 +8670,9 @@ int ObLogPlan::create_subplan_filter_plan(ObLogicalOperator *&top,
LOG_WARN("failed to check whether contains recursive cte", K(ret));
} else if (is_recursive_cte) {
dist_algo = DistAlgo::DIST_PULL_TO_LOCAL;
} else if (!get_optimizer_context().is_var_assign_only_in_root_stmt() &&
get_optimizer_context().has_var_assign()) {
dist_algo = DistAlgo::DIST_PULL_TO_LOCAL;
} else if (OB_FAIL(check_if_subplan_filter_match_partition_wise(top,
subquery_ops,
params,
......
......@@ -3742,22 +3742,25 @@ int ObLogicalOperator::adjust_plan_root_output_exprs()
} else if (output_exprs_.empty()) {
/*do nothing*/
} else if (stmt->is_select_stmt() &&
FALSE_IT(into_item = static_cast<const ObSelectStmt*>(get_stmt())->get_select_into())) {
FALSE_IT(into_item = static_cast<const ObSelectStmt*>(stmt)->get_select_into())) {
/*do nothing*/
} else if (NULL == get_parent() && NULL != into_item && T_INTO_OUTFILE == into_item->into_type_) {
if (OB_FAIL(build_and_put_into_outfile_expr(into_item, output_exprs_))) {
LOG_WARN("failed to add into outfile expr to ctx", K(ret));
} else {
LOG_TRACE("succeed to add into outfile expr to ctx", K(ret));
}
} else if (NULL == get_parent() && check_stmt_can_be_packed(stmt)) {
if (OB_FAIL(build_and_put_pack_expr(output_exprs_))) {
LOG_WARN("failed to add pack expr to context", K(ret));
} else if (NULL == get_parent()) {
if (NULL != into_item && T_INTO_OUTFILE == into_item->into_type_) {
if (OB_FAIL(build_and_put_into_outfile_expr(into_item, output_exprs_))) {
LOG_WARN("failed to add into outfile expr to ctx", K(ret));
} else {
LOG_TRACE("succeed to add into outfile expr to ctx", K(ret));
}
} else {
LOG_TRACE("succeed to add plan root output exprs", K(output_exprs_));
bool need_pack = false;
if (OB_FAIL(check_stmt_can_be_packed(stmt, need_pack))) {
LOG_WARN("failed to check stmt can be pack", K(ret));
} else if (need_pack && OB_FAIL(build_and_put_pack_expr(output_exprs_))) {
LOG_WARN("failed to add pack expr to context", K(ret));
}
}
} else { /*do nothing*/ }
LOG_TRACE("succeed to adjust plan root output exprs", K(output_exprs_));
}
return ret;
}
......@@ -3784,16 +3787,22 @@ int ObLogicalOperator::set_plan_root_output_exprs()
return ret;
}
bool ObLogicalOperator::check_stmt_can_be_packed(const ObDMLStmt *stmt)
int ObLogicalOperator::check_stmt_can_be_packed(const ObDMLStmt *stmt, bool &need_pack)
{
bool need_pack = false;
int ret = OB_SUCCESS;
need_pack = false;
ObSQLSessionInfo *session_info = NULL;
if (NULL != stmt && NULL != get_plan() &&
NULL != (session_info = get_plan()->get_optimizer_context().get_session_info())) {
if (OB_ISNULL(stmt) || OB_ISNULL(get_plan()) ||
OB_ISNULL(session_info = get_plan()->get_optimizer_context().get_session_info())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(ret));
} else {
bool has_var_assign = get_plan()->get_optimizer_context().has_var_assign();
bool is_var_assign_only_in_root = get_plan()->get_optimizer_context().is_var_assign_only_in_root_stmt();
need_pack = stmt->is_select_stmt() && (!session_info->is_inner()) && LOG_EXCHANGE == type_
&& (ObPhyPlanType::OB_PHY_PLAN_DISTRIBUTED == get_phy_plan_type());
&& (ObPhyPlanType::OB_PHY_PLAN_DISTRIBUTED == get_phy_plan_type()) && !has_var_assign;
}
return need_pack;
return ret;
}
int ObLogicalOperator::replace_generated_agg_expr(
......
......@@ -769,7 +769,6 @@ public:
static const int64_t second_child = 1;
static const int64_t third_child = 2;
static const int64_t fourth_child = 3;
static const int64_t SEQUENTIAL_EXECUTION_THRESHOLD = 1000;
ObLogicalOperator(ObLogPlan &plan);
virtual ~ObLogicalOperator();
......@@ -1480,7 +1479,7 @@ public:
inline const ObShardingInfo *get_strong_sharding() const { return strong_sharding_; }
inline void set_strong_sharding(ObShardingInfo* strong_sharding) { strong_sharding_ = strong_sharding; }
bool check_stmt_can_be_packed(const ObDMLStmt *stmt);
int check_stmt_can_be_packed(const ObDMLStmt *stmt, bool &need_pack);
inline ObIArray<ObShardingInfo*> &get_weak_sharding() { return weak_sharding_; }
inline const ObIArray<ObShardingInfo*> &get_weak_sharding() const { return weak_sharding_; }
......
......@@ -240,48 +240,56 @@ bool ObOptimizer::exists_temp_table(const ObIArray<ObSqlTempTableInfo*> &temp_ta
return bret;
}
// max_table_hint used for parallelism at the statement or object level
int ObOptimizer::get_stmt_max_table_parallel_hint(ObDMLStmt &stmt,
int64_t &max_table_hint)
/**
* @brief Get the attr from stmt recursively object
*
* @param stmt
* @param max_dop used for table's parallel attribute
* @param max_table_parallel used for parallelism at the statement or object level
* @return int
*/
int ObOptimizer::get_stmt_parallel_info(ObDMLStmt *stmt,
int64_t &max_table_dop,
int64_t &max_table_parallel)
{
int ret = OB_SUCCESS;
ObSEArray<ObSelectStmt*, 4> child_stmts;
ObQueryCtx *query_ctx = NULL;
int64_t cur_max_table_hint = ObGlobalHint::UNSET_PARALLEL;
if (OB_FAIL(stmt.get_stmt_hint().get_max_table_parallel(stmt, cur_max_table_hint))) {
if (OB_ISNULL(stmt)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(ret));
} else if (OB_FAIL(stmt->get_child_stmts(child_stmts))) {
LOG_WARN("failed to get child stmt", K(ret));
} else if (OB_FAIL(SMART_CALL(get_stmt_max_table_dop(*stmt, max_table_dop)))) {
LOG_WARN("failed to get stmt max table dop", K(ret));
} else if (OB_FAIL(stmt->get_stmt_hint().get_max_table_parallel(*stmt, cur_max_table_hint))) {
LOG_WARN("failed to get max table parallel", K(ret));
} else if (OB_FAIL(stmt.get_child_stmts(child_stmts))) {
LOG_WARN("failed to get child stmts", K(ret));
} else {
max_table_hint = std::max(max_table_hint, cur_max_table_hint);
}
for (int64_t i = 0; OB_SUCC(ret) && i < child_stmts.count(); i++) {
if (OB_ISNULL(child_stmts.at(i))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(ret));
} else if (OB_FAIL(SMART_CALL(get_stmt_max_table_parallel_hint(*child_stmts.at(i),
max_table_hint)))) {
LOG_WARN("failed to get stmt max table dop", K(ret));
} else { /*do nothing*/ }
max_table_parallel = std::max(max_table_parallel, cur_max_table_hint);
for (int64_t i = 0; OB_SUCC(ret) && i < child_stmts.count(); i++) {
if (OB_ISNULL(child_stmts.at(i))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(ret));
} else if (OB_FAIL(SMART_CALL(get_stmt_parallel_info(child_stmts.at(i),
max_table_dop,
max_table_parallel)))) {
LOG_WARN("failed to get stmt max table dop", K(ret));
} else { /*do nothing*/ }
}
}
return ret;
}
// max_table_dop used for table's parallel attribute
int ObOptimizer::get_stmt_max_table_dop(ObDMLStmt &stmt,
int64_t &max_table_dop)
{
int ret = OB_SUCCESS;
ObSEArray<ObSelectStmt*, 4> child_stmts;
ObQueryCtx *query_ctx = NULL;
ObSQLSessionInfo *session_info = NULL;
share::schema::ObSchemaGetterGuard *schema_guard = ctx_.get_schema_guard();
if (OB_ISNULL(schema_guard) || OB_ISNULL(query_ctx = ctx_.get_query_ctx()) ||
if (OB_ISNULL(schema_guard) ||
OB_ISNULL(session_info = ctx_.get_session_info())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(schema_guard), K(query_ctx), K(session_info), K(ret));
} else if (OB_FAIL(stmt.get_child_stmts(child_stmts))) {
LOG_WARN("failed to get child stmts", K(ret));
LOG_WARN("get unexpected null", K(schema_guard), K(session_info), K(ret));
} else {
for (int64_t i = 0; OB_SUCC(ret) && i < stmt.get_table_items().count(); i++) {
TableItem *table_item = NULL;
......@@ -294,8 +302,8 @@ int ObOptimizer::get_stmt_max_table_dop(ObDMLStmt &stmt,
table_item->is_fake_cte_table() ||
table_item->is_joined_table()) {
} else if (table_item->is_temp_table()) {
if (OB_FAIL(child_stmts.push_back(table_item->ref_query_))) {
LOG_WARN("push back failed", K(ret));
if (OB_FAIL(SMART_CALL(get_stmt_max_table_dop(*table_item->ref_query_, max_table_dop)))) {
LOG_WARN("failed to get max table dop from ref query", K(ret));
}
} else if (table_item->is_generated_table()) {
} else {
......@@ -332,15 +340,6 @@ int ObOptimizer::get_stmt_max_table_dop(ObDMLStmt &stmt,
}
}
}
for (int64_t i = 0; OB_SUCC(ret) && i < child_stmts.count(); i++) {
if (OB_ISNULL(child_stmts.at(i))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(ret));
} else if (OB_FAIL(SMART_CALL(get_stmt_max_table_dop(*child_stmts.at(i),
max_table_dop)))) {
LOG_WARN("failed to get stmt max table dop", K(ret));
} else { /*do nothing*/ }
}
}
return ret;
}
......@@ -570,6 +569,9 @@ int ObOptimizer::check_pdml_supported_feature(const ObDMLStmt &stmt,
LOG_WARN("a online ddl expect PDML enabled. but it does not!", K(is_use_pdml), K(ret));
LOG_USER_ERROR(OB_NOT_SUPPORTED, "online ddl without pdml");
}
if (OB_SUCC(ret) && ctx_.has_var_assign() && !ctx_.is_var_assign_only_in_root_stmt()) {
is_use_pdml = false;
}
LOG_TRACE("check use all pdml feature", K(ret), K(is_use_pdml), K(ctx_.is_online_ddl()));
return ret;
}
......@@ -611,7 +613,11 @@ int ObOptimizer::init_env_info(ObDMLStmt &stmt)
int64_t parallel = 1;
bool use_pdml = false;
bool session_enable_parallel = false;
bool has_var_assign = false;
bool is_var_assign_only_in_root_stmt = false;
uint64_t session_force_parallel_dop = 1;
int64_t max_table_dop = 1;
int64_t max_table_hint = 1;
ObDMLStmt *target_stmt = &stmt;
ObSQLSessionInfo *session = ctx_.get_session_info();
if (OB_ISNULL(target_stmt) || OB_ISNULL(session)) {
......@@ -620,6 +626,16 @@ int ObOptimizer::init_env_info(ObDMLStmt &stmt)
} else if (FALSE_IT(ctx_.set_is_online_ddl(session->get_ddl_info().is_ddl()))) {
} else if (OB_FAIL(check_whether_contain_nested_sql(stmt))) {
LOG_WARN("check whether contain nested sql failed", K(ret));
} else if (OB_FAIL(get_stmt_parallel_info(target_stmt,
max_table_dop,
max_table_hint))) {
LOG_WARN("failed to get attributes from stmt", K(ret));
} else if (OB_FAIL(target_stmt->check_var_assign(has_var_assign,
is_var_assign_only_in_root_stmt))) {
LOG_WARN("failed to check has ref assign user var", K(ret));
} else if (OB_FALSE_IT(ctx_.set_has_var_assign(has_var_assign)) ||
OB_FALSE_IT(ctx_.set_is_var_assign_only_in_root_stmt(is_var_assign_only_in_root_stmt))) {
// do nothing
} else if (OB_FAIL(check_pdml_enabled(*target_stmt, *session, use_pdml))) {
LOG_WARN("fail to check enable pdml", K(ret));
} else if (OB_FAIL(get_session_parallel_info(*target_stmt,
......@@ -634,15 +650,7 @@ int ObOptimizer::init_env_info(ObDMLStmt &stmt)
}
ctx_.set_parallel(parallel);
ctx_.set_use_pdml(use_pdml);
int64_t max_table_dop = 1;
int64_t max_table_hint = 1;
if (OB_FAIL(get_stmt_max_table_dop(*target_stmt,
max_table_dop))) {
LOG_WARN("failed to get stmt max table dop", K(ret));
} else if (OB_FAIL(get_stmt_max_table_parallel_hint(*target_stmt,
max_table_hint))) {
LOG_WARN("failed to get stmt max table parallel", K(ret));
} else if (ctx_.get_global_hint().get_parallel_hint() != ObGlobalHint::UNSET_PARALLEL) {
if (ctx_.get_global_hint().get_parallel_hint() != ObGlobalHint::UNSET_PARALLEL) {
ctx_.set_parallel_rule(PXParallelRule::MANUAL_HINT);
ctx_.set_parallel(parallel);
ctx_.add_plan_note(PARALLEL_ENABLED_BY_GLOBAL_HINT, parallel);
......
......@@ -204,9 +204,10 @@ namespace sql
const ObSelectStmt *table_query) const;
int init_env_info(ObDMLStmt &stmt);
int get_stmt_max_table_dop(ObDMLStmt &stmt,
int64_t &max_dop);
int get_stmt_max_table_parallel_hint(ObDMLStmt &stmt,
int64_t &max_table_parallel);
int64_t &max_table_dop);
int get_stmt_parallel_info(ObDMLStmt *stmt,
int64_t &max_table_dop,
int64_t &max_table_parallel);
int get_session_parallel_info(ObDMLStmt &stmt,
bool use_pdml,
bool &session_px_enable_parallel,
......
......@@ -146,7 +146,9 @@ ObOptimizerContext(ObSQLSessionInfo *session_info,
aggregation_optimization_settings_(0),
query_ctx_(query_ctx),
nested_sql_flags_(0),
has_for_update_(false)
has_for_update_(false),
has_var_assign_(false),
is_var_assign_only_in_root_stmt_(false)
{ }
inline common::ObOptStatManager *get_opt_stat_manager() { return opt_stat_manager_; }
inline void set_opt_stat_manager(common::ObOptStatManager *sm) { opt_stat_manager_ = sm; }
......@@ -462,6 +464,10 @@ ObOptimizerContext(ObSQLSessionInfo *session_info,
bool contain_user_nested_sql() const { return nested_sql_flags_ > 0 && !is_online_ddl_; }
void set_for_update() { has_for_update_ = true; }
bool has_for_update() { return has_for_update_;};
inline bool has_var_assign() { return has_var_assign_; }
inline void set_has_var_assign(bool v) { has_var_assign_ = v; }
inline bool is_var_assign_only_in_root_stmt() { return is_var_assign_only_in_root_stmt_; }
inline void set_is_var_assign_only_in_root_stmt(bool v) { is_var_assign_only_in_root_stmt_ = v; }
private:
ObSQLSessionInfo *session_info_;
......@@ -529,6 +535,8 @@ private:
};
};
bool has_for_update_;
bool has_var_assign_;
bool is_var_assign_only_in_root_stmt_;
};
}
}
......
......@@ -1888,6 +1888,11 @@ int ObSelectLogPlan::create_union_all_plan(const ObIArray<ObLogicalOperator*> &c
| DistAlgo::DIST_PARTITION_WISE
| DistAlgo::DIST_PULL_TO_LOCAL
| DistAlgo::DIST_SET_RANDOM;
if (!get_optimizer_context().is_var_assign_only_in_root_stmt() &&
get_optimizer_context().has_var_assign()) {
set_dist_methods &= DistAlgo::DIST_PULL_TO_LOCAL | DistAlgo::DIST_BASIC_METHOD;
}
int64_t random_none_idx = OB_INVALID_INDEX;
DistAlgo hint_dist_methods = get_log_plan_hint().get_valid_set_dist_algo(&random_none_idx);
if (!ignore_hint && DistAlgo::DIST_INVALID_METHOD != hint_dist_methods) {
......@@ -2482,7 +2487,10 @@ int ObSelectLogPlan::get_distributed_set_methods(const EqualSets &equal_sets,
}
}
}
if (OB_SUCC(ret) && !get_optimizer_context().is_var_assign_only_in_root_stmt() &&
get_optimizer_context().has_var_assign()) {
set_dist_methods &= DIST_PULL_TO_LOCAL | DIST_BASIC_METHOD;
}
if (OB_SUCC(ret) && (set_dist_methods & DistAlgo::DIST_NONE_ALL)) {
if (left_sharding->is_distributed() && right_sharding->is_match_all() &&
!right_child.get_contains_das_op() && !right_child.get_contains_fake_cte() &&
......
......@@ -3889,14 +3889,10 @@ int ObDMLStmt::inner_get_share_exprs(ObIArray<ObRawExpr *> &candi_share_exprs) c
return ret;
}
/**
* has_ref_assign_user_var
* 检查stmt及其child stmt中是否包含涉及到赋值操作的用户变量
*/
int ObDMLStmt::has_ref_assign_user_var(bool &has_ref_user_var) const
int ObDMLStmt::find_var_assign_in_query_ctx(bool &is_found) const
{
int ret = OB_SUCCESS;
has_ref_user_var = false;
is_found = false;
if (OB_ISNULL(query_ctx_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(ret));
......@@ -3904,58 +3900,125 @@ int ObDMLStmt::has_ref_assign_user_var(bool &has_ref_user_var) const
// do nothing
} else {
// quick check
bool find = false;
for (int64_t i = 0; OB_SUCC(ret) && !find && i < query_ctx_->all_user_variable_.count(); ++i) {
for (int64_t i = 0; OB_SUCC(ret) && !is_found && i < query_ctx_->all_user_variable_.count(); ++i) {
const ObUserVarIdentRawExpr *cur_expr = query_ctx_->all_user_variable_.at(i);
if (OB_ISNULL(cur_expr)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get null expr", K(ret));
} else if (cur_expr->get_is_contain_assign() || cur_expr->get_query_has_udf()) {
find = true;
is_found = true;
}
}
}
return ret;
}
if (OB_SUCC(ret)){
if (!find) {
// no user variable assignment in query
} else if (OB_FAIL(recursive_check_has_ref_assign_user_var(has_ref_user_var))) {
LOG_WARN("failed to recursive check has assignment ref user var", K(ret));
/**
* @brief
*
* @param has_var_assign check if has var assign expr
* @param need_check_child need to check child stmt
* @return int
*/
int ObDMLStmt::has_ref_assign_user_var(bool &has_var_assign, bool need_check_child) const
{
int ret = OB_SUCCESS;
has_var_assign = false;
bool find = false;
if (OB_FAIL(find_var_assign_in_query_ctx(find))) {
LOG_WARN("failed to find var assign", K(ret));
} else if (!find) {
// no user variable assignment in query
} else if (OB_FAIL(check_has_var_assign_rec(has_var_assign, need_check_child))) {
LOG_WARN("failed to recursive check has assignment ref user var", K(ret));
}
return ret;
}
int ObDMLStmt::check_has_var_assign_rec(bool &has_var_assign, bool need_check_child) const
{
int ret = OB_SUCCESS;
if (OB_FAIL(check_user_vars_has_var_assign(has_var_assign))) {
LOG_WARN("failed to check user vars has var assign expr", K(ret));
} else if (!has_var_assign && need_check_child) {
ObSEArray<ObSelectStmt *, 4> child_stmts;
if (OB_FAIL(get_child_stmts(child_stmts))) {
LOG_WARN("failed to get child stmts", K(ret));
} else {
for (int64_t i = 0; OB_SUCC(ret) && !has_var_assign && i < child_stmts.count(); ++i) {
if (OB_ISNULL(child_stmts.at(i))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(ret));
} else if (OB_FAIL(SMART_CALL(child_stmts.at(i)->check_has_var_assign_rec(has_var_assign,
need_check_child)))) {
LOG_WARN("failed to recursive check has assignment ref user var", K(ret));
}
}
}
}
return ret;
}
int ObDMLStmt::recursive_check_has_ref_assign_user_var(bool &has_ref_user_var) const
int ObDMLStmt::check_user_vars_has_var_assign(bool &has_var_assign) const
{
int ret = OB_SUCCESS;
bool is_stack_overflow = false;
has_ref_user_var = false;
if (OB_FAIL(check_stack_overflow(is_stack_overflow))) {
LOG_WARN("failed to check stack overflow", K(ret));
} else if (is_stack_overflow) {
ret = OB_SIZE_OVERFLOW;
LOG_WARN("too deep recursive", K(ret), K(is_stack_overflow));
}
for (int64_t i = 0; OB_SUCC(ret) && !has_ref_user_var && i < get_user_var_size(); ++i) {
for (int64_t i = 0; OB_SUCC(ret) && !has_var_assign && i < get_user_var_size(); ++i) {
const ObUserVarIdentRawExpr *cur_expr = get_user_vars().at(i);
if (OB_ISNULL(cur_expr)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get null expr", K(ret));
} else if (cur_expr->get_is_contain_assign() || cur_expr->get_query_has_udf()) {
has_ref_user_var = true;
has_var_assign = true;
}
}
if (OB_SUCC(ret) && !has_ref_user_var) {
return ret;
}
/**
* @brief
* this stmt should be root stmt
* @param has_var_assign check has var assign in root stmt
* @param is_var_assign_only_in_root check if var assign expr only existed in root stmt
* @return int
*/
int ObDMLStmt::check_var_assign(bool &has_var_assign, bool &is_var_assign_only_in_root) const
{
int ret = OB_SUCCESS;
has_var_assign = false;
is_var_assign_only_in_root = false;
bool find = false;
if (OB_FAIL(find_var_assign_in_query_ctx(find))) {
LOG_WARN("failed to find var assign", K(ret));
} else if (!find) {
// no user variable assignment in query
} else if (OB_FAIL(check_has_var_assign_rec(has_var_assign, is_var_assign_only_in_root, true))) {
LOG_WARN("failed to recursive check has assignment ref user var", K(ret));
}
return ret;
}
int ObDMLStmt::check_has_var_assign_rec(bool &has_var_assign, bool &is_var_assign_only_in_root, bool is_root) const
{
int ret = OB_SUCCESS;
bool tmp_has_var_assign = false;
if (OB_FAIL(check_user_vars_has_var_assign(tmp_has_var_assign))) {
LOG_WARN("failed to check user vars has var assign expr", K(ret));
} else if (tmp_has_var_assign) {
has_var_assign = true;
is_var_assign_only_in_root = is_root;
}
if (OB_SUCC(ret)) {
ObSEArray<ObSelectStmt *, 4> child_stmts;
if (OB_FAIL(get_child_stmts(child_stmts))) {
LOG_WARN("failed to get child stmts", K(ret));
} else {
for (int64_t i = 0; OB_SUCC(ret) && !has_ref_user_var && i < child_stmts.count(); ++i) {
for (int64_t i = 0; OB_SUCC(ret) && i < child_stmts.count(); ++i) {
if (OB_ISNULL(child_stmts.at(i))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(ret));
} else if (child_stmts.at(i)->recursive_check_has_ref_assign_user_var(has_ref_user_var)) {
} else if (OB_FAIL(SMART_CALL(child_stmts.at(i)->check_has_var_assign_rec(has_var_assign,
is_var_assign_only_in_root,
false)))) {
LOG_WARN("failed to recursive check has assignment ref user var", K(ret));
}
}
......
......@@ -947,10 +947,12 @@ public:
int get_column_exprs(uint64_t table_id, ObIArray<ObRawExpr*> &table_cols) const;
virtual int inner_get_share_exprs(ObIArray<ObRawExpr *> &share_exprs) const;
int has_ref_assign_user_var(bool &has_ref_user_var) const;
int recursive_check_has_ref_assign_user_var(bool &has_ref_user_var) const;
int find_var_assign_in_query_ctx(bool &is_found) const;
int check_user_vars_has_var_assign(bool &has_var_assign) const;
int has_ref_assign_user_var(bool &has_ref_user_var, bool need_check_child = true) const;
int check_has_var_assign_rec(bool &has_ref_user_var, bool need_check_child) const;
int check_var_assign(bool &has_var_assign, bool &is_var_assign_only_in_root) const;
int check_has_var_assign_rec(bool &has_var_assign, bool &is_var_assign_only_in_root, bool is_root) const;
int get_temp_table_ids(ObIArray<uint64_t> &temp_table_ids);
virtual int refill_global_index_dml_info(ObRawExprFactory &expr_factory)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册