diff --git a/src/sql/ob_sql_temp_table.cpp b/src/sql/ob_sql_temp_table.cpp index 15f41c079e..e1fcb84786 100644 --- a/src/sql/ob_sql_temp_table.cpp +++ b/src/sql/ob_sql_temp_table.cpp @@ -124,7 +124,8 @@ int ObSqlTempTableInfo::collect_specified_temp_table(ObIAllocator &allocator, ObSelectStmt *specified_query, const ObIArray &upper_stmts, const ObIArray &table_items, - ObSqlTempTableInfo &temp_table_info) + ObSqlTempTableInfo &temp_table_info, + bool &all_has_filter) { int ret = OB_SUCCESS; temp_table_info.reset(); @@ -134,7 +135,8 @@ int ObSqlTempTableInfo::collect_specified_temp_table(ObIAllocator &allocator, LOG_WARN("unexpected param", K(specified_query), K(upper_stmts), K(table_items));; } else { temp_table_info.table_query_ = specified_query; - for (int64_t i = 0; OB_SUCC(ret) && i < upper_stmts.count(); i ++) { + all_has_filter = upper_stmts.count() > 0; + for (int64_t i = 0; OB_SUCC(ret) && all_has_filter && i < upper_stmts.count(); i ++) { TableItem *table = table_items.at(i); ObDMLStmt *stmt = upper_stmts.at(i); if (OB_ISNULL(stmt) || OB_ISNULL(table) || @@ -152,6 +154,8 @@ int ObSqlTempTableInfo::collect_specified_temp_table(ObIAllocator &allocator, LOG_WARN("failed to collect temp table info", K(ret)); } else if (OB_FAIL(temp_table_info.table_infos_.push_back(table_info))) { LOG_WARN("failed to push back table info", K(ret)); + } else { + all_has_filter &= !table_info.table_filters_.empty(); } } } diff --git a/src/sql/ob_sql_temp_table.h b/src/sql/ob_sql_temp_table.h index 0bad1e7eda..97babfe119 100644 --- a/src/sql/ob_sql_temp_table.h +++ b/src/sql/ob_sql_temp_table.h @@ -110,7 +110,8 @@ public: ObSelectStmt *specified_query, const ObIArray &upper_stmts, const ObIArray &table_items, - ObSqlTempTableInfo &temp_table_info); + ObSqlTempTableInfo &temp_table_info, + bool &all_has_filter); static int collect_temp_table_filters(ObDMLStmt *stmt, TableItem *table, ObIArray &table_filters, diff --git a/src/sql/optimizer/ob_optimizer.cpp b/src/sql/optimizer/ob_optimizer.cpp index ac34ee56f8..b2bc62f65d 100644 --- a/src/sql/optimizer/ob_optimizer.cpp +++ b/src/sql/optimizer/ob_optimizer.cpp @@ -90,8 +90,7 @@ int ObOptimizer::optimize(ObDMLStmt &stmt, ObLogPlan *&logical_plan) int ObOptimizer::get_optimization_cost(ObDMLStmt &stmt, ObLogPlan *&plan, - double &cost, - ObDMLStmt::TempTableInfo *current_temp_table_) + double &cost) { int ret = OB_SUCCESS; cost = 0.0; @@ -107,30 +106,6 @@ int ObOptimizer::get_optimization_cost(ObDMLStmt &stmt, LOG_WARN("failed to init env info", K(ret)); } else if (OB_FAIL(generate_plan_for_temp_table(stmt))) { LOG_WARN("failed to generate plan for temp table", K(ret)); - } else if (NULL != current_temp_table_) { - ObSqlTempTableInfo temp_table_info; - ObRawExpr *temp_table_nonwhere_filter = NULL; - ObRawExpr *temp_table_where_filter = NULL; - if (OB_UNLIKELY(!stmt.is_select_stmt())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("temp table query should be select stmt", K(stmt)); - } else if (OB_FAIL(ObSqlTempTableInfo::collect_specified_temp_table(ctx_.get_allocator(), - current_temp_table_->temp_table_query_, - current_temp_table_->upper_stmts_, - current_temp_table_->table_items_, - temp_table_info))) { - LOG_WARN("failed to collect_specified_temp_table", K(ret)); - } else if (OB_FAIL(try_push_down_temp_table_filter(temp_table_info, - temp_table_nonwhere_filter, - temp_table_where_filter, - static_cast(&stmt)))) { - LOG_WARN("failed to push down filter for temp table", K(ret)); - } else if (NULL != temp_table_where_filter && - OB_FAIL(plan->get_pushdown_filters().push_back(temp_table_where_filter))) { - LOG_WARN("failed to push down filter", K(ret)); - } - } - if (OB_FAIL(ret)) { } else if (OB_FAIL(plan->generate_raw_plan())) { LOG_WARN("failed to perform optimization", K(ret)); } else { @@ -231,10 +206,16 @@ int ObOptimizer::generate_plan_for_temp_table(ObDMLStmt &stmt) } else { OPT_TRACE_TITLE("begin generate plan for temp table ", temp_table_info->table_name_); } + /** + * In table scan op, filters are calculated before `limit`. + * So, we can not push filter into temp table which contain `limit`. + */ if (OB_FAIL(ret)) { - } else if (OB_FAIL(try_push_down_temp_table_filter(*temp_table_info, - temp_table_nonwhere_filter, - temp_table_where_filter))) { + } else if (!ref_query->has_limit() && + OB_FAIL(ObOptimizerUtil::try_push_down_temp_table_filter(ctx_, + *temp_table_info, + temp_table_nonwhere_filter, + temp_table_where_filter))) { LOG_WARN("failed to push down filter for temp table", K(ret)); } else if (NULL != temp_table_where_filter && OB_FAIL(temp_plan->get_pushdown_filters().push_back(temp_table_where_filter))) { @@ -246,10 +227,15 @@ int ObOptimizer::generate_plan_for_temp_table(ObDMLStmt &stmt) } else if (OB_ISNULL(temp_op)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected null", K(ret)); - } else if (NULL != temp_table_nonwhere_filter && - OB_FAIL(temp_op->get_filter_exprs().push_back(temp_table_nonwhere_filter))) { - LOG_WARN("failed to push back", K(ret)); } else { + if (NULL != temp_table_nonwhere_filter) { + ObSEArray expr_array; + if (OB_FAIL(expr_array.push_back(temp_table_nonwhere_filter))) { + LOG_WARN("failed to push back"); + } else if (OB_FAIL(temp_plan->candi_allocate_filter(expr_array))) { + LOG_WARN("failed to push back", K(ret)); + } + } temp_table_info->table_plan_ = temp_op; OPT_TRACE_TITLE("end generate plan for temp table ", temp_table_info->table_name_); } @@ -258,137 +244,6 @@ int ObOptimizer::generate_plan_for_temp_table(ObDMLStmt &stmt) return ret; } -/** - * If every appearance of cte is accompanied by some filter, - * We can combine these filters to reduce the data materialized by cte. - * We try to push these filters to where condition. - * If all filters can be push to where condition, nonwhere_filter will be NULL. - * Otherwise, we might have both where_filter and nonwhere_filter. - * e.g. - * with cte as (select a,count(*) as cnt from t1 group by a) - * select * from cte where a = 1 and cnt = 1 union all select * from cte where a = 2 and cnt = 2; - * nonwhere_filter : (a = 1 and cnt = 1) or (a = 2 and cnt = 2) - * where_filter : (a = 1) or (a = 2) -*/ -int ObOptimizer::try_push_down_temp_table_filter(ObSqlTempTableInfo &info, - ObRawExpr *&nonwhere_filter, - ObRawExpr *&where_filter, - ObSelectStmt *temp_table_query) -{ - int ret = OB_SUCCESS; - bool have_filter = true; - nonwhere_filter = NULL; - where_filter = NULL; - ObSEArray *, 4> temp_table_filters; - ObSEArray parent_stmts; - ObSEArray subqueries; - ObSEArray table_ids; - temp_table_query = (temp_table_query == NULL) ? info.table_query_ : temp_table_query; - for (int64_t i = 0; OB_SUCC(ret) && have_filter && i < info.table_infos_.count(); ++i) { - TableItem *table = info.table_infos_.at(i).table_item_; - ObDMLStmt *stmt = info.table_infos_.at(i).upper_stmt_; - if (OB_ISNULL(table) || OB_ISNULL(stmt)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected null", K(ret)); - } else if (info.table_infos_.at(i).table_filters_.empty()) { - have_filter = false; - } else if (OB_FAIL(temp_table_filters.push_back(&info.table_infos_.at(i).table_filters_))) { - LOG_WARN("failed to push back", K(ret)); - } else if (OB_FAIL(parent_stmts.push_back(stmt))) { - LOG_WARN("failed to push back", K(ret)); - } else if (OB_FAIL(subqueries.push_back(temp_table_query))) { - LOG_WARN("failed to push back", K(ret)); - } else if (OB_FAIL(table_ids.push_back(table->table_id_))) { - LOG_WARN("failed to push back", K(ret)); - } - } - if (OB_SUCC(ret) && have_filter) { - OPT_TRACE("pushdown filter into temp table:", info.table_query_); - bool can_push_all = false; - if (OB_FAIL(ObOptimizerUtil::split_or_filter_into_subquery(parent_stmts, - subqueries, - table_ids, - temp_table_filters, - ctx_, - where_filter, - can_push_all, - /*check_match_index = */false))) { - LOG_WARN("failed to split filter", K(ret)); - } else if (can_push_all) { - // do nothing - } else if (OB_FAIL(push_down_temp_table_filter(info, nonwhere_filter))) { - LOG_WARN("failed to push down remain temp table filter", K(ret)); - } - if (NULL != where_filter) { - OPT_TRACE("succeed to pushdown filter to where:", where_filter); - } - if (NULL != nonwhere_filter) { - OPT_TRACE("succeed to pushdown filter into the top of temp table:", nonwhere_filter); - } - } - return ret; -} - -int ObOptimizer::push_down_temp_table_filter(ObSqlTempTableInfo &info, - ObRawExpr *&temp_table_filter) -{ - int ret = OB_SUCCESS; - ObRawExprFactory &expr_factory = ctx_.get_expr_factory(); - ObSQLSessionInfo *session_info = NULL; - temp_table_filter = NULL; - ObSEArray and_exprs; - ObRawExpr *or_expr = NULL; - bool have_temp_table_filter = true; - if (OB_ISNULL(session_info = ctx_.get_session_info()) || - OB_ISNULL(info.table_query_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpect null param", K(session_info), K(ret)); - } - for (int64_t i = 0; OB_SUCC(ret) && have_temp_table_filter && i < info.table_infos_.count(); ++i) { - have_temp_table_filter &= !info.table_infos_.at(i).table_filters_.empty(); - } - for (int64_t i = 0; OB_SUCC(ret) && have_temp_table_filter && i < info.table_infos_.count(); ++i) { - ObDMLStmt *upper_stmt = info.table_infos_.at(i).upper_stmt_; - TableItem *table = info.table_infos_.at(i).table_item_; - ObIArray &table_filters = info.table_infos_.at(i).table_filters_; - ObSEArray rename_exprs; - ObRawExpr *and_expr = NULL; - if (table_filters.empty() || OB_ISNULL(upper_stmt) || - OB_ISNULL(table)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpect null table info", K(ret)); - } else if (OB_FAIL(ObOptimizerUtil::rename_pushdown_filter(*upper_stmt, - *info.table_query_, - table->table_id_, - session_info, - expr_factory, - table_filters, - rename_exprs))) { - LOG_WARN("failed to rename push down preds", K(ret)); - } else if (OB_FAIL(ObRawExprUtils::build_and_expr(expr_factory, - rename_exprs, - and_expr))) { - LOG_WARN("failed to build and expr", K(ret)); - } - if (OB_SUCC(ret) && OB_FAIL(and_exprs.push_back(and_expr))) { - LOG_WARN("failed to push back expr", K(ret)); - } - } - if (OB_FAIL(ret) || !have_temp_table_filter) { - } else if (OB_FAIL(ObRawExprUtils::build_or_exprs(expr_factory, - and_exprs, - or_expr))) { - LOG_WARN("failed to build or expr", K(ret)); - } else if (OB_FAIL(or_expr->formalize(session_info))) { - LOG_WARN("failed to formalize expr", K(ret)); - } else if (OB_FAIL(or_expr->pull_relation_id())) { - LOG_WARN("failed to pull relation id and levels", K(ret)); - } else { - temp_table_filter = or_expr; - } - return ret; -} - bool ObOptimizer::exists_temp_table(const ObIArray &temp_table_infos, const ObSelectStmt *table_query) const { diff --git a/src/sql/optimizer/ob_optimizer.h b/src/sql/optimizer/ob_optimizer.h index cc72399249..939d34bab2 100644 --- a/src/sql/optimizer/ob_optimizer.h +++ b/src/sql/optimizer/ob_optimizer.h @@ -182,8 +182,7 @@ namespace sql virtual int optimize(ObDMLStmt &stmt, ObLogPlan *&plan); virtual int get_optimization_cost(ObDMLStmt &stmt, ObLogPlan *&plan, - double &cost, - ObDMLStmt::TempTableInfo *current_temp_table_); + double &cost); virtual int get_cte_optimization_cost(ObDMLStmt &root_stmt, ObSelectStmt *cte_query, ObIArray &stmts, @@ -224,13 +223,6 @@ namespace sql int check_force_default_stat(); int calc_link_stmt_count(const ObDMLStmt &stmt, int64_t &count); - int try_push_down_temp_table_filter(ObSqlTempTableInfo &temp_table_info, - ObRawExpr *&temp_table_filter, - ObRawExpr *&where_filter, - ObSelectStmt *temp_table_query = NULL); - int push_down_temp_table_filter(ObSqlTempTableInfo &temp_table_info, - ObRawExpr *&temp_table_filter); - private: ObOptimizerContext &ctx_; DISALLOW_COPY_AND_ASSIGN(ObOptimizer); diff --git a/src/sql/optimizer/ob_optimizer_util.cpp b/src/sql/optimizer/ob_optimizer_util.cpp index 8dcbb2fbf1..42681037c0 100644 --- a/src/sql/optimizer/ob_optimizer_util.cpp +++ b/src/sql/optimizer/ob_optimizer_util.cpp @@ -8923,7 +8923,7 @@ int ObOptimizerUtil::split_or_filter_into_subquery(const ObDMLStmt &parent_stmt, check_match_index))) { LOG_WARN("failed to split or fitler", K(ret)); } - for (int64_t i = 0; OB_SUCC(ret) && i < or_filter_params.count(); i ++) { + for (int64_t i = 0; i < or_filter_params.count(); i ++) { if (OB_NOT_NULL(or_filter_params.at(i))) { or_filter_params.at(i)->~ObIArray(); } @@ -9025,6 +9025,140 @@ int ObOptimizerUtil::split_or_filter_into_subquery(ObIArray & return ret; } +/** + * If every appearance of cte is accompanied by some filter, + * We can combine these filters to reduce the data materialized by cte. + * We try to push these filters to where condition. + * If all filters can be push to where condition, nonwhere_filter will be NULL. + * Otherwise, we might have both where_filter and nonwhere_filter. + * e.g. + * with cte as (select a,count(*) as cnt from t1 group by a) + * select * from cte where a = 1 and cnt = 1 union all select * from cte where a = 2 and cnt = 2; + * nonwhere_filter : (a = 1 and cnt = 1) or (a = 2 and cnt = 2) + * where_filter : (a = 1) or (a = 2) +*/ +int ObOptimizerUtil::try_push_down_temp_table_filter(ObOptimizerContext &opt_ctx, + ObSqlTempTableInfo &info, + ObRawExpr *&nonwhere_filter, + ObRawExpr *&where_filter) +{ + int ret = OB_SUCCESS; + bool have_filter = true; + nonwhere_filter = NULL; + where_filter = NULL; + ObSEArray *, 4> temp_table_filters; + ObSEArray parent_stmts; + ObSEArray subqueries; + ObSEArray table_ids; + ObSelectStmt *temp_table_query = info.table_query_; + for (int64_t i = 0; OB_SUCC(ret) && have_filter && i < info.table_infos_.count(); ++i) { + TableItem *table = info.table_infos_.at(i).table_item_; + ObDMLStmt *stmt = info.table_infos_.at(i).upper_stmt_; + if (OB_ISNULL(table) || OB_ISNULL(stmt)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null", K(ret)); + } else if (info.table_infos_.at(i).table_filters_.empty()) { + have_filter = false; + } else if (OB_FAIL(temp_table_filters.push_back(&info.table_infos_.at(i).table_filters_))) { + LOG_WARN("failed to push back", K(ret)); + } else if (OB_FAIL(parent_stmts.push_back(stmt))) { + LOG_WARN("failed to push back", K(ret)); + } else if (OB_FAIL(subqueries.push_back(temp_table_query))) { + LOG_WARN("failed to push back", K(ret)); + } else if (OB_FAIL(table_ids.push_back(table->table_id_))) { + LOG_WARN("failed to push back", K(ret)); + } + } + + if (OB_SUCC(ret) && have_filter) { + OPT_TRACE("pushdown filter into temp table:", info.table_query_); + bool can_push_all = false; + if (OB_FAIL(ObOptimizerUtil::split_or_filter_into_subquery(parent_stmts, + subqueries, + table_ids, + temp_table_filters, + opt_ctx, + where_filter, + can_push_all, + /*check_match_index = */false))) { + LOG_WARN("failed to split filter", K(ret)); + } else if (can_push_all) { + // do nothing + } else if (OB_FAIL(push_down_temp_table_filter(opt_ctx.get_expr_factory(), opt_ctx.get_session_info(), + info, nonwhere_filter))) { + LOG_WARN("failed to push down remain temp table filter", K(ret)); + } + if (NULL != where_filter) { + OPT_TRACE("succeed to pushdown filter to where:", where_filter); + } + if (NULL != nonwhere_filter) { + OPT_TRACE("succeed to pushdown filter into the top of temp table:", nonwhere_filter); + } + } + return ret; +} + +int ObOptimizerUtil::push_down_temp_table_filter(ObRawExprFactory &expr_factory, + ObSQLSessionInfo *session_info, + ObSqlTempTableInfo &info, + ObRawExpr *&temp_table_filter, + ObSelectStmt *temp_table_query) +{ + int ret = OB_SUCCESS; + temp_table_filter = NULL; + ObSEArray and_exprs; + ObRawExpr *or_expr = NULL; + bool have_temp_table_filter = true; + temp_table_query = (NULL == temp_table_query) ? info.table_query_ : temp_table_query; + if (OB_ISNULL(temp_table_query)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpect null param", K(info), K(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && have_temp_table_filter && i < info.table_infos_.count(); ++i) { + have_temp_table_filter &= !info.table_infos_.at(i).table_filters_.empty(); + } + for (int64_t i = 0; OB_SUCC(ret) && have_temp_table_filter && i < info.table_infos_.count(); ++i) { + ObDMLStmt *upper_stmt = info.table_infos_.at(i).upper_stmt_; + TableItem *table = info.table_infos_.at(i).table_item_; + ObIArray &table_filters = info.table_infos_.at(i).table_filters_; + ObSEArray rename_exprs; + ObRawExpr *and_expr = NULL; + if (table_filters.empty() || OB_ISNULL(upper_stmt) || + OB_ISNULL(table)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpect null table info", K(ret)); + } else if (OB_FAIL(ObOptimizerUtil::rename_pushdown_filter(*upper_stmt, + *temp_table_query, + table->table_id_, + session_info, + expr_factory, + table_filters, + rename_exprs))) { + LOG_WARN("failed to rename push down preds", K(ret)); + } else if (OB_FAIL(ObRawExprUtils::build_and_expr(expr_factory, + rename_exprs, + and_expr))) { + LOG_WARN("failed to build and expr", K(ret)); + } + if (OB_SUCC(ret) && OB_FAIL(and_exprs.push_back(and_expr))) { + LOG_WARN("failed to push back expr", K(ret)); + } + } + if (OB_FAIL(ret) || !have_temp_table_filter) { + } else if (OB_FAIL(ObRawExprUtils::build_or_exprs(expr_factory, + and_exprs, + or_expr))) { + LOG_WARN("failed to build or expr", K(ret)); + } else if (OB_FAIL(or_expr->formalize(session_info))) { + LOG_WARN("failed to formalize expr", K(ret)); + } else if (OB_FAIL(or_expr->pull_relation_id())) { + LOG_WARN("failed to pull relation id and levels", K(ret)); + } else { + temp_table_filter = or_expr; + } + return ret; +} + bool ObOptimizerUtil::find_superset(const ObRelIds &rel_ids, const ObIArray &single_table_ids) { diff --git a/src/sql/optimizer/ob_optimizer_util.h b/src/sql/optimizer/ob_optimizer_util.h index cbd6ffbcc3..7665ca2f78 100644 --- a/src/sql/optimizer/ob_optimizer_util.h +++ b/src/sql/optimizer/ob_optimizer_util.h @@ -1497,6 +1497,16 @@ public: static bool find_superset(const ObRelIds &rel_ids, const ObIArray &single_table_ids); + + static int try_push_down_temp_table_filter(ObOptimizerContext &opt_ctx, + ObSqlTempTableInfo &temp_table_info, + ObRawExpr *&temp_table_filter, + ObRawExpr *&where_filter); + static int push_down_temp_table_filter(ObRawExprFactory &expr_factory, + ObSQLSessionInfo *session_info, + ObSqlTempTableInfo &temp_table_info, + ObRawExpr *&temp_table_filter, + ObSelectStmt *temp_table_query = NULL); private: //disallow construct ObOptimizerUtil(); diff --git a/src/sql/rewrite/ob_transform_rule.cpp b/src/sql/rewrite/ob_transform_rule.cpp index 2cd031e2d1..0827317c47 100644 --- a/src/sql/rewrite/ob_transform_rule.cpp +++ b/src/sql/rewrite/ob_transform_rule.cpp @@ -412,7 +412,7 @@ int ObTransformRule::evaluate_cost(common::ObIArray &parent_stm //optctx.set_only_ds_basic_stat(true); ObOptimizer optimizer(optctx); ObLogPlan *plan = NULL; - if (OB_FAIL(optimizer.get_optimization_cost(*root_stmt, plan, plan_cost, current_temp_table_))) { + if (OB_FAIL(optimizer.get_optimization_cost(*root_stmt, plan, plan_cost))) { LOG_WARN("failed to get optimization cost", K(ret)); } else if (NULL == check_ctx) { // do nothing @@ -435,6 +435,82 @@ int ObTransformRule::evaluate_cost(common::ObIArray &parent_stm return ret; } + +int ObTransformRule::prepare_root_stmt_with_temp_table_filter(ObDMLStmt &root_stmt, ObDMLStmt *&root_stmt_with_filter) +{ + int ret = OB_SUCCESS; + ObSqlTempTableInfo temp_table_info; + ObRawExpr *temp_table_filter = NULL; + ObSelectStmt *sel_root_stmt = static_cast(&root_stmt); + bool have_temp_table_filter = false; + if (NULL == current_temp_table_) { + root_stmt_with_filter = &root_stmt; + } else if (OB_UNLIKELY(!root_stmt.is_select_stmt()) || OB_ISNULL(ctx_) || OB_ISNULL(ctx_->allocator_) || + OB_ISNULL(ctx_->stmt_factory_) || OB_ISNULL(ctx_->session_info_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected params", K(root_stmt)); + } else if (OB_FAIL(ObSqlTempTableInfo::collect_specified_temp_table(*ctx_->allocator_, + current_temp_table_->temp_table_query_, + current_temp_table_->upper_stmts_, + current_temp_table_->table_items_, + temp_table_info, + have_temp_table_filter))) { + LOG_WARN("failed to collect_specified_temp_table", K(ret)); + } else if (have_temp_table_filter) { + TableItem *new_table_item = NULL; + ObSEArray column_exprs; + root_stmt_with_filter = NULL; + ObSelectStmt *sel_stmt_with_filter = NULL; + if (OB_FAIL(ctx_->stmt_factory_->create_stmt(sel_stmt_with_filter))) { + LOG_WARN("failed to create stmt", K(ret)); + } else if (OB_ISNULL(sel_stmt_with_filter)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get unexpected null", K(ret)); + } else if (OB_FALSE_IT(sel_stmt_with_filter->set_query_ctx(sel_root_stmt->get_query_ctx()))) { + } else if (OB_FAIL(sel_stmt_with_filter->adjust_statement_id(ctx_->allocator_, + ctx_->src_qb_name_, + ctx_->src_hash_val_))) { + LOG_WARN("failed to adjust statement id", K(ret)); + } else if (OB_FAIL(ObTransformUtils::add_new_table_item(ctx_, sel_stmt_with_filter, sel_root_stmt, new_table_item))) { + LOG_WARN("failed to add new table item", K(ret)); + } else if (OB_ISNULL(new_table_item)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get unexpected null", K(ret)); + } else if (OB_FAIL(sel_stmt_with_filter->add_from_item(new_table_item->table_id_, false))) { + LOG_WARN("failed to add from item", K(ret)); + } else if (OB_FAIL(sel_stmt_with_filter->rebuild_tables_hash())) { + LOG_WARN("failed to rebuid table hash", K(ret)); + } else if (OB_FAIL(ObTransformUtils::create_columns_for_view(ctx_, + *new_table_item, + sel_stmt_with_filter, + column_exprs))) { + LOG_WARN("failed to create column items", K(ret)); + } else if (OB_FAIL(ObTransformUtils::create_select_item(*ctx_->allocator_, + column_exprs, + sel_stmt_with_filter))) { + LOG_WARN("failed to create select item", K(ret)); + } else if (OB_FAIL(sel_stmt_with_filter->formalize_stmt(ctx_->session_info_))) { + LOG_WARN("failed to formalize stmt", K(ret)); + } else if (OB_FAIL(ObOptimizerUtil::push_down_temp_table_filter(*ctx_->expr_factory_, + ctx_->session_info_, + temp_table_info, + temp_table_filter, + sel_stmt_with_filter))) { + LOG_WARN("failed to push down filter for temp table", K(ret)); + } else if (OB_ISNULL(temp_table_filter)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("filter is null", K(temp_table_info)); + } else if (OB_FAIL(sel_stmt_with_filter->add_condition_expr(temp_table_filter))) { + LOG_WARN("failed to add condition expr", K(ret)); + } else { + root_stmt_with_filter = sel_stmt_with_filter; + } + } else { + root_stmt_with_filter = &root_stmt; + } + return ret; +} + int ObTransformRule::prepare_eval_cost_stmt(common::ObIArray &parent_stmts, ObDMLStmt &stmt, ObDMLStmt *&copied_stmt, @@ -444,6 +520,7 @@ int ObTransformRule::prepare_eval_cost_stmt(common::ObIArray &p ObSEArray old_temp_table_stmts; ObSEArray new_temp_table_stmts; ObDMLStmt *root_stmt = NULL; + ObDMLStmt *root_stmt_with_filter = NULL; ObDMLStmt *copied_trans_stmt = NULL; ObString cur_qb_name; ObDMLStmt *orig_stmt = NULL; @@ -453,8 +530,10 @@ int ObTransformRule::prepare_eval_cost_stmt(common::ObIArray &p LOG_WARN("params are invalid", K(ret), K(ctx_), K(stmt.get_query_ctx())); } else if (OB_FAIL(adjust_transformed_stmt(parent_stmts, &stmt, orig_stmt, root_stmt))) { LOG_WARN("failed to adjust transformed stmt", K(ret)); + } else if (OB_FAIL(prepare_root_stmt_with_temp_table_filter(*root_stmt, root_stmt_with_filter))) { + LOG_WARN("failed to prepare root stmt with temp table filter", K(ret)); } else if (OB_FAIL(ObTransformUtils::deep_copy_stmt(*ctx_->stmt_factory_, *ctx_->expr_factory_, - root_stmt, copied_stmt))) { + root_stmt_with_filter, copied_stmt))) { LOG_WARN("failed to deep copy stmt", K(ret)); } else if (OB_FAIL(deep_copy_temp_table(*copied_stmt, *ctx_->stmt_factory_, diff --git a/src/sql/rewrite/ob_transform_rule.h b/src/sql/rewrite/ob_transform_rule.h index 8ca1284d57..0933e78584 100644 --- a/src/sql/rewrite/ob_transform_rule.h +++ b/src/sql/rewrite/ob_transform_rule.h @@ -420,6 +420,8 @@ private: ObDMLStmt *&copied_stmt, bool is_trans_stmt); + int prepare_root_stmt_with_temp_table_filter(ObDMLStmt &root_stmt, ObDMLStmt *&root_stmt_with_filter); + virtual int is_expected_plan(ObLogPlan *plan, void *check_ctx, bool is_trans_plan,