From be01c52cd48078777986aa4c2c3780c166e1f829 Mon Sep 17 00:00:00 2001 From: SevenJ-swj Date: Mon, 21 Aug 2023 08:40:27 +0000 Subject: [PATCH] fix win maigc ora_rowscn bug --- src/sql/resolver/dml/ob_dml_stmt.cpp | 30 ++++++++++ src/sql/resolver/dml/ob_dml_stmt.h | 2 + src/sql/rewrite/ob_transform_utils.cpp | 65 +++++++++++++++++++++- src/sql/rewrite/ob_transform_utils.h | 4 +- src/sql/rewrite/ob_transform_win_magic.cpp | 52 ++++++++++++----- 5 files changed, 137 insertions(+), 16 deletions(-) diff --git a/src/sql/resolver/dml/ob_dml_stmt.cpp b/src/sql/resolver/dml/ob_dml_stmt.cpp index 831482d756..9b479e68a5 100644 --- a/src/sql/resolver/dml/ob_dml_stmt.cpp +++ b/src/sql/resolver/dml/ob_dml_stmt.cpp @@ -1761,6 +1761,36 @@ int ObDMLStmt::formalize_child_stmt_expr_reference() return ret; } +int ObDMLStmt::get_table_pseudo_column_like_exprs(uint64_t table_id, + ObIArray &pseudo_columns) +{ + int ret = OB_SUCCESS; + for (int64_t i = 0; OB_SUCC(ret) && i < pseudo_column_like_exprs_.count(); i++) { + if (OB_ISNULL(pseudo_column_like_exprs_.at(i))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("pseudo column like expr is null", K(ret)); + } else if (pseudo_column_like_exprs_.at(i)->is_pseudo_column_expr() && + static_cast(pseudo_column_like_exprs_.at(i))->get_table_id() == table_id) { + if (OB_FAIL(pseudo_columns.push_back(pseudo_column_like_exprs_.at(i)))) { + LOG_WARN("push back failed", K(ret)); + } + } + } + return ret; +} + +int ObDMLStmt::get_table_pseudo_column_like_exprs(ObIArray &table_ids, + ObIArray &pseudo_columns) +{ + int ret = OB_SUCCESS; + for (int64_t i = 0; OB_SUCC(ret) && i < table_ids.count(); i++) { + if (OB_FAIL(get_table_pseudo_column_like_exprs(table_ids.at(i), pseudo_columns))) { + LOG_WARN("get table pseduo column like expr failed", K(ret)); + } + } + return ret; +} + int ObDMLStmt::check_pseudo_column_valid() { int ret = OB_SUCCESS; diff --git a/src/sql/resolver/dml/ob_dml_stmt.h b/src/sql/resolver/dml/ob_dml_stmt.h index a1721ef428..10b4133462 100644 --- a/src/sql/resolver/dml/ob_dml_stmt.h +++ b/src/sql/resolver/dml/ob_dml_stmt.h @@ -927,6 +927,8 @@ public: { return pseudo_column_like_exprs_; } const common::ObIArray &get_pseudo_column_like_exprs() const { return pseudo_column_like_exprs_; } + int get_table_pseudo_column_like_exprs(uint64_t table_id, ObIArray &pseudo_columns); + int get_table_pseudo_column_like_exprs(ObIArray &table_id, ObIArray &pseudo_columns); int rebuild_tables_hash(); int update_rel_ids(ObRelIds &rel_ids, const ObIArray &bit_index_map); int update_column_item_rel_id(); diff --git a/src/sql/rewrite/ob_transform_utils.cpp b/src/sql/rewrite/ob_transform_utils.cpp index a6d7674368..d28d249dcd 100644 --- a/src/sql/rewrite/ob_transform_utils.cpp +++ b/src/sql/rewrite/ob_transform_utils.cpp @@ -5330,12 +5330,17 @@ int ObTransformUtils::merge_table_items(ObDMLStmt *stmt, const TableItem *target_table, const ObIArray *output_map, ObIArray *pushed_col_exprs, - ObIArray *merged_col_exprs) + ObIArray *merged_col_exprs, + ObIArray *pushed_pseudo_col_exprs, + ObIArray *merged_pseudo_col_exprs) { int ret = OB_SUCCESS; ObSEArray from_col_exprs; ObSEArray to_col_exprs; + ObSEArray from_pseudo_col_exprs; + ObSEArray to_pseudo_col_exprs; ObSEArray target_column_items; + ObStmtExprReplacer replacer; if (OB_ISNULL(stmt) || OB_ISNULL(source_table) || OB_ISNULL(target_table)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid parameters", K(ret), K(stmt), K(source_table), @@ -5346,6 +5351,63 @@ int ObTransformUtils::merge_table_items(ObDMLStmt *stmt, } else { uint64_t source_table_id = source_table->table_id_; uint64_t target_table_id = target_table->table_id_; + + ObArray target_pseudo_like_column_exprs; + ObArray source_pseudo_like_column_exprs; + if (OB_FAIL(stmt->get_table_pseudo_column_like_exprs(target_table_id, target_pseudo_like_column_exprs))) { + LOG_WARN("get table pseudo column expr failed", K(ret)); + } else if (OB_FAIL(stmt->get_table_pseudo_column_like_exprs(source_table_id, source_pseudo_like_column_exprs))) { + LOG_WARN("get table pseudo column expr failed", K(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < target_pseudo_like_column_exprs.count(); i++) { + if (OB_ISNULL(target_pseudo_like_column_exprs.at(i))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("pseudo col expr is null", K(ret)); + } else if (OB_UNLIKELY(!target_pseudo_like_column_exprs.at(i)->is_pseudo_column_expr())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("pseudo col expr is not pseudo column expr type", K(ret)); + } else { + bool found = false; + ObRawExpr *merged_pseudo_col_expr = NULL; + for (int64_t j = 0; OB_SUCC(ret) && !found && j < source_pseudo_like_column_exprs.count(); j++) { + if (OB_ISNULL(source_pseudo_like_column_exprs.at(j))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("stmt pseudo like column expr is null", K(ret)); + } else if (source_pseudo_like_column_exprs.at(j)->get_expr_type() == + target_pseudo_like_column_exprs.at(i)->get_expr_type()) { + found = true; + if (OB_FAIL(from_pseudo_col_exprs.push_back(target_pseudo_like_column_exprs.at(i))) + || OB_FAIL(to_pseudo_col_exprs.push_back(source_pseudo_like_column_exprs.at(j)))) { + LOG_WARN("push expr into array failed", K(ret)); + } else { + merged_pseudo_col_expr = source_pseudo_like_column_exprs.at(j); + } + } + } + + if (OB_SUCC(ret) && !found) { + static_cast(target_pseudo_like_column_exprs.at(i))->set_table_id(source_table_id); + static_cast(target_pseudo_like_column_exprs.at(i))->set_table_name( + source_table->get_table_name()); + merged_pseudo_col_expr = target_pseudo_like_column_exprs.at(i); + } + + if (OB_FAIL(ret)) { + } else if (pushed_pseudo_col_exprs == NULL || merged_pseudo_col_exprs == NULL) { + //do nothing + } else if (OB_FAIL(pushed_pseudo_col_exprs->push_back(target_pseudo_like_column_exprs.at(i))) + || OB_FAIL(merged_pseudo_col_exprs->push_back(merged_pseudo_col_expr))) { + LOG_WARN("append failed", K(ret)); + } + } + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(replacer.add_replace_exprs(from_pseudo_col_exprs, to_pseudo_col_exprs))) { + LOG_WARN("failed to add replace exprs", K(ret)); + } else if (OB_FAIL(ObOptimizerUtil::remove_item(stmt->get_pseudo_column_like_exprs(), from_pseudo_col_exprs))) { + LOG_WARN("remove item failed", K(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < target_column_items.count(); ++i) { ColumnItem *target_col = NULL; ColumnItem *source_col = NULL; @@ -5410,7 +5472,6 @@ int ObTransformUtils::merge_table_items(ObDMLStmt *stmt, } if (OB_SUCC(ret) && !from_col_exprs.empty()) { - ObStmtExprReplacer replacer; if (OB_FAIL(replacer.add_replace_exprs(from_col_exprs, to_col_exprs))) { LOG_WARN("failed to add replace exprs", K(ret)); } else if (OB_FAIL(stmt->iterate_stmt_expr(replacer))) { diff --git a/src/sql/rewrite/ob_transform_utils.h b/src/sql/rewrite/ob_transform_utils.h index d2f706eb77..fa4165d064 100644 --- a/src/sql/rewrite/ob_transform_utils.h +++ b/src/sql/rewrite/ob_transform_utils.h @@ -982,7 +982,9 @@ public: const TableItem *target_table, const ObIArray *output_map, ObIArray *old_target_col_expr = NULL, - ObIArray *new_target_col_expr = NULL); + ObIArray *new_target_col_expr = NULL, + ObIArray *pushed_pseudo_col_exprs = NULL, + ObIArray *merged_pseudo_col_exprs = NULL); static int merge_table_items(ObSelectStmt *source_stmt, ObSelectStmt *target_stmt, diff --git a/src/sql/rewrite/ob_transform_win_magic.cpp b/src/sql/rewrite/ob_transform_win_magic.cpp index 14e3e0dc52..90f8a4f9f9 100644 --- a/src/sql/rewrite/ob_transform_win_magic.cpp +++ b/src/sql/rewrite/ob_transform_win_magic.cpp @@ -1131,6 +1131,9 @@ int ObTransformWinMagic::adjust_column_and_table(ObDMLStmt *main_stmt, ObSEArray merged_column_expr; ObSEArray pushed_column_exprs; + ObSEArray merged_pseudo_column_exprs; + ObSEArray pushed_pseudo_column_exprs; + ObArray rm_semi_infos; if (OB_ISNULL(main_stmt) || OB_ISNULL(view) || @@ -1162,15 +1165,23 @@ int ObTransformWinMagic::adjust_column_and_table(ObDMLStmt *main_stmt, } // push down column - for (int64_t i = 0; OB_SUCC(ret) && i < main_stmt->get_column_size(); i++) { - if (!ObOptimizerUtil::find_item(main_table_ids, - main_stmt->get_column_items().at(i).table_id_)) { - //do nothing. - } else if (OB_FAIL(view_stmt->add_column_item(main_stmt->get_column_items().at(i)))) { - LOG_WARN("add column item failed", K(ret)); - } + ObArray column_items; + if (OB_FAIL(ret)) { + } else if (OB_FAIL(main_stmt->get_column_items(main_table_ids, column_items))) { + LOG_WARN("get column items failed", K(ret)); + } else if (OB_FAIL(view_stmt->add_column_item(column_items))) { + LOG_WARN("add column item failed", K(ret)); } - + + // push down pseudo column + ObArray pseudo_columns; + if (OB_FAIL(ret)) { + } else if (OB_FAIL(main_stmt->get_table_pseudo_column_like_exprs(main_table_ids, pseudo_columns))) { + LOG_WARN("get table pseudo column like exprs failed", K(ret)); + } else if (OB_FAIL(append(view_stmt->get_pseudo_column_like_exprs(), pseudo_columns))) { + LOG_WARN("append failed", K(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < map_info.semi_info_map_.count(); ++i) { int64_t idx = map_info.semi_info_map_.at(i); SemiInfo *semi = NULL; @@ -1202,14 +1213,16 @@ int ObTransformWinMagic::adjust_column_and_table(ObDMLStmt *main_stmt, main_table, NULL, &pushed_column_exprs, - &merged_column_expr))) { + &merged_column_expr, + &pushed_pseudo_column_exprs, + &merged_pseudo_column_exprs))) { LOG_WARN("failed to merge table items", K(ret)); } else if (OB_FAIL(ObTransformUtils::replace_table_in_semi_infos(main_stmt, view_table, main_table))) { LOG_WARN("failed to replace table info in semi infos", K(ret)); } } - + for (int64_t i = 0; OB_SUCC(ret) && i < map_info.from_map_.count(); i++) { int64_t from_idx = map_info.from_map_.at(i); if (from_idx != OB_INVALID_ID && @@ -1252,13 +1265,26 @@ int ObTransformWinMagic::adjust_column_and_table(ObDMLStmt *main_stmt, } } + + ObSEArray new_col_for_pseudo_cols; + if (OB_FAIL(ret)) { + } else if (OB_FAIL(ObOptimizerUtil::remove_item(main_stmt->get_pseudo_column_like_exprs(), + pushed_pseudo_column_exprs))) { + LOG_WARN("remove item failed", K(ret)); + } else if (OB_FAIL(ObTransformUtils::create_columns_for_view(ctx_, + *view, + main_stmt, + merged_pseudo_column_exprs, + new_col_for_pseudo_cols))) { + LOG_WARN("create columns for view failed", K(ret)); + } else if (OB_FAIL(main_stmt->replace_relation_exprs(pushed_pseudo_column_exprs, new_col_for_pseudo_cols))) { + LOG_WARN("replace inner stmt expr failed", K(ret)); + } + ObSEArray new_col_in_main; - ObSEArray select_exprs; //create select item for view if (OB_FAIL(ret)) { //do nothing. - } else if (OB_FAIL(view_stmt->get_select_exprs(select_exprs))) { - LOG_WARN("failed to get select exprs", K(ret)); } else if (OB_FAIL(ObTransformUtils::create_columns_for_view(ctx_, *view, main_stmt,