From 0f00f1a727fd2edf47d7ed69db221e9ea92edbaa Mon Sep 17 00:00:00 2001 From: hy-guo Date: Mon, 22 Apr 2024 15:41:23 +0000 Subject: [PATCH] fix mv rewrite bugs --- src/sql/rewrite/ob_expand_aggregate_utils.cpp | 27 +++++++ src/sql/rewrite/ob_expand_aggregate_utils.h | 9 ++- src/sql/rewrite/ob_stmt_comparer.cpp | 1 + src/sql/rewrite/ob_transform_mv_rewrite.cpp | 28 ++++--- src/sql/rewrite/ob_transform_or_expansion.cpp | 2 +- src/sql/rewrite/ob_transform_utils.cpp | 80 +++++++++++++------ src/sql/rewrite/ob_transform_utils.h | 4 + 7 files changed, 112 insertions(+), 39 deletions(-) diff --git a/src/sql/rewrite/ob_expand_aggregate_utils.cpp b/src/sql/rewrite/ob_expand_aggregate_utils.cpp index 61594a8a9d..215ba46e6a 100644 --- a/src/sql/rewrite/ob_expand_aggregate_utils.cpp +++ b/src/sql/rewrite/ob_expand_aggregate_utils.cpp @@ -551,6 +551,33 @@ int ObExpandAggregateUtils::add_aggr_item(ObIArray &new_aggr_i return ret; } +int ObExpandAggregateUtils::add_win_expr(common::ObIArray &new_win_exprs, + ObWinFunRawExpr *&win_expr) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(win_expr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get unexpected null", K(ret), K(win_expr)); + } else { + int64_t i = 0; + for (; OB_SUCC(ret) && i < new_win_exprs.count(); ++i) { + if (OB_ISNULL(new_win_exprs.at(i))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get unexpected null", K(ret), K(new_win_exprs.at(i))); + } else if (win_expr->same_as(*new_win_exprs.at(i))) { + win_expr = new_win_exprs.at(i); + break; + } else {/*do nothing*/} + } + if (OB_SUCC(ret) && i == new_win_exprs.count()) { + if (OB_FAIL(new_win_exprs.push_back(win_expr))) { + LOG_WARN("failed to push back aggr expr", K(ret)); + } + } + } + return ret; +} + //T_FUN_VAR_POP == node->type_: (SUM(expr*expr) - SUM(expr)* SUM(expr)/ COUNT(expr)) / COUNT(expr) //T_FUN_VAR_SAMP== node->type_: (SUM(expr*expr) - SUM(expr)* SUM(expr)/ COUNT(expr)) / (COUNT(expr) - 1) int ObExpandAggregateUtils::expand_var_expr(ObAggFunRawExpr *aggr_expr, diff --git a/src/sql/rewrite/ob_expand_aggregate_utils.h b/src/sql/rewrite/ob_expand_aggregate_utils.h index e7a7b1dadf..367558765d 100644 --- a/src/sql/rewrite/ob_expand_aggregate_utils.h +++ b/src/sql/rewrite/ob_expand_aggregate_utils.h @@ -42,6 +42,12 @@ public: ObRawExpr *&replace_expr, ObIArray &new_aggr_items); + static int add_aggr_item(common::ObIArray &new_aggr_items, + ObAggFunRawExpr *&aggr_expr); + + static int add_win_expr(common::ObIArray &new_win_exprs, + ObWinFunRawExpr *&win_expr); + private: int extract_candi_aggr(ObDMLStmt *select_stmt, common::ObIArray &candi_aggr_items, @@ -59,9 +65,6 @@ private: ObRawExpr *&replace_expr, common::ObIArray &new_aggr_items); - int add_aggr_item(common::ObIArray &new_aggr_items, - ObAggFunRawExpr *&aggr_expr); - int expand_var_expr(ObAggFunRawExpr *aggr_expr, ObRawExpr *&replace_expr, ObIArray &new_aggr_items); diff --git a/src/sql/rewrite/ob_stmt_comparer.cpp b/src/sql/rewrite/ob_stmt_comparer.cpp index 16a974c493..1429abe2e2 100644 --- a/src/sql/rewrite/ob_stmt_comparer.cpp +++ b/src/sql/rewrite/ob_stmt_comparer.cpp @@ -987,6 +987,7 @@ int ObStmtComparer::inner_compute_expr(const ObRawExpr *target_expr, // Try to match each param expr if (OB_SUCC(ret) && !is_match && (ObRawExpr::EXPR_OPERATOR == target_expr->get_expr_class() + || ObRawExpr::EXPR_CASE_OPERATOR == target_expr->get_expr_class() || ObRawExpr::EXPR_AGGR == target_expr->get_expr_class() || ObRawExpr::EXPR_SYS_FUNC == target_expr->get_expr_class() || ObRawExpr::EXPR_WINDOW == target_expr->get_expr_class() diff --git a/src/sql/rewrite/ob_transform_mv_rewrite.cpp b/src/sql/rewrite/ob_transform_mv_rewrite.cpp index ea9831526f..b6cfeaea31 100644 --- a/src/sql/rewrite/ob_transform_mv_rewrite.cpp +++ b/src/sql/rewrite/ob_transform_mv_rewrite.cpp @@ -400,11 +400,11 @@ int ObTransformMVRewrite::generate_mv_info(const ObDMLStmt *stmt, ret = OB_ERR_UNEXPECTED; LOG_WARN("data table schema is null", K(ret), K(mv_list.at(i))); } else if (OB_FAIL(mv_infos_.push_back(MvInfo(mv_list.at(i), - data_table_id, - mv_schema, - data_table_schema, - db_schema, - NULL)))) { + data_table_id, + mv_schema, + data_table_schema, + db_schema, + NULL)))) { LOG_WARN("failed to push back mv info", K(ret)); } } @@ -623,6 +623,7 @@ int ObTransformMVRewrite::try_transform_with_one_mv(ObSelectStmt *origin_stmt, LOG_WARN("failed to add transform hint", K(ret)); } else { transform_happened = true; + LOG_DEBUG("succeed to transform with one mv", KPC(new_stmt)); } if (OB_SUCC(ret) && !transform_happened && OB_FAIL(try_trans_helper.recover(origin_stmt->get_query_ctx()))) { @@ -795,13 +796,14 @@ int ObTransformMVRewrite::create_mv_column_item(const MvInfo &mv_info, ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected null", K(ret), K(helper.new_stmt_), K(helper.mv_item_), K(mv_info)); } - for (int64_t i = 0; OB_SUCC(ret) && i < mv_info.view_stmt_->get_select_item_size(); ++i) { + // create mv column item + for (int64_t i = 0; OB_SUCC(ret) && i < mv_info.data_table_schema_->get_column_count(); ++i) { const ObColumnSchemaV2 *col_schema = NULL; ObColumnRefRawExpr *col_expr = NULL; bool is_uni = false; bool is_mul = false; ColumnItem column_item; - if (OB_ISNULL(col_schema = mv_info.data_table_schema_->get_column_schema(OB_APP_MIN_COLUMN_ID + i))) { + if (OB_ISNULL(col_schema = mv_info.data_table_schema_->get_column_schema_by_idx(i))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("column schema is null", K(ret)); } else if (OB_FAIL(ObRawExprUtils::build_column_expr(*ctx_->expr_factory_, *col_schema, col_expr))) { @@ -854,11 +856,19 @@ int ObTransformMVRewrite::create_mv_column_item(const MvInfo &mv_info, LOG_WARN("add column item to stmt failed", K(ret)); } else if (OB_FAIL(col_expr->pull_relation_id())) { LOG_WARN("failed to pullup relation ids", K(ret)); - } else if (OB_FAIL(helper.col_copier_.add_replaced_expr(mv_info.view_stmt_->get_select_item(i).expr_, col_expr))) { - LOG_WARN("failed to add replaced expr", K(ret), KPC(mv_info.view_stmt_->get_select_item(i).expr_), KPC(col_expr)); } } } + // add column expr to copier + for (int64_t i = 0; OB_SUCC(ret) && i < mv_info.view_stmt_->get_select_item_size(); ++i) { + ObColumnRefRawExpr *col_expr = NULL; + if (OB_ISNULL(col_expr = helper.new_stmt_->get_column_expr_by_id(helper.mv_item_->table_id_, OB_APP_MIN_COLUMN_ID + i))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get column id", K(ret), K(helper.mv_item_->table_id_), K(OB_APP_MIN_COLUMN_ID + i)); + } else if (OB_FAIL(helper.col_copier_.add_replaced_expr(mv_info.view_stmt_->get_select_item(i).expr_, col_expr))) { + LOG_WARN("failed to add replaced expr", K(ret), KPC(mv_info.view_stmt_->get_select_item(i).expr_), KPC(col_expr)); + } + } return ret; } diff --git a/src/sql/rewrite/ob_transform_or_expansion.cpp b/src/sql/rewrite/ob_transform_or_expansion.cpp index d9d9f6ca02..cce863dd75 100644 --- a/src/sql/rewrite/ob_transform_or_expansion.cpp +++ b/src/sql/rewrite/ob_transform_or_expansion.cpp @@ -2201,7 +2201,7 @@ int ObTransformOrExpansion::transform_or_expansion(ObSelectStmt *stmt, LOG_WARN("failed to preprocess or condition", K(ret)); } else if (ctx.is_set_distinct_ && !ctx.is_unique_ && OB_FAIL(unique_key_provider.recursive_set_stmt_unique(view_stmt, ctx_, true))) { - LOG_WARN("failed to set stmt unique", K(ret)); + LOG_WARN("failed to set stmt unique", K(ret), KPC(view_stmt)); } else if (!ctx.is_valid_topk_ && OB_FAIL(classify_or_expr(*view_stmt, conds_exprs->at(view_expr_pos)))) { LOG_WARN("failed to classify or expr", K(ret), KPC(conds_exprs->at(view_expr_pos))); diff --git a/src/sql/rewrite/ob_transform_utils.cpp b/src/sql/rewrite/ob_transform_utils.cpp index 9df249eeb5..625bd1a488 100644 --- a/src/sql/rewrite/ob_transform_utils.cpp +++ b/src/sql/rewrite/ob_transform_utils.cpp @@ -38,6 +38,7 @@ #include "sql/resolver/dml/ob_select_resolver.h" #include "sql/parser/ob_parser.h" #include "sql/rewrite/ob_transform_pre_process.h" +#include "sql/rewrite/ob_expand_aggregate_utils.h" namespace oceanbase { using namespace common; @@ -5859,7 +5860,7 @@ int ObTransformUtils::generate_unique_key_for_basic_table(ObTransformerCtx *ctx, LOG_WARN("Failed to get column id", K(ret)); } else if (OB_ISNULL(col_expr = stmt->get_column_expr_by_id(item->table_id_, column_id))) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to get column schema", K(column_id), K(ret)); + LOG_WARN("failed to get column expr", K(item->table_id_), K(column_id), K(ret)); } else if (FALSE_IT(col_expr->set_explicited_reference())) { } else if (OB_FAIL(unique_keys.push_back(col_expr))) { LOG_WARN("failed to push back expr", K(ret)); @@ -14397,6 +14398,11 @@ int ObTransformUtils::expand_mview_table(ObTransformerCtx *ctx, ObDMLStmt *upper expand_view_name, rt_mv_table->table_name_))) { LOG_WARN("failed to write string", K(ret)); + } else if (OB_FAIL(adjust_col_and_sel_for_expand_mview(ctx, + upper_stmt->get_column_items(), + view_stmt->get_select_items(), + rt_mv_table->table_id_))) { + LOG_WARN("failed to adjust column items and select items", K(ret)); } else { rt_mv_table->type_ = TableItem::GENERATED_TABLE; rt_mv_table->ref_id_ = OB_INVALID_ID; @@ -14405,35 +14411,57 @@ int ObTransformUtils::expand_mview_table(ObTransformerCtx *ctx, ObDMLStmt *upper rt_mv_table->ref_query_ = view_stmt; rt_mv_table->table_type_ = MAX_TABLE_TYPE; rt_mv_table->need_expand_rt_mv_ = false; - const ObIArray &col_items = upper_stmt->get_column_items(); - ObIArray &sel_items = view_stmt->get_select_items(); - int64_t pos = OB_INVALID_ID; - // keep the result type for expand real-time view select items - for (int64_t i = 0; OB_SUCC(ret) && i < col_items.count(); ++i) { - if (OB_ISNULL(col_items.at(i).expr_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("get unexpected null", K(ret)); - } else if (col_items.at(i).table_id_ != rt_mv_table->table_id_) { - /* do nothing */ - } else if (FALSE_IT(pos = col_items.at(i).expr_->get_column_id() - OB_APP_MIN_COLUMN_ID)) { - } else if (OB_UNLIKELY(pos < 0 || pos >= sel_items.count())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("invalid array pos", K(pos), K(sel_items.count()), K(ret)); - } else if (OB_FAIL(ObTransformUtils::add_cast_for_replace_if_need(*ctx->expr_factory_, - col_items.at(i).expr_, - sel_items.at(pos).expr_, - ctx->session_info_))) { - LOG_WARN("try add cast expr above failed", K(ret)); - } else { - col_items.at(i).expr_->set_is_rowkey_column(false); - } - } } OPT_TRACE_END_SECTION; } return ret; } +// remove mview hidden column from upper column items and add cast for view select items +int ObTransformUtils::adjust_col_and_sel_for_expand_mview(ObTransformerCtx *ctx, + ObIArray &uppper_col_items, + ObIArray &view_sel_items, + uint64_t mv_table_id) +{ + int ret = OB_SUCCESS; + ObSEArray new_col_items; + int64_t pos = OB_INVALID_ID; + if (OB_ISNULL(ctx) || OB_ISNULL(ctx->expr_factory_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get unexpected null", K(ret), K(ctx)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < uppper_col_items.count(); ++i) { + if (OB_ISNULL(uppper_col_items.at(i).expr_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get unexpected null", K(ret)); + } else if (uppper_col_items.at(i).table_id_ != mv_table_id) { + // not mview column + if (OB_FAIL(new_col_items.push_back(uppper_col_items.at(i)))) { + LOG_WARN("failed to push back column item", K(ret)); + } + } else if (FALSE_IT(pos = uppper_col_items.at(i).expr_->get_column_id() - OB_APP_MIN_COLUMN_ID)) { + } else if (OB_UNLIKELY(pos >= view_sel_items.count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid array pos", K(pos), K(view_sel_items.count()), K(ret)); + } else if (pos < 0) { + // do nothing, it is hidden column of mview + } else if (OB_FAIL(new_col_items.push_back(uppper_col_items.at(i)))) { + LOG_WARN("failed to push back column item", K(ret)); + } else if (OB_FAIL(ObTransformUtils::add_cast_for_replace_if_need(*ctx->expr_factory_, + new_col_items.at(new_col_items.count() - 1).expr_, + view_sel_items.at(pos).expr_, + ctx->session_info_))) { + LOG_WARN("try add cast expr above failed", K(ret)); + } else { + new_col_items.at(new_col_items.count() - 1).expr_->set_is_rowkey_column(false); + } + } + if (OB_SUCC(ret) && OB_FAIL(uppper_col_items.assign(new_col_items))) { + LOG_WARN("failed to assign column items", K(ret)); + } + return ret; +} + // 1. 不进行参数化 // 2. 不需要检查权限 // 3. 添加 dependency table @@ -15099,12 +15127,12 @@ int ObTransformUtils::add_aggr_winfun_expr(ObSelectStmt *stmt, LOG_WARN("get unexpected null", K(ret), K(expr), K(stmt)); } else if (expr->is_aggr_expr()) { ObAggFunRawExpr *agg_expr = static_cast(expr); - if (OB_FAIL(stmt->add_agg_item(*agg_expr))) { + if (OB_FAIL(ObExpandAggregateUtils::add_aggr_item(stmt->get_aggr_items(), agg_expr))) { LOG_WARN("failed to add agg item", K(ret), KPC(agg_expr)); } } else if (expr->is_win_func_expr()) { ObWinFunRawExpr *win_expr = static_cast(expr); - if (OB_FAIL(stmt->get_window_func_exprs().push_back(win_expr))) { + if (OB_FAIL(ObExpandAggregateUtils::add_win_expr(stmt->get_window_func_exprs(), win_expr))) { LOG_WARN("failed to add win func expr", K(ret), KPC(win_expr)); } } else { diff --git a/src/sql/rewrite/ob_transform_utils.h b/src/sql/rewrite/ob_transform_utils.h index 0743c95611..b38f577f89 100644 --- a/src/sql/rewrite/ob_transform_utils.h +++ b/src/sql/rewrite/ob_transform_utils.h @@ -1895,6 +1895,10 @@ public: static int add_aggr_winfun_expr(ObSelectStmt *stmt, ObRawExpr *expr); static int expand_mview_table(ObTransformerCtx *ctx, ObDMLStmt *upper_stmt, TableItem *rt_mv_table); + static int adjust_col_and_sel_for_expand_mview(ObTransformerCtx *ctx, + ObIArray &uppper_col_items, + ObIArray &view_sel_items, + uint64_t mv_table_id); static int generate_view_stmt_from_query_string(const ObString &expand_view, ObTransformerCtx *ctx,