fix subquery coalesce cause update 4016

This commit is contained in:
ChangerR
2023-05-11 08:41:57 +00:00
committed by ob-robot
parent 857ed98699
commit 635cd39eda
4 changed files with 58 additions and 27 deletions

View File

@ -161,6 +161,7 @@ int ObTransformQueryPushDown::need_transform(const common::ObIArray<ObParentDMLS
LOG_WARN("unexpected null", K(ret), K(ctx_), K(query_hint)); LOG_WARN("unexpected null", K(ret), K(ctx_), K(query_hint));
} else if (stmt.get_table_size() == 1) { } else if (stmt.get_table_size() == 1) {
const TableItem *table = NULL; const TableItem *table = NULL;
const ObViewMergeHint *myhint = NULL;
if (OB_ISNULL(table = stmt.get_table_item(0))) { if (OB_ISNULL(table = stmt.get_table_item(0))) {
ret = OB_ERR_UNEXPECTED; ret = OB_ERR_UNEXPECTED;
LOG_WARN("table item is null", K(ret)); LOG_WARN("table item is null", K(ret));
@ -175,8 +176,12 @@ int ObTransformQueryPushDown::need_transform(const common::ObIArray<ObParentDMLS
} else if (!need_trans) { } else if (!need_trans) {
OPT_TRACE("hint reject transform"); OPT_TRACE("hint reject transform");
} }
} else if (query_hint->is_valid_outline_transform(ctx_->trans_list_loc_, } else if (OB_FALSE_IT(myhint =
get_hint(table->ref_query_->get_stmt_hint()))) { static_cast<const ObViewMergeHint*>(get_hint(table->ref_query_->get_stmt_hint())))) {
// do nothing
} else if (myhint != NULL &&
query_hint->is_valid_outline_transform(ctx_->trans_list_loc_, myhint) &&
myhint->enable_query_push_down(ctx_->src_qb_name_)) {
need_trans = true; need_trans = true;
} else { } else {
OPT_TRACE("outline reject transform"); OPT_TRACE("outline reject transform");

View File

@ -2157,6 +2157,8 @@ int ObTransformSubqueryCoalesce::adjust_assign_exprs(ObUpdateStmt *upd_stmt,
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
ObQueryRefRawExpr *coalesce_query_expr = NULL; ObQueryRefRawExpr *coalesce_query_expr = NULL;
ObArray<ObExecParamRawExpr *> all_params; ObArray<ObExecParamRawExpr *> all_params;
ObSEArray<ObRawExpr*, 4> old_exprs;
ObSEArray<ObRawExpr*, 4> new_exprs;
if (OB_ISNULL(upd_stmt) || OB_ISNULL(helper) || OB_ISNULL(coalesce_query)) { if (OB_ISNULL(upd_stmt) || OB_ISNULL(helper) || OB_ISNULL(coalesce_query)) {
ret = OB_ERR_UNEXPECTED; ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpect null param", K(ret)); LOG_WARN("unexpect null param", K(ret));
@ -2194,7 +2196,9 @@ int ObTransformSubqueryCoalesce::adjust_assign_exprs(ObUpdateStmt *upd_stmt,
select_exprs, select_exprs,
index_map, index_map,
coalesce_query_expr, coalesce_query_expr,
coalesce_query))) { coalesce_query,
old_exprs,
new_exprs))) {
LOG_WARN("failed to extract expr", K(ret)); LOG_WARN("failed to extract expr", K(ret));
} }
} else if (assign.expr_->has_flag(CNT_SUB_QUERY)) { } else if (assign.expr_->has_flag(CNT_SUB_QUERY)) {
@ -2203,13 +2207,39 @@ int ObTransformSubqueryCoalesce::adjust_assign_exprs(ObUpdateStmt *upd_stmt,
select_exprs, select_exprs,
index_map, index_map,
coalesce_query_expr, coalesce_query_expr,
coalesce_query))) { coalesce_query,
old_exprs,
new_exprs))) {
LOG_WARN("failed to extract expr", K(ret)); LOG_WARN("failed to extract expr", K(ret));
} }
} }
} }
} }
} }
if (OB_SUCC(ret) && !old_exprs.empty()) {
for (int64_t i = 0; OB_SUCC(ret) && i < upd_stmt->get_update_table_info().count(); ++i) {
ObUpdateTableInfo* table_info = upd_stmt->get_update_table_info().at(i);
if (OB_ISNULL(table_info)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get null table info", K(ret), K(i));
} else {
for (int64_t j = 0; OB_SUCC(ret) && j < table_info->assignments_.count(); ++j) {
ObAssignment &assign = table_info->assignments_.at(j);
if (OB_ISNULL(assign.expr_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpect null expr", K(ret));
} else if (!assign.expr_->has_flag(CNT_ALIAS) &&
!assign.expr_->has_flag(CNT_SUB_QUERY)) {
// do nothing
} else if (OB_FAIL(ObTransformUtils::replace_expr(old_exprs,
new_exprs,
assign.expr_))) {
LOG_WARN("failed to replace expr", K(ret));
}
}
}
}
}
return ret; return ret;
} }
@ -2218,12 +2248,12 @@ int ObTransformSubqueryCoalesce::adjust_alias_assign_exprs(ObRawExpr* &assign_ex
ObIArray<ObRawExpr*> &select_exprs, ObIArray<ObRawExpr*> &select_exprs,
ObIArray<int64_t> &index_map, ObIArray<int64_t> &index_map,
ObQueryRefRawExpr *coalesce_query_expr, ObQueryRefRawExpr *coalesce_query_expr,
ObSelectStmt *coalesce_query) ObSelectStmt *coalesce_query,
ObIArray<ObRawExpr*> &old_exprs,
ObIArray<ObRawExpr*> &new_exprs)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
ObSEArray<ObAliasRefRawExpr*, 4> alias_exprs; ObSEArray<ObAliasRefRawExpr*, 4> alias_exprs;
ObSEArray<ObRawExpr*, 4> old_exprs;
ObSEArray<ObRawExpr*, 4> new_exprs;
ObRawExpr *new_expr = NULL; ObRawExpr *new_expr = NULL;
if (OB_ISNULL(assign_expr)) { if (OB_ISNULL(assign_expr)) {
ret = OB_ERR_UNEXPECTED; ret = OB_ERR_UNEXPECTED;
@ -2236,6 +2266,8 @@ int ObTransformSubqueryCoalesce::adjust_alias_assign_exprs(ObRawExpr* &assign_ex
if (OB_ISNULL(alias_expr) || OB_ISNULL(alias_expr->get_param_expr(0))) { if (OB_ISNULL(alias_expr) || OB_ISNULL(alias_expr->get_param_expr(0))) {
ret = OB_ERR_UNEXPECTED; ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpect null expr", K(ret)); LOG_WARN("unexpect null expr", K(ret));
} else if (ObOptimizerUtil::find_item(old_exprs, alias_expr)) {
// do noting
} else if (alias_expr->is_ref_query_output()) { } else if (alias_expr->is_ref_query_output()) {
ObQueryRefRawExpr *query_ref_expr = static_cast<ObQueryRefRawExpr*>(alias_expr->get_param_expr(0)); ObQueryRefRawExpr *query_ref_expr = static_cast<ObQueryRefRawExpr*>(alias_expr->get_param_expr(0));
int64_t select_idx = alias_expr->get_project_index(); int64_t select_idx = alias_expr->get_project_index();
@ -2257,13 +2289,6 @@ int ObTransformSubqueryCoalesce::adjust_alias_assign_exprs(ObRawExpr* &assign_ex
} }
} }
} }
if (OB_SUCC(ret) && !old_exprs.empty()) {
if (OB_FAIL(ObTransformUtils::replace_expr(old_exprs,
new_exprs,
assign_expr))) {
LOG_WARN("failed to replace expr", K(ret));
}
}
return ret; return ret;
} }
@ -2272,12 +2297,12 @@ int ObTransformSubqueryCoalesce::adjust_query_assign_exprs(ObRawExpr* &assign_ex
ObIArray<ObRawExpr*> &select_exprs, ObIArray<ObRawExpr*> &select_exprs,
ObIArray<int64_t> &index_map, ObIArray<int64_t> &index_map,
ObQueryRefRawExpr *coalesce_query_expr, ObQueryRefRawExpr *coalesce_query_expr,
ObSelectStmt *coalesce_query) ObSelectStmt *coalesce_query,
ObIArray<ObRawExpr*> &old_exprs,
ObIArray<ObRawExpr*> &new_exprs)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
ObSEArray<ObQueryRefRawExpr*, 4> query_ref_exprs; ObSEArray<ObQueryRefRawExpr*, 4> query_ref_exprs;
ObSEArray<ObRawExpr*, 4> old_exprs;
ObSEArray<ObRawExpr*, 4> new_exprs;
ObRawExpr *new_expr = NULL; ObRawExpr *new_expr = NULL;
if (OB_ISNULL(assign_expr)) { if (OB_ISNULL(assign_expr)) {
ret = OB_ERR_UNEXPECTED; ret = OB_ERR_UNEXPECTED;
@ -2290,6 +2315,8 @@ int ObTransformSubqueryCoalesce::adjust_query_assign_exprs(ObRawExpr* &assign_ex
if (OB_ISNULL(query_ref_expr)) { if (OB_ISNULL(query_ref_expr)) {
ret = OB_ERR_UNEXPECTED; ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpect null stmt", K(ret)); LOG_WARN("unexpect null stmt", K(ret));
} else if (ObOptimizerUtil::find_item(old_exprs, query_ref_expr)) {
// do noting
} else if (OB_FAIL(inner_adjust_assign_exprs(query_ref_expr->get_ref_stmt(), } else if (OB_FAIL(inner_adjust_assign_exprs(query_ref_expr->get_ref_stmt(),
0, 0,
helper, helper,
@ -2307,13 +2334,6 @@ int ObTransformSubqueryCoalesce::adjust_query_assign_exprs(ObRawExpr* &assign_ex
LOG_WARN("failed to push back expr", K(ret)); LOG_WARN("failed to push back expr", K(ret));
} }
} }
if (OB_SUCC(ret) && !old_exprs.empty()) {
if (OB_FAIL(ObTransformUtils::replace_expr(old_exprs,
new_exprs,
assign_expr))) {
LOG_WARN("failed to replace expr", K(ret));
}
}
return ret; return ret;
} }

View File

@ -190,14 +190,18 @@ private:
ObIArray<ObRawExpr*> &select_exprs, ObIArray<ObRawExpr*> &select_exprs,
ObIArray<int64_t> &index_map, ObIArray<int64_t> &index_map,
ObQueryRefRawExpr *coalesce_query_expr, ObQueryRefRawExpr *coalesce_query_expr,
ObSelectStmt *coalesce_query); ObSelectStmt *coalesce_query,
ObIArray<ObRawExpr*> &old_exprs,
ObIArray<ObRawExpr*> &new_exprs);
int adjust_query_assign_exprs(ObRawExpr* &assign_expr, int adjust_query_assign_exprs(ObRawExpr* &assign_expr,
StmtCompareHelper *helper, StmtCompareHelper *helper,
ObIArray<ObRawExpr*> &select_exprs, ObIArray<ObRawExpr*> &select_exprs,
ObIArray<int64_t> &index_map, ObIArray<int64_t> &index_map,
ObQueryRefRawExpr *coalesce_query_expr, ObQueryRefRawExpr *coalesce_query_expr,
ObSelectStmt *coalesce_query); ObSelectStmt *coalesce_query,
ObIArray<ObRawExpr*> &old_exprs,
ObIArray<ObRawExpr*> &new_exprs);
int inner_adjust_assign_exprs(ObSelectStmt *stmt, int inner_adjust_assign_exprs(ObSelectStmt *stmt,
const int64_t select_idx, const int64_t select_idx,

View File

@ -153,7 +153,9 @@ int ObTransformViewMerge::check_hint_allowed_merge(ObDMLStmt &stmt,
LOG_WARN("unexpected null", K(ret), K(ctx_), K(query_hint)); LOG_WARN("unexpected null", K(ret), K(ctx_), K(query_hint));
} else if (query_hint->has_outline_data()) { } else if (query_hint->has_outline_data()) {
// outline data allowed merge // outline data allowed merge
if (query_hint->is_valid_outline_transform(ctx_->trans_list_loc_, myhint)) { if (myhint != NULL &&
query_hint->is_valid_outline_transform(ctx_->trans_list_loc_, myhint) &&
myhint->enable_view_merge(ctx_->src_qb_name_)) {
force_merge = true; force_merge = true;
} else { } else {
force_no_merge = true; force_no_merge = true;