From 27a7c865687b42371867335d748b54a85b0cedbc Mon Sep 17 00:00:00 2001 From: cqliang1995 Date: Tue, 30 May 2023 11:47:14 +0000 Subject: [PATCH] fix output expr and select expr error in link scan --- src/sql/code_generator/ob_static_engine_cg.cpp | 14 ++++++++++++++ src/sql/engine/table/ob_link_scan_op.cpp | 11 ++++++----- src/sql/engine/table/ob_link_scan_op.h | 1 + src/sql/optimizer/ob_log_link_scan.cpp | 11 +++++++++++ src/sql/optimizer/ob_log_link_scan.h | 5 +++++ src/sql/optimizer/ob_select_log_plan.cpp | 9 +++++++++ 6 files changed, 46 insertions(+), 5 deletions(-) diff --git a/src/sql/code_generator/ob_static_engine_cg.cpp b/src/sql/code_generator/ob_static_engine_cg.cpp index 7a10ab6809..73c146855d 100644 --- a/src/sql/code_generator/ob_static_engine_cg.cpp +++ b/src/sql/code_generator/ob_static_engine_cg.cpp @@ -5757,6 +5757,8 @@ int ObStaticEngineCG::generate_spec(ObLogLinkScan &op, ObLinkScanSpec &spec, con LOG_WARN("failed to set param infos", K(ret)); } else if (OB_FAIL(spec.set_stmt_fmt(op.get_stmt_fmt_buf(), op.get_stmt_fmt_len()))) { LOG_WARN("failed to set stmt fmt", K(ret)); + } else if (OB_FAIL(spec.select_exprs_.init(op.get_select_exprs().count()))) { + LOG_WARN("init fixed array failed", K(ret), K(op.get_select_exprs().count())); } else if (OB_ISNULL(op.get_plan())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected null ptr", K(ret)); @@ -5767,6 +5769,18 @@ int ObStaticEngineCG::generate_spec(ObLogLinkScan &op, ObLinkScanSpec &spec, con spec.has_for_update_ = op.get_plan()->get_stmt()->has_for_update(); spec.is_reverse_link_ = op.get_reverse_link(); spec.dblink_id_ = op.get_dblink_id(); + for (int64_t i = 0; OB_SUCC(ret) && i < op.get_select_exprs().count(); ++i) { + ObExpr *rt_expr = nullptr; + const ObRawExpr* select_expr = op.get_select_exprs().at(i); + if (OB_ISNULL(select_expr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpect null expr", K(ret)); + } else if (OB_FAIL(generate_rt_expr(*select_expr, rt_expr))) { + LOG_WARN("failed to generate rt expr", K(ret)); + } else if (OB_FAIL(spec.select_exprs_.push_back(rt_expr))) { + LOG_WARN("failed to push back expr", K(ret)); + } + } } return ret; } diff --git a/src/sql/engine/table/ob_link_scan_op.cpp b/src/sql/engine/table/ob_link_scan_op.cpp index d50d400413..6b39c4b10f 100644 --- a/src/sql/engine/table/ob_link_scan_op.cpp +++ b/src/sql/engine/table/ob_link_scan_op.cpp @@ -35,10 +35,10 @@ namespace sql { ObLinkScanSpec::ObLinkScanSpec(common::ObIAllocator &alloc, const ObPhyOperatorType type) - : ObLinkSpec(alloc, type), has_for_update_(false) + : ObLinkSpec(alloc, type), has_for_update_(false), select_exprs_(alloc) {} -OB_SERIALIZE_MEMBER((ObLinkScanSpec, ObLinkSpec)); +OB_SERIALIZE_MEMBER((ObLinkScanSpec, ObLinkSpec), has_for_update_, select_exprs_); ObLinkScanOp::ObLinkScanOp(ObExecContext &exec_ctx, const ObOpSpec &spec, ObOpInput *input) : ObLinkOp(exec_ctx, spec, input), @@ -305,9 +305,10 @@ int ObLinkScanOp::fetch_row() reset_result(); } } else { - const ObIArray &output = spec_.output_; - for (int64_t i = 0; OB_SUCC(ret) && i < output.count(); i++) { - ObExpr *expr = output.at(i); + const ObIArray &select_exprs = + (MY_SPEC.select_exprs_.empty() ? spec_.output_ : MY_SPEC.select_exprs_); + for (int64_t i = 0; OB_SUCC(ret) && i < select_exprs.count(); i++) { + ObExpr *expr = select_exprs.at(i); if (!expr->is_const_expr()) { ObObj value; ObObj new_value; diff --git a/src/sql/engine/table/ob_link_scan_op.h b/src/sql/engine/table/ob_link_scan_op.h index e9c05172ed..0b702497a5 100644 --- a/src/sql/engine/table/ob_link_scan_op.h +++ b/src/sql/engine/table/ob_link_scan_op.h @@ -18,6 +18,7 @@ class ObLinkScanSpec : public ObLinkSpec public: explicit ObLinkScanSpec(common::ObIAllocator &alloc, const ObPhyOperatorType type); bool has_for_update_; + common::ObFixedArray select_exprs_; }; class ObLinkScanOp : public ObLinkOp diff --git a/src/sql/optimizer/ob_log_link_scan.cpp b/src/sql/optimizer/ob_log_link_scan.cpp index f4133c932e..0aa7dd813f 100644 --- a/src/sql/optimizer/ob_log_link_scan.cpp +++ b/src/sql/optimizer/ob_log_link_scan.cpp @@ -19,6 +19,17 @@ ObLogLinkScan::ObLogLinkScan(ObLogPlan &plan) : ObLogLink(plan) {} +int ObLogLinkScan::get_op_exprs(ObIArray &all_exprs) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(append(all_exprs, select_exprs_))) { + LOG_WARN("failed to push back select exprs", K(ret)); + } else if (OB_FAIL(ObLogicalOperator::get_op_exprs(all_exprs))) { + LOG_WARN("failed to get op exprs", K(ret)); + } else { /*do nothing*/ } + return ret; +} + int ObLogLinkScan::allocate_expr_post(ObAllocExprContext &ctx) { int ret = OB_SUCCESS; diff --git a/src/sql/optimizer/ob_log_link_scan.h b/src/sql/optimizer/ob_log_link_scan.h index b033a1a3a7..eec2bcbdc8 100644 --- a/src/sql/optimizer/ob_log_link_scan.h +++ b/src/sql/optimizer/ob_log_link_scan.h @@ -21,8 +21,13 @@ public: ObLogLinkScan(ObLogPlan &plan); virtual ~ObLogLinkScan() {} virtual int allocate_expr_post(ObAllocExprContext &ctx) override; + virtual int get_op_exprs(ObIArray &all_exprs) override; + const common::ObIArray &get_select_exprs() const { return select_exprs_; } + common::ObIArray &get_select_exprs() { return select_exprs_; } private: virtual bool print_flashback_query() const override { return true; }; +private: + common::ObSEArray select_exprs_; }; diff --git a/src/sql/optimizer/ob_select_log_plan.cpp b/src/sql/optimizer/ob_select_log_plan.cpp index a189670b2f..2e22b87e8b 100644 --- a/src/sql/optimizer/ob_select_log_plan.cpp +++ b/src/sql/optimizer/ob_select_log_plan.cpp @@ -4268,13 +4268,22 @@ int ObSelectLogPlan::allocate_link_scan_as_top(ObLogicalOperator *&old_top) { int ret = OB_SUCCESS; ObLogLinkScan *link_scan = NULL; + const ObSelectStmt *stmt = get_stmt(); + ObSEArray select_exprs; if (NULL != old_top) { ret = OB_INVALID_ARGUMENT; LOG_WARN("old_top should be null", K(ret), K(get_stmt())); + } else if (OB_ISNULL(stmt)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null ptr", K(ret), K(stmt)); } else if (OB_ISNULL(link_scan = static_cast(get_log_op_factory(). allocate(*this, LOG_LINK_SCAN)))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("failed to allocate link dml operator", K(ret)); + } else if (OB_FAIL(stmt->get_select_exprs(select_exprs))) { + LOG_WARN("failed to get select exprs", K(ret)); + } else if (OB_FAIL(link_scan->get_select_exprs().assign(select_exprs))) { + LOG_WARN("failed to assign select exprs", K(ret)); } else if (OB_FAIL(link_scan->compute_property())) { LOG_WARN("failed to compute property", K(ret)); } else {