push cte preds when generate plan in cost based rewrite

This commit is contained in:
xianyu-w
2023-09-11 03:10:33 +00:00
committed by ob-robot
parent 73d139ebdb
commit 32bc1e3d3d
6 changed files with 94 additions and 9 deletions

View File

@ -91,7 +91,7 @@ int ObSqlTempTableInfo::collect_temp_tables(ObIAllocator &allocator,
temp_table_infos, query_ctx, do_collect_filter)))) {
LOG_WARN("failed to add all temp tables", K(ret));
} else if (OB_ISNULL(ptr = allocator.alloc(sizeof(ObSqlTempTableInfo)))) {
ret = OB_ERR_UNEXPECTED;
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("get unexpected null", K(ret));
} else {
temp_table_info = new (ptr) ObSqlTempTableInfo();
@ -120,6 +120,45 @@ int ObSqlTempTableInfo::collect_temp_tables(ObIAllocator &allocator,
return ret;
}
int ObSqlTempTableInfo::collect_specified_temp_table(ObIAllocator &allocator,
ObSelectStmt *specified_query,
const ObIArray<ObDMLStmt *> &upper_stmts,
const ObIArray<TableItem *> &table_items,
ObSqlTempTableInfo &temp_table_info)
{
int ret = OB_SUCCESS;
temp_table_info.reset();
if (OB_ISNULL(specified_query) ||
OB_UNLIKELY(upper_stmts.count() != table_items.count())) {
ret = OB_ERR_UNEXPECTED;
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 ++) {
TableItem *table = table_items.at(i);
ObDMLStmt *stmt = upper_stmts.at(i);
if (OB_ISNULL(stmt) || OB_ISNULL(table) ||
OB_UNLIKELY(specified_query != table->ref_query_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected params", K(table_items), K(upper_stmts));
} else {
TableInfo table_info;
table_info.upper_stmt_ = stmt;
table_info.table_item_ = table;
if (OB_FAIL(collect_temp_table_filters(table_info.upper_stmt_,
table_info.table_item_,
table_info.table_filters_,
table_info.filter_conditions_))) {
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));
}
}
}
}
return ret;
}
int ObSqlTempTableInfo::collect_temp_table_filters(ObDMLStmt *stmt,
TableItem *table,
ObIArray<ObRawExpr*> &table_filters,

View File

@ -89,6 +89,14 @@ public:
table_plan_(NULL) {}
virtual ~ObSqlTempTableInfo() {}
void reset() {
temp_table_id_ = OB_INVALID_ID;
table_name_.reset();
table_query_ = NULL;
table_plan_ = NULL;
table_infos_.reset();
}
TO_STRING_KV(K_(temp_table_id),
K_(table_name),
K_(table_infos));
@ -98,6 +106,11 @@ public:
ObIArray<ObSqlTempTableInfo*> &temp_table_infos,
ObQueryCtx *query_ctx,
bool do_collect_filter);
static int collect_specified_temp_table(ObIAllocator &allocator,
ObSelectStmt *specified_query,
const ObIArray<ObDMLStmt *> &upper_stmts,
const ObIArray<TableItem *> &table_items,
ObSqlTempTableInfo &temp_table_info);
static int collect_temp_table_filters(ObDMLStmt *stmt,
TableItem *table,
ObIArray<ObRawExpr*> &table_filters,

View File

@ -90,7 +90,8 @@ int ObOptimizer::optimize(ObDMLStmt &stmt, ObLogPlan *&logical_plan)
int ObOptimizer::get_optimization_cost(ObDMLStmt &stmt,
ObLogPlan *&plan,
double &cost)
double &cost,
ObDMLStmt::TempTableInfo *current_temp_table_)
{
int ret = OB_SUCCESS;
cost = 0.0;
@ -106,6 +107,30 @@ 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<ObSelectStmt *>(&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 {
@ -247,7 +272,8 @@ int ObOptimizer::generate_plan_for_temp_table(ObDMLStmt &stmt)
*/
int ObOptimizer::try_push_down_temp_table_filter(ObSqlTempTableInfo &info,
ObRawExpr *&nonwhere_filter,
ObRawExpr *&where_filter)
ObRawExpr *&where_filter,
ObSelectStmt *temp_table_query)
{
int ret = OB_SUCCESS;
bool have_filter = true;
@ -257,6 +283,7 @@ int ObOptimizer::try_push_down_temp_table_filter(ObSqlTempTableInfo &info,
ObSEArray<const ObDMLStmt *, 4> parent_stmts;
ObSEArray<const ObSelectStmt *, 4> subqueries;
ObSEArray<int64_t, 4> 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_;
@ -269,7 +296,7 @@ int ObOptimizer::try_push_down_temp_table_filter(ObSqlTempTableInfo &info,
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(table->ref_query_))) {
} 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));

View File

@ -182,7 +182,8 @@ namespace sql
virtual int optimize(ObDMLStmt &stmt, ObLogPlan *&plan);
virtual int get_optimization_cost(ObDMLStmt &stmt,
ObLogPlan *&plan,
double &cost);
double &cost,
ObDMLStmt::TempTableInfo *current_temp_table_);
virtual int get_cte_optimization_cost(ObDMLStmt &root_stmt,
ObSelectStmt *cte_query,
ObIArray<ObSelectStmt *> &stmts,
@ -225,7 +226,8 @@ namespace sql
int try_push_down_temp_table_filter(ObSqlTempTableInfo &temp_table_info,
ObRawExpr *&temp_table_filter,
ObRawExpr *&where_filter);
ObRawExpr *&where_filter,
ObSelectStmt *temp_table_query = NULL);
int push_down_temp_table_filter(ObSqlTempTableInfo &temp_table_info,
ObRawExpr *&temp_table_filter);

View File

@ -412,7 +412,7 @@ int ObTransformRule::evaluate_cost(common::ObIArray<ObParentDMLStmt> &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))) {
if (OB_FAIL(optimizer.get_optimization_cost(*root_stmt, plan, plan_cost, current_temp_table_))) {
LOG_WARN("failed to get optimization cost", K(ret));
} else if (NULL == check_ctx) {
// do nothing
@ -788,6 +788,7 @@ int ObTransformRule::transform_temp_tables(ObIArray<ObParentDMLStmt> &parent_stm
}
for(int64_t i = 0; OB_SUCC(ret) && i < temp_table_infos.count(); ++i) {
ObDMLStmt *child_stmt = temp_table_infos.at(i).temp_table_query_;
current_temp_table_ = &temp_table_infos.at(i);
if (OB_ISNULL(child_stmt)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("null child stmt", K(ret));
@ -796,6 +797,7 @@ int ObTransformRule::transform_temp_tables(ObIArray<ObParentDMLStmt> &parent_stm
child_stmt)))) {
LOG_WARN("failed to transform stmt recursively", K(ret));
}
current_temp_table_ = NULL;
//reset ref query
for (int64_t j = 0; OB_SUCC(ret) && j < temp_table_infos.at(i).table_items_.count(); ++j) {
TableItem *temp_table = temp_table_infos.at(i).table_items_.at(j);

View File

@ -274,6 +274,7 @@ public:
transformer_type_(INVALID_TRANSFORM_TYPE),
trans_happened_(false),
cost_based_trans_tried_(false),
current_temp_table_(NULL),
stmt_cost_(-1)
{
}
@ -448,6 +449,7 @@ protected:
uint64_t transformer_type_;
bool trans_happened_;
bool cost_based_trans_tried_;
ObDMLStmt::TempTableInfo *current_temp_table_;
private:
double stmt_cost_;