/** * Copyright (c) 2021 OceanBase * OceanBase CE is licensed under Mulan PubL v2. * You can use this software according to the terms and conditions of the Mulan PubL v2. * You may obtain a copy of Mulan PubL v2 at: * http://license.coscl.org.cn/MulanPubL-2.0 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. * See the Mulan PubL v2 for more details. */ #ifndef OB_TRANSFORM_PREDICATE_MOVE_AROUND_H #define OB_TRANSFORM_PREDICATE_MOVE_AROUND_H #include "sql/rewrite/ob_transform_rule.h" #include "sql/resolver/dml/ob_select_stmt.h" namespace oceanbase { namespace sql { class ObDelUpdStmt; class ObTransformPredicateMoveAround : public ObTransformRule { public: ObTransformPredicateMoveAround(ObTransformerCtx *ctx); virtual ~ObTransformPredicateMoveAround(); virtual int transform_one_stmt(ObIArray &parent_stmts, ObDMLStmt *&stmt, bool &trans_happened) override; virtual int transform_one_stmt_with_outline(ObIArray &parent_stmts, ObDMLStmt *&stmt, bool &trans_happened) override; virtual int construct_transform_hint(ObDMLStmt &stmt, void *trans_params) override; private: virtual int need_transform(const common::ObIArray &parent_stmts, const int64_t current_level, const ObDMLStmt &stmt, bool &need_trans) override; int sort_transed_stmts(); int check_outline_valid_to_transform(const ObDMLStmt &stmt, bool &need_trans); int pullup_predicates(ObDMLStmt *stmt, ObIArray &select_list, ObIArray &properties); int pullup_predicates_from_view(ObDMLStmt &stmt, ObIArray &sel_ids, ObIArray &input_pullup_preds); int generate_set_pullup_predicates(ObSelectStmt &stmt, ObIArray &sel_ids, ObIArray &input_pullup_preds, ObIArray &output_pullup_preds); /** * @brief pullup_predicates_from_set * set stmt的左右子查询中谓词上拉 * @param stmt * @param pullup_preds 上拉的谓词 * @param parent_stmt set stmt的上层stmt,用于改写上拉谓词 */ int pullup_predicates_from_set(ObSelectStmt *stmt, ObIArray &pullup_preds); /** * @brief check_pullup_predicates * 根据set op类型选择需要输出的谓词 * union:选择同构谓词; * interset:合并两侧的谓词; * except:选择左侧的谓词 */ int check_pullup_predicates(ObSelectStmt *stmt, ObIArray &left_pullup_preds, ObIArray &right_pullup_preds, ObIArray &output_pullup_preds); int generate_pullup_predicates(ObSelectStmt &select_stmt, ObIArray &sel_ids, ObIArray &input_pullup_preds, ObIArray &output_pullup_preds); int gather_pullup_preds_from_semi_outer_join(ObDMLStmt &stmt, ObIArray &preds, bool remove_preds = false); int gather_pullup_preds_from_join_table(TableItem *table, ObIArray &preds, bool remove_preds); int remove_pullup_union_predicates(ObIArray &exprs); int remove_useless_equal_const_preds(ObSelectStmt *stmt, ObIArray &exprs, ObIArray &equal_const_preds); int choose_pullup_columns(TableItem &table, ObIArray &columns, ObIArray &view_sel_list); int compute_pullup_predicates(ObSelectStmt &view, const ObIArray &select_list, ObIArray &local_preds, ObIArray &pull_up_preds); int check_expr_pullup_validity(const ObRawExpr *expr, const ObIArray &pullup_list, int64_t &state); int rename_pullup_predicates(ObDMLStmt &stmt, TableItem &view, const ObIArray &view_sel_list, ObIArray &preds); int pullup_predicates_from_const_select(ObSelectStmt *parent_stmt, ObSelectStmt *child_stmt, ObIArray &pullup_preds); int pushdown_predicates(ObDMLStmt *stmt, ObIArray &predicates); /** * @brief pushdown_into_set_stmt * 下推谓词到set stmt的左右子查询中 * @param stmt * @param predicates 待下推的谓词 */ int pushdown_into_set_stmt(ObSelectStmt *stmt, ObIArray &pullup_preds, ObIArray &pushdown_preds); /** * @brief check_pushdown_predicates * 根据左右谓词下推的情况,决定哪些谓词需要加回上层stmt * union:合并左右两侧未下推的谓词;(union需要左右两侧都下推成功) * intersect:选择左右两侧均未下推的谓词;(intersect只需要下推到任意一侧) * except:选择左侧未下推的谓词;(except只需要左侧成功下推) */ int check_pushdown_predicates(ObSelectStmt *stmt, ObIArray &left_pushdown_preds, ObIArray &right_pushdown_preds, ObIArray &output_pushdown_preds); int extract_valid_preds(ObIArray &all_preds, ObIArray &valid_exprs, ObIArray &invalid_exprs); /** * @brief pushdown_into_set_stmt * 下推谓词到set stmt的子查询中 * @param stmt * @param predicates 待下推的谓词 * @param 返回没有下推的谓词,需要加回上层 */ int pushdown_into_set_stmt(ObSelectStmt *stmt, ObIArray &pullup_preds, ObIArray &pushdown_preds, ObSelectStmt *parent_stmt); /** * @brief rename_set_op_predicates * 重命名谓词 * @param child_stmt * @param parent_stmt * @param preds 待改写的谓词 * @param is_pullup * 如果是pullup谓词,则需要从child_stmt改写到parent_stmt * 如果是pushdown谓词,则需要从parent_stmt改写到child_stmt */ int rename_set_op_predicates(ObSelectStmt &child_stmt, ObSelectStmt &parent_stmt, ObIArray &preds, bool is_pullup); int pushdown_into_having(ObSelectStmt &stmt, ObIArray &pullup_preds, ObIArray &pushdown_preds); int pushdown_into_where(ObDMLStmt &stmt, ObIArray &pullup_preds, ObIArray &pushdown_preds); int pushdown_into_semi_info(ObDMLStmt *stmt, SemiInfo *semi_info, ObIArray &pullup_preds, ObIArray &pushdown_preds); int pushdown_semi_info_right_filter(ObDMLStmt *stmt, ObTransformerCtx *ctx, SemiInfo *semi_info); int check_has_shared_query_ref(ObRawExpr *expr, bool &has); int extract_semi_right_table_filter(ObDMLStmt *stmt, SemiInfo *semi_info, ObIArray &right_filters); int pushdown_into_table(ObDMLStmt *stmt, TableItem *table, ObIArray &pullup_preds, ObIArray &preds); int get_pushdown_predicates(ObDMLStmt &stmt, TableItem &table, ObIArray &preds, ObIArray &table_filters); int get_pushdown_predicates(ObDMLStmt &stmt, ObSqlBitSet<> &table_set, ObIArray &preds, ObIArray &table_filters); int pushdown_into_joined_table(ObDMLStmt *stmt, JoinedTable *joined_table, ObIArray &pullup_preds, ObIArray &pushdown_preds); int store_all_preds(const ObDMLStmt &stmt, ObIArray> &all_preds); int store_join_conds(const TableItem *table, ObIArray> &all_preds); int check_transform_happened(const ObDMLStmt &stmt, const ObIArray> &all_preds, bool &is_happened); int check_join_conds_deduced(const TableItem *table, const ObIArray> &all_preds, uint64_t &idx, bool &is_happened); int check_conds_deduced(const ObIArray &old_conditions, const ObIArray &new_conditions, bool &is_happened); int pushdown_through_winfunc(ObSelectStmt &stmt, ObIArray &predicates, ObIArray &down_preds); int pushdown_through_groupby(ObSelectStmt &stmt, ObIArray &output_predicates); int deduce_param_cond_from_aggr_cond(ObItemType expr_type, ObRawExpr *first, ObRawExpr *second, ObRawExpr *&new_predicate); int split_or_having_expr(ObSelectStmt &stmt, ObOpRawExpr &or_qual, ObRawExpr *&new_expr); int check_having_expr(ObSelectStmt &stmt, ObOpRawExpr &or_qual, ObIArray > &sub_exprs, bool &all_contain); int inner_split_or_having_expr(ObSelectStmt &stmt, ObIArray > &sub_exprs, ObRawExpr *&new_expr); int choose_pushdown_preds(ObIArray &preds, ObIArray &invalid_preds, ObIArray &valid_preds); int rename_pushdown_predicates(ObDMLStmt &stmt, TableItem &view, ObIArray &preds); int transform_predicates(ObDMLStmt &stmt, ObIArray &input_preds, ObIArray &target_exprs, ObIArray &output_preds, bool is_pullup = false); int accept_predicates(ObDMLStmt &stmt, ObIArray &conds, ObIArray &properties, ObIArray &new_conds); int extract_generalized_column(ObRawExpr *expr, ObIArray &output); int acquire_transform_params(ObDMLStmt *stmt, ObIArray *&preds); int get_columns_in_filters(ObDMLStmt &stmt, ObIArray &sel_items, ObIArray &columns); int create_equal_exprs_for_insert(ObDelUpdStmt *del_upd_stmt); int print_debug_info(const char *str, ObDMLStmt *stmt, ObIArray &preds); int generate_pullup_predicates_for_dual_stmt(ObDMLStmt &stmt, TableItem &view, const ObIArray &sel_ids, ObIArray &preds); int check_false_condition(ObSelectStmt *stmt, bool &false_cond_exists); int check_enable_no_pred_deduce(ObDMLStmt &stmt, bool &enable_no_pred_deduce); int get_stmt_to_trans(ObDMLStmt *stmt, ObIArray &stmt_to_trans); int pullup_predicates_from_set_stmt(ObDMLStmt *stmt, ObIArray &sel_ids, ObIArray &output_pullup_preds); int generate_pullup_predicates_for_subquery(ObDMLStmt &stmt, ObIArray &pullup_preds); int choose_and_rename_predicates_for_subquery(ObQueryRefRawExpr *subquery, ObIArray &preds, ObIArray &renamed_preds); int generate_basic_table_pullup_preds(ObDMLStmt *stmt, ObIArray &preds); int update_current_property(ObDMLStmt &stmt, ObIArray &exprs, ObIArray &push_down_exprs); int get_exprs_cnt_exec(ObIArray &pullup_preds, ObIArray &conds); int update_subquery_pullup_preds(ObIArray &subquery_exprs, ObIArray ¤t_exprs_can_push); int remove_simple_op_null_condition(ObSelectStmt &stmt, ObIArray &pullup_preds); int is_column_expr_null(ObDMLStmt *stmt, const ObColumnRefRawExpr *expr, bool &is_null, ObIArray &constraints); int extract_filter_column_exprs_for_insert(ObDelUpdStmt &del_upd_stmt, ObIArray &columns); private: typedef ObSEArray PullupPreds; ObArenaAllocator allocator_; hash::ObHashMap stmt_map_; Ob2DArray stmt_pullup_preds_; ObSEArray transed_stmts_; ObSEArray applied_hints_; bool real_happened_; }; } } #endif // OB_TRANSFORM_PREDICATE_MOVE_AROUND_H