From a7ab9bf24cb28cd22bdeda38ec8a6ea8be0cab8a Mon Sep 17 00:00:00 2001 From: SevenJ-swj Date: Mon, 21 Aug 2023 12:40:40 +0000 Subject: [PATCH] optimize resolve columns cost --- src/sql/resolver/dml/ob_dml_resolver.cpp | 11 +++- src/sql/resolver/expr/ob_raw_expr_util.cpp | 74 ++++++++++++++++++++++ src/sql/resolver/expr/ob_raw_expr_util.h | 10 +++ 3 files changed, 93 insertions(+), 2 deletions(-) diff --git a/src/sql/resolver/dml/ob_dml_resolver.cpp b/src/sql/resolver/dml/ob_dml_resolver.cpp index 00a449d8f8..81a99cec30 100755 --- a/src/sql/resolver/dml/ob_dml_resolver.cpp +++ b/src/sql/resolver/dml/ob_dml_resolver.cpp @@ -2625,6 +2625,8 @@ int ObDMLResolver::resolve_columns(ObRawExpr *&expr, ObArray &c { int ret = OB_SUCCESS; ObArray real_exprs; + ObArray ref_exprs; + ObArray replace_ref_exprs; for (int64_t i = 0; OB_SUCC(ret) && i < columns.count(); ++i) { ObQualifiedName& q_name = columns.at(i); ObRawExpr* real_ref_expr = NULL; @@ -2640,10 +2642,15 @@ int ObDMLResolver::resolve_columns(ObRawExpr *&expr, ObArray &c } else if (OB_FAIL(ObRawExprUtils::implict_cast_pl_udt_to_sql_udt(params_.expr_factory_, params_.session_info_, real_ref_expr))) { LOG_WARN("add implict cast to pl udt expr failed", K(ret)); - } else if (OB_FAIL(ObRawExprUtils::replace_ref_column(expr, q_name.ref_expr_, real_ref_expr))) { - LOG_WARN("replace column ref expr failed", K(ret)); + } else if (OB_FAIL(ref_exprs.push_back(q_name.ref_expr_)) + || OB_FAIL(replace_ref_exprs.push_back(real_ref_expr))) { + LOG_WARN("push back failed", K(ret)); } else { /*do nothing*/ } } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(ObRawExprUtils::replace_ref_column(expr, ref_exprs, replace_ref_exprs))) { + LOG_WARN("replace column ref expr failed", K(ret)); + } if (OB_SUCC(ret) && OB_NOT_NULL(expr) && expr->is_sys_func_expr() && OB_FAIL(check_col_param_on_expr(expr))) { diff --git a/src/sql/resolver/expr/ob_raw_expr_util.cpp b/src/sql/resolver/expr/ob_raw_expr_util.cpp index a499cd2276..dc9c0fb2c0 100644 --- a/src/sql/resolver/expr/ob_raw_expr_util.cpp +++ b/src/sql/resolver/expr/ob_raw_expr_util.cpp @@ -3192,6 +3192,51 @@ int ObRawExprUtils::replace_ref_column(ObRawExpr *&raw_expr, ObRawExpr *from, return ret; } +int ObRawExprUtils::replace_ref_column(ObRawExpr *&raw_expr, + ObIArray &from, + ObIArray &to, + const ObIArray *except_exprs) +{ + int ret = OB_SUCCESS; + int64_t idx = -1; + if (OB_ISNULL(raw_expr) || OB_UNLIKELY(from.count() != to.count())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(raw_expr), K(from), K(to)); + } else if (from.count() == 0) { + //do nothing + } else if (NULL != except_exprs && is_contain(*except_exprs, raw_expr)) { + //do nothing + } else if (ObOptimizerUtil::find_item(from, raw_expr, &idx)) { + if (OB_UNLIKELY(idx < 0 || idx >= to.count())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("find item failed", K(ret)); + } else { + raw_expr = to.at(idx); + } + } else if (raw_expr->is_query_ref_expr()) { + ObSelectStmt *ref_stmt = static_cast(raw_expr)->get_ref_stmt(); + ObSEArray relation_exprs; + if (OB_ISNULL(ref_stmt)) { + ret = OB_ERR_UNEXPECTED; + 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, 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, except_exprs)))) { + LOG_WARN("replace reference column failed", K(ret)); + } + } // end for + } + return ret; +} + + int ObRawExprUtils::replace_ref_column(ObIArray&exprs, ObRawExpr *from, ObRawExpr *to, const ObIArray *except_exprs) { @@ -3219,6 +3264,35 @@ int ObRawExprUtils::replace_ref_column(ObIArray&exprs, ObRawExpr *f return ret; } +int ObRawExprUtils::replace_ref_column(ObIArray &exprs, + ObIArray &from, + ObIArray &to, + const ObIArray *except_exprs) +{ + int ret = OB_SUCCESS; + bool is_stack_overflow = false; + if (OB_FAIL(check_stack_overflow(is_stack_overflow))) { + LOG_WARN("check stack overflow failed", K(ret)); + } else if (is_stack_overflow) { + ret = OB_SIZE_OVERFLOW; + LOG_WARN("too deep recursive", K(ret)); + } else if (OB_UNLIKELY(from.count() != to.count())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(from), K(to), K(ret)); + } else { + ObRawExpr *tmp_raw_expr = NULL; + for (int64_t i = 0; OB_SUCC(ret) && i < exprs.count(); ++i) { + 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, except_exprs)))) { + LOG_WARN("failed to replace_ref_column", K(from), K(to), K(ret)); + } else {/*do nothing*/} + } + } + return ret; +} + bool ObRawExprUtils::is_all_column_exprs(const common::ObIArray &exprs) { bool is_all_column = true; diff --git a/src/sql/resolver/expr/ob_raw_expr_util.h b/src/sql/resolver/expr/ob_raw_expr_util.h index f3f931fbdf..959eb11b43 100644 --- a/src/sql/resolver/expr/ob_raw_expr_util.h +++ b/src/sql/resolver/expr/ob_raw_expr_util.h @@ -364,11 +364,21 @@ public: ObRawExpr *from, ObRawExpr *to, const ObIArray *except_exprs = NULL); + + static int replace_ref_column(ObRawExpr *&raw_expr, + ObIArray &from, + ObIArray &to, + 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, const ObIArray *except_exprs = NULL); + + static int replace_ref_column(common::ObIArray &exprs, + ObIArray &from, + ObIArray &to, + const ObIArray *except_exprs = NULL); static int contain_virtual_generated_column(ObRawExpr *&expr, bool &is_contain_vir_gen_column);