From a4c7d7dc9f7878f846cac107f6571402bae9f99b Mon Sep 17 00:00:00 2001 From: my0 Date: Wed, 16 Mar 2022 14:57:48 +0800 Subject: [PATCH] Fix sharable exprs rel_ids not correct bug --- src/sql/optimizer/ob_log_plan.cpp | 12 +-- src/sql/resolver/dml/ob_dml_stmt.cpp | 16 +++- src/sql/resolver/dml/ob_dml_stmt.h | 1 + src/sql/resolver/dml/ob_merge_stmt.cpp | 7 ++ .../expr/ob_expr_relation_analyzer.cpp | 33 +++++--- .../resolver/expr/ob_expr_relation_analyzer.h | 6 +- .../rewrite/ob_transform_aggr_subquery.cpp | 11 ++- .../ob_transform_groupby_placement.cpp | 83 +++++++++---------- .../rewrite/ob_transform_groupby_placement.h | 73 +++++++++------- .../rewrite/ob_transform_semi_to_inner.cpp | 9 +- src/sql/rewrite/ob_transform_utils.cpp | 8 +- .../ob_transform_where_subquery_pullup.cpp | 2 + ...est_transformer_stmt_after_together.result | 3 + ...t_transformer_stmt_after_trans_aggr.result | 2 + 14 files changed, 163 insertions(+), 103 deletions(-) diff --git a/src/sql/optimizer/ob_log_plan.cpp b/src/sql/optimizer/ob_log_plan.cpp index 00670be5d..934e0dfae 100644 --- a/src/sql/optimizer/ob_log_plan.cpp +++ b/src/sql/optimizer/ob_log_plan.cpp @@ -1197,12 +1197,13 @@ int ObLogPlan::generate_inner_join_detectors(const ObIArray& table_i if (OB_ISNULL(expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpect null expr", K(ret)); - } else if (!expr->get_relation_ids().is_subset(table_ids)) { - // do nothing + } else if (!expr->get_relation_ids().is_subset(table_ids) || + expr->has_flag(CNT_SUB_QUERY)) { } else if (OB_FAIL(table_filters.push_back(expr))) { LOG_WARN("failed to push back expr", K(ret)); } else if (OB_FAIL(all_table_filters.push_back(expr))) { LOG_WARN("failed to push back expr", K(ret)); + } else { } } if (OB_SUCC(ret)) { @@ -1268,8 +1269,6 @@ int ObLogPlan::generate_inner_join_detectors(const ObIArray& table_i LOG_WARN("failed to generate R-TES", K(ret)); } } - //对于inner join来说,满足交换律,所以不需要区分L_TES、R_TES - //为了方便之后统一applicable算法,L_TES、R_TES都等于SES if (OB_FAIL(ret)) { } else if (OB_FAIL(inner_detector->L_TES_.add_members(table_set))) { LOG_WARN("failed to generate L-TES", K(ret)); @@ -3715,8 +3714,11 @@ int ObLogPlan::extract_params(ObRawExpr*& expr, const int32_t level, ObIArrayextract_info())) { + if (OB_FAIL(ret)) { + } else if (OB_FAIL(expr->extract_info())) { LOG_WARN("failed to extract expr info", K(ret)); + } else if (OB_FAIL(expr->pull_relation_id_and_levels(get_stmt()->get_current_level()))) { + LOG_WARN("pull up rel id and level failed", K(ret)); } return ret; } diff --git a/src/sql/resolver/dml/ob_dml_stmt.cpp b/src/sql/resolver/dml/ob_dml_stmt.cpp index 3cff16e67..6d9d638b9 100644 --- a/src/sql/resolver/dml/ob_dml_stmt.cpp +++ b/src/sql/resolver/dml/ob_dml_stmt.cpp @@ -1773,7 +1773,21 @@ int ObDMLStmt::get_order_exprs(ObIArray& order_exprs) return ret; } -int ObDMLStmt::formalize_stmt(ObSQLSessionInfo* session_info) +int ObDMLStmt::get_order_exprs(ObIArray &order_exprs) const +{ + int ret = OB_SUCCESS; + for (int64_t i = 0; OB_SUCC(ret) && i < order_items_.count(); i++) { + if (OB_ISNULL(order_items_.at(i).expr_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get unexpected null", K(ret)); + } else if (OB_FAIL(order_exprs.push_back(order_items_.at(i).expr_))) { + LOG_WARN("failed to push back exprs", K(ret)); + } else { /*do nothing*/ } + } + return ret; +} + +int ObDMLStmt::formalize_stmt(ObSQLSessionInfo *session_info) { int ret = OB_SUCCESS; ObArray relation_exprs; diff --git a/src/sql/resolver/dml/ob_dml_stmt.h b/src/sql/resolver/dml/ob_dml_stmt.h index b09c445f5..022bd475f 100644 --- a/src/sql/resolver/dml/ob_dml_stmt.h +++ b/src/sql/resolver/dml/ob_dml_stmt.h @@ -877,6 +877,7 @@ public: return order_items_; } int get_order_exprs(common::ObIArray& order_exprs); + int get_order_exprs(common::ObIArray &order_exprs) const; inline const ObViewTableIds& get_view_table_id_store() const { return view_table_id_store_; diff --git a/src/sql/resolver/dml/ob_merge_stmt.cpp b/src/sql/resolver/dml/ob_merge_stmt.cpp index 6f4b3b6bf..a727d4a6b 100644 --- a/src/sql/resolver/dml/ob_merge_stmt.cpp +++ b/src/sql/resolver/dml/ob_merge_stmt.cpp @@ -99,6 +99,11 @@ int ObMergeStmt::assign(const ObMergeStmt& other) int64_t ObMergeStmt::to_string(char* buf, const int64_t buf_len) const { int64_t pos = 0; + int ret = OB_SUCCESS; + ObArray child_stmts; + if (OB_FAIL(ObDMLStmt::get_child_stmts(child_stmts))) { + databuff_printf(buf, buf_len, pos, "ERROR get child stmts failed"); + } else { J_OBJ_START(); J_KV(N_STMT_TYPE, ((int)stmt_type_), @@ -125,9 +130,11 @@ int64_t ObMergeStmt::to_string(char* buf, const int64_t buf_len) const N_PARTITION_EXPR, part_expr_items_, K_(all_table_columns), + K(child_stmts), N_QUERY_CTX, stmt_hint_); J_OBJ_END(); + } return pos; } diff --git a/src/sql/resolver/expr/ob_expr_relation_analyzer.cpp b/src/sql/resolver/expr/ob_expr_relation_analyzer.cpp index 70a029984..4866214ca 100644 --- a/src/sql/resolver/expr/ob_expr_relation_analyzer.cpp +++ b/src/sql/resolver/expr/ob_expr_relation_analyzer.cpp @@ -44,36 +44,43 @@ ObExprRelationAnalyzer::ObExprRelationAnalyzer() : query_exprs_() int ObExprRelationAnalyzer::pull_expr_relation_id_and_levels(ObRawExpr* expr, int32_t cur_stmt_level) { int ret = OB_SUCCESS; + UNUSED(cur_stmt_level); + int64_t expr_level = -1; if (OB_ISNULL(expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("expr is null", K(ret), K(expr)); - } else if (OB_FAIL(visit_expr(*expr, cur_stmt_level))) { + } else if (OB_FAIL(visit_expr(*expr, expr_level))) { LOG_WARN("failed to pull expr relation id and levels", K(ret)); } return ret; } -int ObExprRelationAnalyzer::visit_expr(ObRawExpr& expr, int32_t stmt_level) +int ObExprRelationAnalyzer::visit_expr(ObRawExpr &expr, int64_t &expr_level) { int ret = OB_SUCCESS; // corner case: select min(t1.c1) from t1 group by c2 order by (select avg(t1.c1) from t2); // avg(t1.1) exists in the subquery, but belongs to the main query - int64_t expr_level = expr.is_aggr_expr() ? expr.get_expr_level() : stmt_level; + expr_level = -1; int64_t param_count = expr.get_param_count(); - - if (OB_FAIL(init_expr_info(expr))) { + if (OB_FAIL(init_expr_info(expr, expr_level))) { LOG_WARN("failed into init expr level and relation ids", K(ret)); } for (int64_t i = 0; OB_SUCC(ret) && i < param_count; ++i) { - ObRawExpr* param = NULL; + ObRawExpr *param = NULL; + int64_t param_level = -1; if (OB_ISNULL(param = expr.get_param_expr(i))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("param expr is null", K(ret)); - } else if (OB_FAIL(SMART_CALL(visit_expr(*param, stmt_level)))) { + } else if (OB_FAIL(SMART_CALL(visit_expr(*param, param_level)))) { LOG_WARN("failed to visit param", K(ret)); + } else if (param_level > expr_level) { + expr.get_relation_ids().reuse(); + expr_level = param_level; + } + if (OB_FAIL(ret)) { } 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(expr_level)) { + } else if (expr_level != param_level || expr_level < 0) { // skip } else if (OB_FAIL(expr.get_relation_ids().add_members(param->get_relation_ids()))) { LOG_WARN("failed to add relation ids", K(ret)); @@ -82,7 +89,7 @@ int ObExprRelationAnalyzer::visit_expr(ObRawExpr& expr, int32_t stmt_level) return ret; } -int ObExprRelationAnalyzer::init_expr_info(ObRawExpr& expr) +int ObExprRelationAnalyzer::init_expr_info(ObRawExpr &expr, int64_t &expr_level) { int ret = OB_SUCCESS; expr.get_expr_levels().reuse(); @@ -92,7 +99,7 @@ int ObExprRelationAnalyzer::init_expr_info(ObRawExpr& expr) if (expr.is_column_ref_expr() || expr.is_aggr_expr() || expr.is_set_op_expr() || expr.is_win_func_expr() || T_ORA_ROWSCN == expr.get_expr_type()) { - int32_t expr_level = expr.get_expr_level(); + expr_level = expr.get_expr_level(); if (OB_UNLIKELY(expr_level >= OB_MAX_SUBQUERY_LAYER_NUM || expr_level < 0)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("the subquery nested layers is out of range", K(ret), K(expr_level)); @@ -114,6 +121,7 @@ int ObExprRelationAnalyzer::init_expr_info(ObRawExpr& expr) } } else if (expr.is_query_ref_expr()) { ObQueryRefRawExpr &query = static_cast(expr); + expr_level = query.get_expr_level(); if (OB_FAIL(query_exprs_.push_back(&query))) { LOG_WARN("failed to push back query ref", K(ret)); } else if (OB_UNLIKELY(!query.is_ref_stmt())) { @@ -142,11 +150,12 @@ int ObExprRelationAnalyzer::visit_stmt(ObDMLStmt* stmt) LOG_WARN("failed to get relation exprs", K(ret)); } else { for (int64_t i = 0; OB_SUCC(ret) && i < relation_exprs.count(); ++i) { - ObRawExpr* expr = NULL; + ObRawExpr *expr = NULL; + int64_t expr_level = -1; if (OB_ISNULL(expr = relation_exprs.at(i))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("relation expr is null", K(ret), K(expr)); - } else if (OB_FAIL(visit_expr(*expr, stmt->get_current_level()))) { + } else if (OB_FAIL(visit_expr(*expr, expr_level))) { LOG_WARN("failed to visit expr", K(ret)); } } diff --git a/src/sql/resolver/expr/ob_expr_relation_analyzer.h b/src/sql/resolver/expr/ob_expr_relation_analyzer.h index 396e9c29b..6803a503c 100644 --- a/src/sql/resolver/expr/ob_expr_relation_analyzer.h +++ b/src/sql/resolver/expr/ob_expr_relation_analyzer.h @@ -25,9 +25,9 @@ public: int pull_expr_relation_id_and_levels(ObRawExpr* expr, int32_t cur_stmt_level); private: - int init_expr_info(ObRawExpr& expr); - int visit_expr(ObRawExpr& expr, int32_t stmt_level); - int visit_stmt(ObDMLStmt* stmt); + int init_expr_info(ObRawExpr &expr, int64_t &expr_level); + int visit_expr(ObRawExpr &expr, int64_t &expr_level); + int visit_stmt(ObDMLStmt *stmt); private: // auto_free = false, only used in function stack diff --git a/src/sql/rewrite/ob_transform_aggr_subquery.cpp b/src/sql/rewrite/ob_transform_aggr_subquery.cpp index 02422ed11..982937a37 100644 --- a/src/sql/rewrite/ob_transform_aggr_subquery.cpp +++ b/src/sql/rewrite/ob_transform_aggr_subquery.cpp @@ -1186,9 +1186,6 @@ int ObTransformAggrSubquery::revert_vec_assign_exprs(ObSelectStmt *&child_stmt, return ret; } -/** - * 获取from list中所有基表的primary key - */ int ObTransformAggrSubquery::get_unique_keys(ObDMLStmt &stmt, ObIArray &pkeys, const bool is_first_trans) { int ret = OB_SUCCESS; @@ -1593,7 +1590,13 @@ int ObTransformAggrSubquery::is_valid_group_by(const ObSelectStmt& subquery, boo LOG_WARN("failed to compute const exprs", K(ret)); } for (int64_t i = 0; OB_SUCC(ret) && is_valid && i < subquery.get_group_expr_size(); ++i) { - if (ObOptimizerUtil::is_const_expr(subquery.get_group_exprs().at(i), subquery.get_current_level())) { + bool is_correlated = false; + if (OB_FAIL(ObTransformUtils::is_correlated_expr( + subquery.get_group_exprs().at(i), subquery.get_current_level() - 1, is_correlated))) { + LOG_WARN("judge group expr correlated failed", K(ret)); + } else if (is_correlated) { + is_valid = false; + } else if (ObOptimizerUtil::is_const_expr(subquery.get_group_exprs().at(i), subquery.get_current_level())) { // do nothing } else if (ObOptimizerUtil::find_item(const_exprs, subquery.get_group_exprs().at(i))) { // do nothing diff --git a/src/sql/rewrite/ob_transform_groupby_placement.cpp b/src/sql/rewrite/ob_transform_groupby_placement.cpp index 1437fac4e..623aee189 100644 --- a/src/sql/rewrite/ob_transform_groupby_placement.cpp +++ b/src/sql/rewrite/ob_transform_groupby_placement.cpp @@ -177,20 +177,45 @@ int ObTransformGroupByPlacement::check_groupby_validity(const ObSelectStmt& stmt ObSEArray exprs; if (OB_FAIL(stmt.get_select_exprs(exprs))) { LOG_WARN("failed to get select exprs", K(ret)); - } else if (OB_FAIL(append(exprs, stmt.get_having_exprs()))) { - LOG_WARN("failed to get having exprs", K(ret)); - } else { - for (int64_t i = 0; OB_SUCC(ret) && i < stmt.get_order_item_size(); ++i) { - if (OB_FAIL(exprs.push_back(stmt.get_order_item(i).expr_))) { - LOG_WARN("failed to push back expr", K(ret)); - } + } else if (OB_FAIL(stmt.get_order_exprs(exprs))) { + LOG_WARN("failed to get order exprs", K(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && is_valid && i < exprs.count(); i++) { + if (OB_FAIL(check_group_by_subset(exprs.at(i), stmt.get_group_exprs(), is_valid))) { + LOG_WARN("check group by exprs failed", K(ret)); } - ObSEArray col_exprs; - for (int64_t i = 0; OB_SUCC(ret) && i < exprs.count(); ++i) { - if (OB_FAIL(extract_non_agg_columns(exprs.at(i), stmt.get_current_level(), col_exprs))) { - LOG_WARN("failed to extract non agg columns", K(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && is_valid && i < stmt.get_having_exprs().count(); i++) { + if (OB_FAIL(check_group_by_subset(stmt.get_having_exprs().at(i), stmt.get_group_exprs(), is_valid))) { + LOG_WARN("check group by exprs failed", K(ret)); + } + } + return ret; +} + +int ObTransformGroupByPlacement::check_group_by_subset(ObRawExpr *expr, + const ObIArray &group_exprs, + bool &bret) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(expr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("expr is null", K(ret)); + } else { + bret = true; + int64_t idx = -1; + if (expr->has_flag(IS_AGG) || expr->has_flag(IS_CONST) + || expr->has_flag(IS_EXEC_PARAM) || expr->has_flag(IS_PARAM)) { + //do nothing + } else if (!ObRawExprUtils::find_expr(group_exprs, expr)) { + if (expr->get_param_count() == 0) { + bret = false; } else { - is_valid = ObOptimizerUtil::subset_exprs(col_exprs, stmt.get_group_exprs()); + for (int64_t i = 0; OB_SUCC(ret) && bret && i < expr->get_param_count(); i++) { + if (SMART_CALL(check_group_by_subset(expr->get_param_expr(i), group_exprs, bret))) { + LOG_WARN("check group by subset faield", K(ret)); + } + } } } } @@ -397,39 +422,8 @@ int ObTransformGroupByPlacement::get_null_side_tables( return ret; } -int ObTransformGroupByPlacement::extract_non_agg_columns( - ObRawExpr* expr, const int64_t stmt_level, ObIArray& col_exprs) -{ - int ret = OB_SUCCESS; - bool is_stack_overflow = false; - if (OB_ISNULL(expr)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("expr is null", K(ret)); - } else if (OB_FAIL(check_stack_overflow(is_stack_overflow))) { - LOG_WARN("failed to check stack overflow", K(ret)); - } else if (is_stack_overflow) { - ret = OB_SIZE_OVERFLOW; - LOG_WARN("too deep recursive", K(ret), K(is_stack_overflow)); - } else if (!expr->get_expr_levels().has_member(stmt_level)) { - // do nothing - } else if (expr->is_column_ref_expr()) { - if (OB_FAIL(col_exprs.push_back(expr))) { - LOG_WARN("failed to push back expr", K(ret)); - } - } else if (expr->is_aggr_expr()) { - // do nothing - } else if (expr->has_flag(CNT_COLUMN)) { - for (int64_t i = 0; OB_SUCC(ret) && i < expr->get_param_count(); ++i) { - if (OB_FAIL(SMART_CALL(extract_non_agg_columns(expr->get_param_expr(i), stmt_level, col_exprs)))) { - LOG_WARN("failed to extract non agg columns", K(ret)); - } - } - } - return ret; -} - int ObTransformGroupByPlacement::is_filterable_join( - ObSelectStmt* stmt, ObRawExpr* join_cond, ObIArray& params, bool& is_valid) + ObSelectStmt *stmt, ObRawExpr *join_cond, ObIArray ¶ms, bool &is_valid) { int ret = OB_SUCCESS; is_valid = true; @@ -1603,7 +1597,6 @@ int ObTransformGroupByPlacement::check_groupby_pullup_validity(ObDMLStmt* stmt, // do nothing } else if (OB_FAIL(sub_stmt->has_rand(has_rand))) { LOG_WARN("failed to check stmt has rand func", K(ret)); - // stmt不能包含rand函数 https://work.aone.alibaba-inc.com/issue/35875561 } else if (!(can_pullup = !has_rand)) { // do nothing } else if (OB_FALSE_IT(helper.need_merge_ = sub_stmt->get_stmt_hint().enable_view_merge())) { diff --git a/src/sql/rewrite/ob_transform_groupby_placement.h b/src/sql/rewrite/ob_transform_groupby_placement.h index 551a092e0..85bb0221e 100644 --- a/src/sql/rewrite/ob_transform_groupby_placement.h +++ b/src/sql/rewrite/ob_transform_groupby_placement.h @@ -127,67 +127,80 @@ private: int transform_aggregation_expr(ObDMLStmt& stmt, ObAggFunRawExpr& aggr_expr, ObIArray& eager_aggr_views, ObIArray& table_types, ObRawExpr*& new_aggr_expr); - int convert_aggr_expr(ObDMLStmt* stmt, ObAggFunRawExpr* aggr_expr, ObRawExpr*& output_expr); + int convert_aggr_expr(ObDMLStmt *stmt, ObAggFunRawExpr *aggr_expr, ObRawExpr *&output_expr); int build_case_when( - ObDMLStmt* stmt, ObRawExpr* when_expr, ObRawExpr* value_expr, ObRawExpr* else_expr, ObRawExpr*& case_when); + ObDMLStmt *stmt, ObRawExpr *when_expr, ObRawExpr *value_expr, ObRawExpr *else_expr, ObRawExpr *&case_when); - int has_stmt_column(ObRawExpr* expr, const int64_t stmt_level, bool& has); + int has_stmt_column( + ObRawExpr *expr, const int64_t stmt_level, bool &has); - int get_count_star(ObDMLStmt& stmt, TableItem* table_item, bool is_outer_join_table, ObRawExpr*& count_column); + int get_count_star( + ObDMLStmt &stmt, TableItem *table_item, bool is_outer_join_table, ObRawExpr *&count_column); int get_view_column( - ObDMLStmt& stmt, TableItem* table_item, bool is_outer_join_table, ObRawExpr* aggr_expr, ObRawExpr*& aggr_column); + ObDMLStmt &stmt, TableItem *table_item, bool is_outer_join_table, ObRawExpr *aggr_expr, ObRawExpr *&aggr_column); int wrap_case_when_for_count( - ObDMLStmt* stmt, ObColumnRefRawExpr* view_count, ObRawExpr*& output, bool is_count_star = false); + ObDMLStmt *stmt, ObColumnRefRawExpr *view_count, ObRawExpr *&output, bool is_count_star = false); - int update_joined_table(TableItem* table, const TableItem* old_table, TableItem* new_table, bool& is_found); + int update_joined_table( + TableItem *table, const TableItem *old_table, TableItem *new_table, bool &is_found); - int check_unique(ObSelectStmt* stmt, PushDownParam& param, bool& is_unique); + int check_unique( + ObSelectStmt *stmt, PushDownParam ¶m, bool &is_unique); int add_exprs( - const ObIArray& exprs, int64_t stmt_level, ObSqlBitSet<>& table_set, ObIArray& dest); + const ObIArray &exprs, int64_t stmt_level, ObSqlBitSet<> &table_set, ObIArray &dest); - int extract_non_agg_columns(ObRawExpr* expr, const int64_t stmt_level, ObIArray& col_exprs); - - int merge_tables(ObIArray& params, const ObSqlBitSet<>& table_set); + int merge_tables(ObIArray ¶ms, const ObSqlBitSet<> &table_set); ///////////////////// transform group by pull up ////////////////////////////// int transform_groupby_pull_up( - common::ObIArray& parent_stmts, ObDMLStmt*& stmt, bool& trans_happened); + common::ObIArray &parent_stmts, ObDMLStmt *&stmt, bool &trans_happened); - int check_groupby_pullup_validity(ObDMLStmt* stmt, ObIArray& valid_views); + int check_groupby_pullup_validity( + ObDMLStmt *stmt, ObIArray &valid_views); - int check_groupby_pullup_validity(ObDMLStmt* stmt, TableItem* table, PullupHelper& helper, bool contain_inner_table, - ObSqlBitSet<>& ignore_tables, ObIArray& valid_views, bool& is_valid); + int check_groupby_pullup_validity( + ObDMLStmt *stmt, TableItem *table, PullupHelper &helper, bool contain_inner_table, + ObSqlBitSet<> &ignore_tables, ObIArray &valid_views, bool &is_valid); - int check_ignore_views(ObDMLStmt& stmt, ObIArray& conditions, ObSqlBitSet<>& ignore_tables); + int check_ignore_views( + ObDMLStmt &stmt, ObIArray &conditions, ObSqlBitSet<> &ignore_tables); - int is_contain_aggr_item(ObColumnRefRawExpr* column_expr, TableItem* view_table, bool& is_contain); + int is_contain_aggr_item( + ObColumnRefRawExpr *column_expr, TableItem *view_table, bool &is_contain); - int is_valid_group_stmt(ObSelectStmt* sub_stmt, bool& is_valid_group); + int is_valid_group_stmt( + ObSelectStmt *sub_stmt, bool &is_valid_group); - int check_null_propagate(ObDMLStmt* parent_stmt, ObSelectStmt* child_stmt, PullupHelper& helper, bool& is_valid); + int check_null_propagate( + ObDMLStmt *parent_stmt, ObSelectStmt* child_stmt, PullupHelper &helper, bool &is_valid); - int find_not_null_column(ObDMLStmt& parent_stmt, ObSelectStmt& child_stmt, PullupHelper& helper, - ObIArray& column_exprs, ObRawExpr*& not_null_column); - - int find_not_null_column_with_condition(ObDMLStmt& parent_stmt, ObSelectStmt& child_stmt, PullupHelper& helper, - ObIArray& column_exprs, ObRawExpr*& not_null_column); + int find_not_null_column( + ObDMLStmt &parent_stmt, ObSelectStmt &child_stmt, PullupHelper &helper, + ObIArray &column_exprs, ObRawExpr *¬_null_column); + int find_not_null_column_with_condition( + ObDMLStmt &parent_stmt, ObSelectStmt &child_stmt, PullupHelper &helper, + ObIArray &column_exprs, ObRawExpr *¬_null_column); + int find_null_propagate_column( - ObRawExpr* condition, ObIArray& columns, ObRawExpr*& null_propagate_column, bool& is_valid); + ObRawExpr *condition, ObIArray &columns, ObRawExpr *&null_propagate_column, bool &is_valid); - int do_groupby_pull_up(ObSelectStmt* stmt, PullupHelper& helper); + int do_groupby_pull_up(ObSelectStmt *stmt, PullupHelper &helper); - int get_trans_view(ObDMLStmt* stmt, ObSelectStmt*& view_stmt); + int get_trans_view(ObDMLStmt *stmt, ObSelectStmt *&view_stmt); - int wrap_case_when_if_necessary(ObSelectStmt& child_stmt, PullupHelper& helper, ObIArray& exprs); + int wrap_case_when_if_necessary( + ObSelectStmt &child_stmt, PullupHelper &helper, ObIArray &exprs); - int wrap_case_when(ObSelectStmt& child_stmt, ObRawExpr* not_null_column, ObRawExpr*& expr); + int wrap_case_when( + ObSelectStmt &child_stmt, ObRawExpr *not_null_column, ObRawExpr *&expr); + int check_group_by_subset(ObRawExpr *expr, const ObIArray &group_exprs, bool &bret); private: // help functions int64_t get_count_sum_num(const ObIArray& exprs) diff --git a/src/sql/rewrite/ob_transform_semi_to_inner.cpp b/src/sql/rewrite/ob_transform_semi_to_inner.cpp index ebcdc409c..c673479ce 100644 --- a/src/sql/rewrite/ob_transform_semi_to_inner.cpp +++ b/src/sql/rewrite/ob_transform_semi_to_inner.cpp @@ -189,8 +189,13 @@ int ObTransformSemiToInner::check_basic_validity(ObDMLStmt* root_stmt, ObDMLStmt LOG_WARN("failed to check can add distinct", K(ret)); } else if (!is_valid) { LOG_TRACE("semi right table output can not add distinct"); - } else if (OB_FAIL( - check_join_condition_match_index(root_stmt, stmt, semi_info, semi_info.semi_conditions_, is_valid))) { + } else if (stmt.get_stmt_hint().enable_unnest()) { + //do nothing + need_check_cost = false; + is_valid = true; + } else if (OB_FAIL(check_join_condition_match_index(root_stmt, stmt, semi_info, + semi_info.semi_conditions_, + is_valid))) { LOG_WARN("failed to check join condition match index", K(ret)); } else { need_check_cost = is_valid | need_add_distinct; diff --git a/src/sql/rewrite/ob_transform_utils.cpp b/src/sql/rewrite/ob_transform_utils.cpp index 6acac481b..96d63a146 100644 --- a/src/sql/rewrite/ob_transform_utils.cpp +++ b/src/sql/rewrite/ob_transform_utils.cpp @@ -5332,7 +5332,13 @@ int ObTransformUtils::create_simple_view( LOG_WARN("failed to create stmt", K(ret)); } else if (OB_FAIL(view_stmt->ObDMLStmt::assign(*stmt))) { LOG_WARN("failed to assign stmt", K(ret)); - } else { + } else if (!stmt->is_select_stmt()) { + //do nothing + } else if (OB_FAIL(view_stmt->get_sample_infos().assign(static_cast(stmt)->get_sample_infos()))) { + LOG_WARN("assign array failed", K(ret)); + } + + if (OB_SUCC(ret)) { view_stmt->set_stmt_type(stmt::T_SELECT); // 1. handle table, columns, from // dml_stmt: from table, semi table, joined table diff --git a/src/sql/rewrite/ob_transform_where_subquery_pullup.cpp b/src/sql/rewrite/ob_transform_where_subquery_pullup.cpp index a790b1a4c..d01bce21e 100644 --- a/src/sql/rewrite/ob_transform_where_subquery_pullup.cpp +++ b/src/sql/rewrite/ob_transform_where_subquery_pullup.cpp @@ -2353,6 +2353,8 @@ int ObWhereSubQueryPullup::unnest_single_set_subquery(ObDMLStmt* stmt, ObQueryRe LOG_WARN("failed to merge others to parent stmt", K(ret)); } else if (OB_FAIL(stmt->get_stmt_hint().add_view_merge_hint(&(subquery->get_stmt_hint())))) { LOG_WARN("Failed to add view merge hint", K(ret)); + } else if (OB_FAIL(append(stmt->get_stmt_hint().part_hints_, subquery->get_stmt_hint().part_hints_))) { + LOG_WARN("Failed to append partition hint", K(ret)); } else if (OB_FAIL(stmt->replace_inner_stmt_expr(query_refs, select_list))) { LOG_WARN("failed to replace inner stmt expr", K(ret)); } else if (OB_FAIL(ObOptimizerUtil::remove_item(stmt->get_subquery_exprs(), query_expr))) { diff --git a/unittest/sql/rewrite/result/test_transformer_stmt_after_together.result b/unittest/sql/rewrite/result/test_transformer_stmt_after_together.result index a89734ed3..3738ace8e 100644 --- a/unittest/sql/rewrite/result/test_transformer_stmt_after_together.result +++ b/unittest/sql/rewrite/result/test_transformer_stmt_after_together.result @@ -14869,6 +14869,7 @@ SQL: select * from t1 right join t3 on (t1.c1 = t3.c1) where t3.c1 = (select t2. "CNT_IS_EXPR" ], "rel_id": [ + 1 ], "expr_levels": [ 0 @@ -16316,6 +16317,7 @@ SQL: select * from t3 left join t1 on (t1.c1 = t3.c1) where t3.c1 = (select t2.c "CNT_IS_EXPR" ], "rel_id": [ + 2 ], "expr_levels": [ 0 @@ -18279,6 +18281,7 @@ SQL: select * from t3 left join (t1 inner join t4 on (t1.c2 = t4.c1)) on (t1.c2 "CNT_IS_EXPR" ], "rel_id": [ + 2 ], "expr_levels": [ 0 diff --git a/unittest/sql/rewrite/result/test_transformer_stmt_after_trans_aggr.result b/unittest/sql/rewrite/result/test_transformer_stmt_after_trans_aggr.result index 2a8375c40..99bc2aa1b 100644 --- a/unittest/sql/rewrite/result/test_transformer_stmt_after_trans_aggr.result +++ b/unittest/sql/rewrite/result/test_transformer_stmt_after_trans_aggr.result @@ -86426,6 +86426,7 @@ SQL: SELECT MIN(1) FROM agg_t2 ORDER BY (SELECT AVG(c2) FROM agg_t1); "CNT_AGG" ], "rel_id": [ + 1 ], "expr_levels": [ 0 @@ -96957,6 +96958,7 @@ SQL: select * from (select c1 as col from t1) as L where col = (select max(c1) f "IS_RANGE_COND" ], "rel_id": [ + 1 ], "expr_levels": [ 0