/** * 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_PRE_PROCESS_H_ #define OB_TRANSFORM_PRE_PROCESS_H_ #include "sql/rewrite/ob_transform_rule.h" #include "sql/resolver/dml/ob_select_stmt.h" #include "sql/rewrite/ob_transform_utils.h" #include "sql/ob_sql_context.h" namespace oceanbase { namespace sql { typedef std::pair JoinTableIdPair; class ObTransformPreProcess: public ObTransformRule { public: explicit ObTransformPreProcess(ObTransformerCtx *ctx) : ObTransformRule(ctx, TransMethod::POST_ORDER) { } virtual ~ObTransformPreProcess() {} virtual int transform_one_stmt(common::ObIArray &parent_stmts, ObDMLStmt *&stmt, bool &trans_happened) override; static int transform_expr(ObRawExprFactory &expr_factory, const ObSQLSessionInfo &session, ObRawExpr *&expr, bool &trans_happened); private: virtual int need_transform(const common::ObIArray &parent_stmts, const int64_t current_level, const ObDMLStmt &stmt, bool &need_trans) override; // used for transform in expr to or exprs struct DistinctObjMeta { ObObjType obj_type_; ObCollationType coll_type_; ObCollationLevel coll_level_; DistinctObjMeta(ObObjType obj_type, ObCollationType coll_type, ObCollationLevel coll_level) : obj_type_(obj_type), coll_type_(coll_type), coll_level_(coll_level) { if (!ObDatumFuncs::is_string_type(obj_type_)) { coll_type_ = CS_TYPE_MAX; coll_level_ = CS_LEVEL_INVALID; } } DistinctObjMeta() : obj_type_(common::ObMaxType), coll_type_(common::CS_TYPE_MAX) , coll_level_(CS_LEVEL_INVALID){} bool operator==(const DistinctObjMeta &other) const { bool cs_level_equal = lib::is_oracle_mode() ? true : (coll_level_ == other.coll_level_); return obj_type_ == other.obj_type_ && coll_type_ == other.coll_type_ && cs_level_equal; } TO_STRING_KV(K_(obj_type), K_(coll_type)); }; /* * following functions are used to add all rowkey columns */ int add_all_rowkey_columns_to_stmt(ObDMLStmt *stmt, bool &trans_happened); int add_all_rowkey_columns_to_stmt(const ObTableSchema &table_schema, const TableItem &table_item, ObRawExprFactory &expr_factory, ObDMLStmt &stmt, ObIArray &column_items); /* * following functions are for grouping sets and multi rollup */ int transform_for_grouping_sets_and_multi_rollup(ObDMLStmt *&stmt, bool &trans_happened); int add_generated_table_as_temp_table(ObTransformerCtx *ctx, ObDMLStmt *stmt); int replace_with_set_stmt_view(ObSelectStmt *origin_stmt, ObSelectStmt *grouping_sets_view, ObSelectStmt *&union_stmt); int create_set_view_stmt(ObSelectStmt *origin_stmt, ObSelectStmt *&set_view_stmt); int create_select_list_from_grouping_sets(ObSelectStmt *stmt, common::ObIArray &groupby_exprs_list, int64_t cur_index, ObIArray &old_exprs, ObIArray &new_exprs, int64_t origin_groupby_num = -1); int64_t get_total_count_of_groupby_stmt(ObIArray &grouping_sets_items, ObIArray &multi_rollup_items); int get_groupby_exprs_list(ObIArray &grouping_sets_items, ObIArray &multi_rollup_items, ObIArray &groupby_exprs_list); int expand_multi_rollup_items(ObIArray &multi_rollup_items, ObIArray &rollup_list_exprs); int combination_two_rollup_list(ObIArray &rollup_list_exprs1, ObIArray &rollup_list_exprs2, ObIArray &rollup_list_exprs); /* * following functions are for hierarchical query */ int transform_for_hierarchical_query(ObDMLStmt *stmt, bool &trans_happened); /** * @brief create_connect_by_view * 为层次查询构建一个spj,封装所有与层次查询相关的计算 * 包括所有的from item、where condition内的join条件 * 外层引用的connect by相关运算及伪列作为视图投影 */ int create_connect_by_view(ObSelectStmt &stmt); /** * @brief create_and_mock_join_view * 将所有的from item及其相关的连接谓词分离成一个spj * 并且copy一份构成connect by的右孩子节点 */ int create_and_mock_join_view(ObSelectStmt &stmt); /** * @brirf classify_join_conds * 将stmt的where condition分成普通的连接谓词和其他谓词 * 普通的连接谓词:引用两张表以上的谓词,并且不含有LEVEL、CONNECT_BY_ISLEAF、 * CONNECT_BY_ISCYCLE、PRIOR、CONNECT_BY_ROOT */ int classify_join_conds(ObSelectStmt &stmt, ObIArray &normal_join_conds, ObIArray &other_conds); int is_cond_in_one_from_item(ObSelectStmt &stmt, ObRawExpr *expr, bool &in_from_item); int extract_connect_by_related_exprs(ObSelectStmt &stmt, ObIArray &special_exprs); int extract_connect_by_related_exprs(ObRawExpr *expr, ObIArray &special_exprs); uint64_t get_real_tid(uint64_t tid, ObSelectStmt &stmt); /* * follow functions are used for eliminate having */ int eliminate_having(ObDMLStmt *stmt, bool &trans_happened); /* * following functions are used to replace func is serving tenant */ int replace_func_is_serving_tenant(ObDMLStmt *&stmt, bool &trans_happened); int recursive_replace_func_is_serving_tenant(ObDMLStmt &stmt, ObRawExpr *&cond_expr, bool &trans_happened); int calc_const_raw_expr_and_get_int(const ObStmt &stmt, ObRawExpr *const_expr, ObExecContext &exec_ctx, ObSQLSessionInfo *session, ObIAllocator &allocator, int64_t &result); int transform_for_merge_into(ObDMLStmt *stmt, bool &trans_happened); /* * following functions are used for temporary and se table */ int transform_for_temporary_table(ObDMLStmt *&stmt, bool &trans_happened); int add_filter_for_temporary_table(ObDMLStmt &stmt, const TableItem &table_item); int collect_all_tableitem(ObDMLStmt *stmt, TableItem *table_item, common::ObArray &table_item_list); int transform_exprs(ObDMLStmt *stmt, bool &trans_happened); int transform_for_nested_aggregate(ObDMLStmt *&stmt, bool &trans_happened); int generate_child_level_aggr_stmt(ObSelectStmt *stmt, ObSelectStmt *&sub_stmt); int get_first_level_output_exprs(ObSelectStmt *sub_stmt, common::ObIArray& inner_aggr_exprs); int generate_parent_level_aggr_stmt(ObSelectStmt *&stmt, ObSelectStmt *sub_stmt); int remove_nested_aggr_exprs(ObSelectStmt *stmt); int construct_column_items_from_exprs(const ObIArray &column_exprs, ObIArray &column_items); /* * following functions are used to transform in_expr to or_expr */ static int transform_in_or_notin_expr_with_row(ObRawExprFactory &expr_factory, const ObSQLSessionInfo &session, const bool is_in_expr, ObRawExpr *&in_expr, bool &trans_happened); static int transform_in_or_notin_expr_without_row(ObRawExprFactory &expr_factory, const ObSQLSessionInfo &session, const bool is_in_expr, ObRawExpr *&in_epxr, bool &trans_happened); static int create_partial_expr(ObRawExprFactory &expr_factory, ObRawExpr *left_expr, ObIArray &same_type_exprs, const bool is_in_expr, ObIArray &transed_in_exprs); /* * following functions are used to transform arg_case_expr to case_expr */ static int transform_arg_case_recursively(ObRawExprFactory &expr_factory, const ObSQLSessionInfo &session, ObRawExpr *&expr, bool &trans_happened); static int transform_arg_case_expr(ObRawExprFactory &expr_factory, const ObSQLSessionInfo &session, ObRawExpr *&expr, bool &trans_happened); static int create_equal_expr_for_case_expr(ObRawExprFactory &expr_factory, const ObSQLSessionInfo &session, ObRawExpr *arg_expr, ObRawExpr *when_expr, const ObExprResType &case_res_type, ObOpRawExpr *&equal_expr); static int add_row_type_to_array_no_dup(common::ObIArray> &row_type_array, const ObSEArray &row_type); static bool is_same_row_type(const common::ObIArray &left, const common::ObIArray &right); static int get_final_transed_or_and_expr( ObRawExprFactory &expr_factory, const ObSQLSessionInfo &session, const bool is_in_expr, common::ObIArray &transed_in_exprs, ObRawExpr *&final_or_expr); static int check_and_transform_in_or_notin(ObRawExprFactory &expr_factory, const ObSQLSessionInfo &session, ObRawExpr *&in_expr, bool &trans_happened); static int replace_in_or_notin_recursively(ObRawExprFactory &expr_factory, const ObSQLSessionInfo &session, ObRawExpr *&root_expr, bool &trans_happened); int transformer_aggr_expr(ObDMLStmt *stmt, bool &trans_happened); int transform_rownum_as_limit_offset(const ObIArray &parent_stmts, ObDMLStmt *&stmt, bool &trans_happened); int transform_common_rownum_as_limit(ObDMLStmt *&stmt, bool &trans_happened); int try_transform_common_rownum_as_limit(ObDMLStmt *stmt, ObRawExpr *&limit_expr); int transform_generated_rownum_as_limit(const ObIArray &parent_stmts, ObDMLStmt *stmt, bool &trans_happened); int try_transform_generated_rownum_as_limit_offset(ObDMLStmt *upper_stmt, ObSelectStmt *select_stmt, ObRawExpr *&limit_expr, ObRawExpr *&offset_expr); int transform_generated_rownum_eq_cond(ObRawExpr *eq_value, ObRawExpr *&limit_expr, ObRawExpr *&offset_expr); int expand_grouping_sets_items(common::ObIArray &grouping_sets_items, common::ObIArray &grouping_sets_exprs); int replace_select_and_having_exprs(ObSelectStmt *select_stmt, ObIArray &old_exprs, ObIArray &new_exprs, ObIArray &groupby_exprs_list, int64_t cur_index = -1, int64_t origin_groupby_num = -1); int replace_stmt_special_exprs(ObSelectStmt *select_stmt, ObRawExpr *&expr, common::ObIArray &old_exprs, common::ObIArray &new_exprs, ObIArray &groupby_exprs_list, bool ignore_const = false, int64_t cur_index = -1, int64_t origin_groupby_num = -1); int replace_aggr_exprs_in_select_and_having(ObRawExpr *&expr, ObIArray &groupby_exprs, ObIArray &rollup_exprs, ObIArray &aggr_items, ObIArray &groupby_exprs_list, int64_t cur_index, ObIArray &old_exprs, ObIArray &new_exprs, ObRelIds &rel_ids, int64_t origin_groupby_num = -1, bool using_rel_ids = true); int calc_grouping_in_grouping_sets(ObRawExpr *&expr, ObIArray &groupby_exprs, ObIArray &rollup_exprs, ObIArray &aggr_items, ObIArray &old_exprs, ObIArray &new_exprs, ObRelIds &rel_ids, bool using_rel_ids = true); int calc_grouping_id_in_grouping_sets(ObRawExpr *&expr, ObIArray &groupby_exprs, ObIArray &rollup_exprs, ObIArray &aggr_items, ObIArray &old_exprs, ObIArray &new_exprs, ObRelIds &rel_ids, bool using_rel_ids = true); int calc_group_id_in_grouping_sets(ObRawExpr *&expr, ObIArray &groupby_exprs, ObIArray &rollup_exprs, ObIArray &aggr_items, ObIArray &groupby_exprs_list, int64_t cur_index, ObIArray &old_exprs, ObIArray &new_exprs, ObRelIds &rel_ids, int64_t origin_groupby_num = -1, bool using_rel_ids = true); bool is_select_expr_in_other_groupby_exprs(ObRawExpr *expr, ObIArray &groupby_exprs_list, int64_t cur_index); bool is_expr_in_select_item(ObIArray &select_items, ObRawExpr *expr); int extract_select_expr_and_replace_expr(ObRawExpr *expr, ObIArray &groupby_exprs, ObIArray &rollup_exprs, ObIArray &aggr_items, ObIArray &groupby_exprs_list, int64_t cur_index, ObIArray &select_items, ObIArray &old_exprs, ObIArray &new_exprs, ObRelIds &rel_ids, int64_t origin_groupby_num = -1); int extract_stmt_replace_expr(ObSelectStmt *select_stmt, ObIArray &old_exprs); int extract_replace_expr_from_select_expr(ObRawExpr *expr, ObSelectStmt *select_stmt, ObIArray &old_exprs); int replace_group_id_in_stmt(ObSelectStmt *stmt); int replace_group_id_in_expr_recursive(ObRawExpr *&expr); /* * following functions are used for transform rowid in subquery */ int transformer_rowid_expr(ObDMLStmt *stmt, bool &trans_happened); int do_transform_rowid_expr(ObDMLStmt &stmt, ObColumnRefRawExpr *empty_rowid_col_expr, ObRawExpr *&new_rowid_expr); int recursive_generate_rowid_select_item(ObSelectStmt *select_stmt, ObRawExpr *&rowid_expr); int check_can_gen_rowid_on_this_table(ObSelectStmt *select_stmt, TableItem *this_item, bool &can_gen_rowid); int build_rowid_expr(ObSelectStmt *stmt, TableItem *table_item, ObSysFunRawExpr *&rowid_expr); int create_rowid_item_for_stmt(ObDMLStmt *select_stmt, TableItem *table_item, ObRawExpr *&rowid_expr); int add_rowid_constraint(ObDMLStmt &stmt); int check_stmt_contain_param_expr(ObDMLStmt *stmt, bool &contain); int check_stmt_can_batch(ObDMLStmt *batch_stmt, bool &can_batch); int check_contain_param_expr(ObDMLStmt *stmt, TableItem *table_item, bool &contain_param); int transform_for_upd_del_batch_stmt(ObDMLStmt *batch_stmt, ObSelectStmt* inner_view_stmt, bool &trans_happened); int create_inner_view_stmt(ObDMLStmt *batch_stmt, ObSelectStmt*& inner_view_stmt); int transform_for_ins_batch_stmt(ObDMLStmt *batch_stmt, bool &trans_happened); int transform_for_batch_stmt(ObDMLStmt *batch_stmt, bool &trans_happened); int formalize_batch_stmt(ObDMLStmt *batch_stmt, ObSelectStmt* inner_view_stmt, const ObIArray &other_exprs, bool &trans_happened); int mock_select_list_for_upd_del(ObDMLStmt &batch_stmt, ObSelectStmt &inner_view); int mock_select_list_for_ins_values(ObDMLStmt &batch_stmt, ObSelectStmt &inner_view, bool &trans_happened); int mock_select_list_for_ins_select(ObDMLStmt &batch_stmt, ObSelectStmt &inner_view, bool &trans_happened); int create_stmt_id_expr(ObPseudoColumnRawExpr *&stmt_id_expr); int create_params_expr(ObPseudoColumnRawExpr *&pseudo_param_expr, ObRawExpr *origin_param_expr, int64_t name_id); int create_params_exprs(ObDMLStmt &batch_stmt, ObIArray ¶ms_exprs); int mock_select_list_for_inner_view(ObDMLStmt &batch_stmt, ObSelectStmt &inner_view); int transform_full_outer_join(ObDMLStmt *&stmt, bool &trans_happened); int check_join_condition(ObDMLStmt *stmt, JoinedTable *table, bool &has_equal, bool &has_subquery); /** * @brief recursively_eliminate_full_join * 以左-右-后的方式后续遍历from item及semi from item中的joined_table结构 */ int recursively_eliminate_full_join(ObDMLStmt &stmt, TableItem &table_item, bool &trans_happened); /** * @brief expand_full_outer_join * for select stmt contains a single full outer join, expand to left join union all anti join */ int expand_full_outer_join(ObSelectStmt *&ref_query); int create_select_items_for_semi_join(ObDMLStmt *stmt, TableItem *from_table_item, const ObIArray &select_items, ObIArray &output_select_items); int switch_left_outer_to_semi_join(ObSelectStmt *&sub_stmt, JoinedTable *joined_table, const ObIArray &select_items); int extract_idx_from_table_items(ObDMLStmt *sub_stmt, const TableItem *table_item, ObSqlBitSet<> &rel_ids); int transform_rollup_exprs(ObDMLStmt *stmt, bool &trans_happened); int get_rollup_const_exprs(ObSelectStmt *stmt, ObIArray &const_exprs, ObIArray &const_remove_const_exprs, ObIArray &exec_params, ObIArray &exec_params_remove_const_exprs, ObIArray &column_ref_exprs, ObIArray &column_ref_remove_const_exprs, bool &trans_happened); int replace_remove_const_exprs(ObSelectStmt *stmt, ObIArray &const_exprs, ObIArray &const_remove_const_exprs, ObIArray &exec_params, ObIArray &exec_params_remove_const_exprs, ObIArray &column_ref_exprs, ObIArray &column_ref_remove_const_exprs); private: DISALLOW_COPY_AND_ASSIGN(ObTransformPreProcess); }; } } #endif /* OB_TRANSFORM_PRE_PROCESS_H_ */