diff --git a/src/sql/rewrite/ob_transform_or_expansion.cpp b/src/sql/rewrite/ob_transform_or_expansion.cpp index 58fc6307e1..8299cc836a 100644 --- a/src/sql/rewrite/ob_transform_or_expansion.cpp +++ b/src/sql/rewrite/ob_transform_or_expansion.cpp @@ -613,6 +613,64 @@ int ObTransformOrExpansion::try_do_transform_left_join(ObIArray return ret; } +int ObTransformOrExpansion::get_joined_table_pushdown_conditions(const TableItem *cur_table, + const ObDMLStmt *trans_stmt, + ObIArray &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(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 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; diff --git a/src/sql/rewrite/ob_transform_or_expansion.h b/src/sql/rewrite/ob_transform_or_expansion.h index 73003f758e..84402de7bc 100644 --- a/src/sql/rewrite/ob_transform_or_expansion.h +++ b/src/sql/rewrite/ob_transform_or_expansion.h @@ -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 &pushdown_conds); int add_select_item_to_ref_query(ObSelectStmt *stmt, const uint64_t flag_table_id, StmtUniqueKeyProvider &unique_key_provider, diff --git a/src/sql/rewrite/ob_transform_utils.cpp b/src/sql/rewrite/ob_transform_utils.cpp index d69cb66241..5d1f146656 100644 --- a/src/sql/rewrite/ob_transform_utils.cpp +++ b/src/sql/rewrite/ob_transform_utils.cpp @@ -8013,73 +8013,6 @@ int ObTransformUtils::find_hashset(ObRawExpr *expr, return ret; } -int ObTransformUtils::generate_col_exprs(ObDMLStmt *stmt, - const ObIArray &tables, - const ObIArray &tmp_select_exprs, - const ObIArray &tmp_column_exprs, - ObIArray &old_column_exprs, - ObIArray &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 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(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(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 &semi_infos, ObIArray &tables) diff --git a/src/sql/rewrite/ob_transform_utils.h b/src/sql/rewrite/ob_transform_utils.h index 4d858cc72e..fb4426d8a9 100644 --- a/src/sql/rewrite/ob_transform_utils.h +++ b/src/sql/rewrite/ob_transform_utils.h @@ -2029,14 +2029,6 @@ private: ObSelectStmt *view_stmt, ObIArray &common_exprs, const ObIArray *extra_view_exprs = NULL); - - static int generate_col_exprs(ObDMLStmt *stmt, - const ObIArray &tables, - const ObIArray &tmp_select_exprs, - const ObIArray &tmp_column_exprs, - ObIArray &old_column_exprs, - ObIArray &new_column_exprs); - static int is_scalar_expr(ObRawExpr* expr, bool &is_scalar); static int check_is_bypass_string_expr(const ObRawExpr *expr,