diff --git a/src/sql/optimizer/ob_log_update.cpp b/src/sql/optimizer/ob_log_update.cpp index 82efcfe6f672d4591f6926f5e50bead8723d8406..45670f9458515eb401464f9220388a56e41803f8 100644 --- a/src/sql/optimizer/ob_log_update.cpp +++ b/src/sql/optimizer/ob_log_update.cpp @@ -204,20 +204,22 @@ int ObLogUpdate::allocate_exchange_post(AllocExchContext* ctx) LOG_WARN("fail to copy subpart expr", K(ret)); } else { CK(PARTITION_LEVEL_MAX != part_level); + ObArray value_exprs; for (int64_t assign_idx = 0; OB_SUCC(ret) && assign_idx < index_infos.at(i).assignments_.count(); assign_idx++) { ObColumnRefRawExpr* col = index_infos.at(i).assignments_.at(assign_idx).column_expr_; ObRawExpr* value = index_infos.at(i).assignments_.at(assign_idx).expr_; if (PARTITION_LEVEL_ZERO != part_level) { - if (OB_FAIL(ObRawExprUtils::replace_ref_column(new_part_expr, col, value))) { + if (OB_FAIL(ObRawExprUtils::replace_ref_column(new_part_expr, col, value, NULL, &value_exprs))) { LOG_WARN("fail to replace ref column", K(ret)); } } if (PARTITION_LEVEL_TWO == part_level) { - if (OB_FAIL(ObRawExprUtils::replace_ref_column(new_subpart_expr, col, value))) { + if (OB_FAIL(ObRawExprUtils::replace_ref_column(new_subpart_expr, col, value, NULL, &value_exprs))) { LOG_WARN("fail to replace ref column", K(ret)); } } + OZ(value_exprs.push_back(index_infos.at(i).assignments_.at(assign_idx).expr_)); } // for assignments end } if (OB_SUCC(ret)) { diff --git a/src/sql/resolver/expr/ob_raw_expr_util.cpp b/src/sql/resolver/expr/ob_raw_expr_util.cpp index 74878a6496fb21788a4eb24685c5ab987cb11850..ac7bfc6320df84a7e256fae4680724d645b407cf 100644 --- a/src/sql/resolver/expr/ob_raw_expr_util.cpp +++ b/src/sql/resolver/expr/ob_raw_expr_util.cpp @@ -1412,8 +1412,9 @@ int ObRawExprUtils::replace_all_ref_column( } // if %expr_factory is not NULL, will deep copy %to expr. default behavior is shallow copy -int ObRawExprUtils::replace_ref_column( - ObRawExpr*& raw_expr, ObRawExpr* from, ObRawExpr* to, ObRawExprFactory* expr_factory) +// if except_exprs is not NULL, will skip the expr in except_exprs +int ObRawExprUtils::replace_ref_column(ObRawExpr*& raw_expr, ObRawExpr* from, ObRawExpr* to, + ObRawExprFactory* expr_factory, const ObIArray* except_exprs) { int ret = OB_SUCCESS; if (OB_ISNULL(raw_expr) || OB_ISNULL(from) || OB_ISNULL(to)) { @@ -1423,6 +1424,8 @@ int ObRawExprUtils::replace_ref_column( // do nothing // in case: parent(child) = to (from) // replace as: parenet(child) = to (to) + } else if (NULL != except_exprs && is_contain(*except_exprs, raw_expr)) { + // do nothing } else if (raw_expr == from) { if (NULL != expr_factory) { ObRawExpr* new_to = NULL; @@ -1446,14 +1449,14 @@ int ObRawExprUtils::replace_ref_column( LOG_WARN("get unexpected null", K(ret), K(ref_stmt)); } else if (OB_FAIL(ref_stmt->get_relation_exprs(relation_exprs))) { LOG_WARN("failed to get relation exprs", K(ret)); - } else if (OB_FAIL(SMART_CALL(replace_ref_column(relation_exprs, from, to)))) { + } else if (OB_FAIL(SMART_CALL(replace_ref_column(relation_exprs, from, to, except_exprs)))) { LOG_WARN("replace reference column failed", K(ret)); } } else { int64_t N = raw_expr->get_param_count(); for (int64_t i = 0; OB_SUCC(ret) && i < N; ++i) { ObRawExpr*& child_expr = raw_expr->get_param_expr(i); - if (OB_FAIL(SMART_CALL(replace_ref_column(child_expr, from, to, expr_factory)))) { + if (OB_FAIL(SMART_CALL(replace_ref_column(child_expr, from, to, expr_factory, except_exprs)))) { LOG_WARN("replace reference column failed", K(ret)); } } // end for @@ -1461,7 +1464,8 @@ int ObRawExprUtils::replace_ref_column( return ret; } -int ObRawExprUtils::replace_ref_column(ObIArray& exprs, ObRawExpr* from, ObRawExpr* to) +int ObRawExprUtils::replace_ref_column( + ObIArray& exprs, ObRawExpr* from, ObRawExpr* to, const ObIArray* except_exprs) { int ret = OB_SUCCESS; bool is_stack_overflow = false; @@ -1479,7 +1483,7 @@ int ObRawExprUtils::replace_ref_column(ObIArray& exprs, ObRawExpr* f ObRawExpr*& raw_expr = tmp_raw_expr; if (OB_FAIL(exprs.at(i, raw_expr))) { LOG_WARN("failed to get raw expr", K(i), K(ret)); - } else if (OB_FAIL(SMART_CALL(replace_ref_column(raw_expr, from, to)))) { + } else if (OB_FAIL(SMART_CALL(replace_ref_column(raw_expr, from, to, NULL, except_exprs)))) { LOG_WARN("failed to replace_ref_column", K(from), K(to), K(ret)); } else { /*do nothing*/ } diff --git a/src/sql/resolver/expr/ob_raw_expr_util.h b/src/sql/resolver/expr/ob_raw_expr_util.h index ceef3aa5515bf772424b7e5904ba1e86b193a01e..7c51909e0bfb71a3548cbca3d0181674e09c9c0a 100644 --- a/src/sql/resolver/expr/ob_raw_expr_util.h +++ b/src/sql/resolver/expr/ob_raw_expr_util.h @@ -211,10 +211,12 @@ public: /// replace all `from' to `to' in the raw_expr static int replace_all_ref_column(ObRawExpr*& raw_expr, const common::ObIArray& exprs, int64_t& offset); // if %expr_factory is not NULL, will deep copy %to expr. default behavior is shallow copy - static int replace_ref_column( - ObRawExpr*& raw_expr, ObRawExpr* from, ObRawExpr* to, ObRawExprFactory* expr_factory = NULL); + // if except_exprs is not NULL, will skip the expr in except_exprs + static int replace_ref_column(ObRawExpr*& raw_expr, ObRawExpr* from, ObRawExpr* to, + ObRawExprFactory* expr_factory = NULL, const ObIArray* except_exprs = NULL); static int replace_level_column(ObRawExpr*& raw_expr, ObRawExpr* to, bool& replaced); - static int replace_ref_column(common::ObIArray& exprs, ObRawExpr* from, ObRawExpr* to); + static int replace_ref_column(common::ObIArray& exprs, ObRawExpr* from, ObRawExpr* to, + const ObIArray* except_exprs = NULL); static bool all_column_exprs(const common::ObIArray& exprs); /// extract column exprs from the raw expr static int extract_column_exprs(const ObRawExpr* raw_expr, common::ObIArray& column_exprs);