fix outline unstable problems

This commit is contained in:
jingtaoye35
2023-08-31 07:40:41 +00:00
committed by ob-robot
parent 82818ce743
commit cead89b3b8
3 changed files with 74 additions and 61 deletions

View File

@ -45,6 +45,22 @@ int ObTransformPredicateMoveAround::transform_one_stmt(
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
UNUSED(parent_stmts); UNUSED(parent_stmts);
if (OB_FAIL(do_transform_predicate_move_around(stmt, trans_happened))) {
LOG_WARN("failed to do transform_predicate_move_around", K(ret));
} else if (transed_stmts_.empty() || !trans_happened) {
// transform not happened actually
} else if (OB_FAIL(adjust_transed_stmts())) {
LOG_WARN("sort sort transed stmts failed", K(ret));
} else if (OB_FAIL(add_transform_hint(*stmt, &transed_stmts_))) {
LOG_WARN("add transform hint failed", K(ret));
}
transed_stmts_.reuse();
return ret;
}
int ObTransformPredicateMoveAround::do_transform_predicate_move_around(ObDMLStmt *&stmt, bool &trans_happened)
{
int ret = OB_SUCCESS;
bool is_happened = false; bool is_happened = false;
if (OB_ISNULL(stmt)) { if (OB_ISNULL(stmt)) {
ret = OB_ERR_UNEXPECTED; ret = OB_ERR_UNEXPECTED;
@ -76,14 +92,6 @@ int ObTransformPredicateMoveAround::transform_one_stmt(
temp_table_infos_.at(i)->~ObSqlTempTableInfo(); temp_table_infos_.at(i)->~ObSqlTempTableInfo();
} }
} }
if (OB_FAIL(ret) || transed_stmts_.empty() || !trans_happened) {
// transform not happened actually
} else if (OB_FAIL(adjust_transed_stmts())) {
LOG_WARN("sort sort transed stmts failed", K(ret));
} else if (OB_FAIL(add_transform_hint(*stmt, &transed_stmts_))) {
LOG_WARN("add transform hint failed", K(ret));
}
transed_stmts_.reuse();
temp_table_infos_.reuse(); temp_table_infos_.reuse();
return ret; return ret;
} }
@ -253,18 +261,24 @@ int ObTransformPredicateMoveAround::check_outline_valid_to_transform(const ObDML
return ret; return ret;
} }
int ObTransformPredicateMoveAround::transform_one_stmt_with_outline(
int ObTransformPredicateMoveAround::transform_one_stmt_with_outline(ObIArray<ObParentDMLStmt> &parent_stmts, ObIArray<ObParentDMLStmt> &parent_stmts,
ObDMLStmt *&stmt, ObDMLStmt *&stmt,
bool &trans_happened) { bool &trans_happened) {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
if (OB_FAIL(transform_one_stmt(parent_stmts, stmt, trans_happened))) { UNUSED(parent_stmts);
LOG_WARN("transform one stmt with outline failed", K(ret)); if (OB_FAIL(do_transform_predicate_move_around(stmt, trans_happened))) {
} else if (!trans_happened) { LOG_WARN("failed to do transform_predicate_move_around", K(ret));
LOG_DEBUG("outline data trans not happened"); } else if (transed_stmts_.empty() || !trans_happened) {
LOG_TRACE("outline data trans not happened");
} else if (OB_FAIL(adjust_transed_stmts())) {
LOG_WARN("sort sort transed stmts failed", K(ret));
} else if (OB_FAIL(add_transform_hint(*stmt, &transed_stmts_))) {
LOG_WARN("add transform hint failed", K(ret));
} else { } else {
ctx_->trans_list_loc_ += applied_hints_.count(); ctx_->trans_list_loc_ += transed_stmts_.count();
} }
transed_stmts_.reuse();
return ret; return ret;
} }
@ -1295,7 +1309,7 @@ int ObTransformPredicateMoveAround::pushdown_predicates(
SMART_VAR(PredsArray, all_old_preds) { SMART_VAR(PredsArray, all_old_preds) {
ObIArray<FromItem> &from_items = stmt->get_from_items(); ObIArray<FromItem> &from_items = stmt->get_from_items();
ObIArray<SemiInfo*> &semi_infos = stmt->get_semi_infos(); ObIArray<SemiInfo*> &semi_infos = stmt->get_semi_infos();
if ((!is_happened || !real_happened_) && OB_FAIL(store_all_preds(*stmt, all_old_preds))) { if (OB_FAIL(store_all_preds(*stmt, all_old_preds))) {
LOG_WARN("failed to store all preds", K(ret)); LOG_WARN("failed to store all preds", K(ret));
} else if (OB_FAIL(gather_pullup_preds_from_semi_outer_join(*stmt, stmt->get_condition_exprs(), true))) { } else if (OB_FAIL(gather_pullup_preds_from_semi_outer_join(*stmt, stmt->get_condition_exprs(), true))) {
LOG_WARN("failed to pullup preds from semi outer join", K(ret)); LOG_WARN("failed to pullup preds from semi outer join", K(ret));
@ -1320,7 +1334,7 @@ int ObTransformPredicateMoveAround::pushdown_predicates(
} }
} }
if (OB_FAIL(ret)) { if (OB_FAIL(ret)) {
} else if (OB_FAIL(check_transform_happened(*stmt, all_old_preds, is_happened))) { } else if (OB_FAIL(check_transform_happened(all_old_preds, *stmt, is_happened))) {
LOG_WARN("failed to check transform happened", K(ret)); LOG_WARN("failed to check transform happened", K(ret));
} else if (is_happened && OB_FAIL(add_var_to_array_no_dup(transed_stmts_, stmt))) { } else if (is_happened && OB_FAIL(add_var_to_array_no_dup(transed_stmts_, stmt))) {
LOG_WARN("append transed stmt failed", K(ret)); LOG_WARN("append transed stmt failed", K(ret));
@ -1402,17 +1416,15 @@ int ObTransformPredicateMoveAround::store_join_conds(const TableItem *table,
return ret; return ret;
} }
int ObTransformPredicateMoveAround::check_transform_happened(const ObDMLStmt &stmt, int ObTransformPredicateMoveAround::check_transform_happened(const ObIArray<ObSEArray<ObRawExpr*, 16>> &all_preds,
const ObIArray<ObSEArray<ObRawExpr*, 16>> &all_preds, ObDMLStmt &stmt,
bool &is_happened) bool &is_happened)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
const ObIArray<JoinedTable*> &join_tables = stmt.get_joined_tables(); ObIArray<JoinedTable*> &join_tables = stmt.get_joined_tables();
const ObIArray<SemiInfo*> &semi_infos = stmt.get_semi_infos(); ObIArray<SemiInfo*> &semi_infos = stmt.get_semi_infos();
bool real_happened = is_happened && real_happened_; bool real_happened = is_happened && real_happened_;
if (real_happened) { if (OB_UNLIKELY(all_preds.empty())) {
// do nothing
} else if (OB_UNLIKELY(all_preds.empty())) {
ret = OB_ERR_UNEXPECTED; ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected empty", K(ret), K(all_preds.count())); LOG_WARN("unexpected empty", K(ret), K(all_preds.count()));
} else if (OB_FAIL(check_conds_deduced(all_preds.at(0), stmt.get_condition_exprs(), real_happened))) { } else if (OB_FAIL(check_conds_deduced(all_preds.at(0), stmt.get_condition_exprs(), real_happened))) {
@ -1420,7 +1432,7 @@ int ObTransformPredicateMoveAround::check_transform_happened(const ObDMLStmt &st
} else { } else {
uint64_t idx = 1; uint64_t idx = 1;
for (int64_t i = 0; !real_happened && OB_SUCC(ret) && i < join_tables.count(); ++i) { for (int64_t i = 0; !real_happened && OB_SUCC(ret) && i < join_tables.count(); ++i) {
if (OB_FAIL(check_join_conds_deduced(join_tables.at(i), all_preds, idx, real_happened))) { if (OB_FAIL(check_join_conds_deduced(all_preds, idx, join_tables.at(i), real_happened))) {
LOG_WARN("failed to check join conds deduced", K(ret)); LOG_WARN("failed to check join conds deduced", K(ret));
} }
} }
@ -1447,17 +1459,18 @@ int ObTransformPredicateMoveAround::check_transform_happened(const ObDMLStmt &st
return ret; return ret;
} }
int ObTransformPredicateMoveAround::check_join_conds_deduced(const TableItem *table, int ObTransformPredicateMoveAround::check_join_conds_deduced(
const ObIArray<ObSEArray<ObRawExpr*, 16>> &all_preds, const ObIArray<ObSEArray<ObRawExpr*, 16>> &all_preds,
uint64_t &idx, uint64_t &idx,
bool &is_happened) TableItem *table,
bool &is_happened)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
if (OB_ISNULL(table)) { if (OB_ISNULL(table)) {
ret = OB_ERR_UNEXPECTED; ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected null", K(ret)); LOG_WARN("unexpected null", K(ret));
} else if (!is_happened && table->is_joined_table()) { } else if (!is_happened && table->is_joined_table()) {
const JoinedTable *join_table = static_cast<const JoinedTable*>(table); JoinedTable *join_table = static_cast<JoinedTable*>(table);
if (OB_UNLIKELY(all_preds.count() <= idx)) { if (OB_UNLIKELY(all_preds.count() <= idx)) {
ret = OB_ERR_UNEXPECTED; ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected idx", K(ret), K(idx), K(all_preds.count())); LOG_WARN("unexpected idx", K(ret), K(idx), K(all_preds.count()));
@ -1467,9 +1480,9 @@ int ObTransformPredicateMoveAround::check_join_conds_deduced(const TableItem *ta
++idx; ++idx;
} }
if (OB_FAIL(ret) || is_happened) { if (OB_FAIL(ret) || is_happened) {
} else if (OB_FAIL(SMART_CALL(check_join_conds_deduced(join_table->left_table_, all_preds, idx, is_happened)))) { } else if (OB_FAIL(SMART_CALL(check_join_conds_deduced(all_preds, idx, join_table->left_table_, is_happened)))) {
LOG_WARN("failed to check join conds deduced", K(ret)); LOG_WARN("failed to check join conds deduced", K(ret));
} else if (OB_FAIL(SMART_CALL(check_join_conds_deduced(join_table->right_table_, all_preds, idx, is_happened)))) { } else if (OB_FAIL(SMART_CALL(check_join_conds_deduced(all_preds, idx, join_table->right_table_, is_happened)))) {
LOG_WARN("failed to check join conds deduced", K(ret)); LOG_WARN("failed to check join conds deduced", K(ret));
} }
} }
@ -1477,30 +1490,30 @@ int ObTransformPredicateMoveAround::check_join_conds_deduced(const TableItem *ta
} }
int ObTransformPredicateMoveAround::check_conds_deduced(const ObIArray<ObRawExpr *> &old_conditions, int ObTransformPredicateMoveAround::check_conds_deduced(const ObIArray<ObRawExpr *> &old_conditions,
const ObIArray<ObRawExpr *> &new_conditions, ObIArray<ObRawExpr *> &new_conditions,
bool &is_happened) bool &is_happened)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
if (!is_happened || !real_happened_) { bool happened = false;
bool happened = false; uint64_t new_conditions_count = new_conditions.count();
uint64_t new_conditions_count = new_conditions.count(); uint64_t old_conditions_count = old_conditions.count();
uint64_t old_conditions_count = old_conditions.count(); if (new_conditions_count != old_conditions_count) {
if (new_conditions_count != old_conditions_count) { happened = true;
happened = true; } else {
} else { for (int64_t i = 0; !happened && i < new_conditions_count; ++i) {
for (int64_t i = 0; OB_SUCC(ret) && !happened && i < new_conditions_count; ++i) { if (!ObPredicateDeduce::find_equal_expr(old_conditions, new_conditions.at(i)) ||
if (!ObPredicateDeduce::find_equal_expr(old_conditions, new_conditions.at(i)) || !ObPredicateDeduce::find_equal_expr(new_conditions, old_conditions.at(i))) {
!ObPredicateDeduce::find_equal_expr(new_conditions, old_conditions.at(i))) { happened = true;
happened = true;
}
} }
} }
if (OB_SUCC(ret) && happened) {
is_happened = true;
real_happened_ = true;
}
LOG_DEBUG("check transform happened", K(old_conditions), K(new_conditions), K(is_happened));
} }
if (happened) {
is_happened = true;
real_happened_ = true;
} else if (OB_FAIL(new_conditions.assign(old_conditions))) {
LOG_WARN("failed to assign exprs", K(ret));
}
LOG_DEBUG("check transform happened", K(old_conditions), K(new_conditions), K(happened));
return ret; return ret;
} }
@ -3566,8 +3579,7 @@ int ObTransformPredicateMoveAround::check_enable_no_pred_deduce(ObDMLStmt &stmt,
LOG_WARN("unexpected null", K(ret), K(ctx_), K(query_hint)); LOG_WARN("unexpected null", K(ret), K(ctx_), K(query_hint));
} else if (query_hint->has_outline_data()) { } else if (query_hint->has_outline_data()) {
bool has_hint = ObOptimizerUtil::find_item(applied_hints_, hint); bool has_hint = ObOptimizerUtil::find_item(applied_hints_, hint);
enable_no_pred_deduce = (hint == NULL ? true : enable_no_pred_deduce = (hint == NULL ? true : (has_hint ? hint->is_disable_hint() : true));
(has_hint ? hint->is_disable_hint() : true));
} else { } else {
const ObHint *no_rewrite = stmt.get_stmt_hint().get_no_rewrite_hint(); const ObHint *no_rewrite = stmt.get_stmt_hint().get_no_rewrite_hint();
enable_no_pred_deduce = (hint == NULL ? no_rewrite != NULL : hint->is_disable_hint()); enable_no_pred_deduce = (hint == NULL ? no_rewrite != NULL : hint->is_disable_hint());

View File

@ -55,6 +55,7 @@ public:
virtual int construct_transform_hint(ObDMLStmt &stmt, void *trans_params) override; virtual int construct_transform_hint(ObDMLStmt &stmt, void *trans_params) override;
private: private:
int do_transform_predicate_move_around(ObDMLStmt *&stmt, bool &trans_happened);
virtual int need_transform(const common::ObIArray<ObParentDMLStmt> &parent_stmts, virtual int need_transform(const common::ObIArray<ObParentDMLStmt> &parent_stmts,
const int64_t current_level, const int64_t current_level,
@ -258,15 +259,15 @@ private:
int store_all_preds(const ObDMLStmt &stmt, ObIArray<ObSEArray<ObRawExpr*, 16>> &all_preds); int store_all_preds(const ObDMLStmt &stmt, ObIArray<ObSEArray<ObRawExpr*, 16>> &all_preds);
int store_join_conds(const TableItem *table, ObIArray<ObSEArray<ObRawExpr*, 16>> &all_preds); int store_join_conds(const TableItem *table, ObIArray<ObSEArray<ObRawExpr*, 16>> &all_preds);
int check_transform_happened(const ObDMLStmt &stmt, int check_transform_happened(const ObIArray<ObSEArray<ObRawExpr*, 16>> &all_preds,
const ObIArray<ObSEArray<ObRawExpr*, 16>> &all_preds, ObDMLStmt &stmt,
bool &is_happened); bool &is_happened);
int check_join_conds_deduced(const TableItem *table, int check_join_conds_deduced(const ObIArray<ObSEArray<ObRawExpr*, 16>> &all_preds,
const ObIArray<ObSEArray<ObRawExpr*, 16>> &all_preds,
uint64_t &idx, uint64_t &idx,
TableItem *table,
bool &is_happened); bool &is_happened);
int check_conds_deduced(const ObIArray<ObRawExpr *> &old_conditions, int check_conds_deduced(const ObIArray<ObRawExpr *> &old_conditions,
const ObIArray<ObRawExpr *> &new_conditions, ObIArray<ObRawExpr *> &new_conditions,
bool &is_happened); bool &is_happened);
int pushdown_through_winfunc(ObSelectStmt &stmt, int pushdown_through_winfunc(ObSelectStmt &stmt,

View File

@ -1074,8 +1074,8 @@ int ObWhereSubQueryPullup::transform_single_set_query(ObDMLStmt *stmt,
cond_exprs.at(i), cond_exprs.at(i),
true, true,
queries))) { queries))) {
LOG_WARN("failed to get single set subquery", K(ret)); LOG_WARN("failed to get single set subquery", K(ret));
} }
for (int64_t j = 0; OB_SUCC(ret) && j < queries.count(); ++j) { for (int64_t j = 0; OB_SUCC(ret) && j < queries.count(); ++j) {
ObSelectStmt *subquery = NULL; ObSelectStmt *subquery = NULL;
ObQueryRefRawExpr *query_expr = queries.at(j).query_ref_expr_; ObQueryRefRawExpr *query_expr = queries.at(j).query_ref_expr_;