From 2e28ad4ffa54c5048ad126978849d6fe49497c0c Mon Sep 17 00:00:00 2001 From: yaojing624 Date: Tue, 8 Aug 2023 10:48:42 +0000 Subject: [PATCH] Fix: There is a shared expression in the virtual generated column, which causes an error --- src/sql/optimizer/ob_log_table_scan.cpp | 48 ++++++++++++++++++++++ src/sql/optimizer/ob_log_table_scan.h | 1 + src/sql/resolver/expr/ob_raw_expr_util.cpp | 24 +++++++++++ src/sql/resolver/expr/ob_raw_expr_util.h | 2 + 4 files changed, 75 insertions(+) diff --git a/src/sql/optimizer/ob_log_table_scan.cpp b/src/sql/optimizer/ob_log_table_scan.cpp index bdbd9530e9..007db0ce04 100644 --- a/src/sql/optimizer/ob_log_table_scan.cpp +++ b/src/sql/optimizer/ob_log_table_scan.cpp @@ -287,6 +287,52 @@ int ObLogTableScan::extract_file_column_exprs_recursively(ObRawExpr *expr) return ret; } +// If the filter is indexed before returning to the table, +// and there are generated columns, deep copy is required +int ObLogTableScan::copy_filter_before_index_back() +{ + int ret = OB_SUCCESS; + ObIArray &filters = get_filter_exprs(); + const auto &flags = get_filter_before_index_flags(); + if (OB_FAIL(filter_before_index_back_set())) { + LOG_WARN("Failed to filter_before_index_back_set", K(ret)); + } else if (get_index_back() && !flags.empty()) { + ObRawExprCopier copier(get_plan()->get_optimizer_context().get_expr_factory()); + const ObDMLStmt *stmt = NULL; + ObArray column_exprs; + if (OB_ISNULL(stmt = get_stmt())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get unexpected null", K(get_stmt()), K(ret)); + } else if (OB_FAIL(stmt->get_column_exprs(column_exprs))) { + LOG_WARN("failed to get column exprs", K(ret)); + } else if (OB_FAIL(copier.add_skipped_expr(column_exprs))) { + LOG_WARN("failed to add skipped exprs", K(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < filters.count(); ++i) { + if (filters.at(i)->has_flag(CNT_PL_UDF)) { + // do nothing. + } else if (flags.at(i)) { + if (get_index_back() && get_is_index_global() && filters.at(i)->has_flag(CNT_SUB_QUERY)) { + // do nothing. + } else { + bool is_contain_vir_gen_column = false; + // ObArray column_exprs; + // scan_pushdown before index back conculde virtual generated column + // need copy for avoiding shared expression. + if (OB_FAIL(ObRawExprUtils::contain_virtual_generated_column(filters.at(i), is_contain_vir_gen_column))) { + LOG_WARN("fail to contain virtual gen column", K(ret)); + } else if (is_contain_vir_gen_column) { + if (OB_FAIL(copier.copy(filters.at(i), filters.at(i)))) { + LOG_WARN("failed to copy exprs", K(ret)); + } + } + } + } + } + } + + return ret; +} int ObLogTableScan::generate_access_exprs() { int ret = OB_SUCCESS; @@ -295,6 +341,8 @@ int ObLogTableScan::generate_access_exprs() if (OB_ISNULL(get_plan()) || OB_ISNULL(stmt = get_stmt())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected null", K(get_plan()), K(get_stmt()), K(ret)); + } else if (OB_FAIL(copy_filter_before_index_back())) { + LOG_WARN("failed to copy filter before index back", K(ret)); } else if (OB_FAIL(generate_necessary_rowkey_and_partkey_exprs())) { LOG_WARN("failed to generate rowkey and part exprs", K(ret)); } else if (use_batch() diff --git a/src/sql/optimizer/ob_log_table_scan.h b/src/sql/optimizer/ob_log_table_scan.h index e1ba7f18ec..2e897f74d5 100644 --- a/src/sql/optimizer/ob_log_table_scan.h +++ b/src/sql/optimizer/ob_log_table_scan.h @@ -426,6 +426,7 @@ public: ObRawExpr *&real_expr); int get_phy_location_type(ObTableLocationType &location_type); virtual int generate_access_exprs(); + int copy_filter_before_index_back(); void set_use_batch(bool use_batch) { use_batch_ = use_batch; } bool use_batch() const { return use_batch_; } // only use group_id_expr_ when use_batch() is true. diff --git a/src/sql/resolver/expr/ob_raw_expr_util.cpp b/src/sql/resolver/expr/ob_raw_expr_util.cpp index c06b362517..85aec20753 100644 --- a/src/sql/resolver/expr/ob_raw_expr_util.cpp +++ b/src/sql/resolver/expr/ob_raw_expr_util.cpp @@ -3440,6 +3440,30 @@ int ObRawExprUtils::extract_col_aggr_exprs(ObRawExpr* expr, return ret; } +int ObRawExprUtils::contain_virtual_generated_column(ObRawExpr *&expr, bool &is_contain_vir_gen_column) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(expr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("expr is null", K(ret)); + } else if (expr->is_column_ref_expr() && + static_cast(expr)->is_virtual_generated_column() && + !static_cast(expr)->is_xml_column()) { + is_contain_vir_gen_column = true; + } + for (int64_t j = 0; OB_SUCC(ret) && is_contain_vir_gen_column == false && j < expr->get_param_count(); j++) { + if (OB_ISNULL(expr->get_param_expr(j))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("param_expr is NULL", K(j), K(ret)); + } else if (OB_FAIL(SMART_CALL(contain_virtual_generated_column(expr->get_param_expr(j), is_contain_vir_gen_column)))) { + LOG_WARN("fail to contain virtual gen column", K(j), K(ret)); + } else { + LOG_TRACE("conclude virtual generated column", K(is_contain_vir_gen_column)); + } + } + return ret; +} + int ObRawExprUtils::extract_column_exprs(const ObIArray &exprs, ObIArray &column_exprs, bool need_pseudo_column) diff --git a/src/sql/resolver/expr/ob_raw_expr_util.h b/src/sql/resolver/expr/ob_raw_expr_util.h index 5b01af8ae8..9cf42c0ace 100644 --- a/src/sql/resolver/expr/ob_raw_expr_util.h +++ b/src/sql/resolver/expr/ob_raw_expr_util.h @@ -368,6 +368,8 @@ public: ObRawExpr *from, ObRawExpr *to, const ObIArray *except_exprs = NULL); + static int contain_virtual_generated_column(ObRawExpr *&expr, + bool &is_contain_vir_gen_column); static bool is_all_column_exprs(const common::ObIArray &exprs); static int extract_set_op_exprs(const ObRawExpr *raw_expr,