/** * 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 OCEANBASE_SQL_OB_PHYSICAL_PLAN_CTX_H #define OCEANBASE_SQL_OB_PHYSICAL_PLAN_CTX_H #include "share/ob_autoincrement_param.h" #include "common/sql_mode/ob_sql_mode.h" #include "common/ob_hint.h" #include "common/ob_field.h" #include "common/ob_clock_generator.h" #include "storage/transaction/ob_trans_define.h" #include "lib/container/ob_fixed_array.h" #include "lib/container/ob_2d_array.h" #include "sql/plan_cache/ob_plan_cache_util.h" #include "sql/engine/user_defined_function/ob_udf_ctx_mgr.h" #include "sql/engine/expr/ob_expr.h" namespace oceanbase { namespace sql { class ObResultSet; class ObSQLSessionInfo; class ObPhysicalPlan; class ObExecContext; class ObUdfCtxMgr; struct ObPxDmlRowInfo; struct PartParamIdxArray { PartParamIdxArray() : part_id_(-1), part_param_idxs_() {} TO_STRING_KV(K_(part_id), K_(part_param_idxs)); int64_t part_id_; ObFixedArray part_param_idxs_; }; typedef common::ObFixedArray BatchParamIdxArray; typedef common::ObFixedArray ImplicitCursorInfoArray; struct ObRemoteSqlInfo { ObRemoteSqlInfo() : use_ps_(false), is_batched_stmt_(false), remote_sql_(), ps_params_(nullptr) {} TO_STRING_KV(K_(use_ps), K_(is_batched_stmt), K_(remote_sql), KPC_(ps_params)); bool use_ps_; bool is_batched_stmt_; common::ObString remote_sql_; ParamStore* ps_params_; }; class ObPhysicalPlanCtx { OB_UNIS_VERSION(1); public: typedef common::Ob2DArray ParamStore; explicit ObPhysicalPlanCtx(common::ObIAllocator& allocator); virtual ~ObPhysicalPlanCtx(); inline void set_tenant_id(uint64_t tenant_id) { tenant_id_ = tenant_id; } inline void set_show_seed(bool show_seed) { is_show_seed_ = show_seed; } inline uint64_t get_tenant_id() { return tenant_id_; } inline bool get_show_seed() const { return is_show_seed_; } inline void set_tenant_schema_version(const int64_t version) { tenant_schema_version_ = version; } inline int64_t get_tenant_schema_version() const { return tenant_schema_version_; } /** * @brief: set the timestamp when the execution of this plan should time out * @param: ts_timeout_us [in] the microseconds timeout */ inline void set_timeout_timestamp(const int64_t ts_timeout_us) { ts_timeout_us_ = ts_timeout_us; } inline int64_t get_timeout_timestamp() const { return ts_timeout_us_; } inline int64_t get_ps_timeout_timestamp() const { return ts_timeout_us_ - ESTIMATE_PS_RESERVE_TIME; } inline int64_t get_trans_timeout_timestamp() const { return ts_timeout_us_ - ESTIMATE_TRANS_RESERVE_TIME; } inline bool is_timeout(int64_t* remain_us = NULL) const { int64_t now = common::ObClockGenerator::getClock(); if (remain_us != NULL) { if (OB_LIKELY(ts_timeout_us_ > 0)) { *remain_us = ts_timeout_us_ - now; } else { *remain_us = INT64_MAX; // no timeout } } return (ts_timeout_us_ > 0 && now > ts_timeout_us_); } // snapshot timestamp used for transaction set consistency check inline int64_t get_tsc_timestamp() const { return tsc_snapshot_timestamp_; } inline void set_tsc_timestamp(int64_t ts) { tsc_snapshot_timestamp_ = ts; } inline void set_consistency_level(const common::ObConsistencyLevel consistency) { consistency_level_ = consistency; } inline common::ObConsistencyLevel get_consistency_level() const { return consistency_level_; } void restore_param_store(const int64_t param_count); // param store int reserve_param_space(int64_t param_count); const ParamStore& get_param_store() const { return param_store_; } ParamStore& get_param_store_for_update() { return param_store_; } const common::ObObjParam* get_param_mem() const { if (param_store_.count() <= 0) { return nullptr; } else { return ¶m_store_.at(0); } } DatumParamStore& get_datum_param_store() { return datum_param_store_; } const DatumParamStore& get_datum_param_store() const { return datum_param_store_; } const ObIArray& get_param_frame_ptrs() const { return param_frame_ptrs_; } int init_datum_param_store(); void reset_datum_param_store() { param_store_.reuse(); datum_param_store_.reuse(); param_frame_ptrs_.reuse(); param_frame_capacity_ = 0; } int extend_datum_param_store(DatumParamStore& ext_datum_store); ObRemoteSqlInfo& get_remote_sql_info() { return remote_sql_info_; } bool is_terminate(int& ret) const; void set_cur_time(const int64_t& session_val) { cur_time_.set_timestamp(session_val); } void set_cur_time(const int64_t& session_val, const ObSQLSessionInfo& session); const common::ObObj& get_cur_time() const { return cur_time_; } int64_t get_cur_time_tardy_value() const { return cur_time_.get_datetime() + DELTA_TARDY_TIME_US; } bool has_cur_time() const { return common::ObTimestampType == cur_time_.get_type(); } void set_merging_frozen_time(const common::ObPreciseDateTime& val) { merging_frozen_time_.set_timestamp(val); } const common::ObObj& get_merging_frozen_time() const { return merging_frozen_time_; } bool has_merging_frozen_time() const { return common::ObTimestampType == merging_frozen_time_.get_type(); } char* get_message() const { return const_cast(message_); } void set_message(const char* message) { snprintf(message_, common::MSG_SIZE, "%s", message); } int64_t get_affected_rows() const { return affected_rows_; } void set_affected_rows(int64_t affected_rows) { affected_rows_ = affected_rows; } inline void add_affected_rows(int64_t affected_rows) { affected_rows_ += affected_rows; } int64_t get_found_rows() const { return found_rows_; } void set_found_rows(int64_t found_rows) { found_rows_ = found_rows; } /*void set_start_trans_param(const transaction::ObStartTransParam &start_trans_param) { start_trans_param_ = start_trans_param; }*/ transaction::ObStartTransParam& get_start_trans_param() { return start_trans_param_; } inline void set_autoinc_cache_handle(share::CacheHandle* handle) { autoinc_cache_handle_ = handle; } inline share::CacheHandle* get_autoinc_cache_handle() const { return autoinc_cache_handle_; } inline int set_autoinc_params(common::ObIArray& autoinc_params) { return autoinc_params_.assign(autoinc_params); } inline common::ObIArray& get_autoinc_params() { return autoinc_params_; } inline uint64_t calc_last_insert_id_session() { if (last_insert_id_cur_stmt_ > 0) { last_insert_id_session_ = last_insert_id_cur_stmt_; last_insert_id_changed_ = true; } return last_insert_id_session_; } inline void set_last_insert_id_session(const uint64_t last_insert_id) { last_insert_id_session_ = last_insert_id; } inline uint64_t get_last_insert_id_session() const { return last_insert_id_session_; } inline uint64_t calc_last_insert_id_to_client() { if (0 == last_insert_id_to_client_) { last_insert_id_to_client_ = last_insert_id_cur_stmt_ > 0 ? last_insert_id_cur_stmt_ : (last_insert_id_with_expr_ ? last_insert_id_session_ : autoinc_col_value_); } return last_insert_id_to_client_; } inline void set_last_insert_id_to_client(const uint64_t last_insert_id) { last_insert_id_to_client_ = last_insert_id; } inline uint64_t get_last_insert_id_to_client() { return last_insert_id_to_client_; } inline void record_last_insert_id_cur_stmt() { if (0 == last_insert_id_cur_stmt_ && autoinc_id_tmp_ > 0) { last_insert_id_cur_stmt_ = autoinc_id_tmp_; } } inline void set_last_insert_id_cur_stmt(const uint64_t last_insert_id) { last_insert_id_cur_stmt_ = last_insert_id; } inline uint64_t get_last_insert_id_cur_stmt() { return last_insert_id_cur_stmt_; } inline void set_autoinc_id_tmp(const uint64_t autoinc_id) { autoinc_id_tmp_ = autoinc_id; } inline uint64_t get_autoinc_id_tmp() { return autoinc_id_tmp_; } inline void set_autoinc_col_value(const uint64_t autoinc_value) { autoinc_col_value_ = autoinc_value; } inline uint64_t get_autoinc_col_value() { return autoinc_col_value_; } inline void set_last_insert_id_with_expr(const bool with_expr) { last_insert_id_with_expr_ = with_expr; } inline bool get_last_insert_id_with_expr() { return last_insert_id_with_expr_; } inline void set_last_insert_id_changed(const bool changed) { last_insert_id_changed_ = changed; } inline bool get_last_insert_id_changed() const { return last_insert_id_changed_; } void set_phy_plan(const ObPhysicalPlan* phy_plan); inline const ObPhysicalPlan* get_phy_plan() const { return phy_plan_; } inline void set_or_expand_transformed(const bool is_or_expand_transformed) { is_or_expand_transformed_ = is_or_expand_transformed; } inline bool get_or_expand_transformed() const { return is_or_expand_transformed_; } inline void reset_for_quick_retry() { affected_rows_ = 0; row_matched_count_ = 0; row_duplicated_count_ = 0; row_deleted_count_ = 0; } inline void set_bind_array_count(int64_t bind_array_count) { bind_array_count_ = bind_array_count; } inline int64_t get_bind_array_count() const { return bind_array_count_; } // current index for array binding parameters. // CAUTION: this index only used in static typing engine's operators && expressions, // the old engine get it from ObExprCtx::cur_array_index_ void set_bind_array_idx(const int64_t idx) { bind_array_idx_ = idx; } int64_t get_bind_array_idx() const { return bind_array_idx_; } void inc_bind_array_idx() { bind_array_idx_++; } void set_worker_count(int64_t worker_count) { unsed_worker_count_since_222rel_ = worker_count; } inline void set_exec_ctx(const ObExecContext* exec_ctx) { exec_ctx_ = exec_ctx; } void set_error_ignored(bool ignored) { is_error_ignored_ = ignored; } bool is_error_ignored() const { return is_error_ignored_; } void set_select_into(bool is_select_into) { is_select_into_ = is_select_into; } bool is_select_into() const { return is_select_into_; } void set_is_result_accurate(bool is_accurate) { is_result_accurate_ = is_accurate; } bool is_result_accurate() const { return is_result_accurate_; } void set_foreign_key_checks(bool foreign_key_checks) { foreign_key_checks_ = foreign_key_checks; } bool need_foreign_key_checks() const { return foreign_key_checks_; } inline bool is_affect_found_row() const { return is_affect_found_row_; } inline void set_is_affect_found_row(bool is_affect_found_row) { is_affect_found_row_ = is_affect_found_row; } int sync_last_value_local(); int sync_last_value_global(); int set_row_matched_count(int64_t row_count); inline void add_row_matched_count(int64_t row_count) { row_matched_count_ += row_count; } int64_t get_row_matched_count() const { return row_matched_count_; } int set_row_duplicated_count(int64_t row_count); inline void add_row_duplicated_count(int64_t row_count) { row_duplicated_count_ += row_count; } int64_t get_row_duplicated_count() const { return row_duplicated_count_; } int set_row_deleted_count(int64_t row_count); inline void add_row_deleted_count(int64_t row_count) { row_deleted_count_ += row_count; } int64_t get_row_deleted_count() const { return row_deleted_count_; } void set_expr_op_size(int64_t expr_op_size) { expr_op_size_ = expr_op_size; } int64_t get_expr_op_size() const { return expr_op_size_; } void set_ignore_stmt(bool is_ignore) { is_ignore_stmt_ = is_ignore; } bool is_ignore_stmt() const { return is_ignore_stmt_; } bool is_plain_select_stmt() const; ObTableScanStat& get_table_scan_stat() { return table_scan_stat_; } void set_table_row_count_list_capacity(uint32_t capacity) { table_row_count_list_.set_capacity(capacity); } ObIArray& get_table_row_count_list() { return table_row_count_list_; } inline bool& get_is_multi_dml() { return is_multi_dml_; } inline bool is_new_engine() { return is_new_engine_; } int set_batched_stmt_partition_ids(ObIArray& partition_ids); int assign_batch_stmt_param_idxs(const BatchParamIdxArray& param_idxs); inline const BatchParamIdxArray& get_batched_stmt_param_idxs() const { return batched_stmt_param_idxs_; } inline int create_implicit_cursor_infos(int64_t cursor_count) { return implicit_cursor_infos_.prepare_allocate(cursor_count); } const ImplicitCursorInfoArray& get_implicit_cursor_infos() const { return implicit_cursor_infos_; } int merge_implicit_cursor_info(const ObImplicitCursorInfo& implicit_cursor_info); int merge_implicit_cursors(const common::ObIArray& implicit_cursors); void reset_cursor_info(); void set_cur_stmt_id(int64_t cur_stmt_id) { cur_stmt_id_ = cur_stmt_id; } int64_t get_cur_stmt_id() const { return cur_stmt_id_; } int switch_implicit_cursor(); const ObIArray* get_part_param_idxs(int64_t part_id) const; void set_large_query(bool v) { is_large_query_ = v; } bool is_large_query() { return is_large_query_; } void add_px_dml_row_info(const ObPxDmlRowInfo& dml_row_info); TO_STRING_KV("tenant_id", tenant_id_); private: int extend_param_frame(const int64_t old_size); int reserve_param_frame(const int64_t capacity); private: DISALLOW_COPY_AND_ASSIGN(ObPhysicalPlanCtx); private: static const int64_t ESTIMATE_PS_RESERVE_TIME = 100 * 1000; static const int64_t ESTIMATE_TRANS_RESERVE_TIME = 70 * 1000; // oracle calc time during running, not before running. // oracle datetime func has two categoris: sysdate/systimestamp, current_date/current_timestamp/localtimestamp // so we use `cur_time_` for first used-category, `cur_time_ + DELTA_TARDY_TIME_US` for second used-category. static const int64_t DELTA_TARDY_TIME_US = 5; common::ObIAllocator& allocator_; private: /** * @note these member need serialize */ int64_t tenant_id_; // used for TRANSACTION SET CONSISTENCY check int64_t tsc_snapshot_timestamp_; // only used when the sql contains fun like current_time common::ObObj cur_time_; // used for session common::ObObj merging_frozen_time_; // execution timeout for this round of execution int64_t ts_timeout_us_; common::ObConsistencyLevel consistency_level_; ParamStore param_store_; DatumParamStore datum_param_store_; common::ObSEArray param_frame_ptrs_; int64_t param_frame_capacity_; // used for function sys_view_bigint_param(idx), @note unused anymore common::ObSEArray sys_view_bigint_params_; ObSQLMode sql_mode_; common::ObFixedArray autoinc_params_; // from session to remote; last_insert_id in session; uint64_t last_insert_id_session_; // error or warning message char message_[common::MSG_SIZE]; // only for serialize expr_op_size_ in ObExecContext, which is still using old serialize macro, // so we can't add any member in its serialize func because of compat problem. // fortunately, there is no compat problem for ObPhysicalPlanCtx. int64_t expr_op_size_; bool is_ignore_stmt_; int64_t bind_array_count_; // current index for array binding parameters. // CAUTION: this index only used in static typing engine's operators && expressions, // the old engine get it from ObExprCtx::cur_array_index_ int64_t bind_array_idx_; int64_t tenant_schema_version_; private: /** * @note these member not need serialize */ transaction::ObStartTransParam start_trans_param_; int64_t affected_rows_; // specified this plan whether affect found_row() result bool is_affect_found_row_; int64_t found_rows_; const ObPhysicalPlan* phy_plan_; // if current expr is in insert values, this is the expr's index in value row int64_t curr_col_index_; share::CacheHandle* autoinc_cache_handle_; // last_insert_id return to client uint64_t last_insert_id_to_client_; // first auto-increment value in current stmt uint64_t last_insert_id_cur_stmt_; // auto-increment value uint64_t autoinc_id_tmp_; // auto-increment column value uint64_t autoinc_col_value_; // set if last_insert_id(expr) called bool last_insert_id_with_expr_; // if updated, last_insert_id should update in session too bool last_insert_id_changed_; // use for mysql_info int64_t row_matched_count_; // duplicated or changed int64_t row_duplicated_count_; int64_t row_deleted_count_; bool is_error_ignored_; bool is_select_into_; bool is_result_accurate_; bool foreign_key_checks_; int64_t unsed_worker_count_since_222rel_; // deprecated const ObExecContext* exec_ctx_; ObTableScanStat table_scan_stat_; common::ObFixedArray table_row_count_list_; // (table_id, table_row_count) // pairs BatchParamIdxArray batched_stmt_param_idxs_; ImplicitCursorInfoArray implicit_cursor_infos_; // implicit cursor current stmt id int64_t cur_stmt_id_; bool is_or_expand_transformed_; bool is_show_seed_; bool is_multi_dml_; bool is_new_engine_; ObRemoteSqlInfo remote_sql_info_; bool is_large_query_; }; } // namespace sql } // namespace oceanbase #endif // OCEANBASE_SQL_OB_PHYSICAL_PLAN_CTX_H