From b096903542486e536f3e2fbe4d54e5aa8b9eb912 Mon Sep 17 00:00:00 2001 From: obdev Date: Fri, 4 Nov 2022 10:08:01 +0000 Subject: [PATCH] [bugfix] fix serveral rewrite bugs --- .../expr/ob_expr_relation_analyzer.cpp | 3 +- .../ob_transform_predicate_move_around.cpp | 58 +++++++++++++++++-- .../ob_transform_predicate_move_around.h | 7 ++- .../ob_transform_where_subquery_pullup.cpp | 1 - 4 files changed, 61 insertions(+), 8 deletions(-) diff --git a/src/sql/resolver/expr/ob_expr_relation_analyzer.cpp b/src/sql/resolver/expr/ob_expr_relation_analyzer.cpp index 1e7994736..366f5e43c 100644 --- a/src/sql/resolver/expr/ob_expr_relation_analyzer.cpp +++ b/src/sql/resolver/expr/ob_expr_relation_analyzer.cpp @@ -90,8 +90,7 @@ int ObExprRelationAnalyzer::visit_expr(ObRawExpr &expr, int32_t stmt_level) LOG_WARN("param expr is null", K(ret), K(param), K(i), K(expr)); } else if (OB_FAIL(SMART_CALL(visit_expr(*param, stmt_level)))) { LOG_WARN("failed to visit param", K(ret)); - } else if (!expr.is_query_ref_expr() && - OB_FAIL(expr.get_expr_levels().add_members(param->get_expr_levels()))) { + } else if (OB_FAIL(expr.get_expr_levels().add_members(param->get_expr_levels()))) { LOG_WARN("failed to add expr levels", K(ret)); } else if (!param->get_expr_levels().has_member(stmt_level)) { // skip diff --git a/src/sql/rewrite/ob_transform_predicate_move_around.cpp b/src/sql/rewrite/ob_transform_predicate_move_around.cpp index ad12e7566..6caa4eb11 100644 --- a/src/sql/rewrite/ob_transform_predicate_move_around.cpp +++ b/src/sql/rewrite/ob_transform_predicate_move_around.cpp @@ -2084,6 +2084,58 @@ int ObTransformPredicateMoveAround::pushdown_into_semi_info(ObDMLStmt *stmt, return ret; } +int ObTransformPredicateMoveAround::extract_semi_right_table_filter(ObDMLStmt *stmt, + SemiInfo *semi_info, + ObIArray &right_filters) +{ + int ret = OB_SUCCESS; + ObSqlBitSet<> right_table_set; + if (OB_ISNULL(stmt) || OB_ISNULL(semi_info)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("params have null", K(ret), K(stmt), K(semi_info)); + } else if (OB_FAIL(stmt->get_table_rel_ids(semi_info->right_table_id_, + right_table_set))) { + LOG_WARN("failed to get right table set", K(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < semi_info->semi_conditions_.count(); ++i) { + ObRawExpr *expr = semi_info->semi_conditions_.at(i); + bool has = false; + if (OB_ISNULL(expr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("source expr shoud not be null", K(ret)); + } else if (expr->get_relation_ids().is_empty()) { + // do nothing + } else if (!right_table_set.is_superset2(expr->get_relation_ids())) { + /* do nothing */ + } else if (OB_FAIL(check_has_shared_query_ref(expr, has))) { + LOG_WARN("failed to check has shared query ref", K(ret)); + } else if (has) { + // do nothing + } else if (OB_FAIL(right_filters.push_back(expr))) { + LOG_WARN("failed to push back column expr", K(ret)); + } + } + return ret; +} + +int ObTransformPredicateMoveAround::check_has_shared_query_ref(ObRawExpr *expr, bool &has) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(expr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("expr is null", K(ret), K(expr)); + } else if (expr->is_query_ref_expr() && expr->get_ref_count() > 1) { + has = true; + } else if (expr->has_flag(CNT_SUB_QUERY)) { + for (int64_t i = 0; OB_SUCC(ret) && !has && i < expr->get_param_count(); ++i) { + if (OB_FAIL(SMART_CALL(check_has_shared_query_ref(expr->get_param_expr(i), has)))) { + LOG_WARN("failed to check has shared query ref", K(ret)); + } + } + } + return ret; +} + // pushdown right table filter in semi condition: // 1. if right table is a basic table, create a generate table. // 2. pushdown the right table filters into the generate table. @@ -2104,8 +2156,7 @@ int ObTransformPredicateMoveAround::pushdown_semi_info_right_filter(ObDMLStmt *s } else if (OB_ISNULL(right_table = stmt->get_table_item_by_id(semi_info->right_table_id_))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected null", K(ret), K(right_table)); - } else if (OB_FAIL(ObTransformUtils::extract_table_exprs(*stmt, semi_info->semi_conditions_, - *right_table, right_filters))) { + } else if (OB_FAIL(extract_semi_right_table_filter(stmt, semi_info, right_filters))) { LOG_WARN("failed to extract table exprs", K(ret)); } else if (right_filters.empty()) { // do nothing @@ -2117,8 +2168,7 @@ int ObTransformPredicateMoveAround::pushdown_semi_info_right_filter(ObDMLStmt *s LOG_WARN("failed to create view with table", K(ret)); } else if (FALSE_IT(right_filters.reuse())) { // do nothing - } else if (OB_FAIL(ObTransformUtils::extract_table_exprs(*stmt, semi_info->semi_conditions_, - *right_table, right_filters))) { + } else if (OB_FAIL(extract_semi_right_table_filter(stmt, semi_info, right_filters))) { LOG_WARN("failed to extract table exprs", K(ret)); } diff --git a/src/sql/rewrite/ob_transform_predicate_move_around.h b/src/sql/rewrite/ob_transform_predicate_move_around.h index d64a1ec87..1f0035150 100644 --- a/src/sql/rewrite/ob_transform_predicate_move_around.h +++ b/src/sql/rewrite/ob_transform_predicate_move_around.h @@ -194,7 +194,12 @@ private: int pushdown_semi_info_right_filter(ObDMLStmt *stmt, ObTransformerCtx *ctx, SemiInfo *semi_info); - + + int check_has_shared_query_ref(ObRawExpr *expr, bool &has); + + int extract_semi_right_table_filter(ObDMLStmt *stmt, + SemiInfo *semi_info, + ObIArray &right_filters); int pushdown_into_table(ObDMLStmt *stmt, TableItem *table, ObIArray &pullup_preds, diff --git a/src/sql/rewrite/ob_transform_where_subquery_pullup.cpp b/src/sql/rewrite/ob_transform_where_subquery_pullup.cpp index 173d159dc..30c9f66ed 100644 --- a/src/sql/rewrite/ob_transform_where_subquery_pullup.cpp +++ b/src/sql/rewrite/ob_transform_where_subquery_pullup.cpp @@ -342,7 +342,6 @@ int ObWhereSubQueryPullup::check_basic_validity(ObDMLStmt *stmt, int ret = OB_SUCCESS; bool &is_valid = trans_param.can_be_transform_; ObSelectStmt *subquery = trans_param.subquery_; - bool check_status = false; if (OB_ISNULL(expr) || OB_ISNULL(stmt) || OB_ISNULL(subquery)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("NULL pointer error", K(ret), K(expr), K(stmt), K(subquery)); -- GitLab