Enable pushing down predicates when or_expansion happens on join_table

This commit is contained in:
jingtaoye35 2024-06-20 02:47:26 +00:00 committed by ob-robot
parent 012c3bbd2c
commit a164f7be0a
4 changed files with 72 additions and 78 deletions

View File

@ -613,6 +613,64 @@ int ObTransformOrExpansion::try_do_transform_left_join(ObIArray<ObParentDMLStmt>
return ret;
}
int ObTransformOrExpansion::get_joined_table_pushdown_conditions(const TableItem *cur_table,
const ObDMLStmt *trans_stmt,
ObIArray<ObRawExpr *> &pushdown_conds)
{
int ret = OB_SUCCESS;
ObSqlBitSet<> table_set;
const JoinedTable *cur_join_table = NULL;
const TableItem *left_table = NULL;
const TableItem *right_table = NULL;
bool left_on_null_side = false;
bool right_on_null_side = false;
if (OB_ISNULL(cur_table) || OB_ISNULL(trans_stmt) || OB_UNLIKELY(!cur_table->is_joined_table())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected", K(ret), KP(cur_table), K(cur_table->is_joined_table()));
} else if (FALSE_IT(cur_join_table = static_cast<const JoinedTable*>(cur_table))) {
} else if (!cur_join_table->is_left_join() && !cur_join_table->is_inner_join()) {
/* do nothing */
} else if (OB_ISNULL(left_table = cur_join_table->left_table_) ||
OB_ISNULL(right_table = cur_join_table->right_table_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected", K(ret), KP(left_table), KP(right_table));
} else {
if (left_table->is_basic_table() || left_table->is_generated_table()) {
if (OB_FAIL(ObOptimizerUtil::is_table_on_null_side(trans_stmt,
left_table->table_id_,
left_on_null_side))) {
LOG_WARN("failed to check table on null side", K(ret));
} else if (!left_on_null_side &&
OB_FAIL(trans_stmt->get_table_rel_ids(*left_table, table_set))) {
LOG_WARN("failed to get table rel ids", K(ret));
}
}
if (OB_SUCC(ret) && (right_table->is_basic_table() || right_table->is_generated_table())) {
if (OB_FAIL(ObOptimizerUtil::is_table_on_null_side(trans_stmt,
right_table->table_id_,
right_on_null_side))) {
LOG_WARN("failed to check table on null side", K(ret));
} else if (!right_on_null_side &&
OB_FAIL(trans_stmt->get_table_rel_ids(*right_table, table_set))) {
LOG_WARN("failed to get table rel ids", K(ret));
}
}
for (int64_t i = 0; OB_SUCC(ret) && i < trans_stmt->get_condition_exprs().count(); i++) {
ObRawExpr *cond = NULL;
if (OB_ISNULL(cond = trans_stmt->get_condition_exprs().at(i))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected null", K(ret));
} else if (!cond->get_relation_ids().is_subset(table_set) ||
cond->has_flag(CNT_SUB_QUERY)) {
/* do not push down */
} else if (OB_FAIL(pushdown_conds.push_back(cond))) {
LOG_WARN("failed to push cond", K(ret));
} else { /* do nothing */ }
}
}
return ret;
}
int ObTransformOrExpansion::create_single_joined_table_stmt(ObDMLStmt *trans_stmt,
uint64_t joined_table_id,
TableItem *&view_table,
@ -620,6 +678,7 @@ int ObTransformOrExpansion::create_single_joined_table_stmt(ObDMLStmt *trans_stm
{
int ret = OB_SUCCESS;
TableItem *cur_table = NULL;
ObSEArray<ObRawExpr *, 4> push_conditions;
view_table = NULL;
ref_query = NULL;
if (OB_ISNULL(trans_stmt)) {
@ -629,7 +688,14 @@ int ObTransformOrExpansion::create_single_joined_table_stmt(ObDMLStmt *trans_stm
LOG_WARN("failed to get table", K(ret));
} else if (OB_ISNULL(cur_table)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(ret), K(cur_table));
LOG_WARN("get unexpected", K(ret), KP(cur_table));
} else if (OB_FAIL(get_joined_table_pushdown_conditions(cur_table,
trans_stmt,
push_conditions))) {
LOG_WARN("failed to get single joined table condititons", K(ret));
} else if (OB_FAIL(ObOptimizerUtil::remove_item(trans_stmt->get_condition_exprs(),
push_conditions))) {
LOG_WARN("failed to remove pushed conditions", K(ret));
} else if (OB_FAIL(ObTransformUtils::replace_with_empty_view(ctx_,
trans_stmt,
view_table,
@ -638,7 +704,8 @@ int ObTransformOrExpansion::create_single_joined_table_stmt(ObDMLStmt *trans_stm
} else if (OB_FAIL(ObTransformUtils::create_inline_view(ctx_,
trans_stmt,
view_table,
cur_table))) {
cur_table,
&push_conditions))) {
LOG_WARN("failed to create inline view", K(ret));
} else if (OB_ISNULL(view_table)) {
ret = OB_ERR_UNEXPECTED;

View File

@ -163,7 +163,9 @@ private:
uint64_t joined_table_id,
TableItem *&view_table,
ObSelectStmt *&ref_query);
int get_joined_table_pushdown_conditions(const TableItem *cur_table,
const ObDMLStmt *trans_stmt,
ObIArray<ObRawExpr *> &pushdown_conds);
int add_select_item_to_ref_query(ObSelectStmt *stmt,
const uint64_t flag_table_id,
StmtUniqueKeyProvider &unique_key_provider,

View File

@ -8013,73 +8013,6 @@ int ObTransformUtils::find_hashset(ObRawExpr *expr,
return ret;
}
int ObTransformUtils::generate_col_exprs(ObDMLStmt *stmt,
const ObIArray<TableItem *> &tables,
const ObIArray<ObRawExpr *> &tmp_select_exprs,
const ObIArray<ObRawExpr *> &tmp_column_exprs,
ObIArray<ObRawExpr *> &old_column_exprs,
ObIArray<ObRawExpr *> &new_column_exprs)
{
int ret = OB_SUCCESS;
if (OB_ISNULL(stmt) || (tmp_column_exprs.count() != tmp_select_exprs.count())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected input", K(ret), K(stmt));
} else {
for (int64_t i = 0; OB_SUCC(ret) && i < tmp_select_exprs.count(); ++i) {
ObRawExpr *tmp_select_expr = NULL;
ObRawExpr *tmp_column_expr = NULL;
if (OB_ISNULL(tmp_select_expr = tmp_select_exprs.at(i)) ||
OB_ISNULL(tmp_column_expr = tmp_column_exprs.at(i))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected NULL", K(ret), K(tmp_select_expr), K(tmp_column_expr));
} else {
if (ob_is_enumset_tc(tmp_select_expr->get_data_type())) {
OZ(tmp_column_expr->set_enum_set_values(tmp_select_expr->get_enum_set_values()));
}
for (int64_t j = 0; OB_SUCC(ret) && j < tables.count(); ++j) {
ObColumnRefRawExpr *col_expr = NULL;
TableItem *table = tables.at(j);
uint64_t table_id = OB_INVALID_INDEX;
ObRawExpr *tmp_raw_expr = NULL;
if (OB_ISNULL(table)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null table", K(ret));
} else if (!tmp_select_expr->is_column_ref_expr()) {
ObSEArray<uint64_t, 8> table_ids;
// joined table allows non-column ref exprs
if (!table->is_joined_table()) {
} else if (OB_FAIL(ObRawExprUtils::extract_table_ids(tmp_select_expr, table_ids))) {
LOG_WARN("failed to extract table ids", K(ret));
} else if (ObOptimizerUtil::is_subset(table_ids,
static_cast<JoinedTable *>(table)->single_table_ids_)) {
if (OB_FAIL(add_var_to_array_no_dup(old_column_exprs, tmp_select_expr))) {
LOG_WARN("failed to add select expr", K(ret));
} else if (OB_FAIL(add_var_to_array_no_dup(new_column_exprs, tmp_column_expr))) {
LOG_WARN("failed to add column expr", K(ret));
}
}
} else if (OB_FALSE_IT(col_expr = static_cast<ObColumnRefRawExpr *>(tmp_select_expr))) {
} else if (OB_FALSE_IT(table_id = table->is_generated_table() ? table->table_id_ :
col_expr->get_table_id())) {
} else if (OB_ISNULL(col_expr = stmt->get_column_expr_by_id(table_id,
col_expr->get_column_id()))) {
// do nothing
} else if (OB_FALSE_IT(tmp_raw_expr = col_expr)) {
} else if (is_contain(old_column_exprs, tmp_raw_expr) ||
is_contain(old_column_exprs, tmp_select_expr)) {
// since we have multi tables, the iteration here may contain redundant columns
} else if (OB_FAIL(old_column_exprs.push_back(col_expr))) {
LOG_WARN("failed to push back expr", K(ret));
} else if (OB_FAIL(new_column_exprs.push_back(tmp_column_expr))) {
LOG_WARN("failed to push back new column expr", K(ret));
}
}
}
}
}
return ret;
}
int ObTransformUtils::extract_right_tables_from_semi_infos(ObDMLStmt *stmt,
const ObIArray<SemiInfo *> &semi_infos,
ObIArray<TableItem *> &tables)

View File

@ -2029,14 +2029,6 @@ private:
ObSelectStmt *view_stmt,
ObIArray<ObRawExpr *> &common_exprs,
const ObIArray<ObRawExpr *> *extra_view_exprs = NULL);
static int generate_col_exprs(ObDMLStmt *stmt,
const ObIArray<TableItem *> &tables,
const ObIArray<ObRawExpr *> &tmp_select_exprs,
const ObIArray<ObRawExpr *> &tmp_column_exprs,
ObIArray<ObRawExpr *> &old_column_exprs,
ObIArray<ObRawExpr *> &new_column_exprs);
static int is_scalar_expr(ObRawExpr* expr, bool &is_scalar);
static int check_is_bypass_string_expr(const ObRawExpr *expr,