Enable pushing down predicates when or_expansion happens on join_table
This commit is contained in:
parent
012c3bbd2c
commit
a164f7be0a
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user