diff --git a/src/sql/optimizer/ob_join_order.cpp b/src/sql/optimizer/ob_join_order.cpp index 1b59b8346b..748eec4d4c 100644 --- a/src/sql/optimizer/ob_join_order.cpp +++ b/src/sql/optimizer/ob_join_order.cpp @@ -3471,7 +3471,7 @@ int ObJoinOrder::compute_const_exprs_for_subquery(uint64_t table_id, { int ret = OB_SUCCESS; if (OB_ISNULL(get_plan()) || OB_ISNULL(get_plan()->get_stmt()) || - OB_ISNULL(root) || OB_ISNULL(root->get_stmt())) { + OB_ISNULL(root) || OB_ISNULL(root->get_stmt()) || OB_ISNULL(root->get_plan())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected null", K(root), K(ret)); } else if (OB_UNLIKELY(!root->get_stmt()->is_select_stmt())) { @@ -3493,6 +3493,7 @@ int ObJoinOrder::compute_const_exprs_for_subquery(uint64_t table_id, } else if (OB_FAIL(ObOptimizerUtil::get_subplan_const_column(*parent_stmt, table_id, *child_stmt, + root->get_plan()->get_onetime_query_refs(), output_const_exprs_))) { LOG_WARN("failed to get subplan const column expr", K(ret)); } else if (OB_FAIL(ObOptimizerUtil::compute_const_exprs(restrict_info_set_, output_const_exprs_))) { diff --git a/src/sql/optimizer/ob_log_del_upd.cpp b/src/sql/optimizer/ob_log_del_upd.cpp index 17e4061ccd..e855f76cbc 100644 --- a/src/sql/optimizer/ob_log_del_upd.cpp +++ b/src/sql/optimizer/ob_log_del_upd.cpp @@ -271,6 +271,24 @@ int IndexDMLInfo::generate_column_old_values_exprs() return ret; } +int IndexDMLInfo::is_new_row_expr(const ObRawExpr *expr, bool &bret) const +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(expr)) { + bret = false; + } else { + bret = ObOptimizerUtil::find_item(column_convert_exprs_, expr) + || ObOptimizerUtil::find_item(ck_cst_exprs_, expr) + || lookup_part_id_expr_ == expr + || new_part_id_expr_ == expr + || new_rowid_expr_ == expr; + } + for (int64_t i = 0; OB_SUCC(ret) && !bret && i < assignments_.count(); ++i) { + bret = assignments_.at(i).expr_ == expr; + } + return ret; +} + ObLogDelUpd::ObLogDelUpd(ObDelUpdLogPlan &plan) : ObLogicalOperator(plan), my_dml_plan_(plan), @@ -1479,3 +1497,18 @@ int ObLogDelUpd::print_used_hint(PlanText &plan_text) } return ret; } + +int ObLogDelUpd::is_my_fixed_expr(const ObRawExpr *expr, bool &is_fixed) +{ + int ret = OB_SUCCESS; + const ObIArray &index_dml_infos = get_index_dml_infos(); + for (int64_t i = 0; OB_SUCC(ret) && !is_fixed && i < index_dml_infos.count(); ++i) { + if (OB_ISNULL(index_dml_infos.at(i))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("index dml info is null", K(ret)); + } else if (OB_FAIL(index_dml_infos.at(i)->is_new_row_expr(expr, is_fixed))) { + LOG_WARN("failed to check is new row expr", K(ret)); + } + } + return ret; +} diff --git a/src/sql/optimizer/ob_log_del_upd.h b/src/sql/optimizer/ob_log_del_upd.h index 3e2c4f2083..2f5da1774e 100644 --- a/src/sql/optimizer/ob_log_del_upd.h +++ b/src/sql/optimizer/ob_log_del_upd.h @@ -116,6 +116,7 @@ public: ObIArray &access_exprs, int64_t col_cnt = -1); int generate_column_old_values_exprs(); + int is_new_row_expr(const ObRawExpr *expr, bool &bret) const; public: // e.g.: // create view V as select * from T1 as T; @@ -183,7 +184,6 @@ public: K_(ck_cst_exprs), K_(is_update_unique_key), K_(is_update_part_key), - K_(assignments), K_(distinct_algo), K_(related_index_ids)); }; @@ -327,6 +327,7 @@ public: int replace_dml_info_exprs( ObRawExprReplacer &replacer, const ObIArray &index_dml_infos); + virtual int is_my_fixed_expr(const ObRawExpr *expr, bool &is_fixed) override; protected: virtual int generate_rowid_expr_for_trigger() = 0; virtual int generate_multi_part_partition_id_expr() = 0; diff --git a/src/sql/optimizer/ob_logical_operator.cpp b/src/sql/optimizer/ob_logical_operator.cpp index 2f6d65880a..159bbd822e 100644 --- a/src/sql/optimizer/ob_logical_operator.cpp +++ b/src/sql/optimizer/ob_logical_operator.cpp @@ -2133,7 +2133,7 @@ int ObLogicalOperator::check_need_pushdown_expr(const bool producer_id, } else if (OB_ISNULL(child_.at(0))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected null", K(ret)); - } else if (child_.at(0)->is_expr_operator() || is_dml_operator()) { + } else if (child_.at(0)->is_expr_operator()) { need_pushdown = false; } return ret; diff --git a/src/sql/optimizer/ob_optimizer_util.cpp b/src/sql/optimizer/ob_optimizer_util.cpp index 1edc05b2e5..e4c6c111f2 100644 --- a/src/sql/optimizer/ob_optimizer_util.cpp +++ b/src/sql/optimizer/ob_optimizer_util.cpp @@ -4788,16 +4788,20 @@ bool ObOptimizerUtil::has_equal_join_conditions(const ObIArray &join int ObOptimizerUtil::get_subplan_const_column(const ObDMLStmt &parent_stmt, const uint64_t table_id, const ObSelectStmt &child_stmt, + const ObIArray &exec_ref_exprs, ObIArray &output_exprs) { int ret = OB_SUCCESS; for (int64_t i = 0; OB_SUCC(ret) && i < child_stmt.get_select_item_size(); ++i) { const ObRawExpr *expr = child_stmt.get_select_item(i).expr_; ObRawExpr *parent_expr = NULL; + bool is_const = false; if (OB_ISNULL(expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("expr is null", K(ret), K(expr)); - } else if (!expr->is_const_expr()) { + } else if (OB_FAIL(is_const_expr_recursively(expr, exec_ref_exprs, is_const))) { + LOG_WARN("failed to check expr is const expr", K(ret)); + } else if (!is_const) { // do nothing } else if (NULL == (parent_expr = parent_stmt.get_column_expr_by_id(table_id, OB_APP_MIN_COLUMN_ID + i))) { diff --git a/src/sql/optimizer/ob_optimizer_util.h b/src/sql/optimizer/ob_optimizer_util.h index 82d68184d8..db316a2408 100644 --- a/src/sql/optimizer/ob_optimizer_util.h +++ b/src/sql/optimizer/ob_optimizer_util.h @@ -877,6 +877,7 @@ public: static int get_subplan_const_column(const ObDMLStmt &parent_stmt, const uint64_t table_id, const ObSelectStmt &child_stmt, + const ObIArray &exec_ref_exprs, ObIArray &output_exprs); /* diff --git a/src/sql/rewrite/ob_transform_utils.cpp b/src/sql/rewrite/ob_transform_utils.cpp index 0d63885f28..a6cf80cd3d 100644 --- a/src/sql/rewrite/ob_transform_utils.cpp +++ b/src/sql/rewrite/ob_transform_utils.cpp @@ -4728,6 +4728,7 @@ int ObTransformUtils::compute_generate_table_property(const ObDMLStmt *stmt, ObSelectStmt *ref_query = NULL; ObSEArray cur_cond_exprs; ObSqlBitSet<> table_set; + ObSEArray dummy_exprs; if (OB_ISNULL(stmt) || OB_ISNULL(table) || OB_ISNULL(check_helper.alloc_) || OB_ISNULL(check_helper.fd_factory_) || OB_ISNULL(check_helper.expr_factory_)) { ret = OB_ERR_UNEXPECTED; @@ -4749,6 +4750,7 @@ int ObTransformUtils::compute_generate_table_property(const ObDMLStmt *stmt, } else if (OB_FAIL(ObOptimizerUtil::get_subplan_const_column(*stmt, table->table_id_, *ref_query, + dummy_exprs, res_info.const_exprs_))) { LOG_WARN("failed to get subplan const column", K(ret)); } else if (OB_FAIL(ObOptimizerUtil::convert_subplan_scan_expr(*check_helper.expr_factory_,