/** * 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_CONTEXT_ #define OCEANBASE_SQL_CONTEXT_ #include "ob_sql_utils.h" #include "lib/net/ob_addr.h" #include "lib/hash/ob_placement_hashset.h" #include "lib/container/ob_2d_array.h" #include "sql/optimizer/ob_table_partition_info.h" #include "sql/monitor/ob_exec_stat.h" #include "lib/hash_func/murmur_hash.h" #include "sql/ob_sql_temp_table.h" #include "sql/plan_cache/ob_plan_cache_util.h" #include "observer/omt/ob_tenant_config_mgr.h" #include "share/client_feedback/ob_feedback_partition_struct.h" #include "sql/dblink/ob_dblink_utils.h" #ifdef OB_BUILD_SPM #include "sql/spm/ob_spm_define.h" #endif namespace oceanbase { namespace common { class ObMySQLProxy; class ObPartMgr; } namespace share { namespace schema { class ObSchemaGetterGuard; class ObTableSchema; class ObColumnSchemaV2; } } namespace pl { class ObPL; } namespace sql { typedef common::ObIArray ObTablePartitionInfoArray; //ObLocationConstraint如果只有一项, 则仅需要约束该location type是否一致; // 如果有多项,则需要校验每一项location对应的物理分布是否一样 struct LocationConstraint; typedef common::ObSEArray ObLocationConstraint; typedef common::ObFixedArray ObPlanLocationConstraint; typedef common::ObSEArray ObPwjConstraint; typedef common::ObFixedArray ObPlanPwjConstraint; class ObShardingInfo; struct LocationConstraint { enum InclusionType { NotSubset = 0, // no inclusion relationship LeftIsSuperior, // left contains all the elements in right set RightIsSuperior // right contains all the elements in left set }; enum ConstraintFlag { NoExtraFlag = 0, IsMultiPartInsert = 1, // 分区裁剪后基表只涉及到一个一级分区 SinglePartition = 1 << 1, // 分区裁剪后基表每个一级分区都只涉及一个二级分区 SingleSubPartition = 1 << 2, // is duplicate table not in dml DupTabNotInDML = 1 << 3 }; TableLocationKey key_; ObTableLocationType phy_loc_type_; int64_t constraint_flags_; // only used in plan generate ObTablePartitionInfo *table_partition_info_; LocationConstraint() : key_(), phy_loc_type_(), constraint_flags_(NoExtraFlag), table_partition_info_(NULL) {} inline uint64_t hash() const { uint64_t hash_ret = key_.hash(); hash_ret = common::murmurhash(&phy_loc_type_, sizeof(ObTableLocationType), hash_ret); return hash_ret; } inline void add_constraint_flag(ConstraintFlag flag) { constraint_flags_ |= flag; } inline bool is_multi_part_insert() const { return constraint_flags_ & IsMultiPartInsert; } inline bool is_partition_single() const { return constraint_flags_ & SinglePartition; } inline bool is_subpartition_single() const { return constraint_flags_ & SingleSubPartition; } inline bool is_dup_table_not_in_dml() const {return constraint_flags_ & DupTabNotInDML; } bool operator==(const LocationConstraint &other) const; bool operator!=(const LocationConstraint &other) const; // calculate the inclusion relationship between ObLocationConstraints static int calc_constraints_inclusion(const ObLocationConstraint *left, const ObLocationConstraint *right, InclusionType &inclusion_result); TO_STRING_KV(K_(key), K_(phy_loc_type), K_(constraint_flags)); }; struct ObLocationConstraintContext { enum InclusionType { NotSubset = 0, // no inclusion relationship LeftIsSuperior, // left contains all the elements in right set RightIsSuperior // right contains all the elements in left set }; ObLocationConstraintContext() : base_table_constraints_(), strict_constraints_(), non_strict_constraints_(), dup_table_replica_cons_() { } ~ObLocationConstraintContext() { } static int calc_constraints_inclusion(const ObPwjConstraint *left, const ObPwjConstraint *right, InclusionType &inclusion_result); TO_STRING_KV(K_(base_table_constraints), K_(strict_constraints), K_(non_strict_constraints), K_(dup_table_replica_cons)); // 基表location约束,包括TABLE_SCAN算子上的基表和INSERT算子上的基表 ObLocationConstraint base_table_constraints_; // 严格partition wise join约束,要求同一个分组内的基表分区逻辑上和物理上都相等。 // 每个分组是一个array,保存了对应基表在base_table_constraints_中的偏移 common::ObSEArray strict_constraints_; // 严格partition wise join约束,要求用一个分组内的基表分区物理上相等。 // 每个分组是一个array,保存了对应基表在base_table_constraints_中的偏移 common::ObSEArray non_strict_constraints_; // constraints for duplicate table's replica selection // if not found values in this array, just use local server's replica. common::ObSEArray dup_table_replica_cons_; }; class ObIVtScannerableFactory; class ObSQLSessionMgr; class ObSQLSessionInfo; class ObIVirtualTableIteratorFactory; class ObRawExpr; class ObSQLSessionInfo; class ObSelectStmt; class ObMultiStmtItem { public: ObMultiStmtItem() : is_part_of_multi_stmt_(false), seq_num_(0), sql_(), batched_queries_(NULL), is_ps_mode_(false), ab_cnt_(0) { } ObMultiStmtItem(bool is_part_of_multi, int64_t seq_num, const common::ObString &sql) : is_part_of_multi_stmt_(is_part_of_multi), seq_num_(seq_num), sql_(sql), batched_queries_(NULL), is_ps_mode_(false), ab_cnt_(0) { } ObMultiStmtItem(bool is_part_of_multi, int64_t seq_num, const common::ObString &sql, const common::ObIArray *queries, bool is_multi_vas_opt) : is_part_of_multi_stmt_(is_part_of_multi), seq_num_(seq_num), sql_(sql), batched_queries_(queries), is_ps_mode_(false), ab_cnt_(0) { } virtual ~ObMultiStmtItem() {} void reset() { is_part_of_multi_stmt_ = false; seq_num_ = 0; sql_.reset(); batched_queries_ = NULL; } inline bool is_part_of_multi_stmt() const { return is_part_of_multi_stmt_; } inline int64_t get_seq_num() const { return seq_num_; } inline const common::ObString &get_sql() const { return sql_; } inline bool is_batched_multi_stmt() const { bool is_batch = false; if (is_ps_mode_) { is_batch = (ab_cnt_ > 0); } else { is_batch = NULL != batched_queries_; } return is_batch; } inline int64_t get_batched_stmt_cnt() const { int64_t batch_cnt = 0; if (is_ps_mode_) { batch_cnt = ab_cnt_; } else if (batched_queries_ != nullptr) { batch_cnt = batched_queries_->count(); } return batch_cnt; } inline const common::ObIArray *get_queries() const { return batched_queries_; } inline void set_batched_queries(const common::ObIArray *batched_queries) { batched_queries_ = batched_queries; } inline bool is_ab_batch_opt() { return (is_ps_mode_ && ab_cnt_ > 0); } inline void set_ps_mode(bool ps) { is_ps_mode_ = ps; } inline bool is_ps_mode() { return is_ps_mode_; } inline void set_ab_cnt(int64_t cnt) { ab_cnt_ = cnt; } inline int64_t get_ab_cnt() { return ab_cnt_; } TO_STRING_KV(K_(is_part_of_multi_stmt), K_(seq_num), K_(sql), KPC_(batched_queries), K_(is_ps_mode), K_(ab_cnt)); private: bool is_part_of_multi_stmt_; // 是否为multi stmt,非multi stmt也使用这个结构体,因此需要这个标记 int64_t seq_num_; // 表示是在multi stmt中的第几条 common::ObString sql_; // is set only when doing multi-stmt optimization const common::ObIArray *batched_queries_; bool is_ps_mode_; int64_t ab_cnt_; }; struct ObInsertRewriteOptCtx { ObInsertRewriteOptCtx() : can_do_opt_(false), row_count_(0) {} void set_can_do_insert_batch_opt(int64_t row_count) { can_do_opt_ = true; row_count_ = row_count; } bool is_do_insert_batch_opt() const { bool bret = false; if (can_do_opt_ && row_count_ > 1) { bret = true; } return bret; } inline void clear() { can_do_opt_ = false; row_count_ = 0; } inline void reset() { clear(); } bool can_do_opt_; int64_t row_count_; }; class ObQueryRetryInfo { public: ObQueryRetryInfo() : inited_(false), is_rpc_timeout_(false), last_query_retry_err_(common::OB_SUCCESS), retry_cnt_(0), query_switch_leader_retry_timeout_ts_(0) { } virtual ~ObQueryRetryInfo() {} int init(); void reset(); void clear(); void clear_state_before_each_retry() { is_rpc_timeout_ = false; // 这里不能清除逐次重试累计的成员,如:invalid_servers_,last_query_retry_err_ } bool is_inited() const { return inited_; } void set_is_rpc_timeout(bool is_rpc_timeout); bool is_rpc_timeout() const; void set_last_query_retry_err(int last_query_retry_err) { last_query_retry_err_ = last_query_retry_err; } bool should_fast_fail(uint64_t tenant_id) { bool fast_fail = false; if (0 == query_switch_leader_retry_timeout_ts_) { query_switch_leader_retry_timeout_ts_ = INT64_MAX; // start timing from first retry, not from query start omt::ObTenantConfigGuard tenant_config(TENANT_CONF(tenant_id)); if (tenant_config.is_valid()) { int64_t timeout = tenant_config->ob_query_switch_leader_retry_timeout; if (timeout > 0) { query_switch_leader_retry_timeout_ts_ = timeout + common::ObTimeUtility::current_time(); } } } if (query_switch_leader_retry_timeout_ts_ < common::ObTimeUtility::current_time()) { fast_fail = true; } return fast_fail; } // 1. timeout 场景下,尽量反馈上次的错误码,使得报错原因可理解 // 2. 其余场景下,用于获取上次错误码,来决策本地重试行为(如 remote plan 优化走不走) int get_last_query_retry_err() const { return last_query_retry_err_; } void inc_retry_cnt() { retry_cnt_++; } int64_t get_retry_cnt() const { return retry_cnt_; } TO_STRING_KV(K_(inited), K_(is_rpc_timeout), K_(last_query_retry_err)); private: bool inited_; // 这个变量用于写一些防御性代码,基本没用 // 用于标记是否是rpc返回的timeout错误码(包括本地超时和回包中的超时错误码) bool is_rpc_timeout_; // 重试阶段可以将错误码的处理分为三类: // 1.重试到超时,将timeout返回给客户端; // 2.不再重试的错误码,直接将其返回给客客户端; // 3.重试到超时,但是将原始错误码返回给客户端,当前仅有 OB_NOT_SUPPORTED, // 对于这类错误码需要正确记录到last_query_retry_err_中,不应该被类型1或2的错误码覆盖。 int last_query_retry_err_; // this value include local retry & packet retry int64_t retry_cnt_; // for fast fail, int64_t query_switch_leader_retry_timeout_ts_; private: DISALLOW_COPY_AND_ASSIGN(ObQueryRetryInfo); }; class ObSqlSchemaGuard { public: ObSqlSchemaGuard() { reset(); } ~ObSqlSchemaGuard() { reset(); } void set_schema_guard(share::schema::ObSchemaGetterGuard *schema_guard) { schema_guard_ = schema_guard; } share::schema::ObSchemaGetterGuard *get_schema_guard() const { return schema_guard_; } void reset(); int get_dblink_schema(const uint64_t tenant_id, const uint64_t dblink_id, const share::schema::ObDbLinkSchema *&dblink_schema); int get_table_schema(uint64_t dblink_id, const common::ObString &database_name, const common::ObString &table_name, const share::schema::ObTableSchema *&table_schema, sql::ObSQLSessionInfo *session_info, const ObString &dblink_name, bool is_reverse_link); int set_link_table_schema(uint64_t dblink_id, const common::ObString &database_name, share::schema::ObTableSchema *table_schema); int get_table_schema(uint64_t table_id, uint64_t ref_table_id, const ObDMLStmt *stmt, const ObTableSchema *&table_schema); int get_table_schema(uint64_t table_id, const TableItem *table_item, const ObTableSchema *&table_schema); int get_table_schema(uint64_t table_id, const share::schema::ObTableSchema *&table_schema, bool is_link = false) const; int get_database_schema(const uint64_t database_id, const ObDatabaseSchema *&database_schema); int get_column_schema(uint64_t table_id, const common::ObString &column_name, const share::schema::ObColumnSchemaV2 *&column_schema, bool is_link = false) const; int get_column_schema(uint64_t table_id, uint64_t column_id, const share::schema::ObColumnSchemaV2 *&column_schema, bool is_link = false) const; int get_table_schema_version(const uint64_t table_id, int64_t &schema_version) const; int get_can_read_index_array(uint64_t table_id, uint64_t *index_tid_array, int64_t &size, bool with_mv, bool with_global_index = true, bool with_domain_index = true, bool with_spatial_index = true); int get_table_mlog_schema(const uint64_t table_id, const ObTableSchema *&mlog_schema); int get_link_table_schema(uint64_t table_id, const share::schema::ObTableSchema *&table_schema) const; int get_link_column_schema(uint64_t table_id, const common::ObString &column_name, const share::schema::ObColumnSchemaV2 *&column_schema) const; int get_link_column_schema(uint64_t table_id, uint64_t column_id, const share::schema::ObColumnSchemaV2 *&column_schema) const; int fetch_link_current_scn(uint64_t dblink_id, uint64_t tenant_id, ObSQLSessionInfo *session_info, uint64_t ¤t_scn); // get current scn from dblink. return OB_INVALID_ID if remote server not support current_scn int get_link_current_scn(uint64_t dblink_id, uint64_t tenant_id, ObSQLSessionInfo *session_info, uint64_t ¤t_scn); public: static TableItem *get_table_item_by_ref_id(const ObDMLStmt *stmt, uint64_t ref_table_id); static bool is_link_table(const ObDMLStmt *stmt, uint64_t table_id); private: share::schema::ObSchemaGetterGuard *schema_guard_; common::ObArenaAllocator allocator_; common::ObSEArray table_schemas_; uint64_t next_link_table_id_; // key is dblink_id, value is current scn. common::hash::ObHashMap dblink_scn_; }; #ifndef OB_BUILD_SPM struct ObBaselineKey { ObBaselineKey() : db_id_(common::OB_INVALID_ID), constructed_sql_(), sql_id_() {} ObBaselineKey(uint64_t db_id, const ObString &constructed_sql, const ObString &sql_id) : db_id_(db_id), constructed_sql_(constructed_sql), sql_id_(sql_id) {} inline void reset() { db_id_ = common::OB_INVALID_ID; constructed_sql_.reset(); sql_id_.reset(); } TO_STRING_KV(K_(db_id), K_(constructed_sql), K_(sql_id)); uint64_t db_id_; common::ObString constructed_sql_; common::ObString sql_id_; }; struct ObSpmCacheCtx { ObSpmCacheCtx() : bl_key_() {} inline void reset() { bl_key_.reset(); } ObBaselineKey bl_key_; }; #endif struct ObSqlCtx { OB_UNIS_VERSION(1); public: ObSqlCtx(); ~ObSqlCtx() { reset(); } int set_partition_infos(const ObTablePartitionInfoArray &info, common::ObIAllocator &allocator); int set_related_user_var_names(const common::ObIArray &user_var_names, common::ObIAllocator &allocator); int set_location_constraints(const ObLocationConstraintContext &location_constraint, ObIAllocator &allocator); int set_multi_stmt_rowkey_pos(const common::ObIArray &multi_stmt_rowkey_pos, common::ObIAllocator &alloctor); void reset(); bool handle_batched_multi_stmt() const { return multi_stmt_item_.is_batched_multi_stmt(); } void reset_reroute_info() { if (nullptr != reroute_info_) { op_reclaim_free(reroute_info_); } reroute_info_ = NULL; } share::ObFeedbackRerouteInfo *get_or_create_reroute_info() { if (nullptr == reroute_info_) { reroute_info_ = op_reclaim_alloc(share::ObFeedbackRerouteInfo); } return reroute_info_; } share::ObFeedbackRerouteInfo *get_reroute_info() { return reroute_info_; } bool is_batch_params_execute() const { return multi_stmt_item_.is_batched_multi_stmt() || is_do_insert_batch_opt(); } int64_t get_batch_params_count() const { int64_t count = 0; if (multi_stmt_item_.is_batched_multi_stmt()) { count = multi_stmt_item_.get_batched_stmt_cnt(); } else if (is_do_insert_batch_opt()) { count = get_insert_batch_row_cnt(); } return count; } bool is_do_insert_batch_opt() const { return ins_opt_ctx_.is_do_insert_batch_opt(); } inline int64_t get_insert_batch_row_cnt() const { return ins_opt_ctx_.row_count_; } void set_is_do_insert_batch_opt(int64_t row_count) { ins_opt_ctx_.set_can_do_insert_batch_opt(row_count); } void reset_do_insert_batch_opt() { ins_opt_ctx_.reset(); } void set_enable_strict_defensive_check(bool v) { enable_strict_defensive_check_ = v; } bool get_enable_strict_defensive_check() { return enable_strict_defensive_check_; } void set_enable_user_defined_rewrite(bool v) { enable_user_defined_rewrite_ = v; } bool get_enable_user_defined_rewrite() { return enable_user_defined_rewrite_; } // release dynamic allocated memory // void clear(); public: ObMultiStmtItem multi_stmt_item_; ObSQLSessionInfo *session_info_; share::schema::ObSchemaGetterGuard *schema_guard_; pl::ObPLBlockNS *secondary_namespace_; bool plan_cache_hit_; bool self_add_plan_; //used for retry query, and add plan to plan cache in this query; int disable_privilege_check_; //internal user set disable privilege check bool force_print_trace_; // [OUT]if the trace log is enabled by hint bool is_show_trace_stmt_; // [OUT] int64_t retry_times_; char sql_id_[common::OB_MAX_SQL_ID_LENGTH + 1]; ExecType exec_type_; bool is_prepare_protocol_; bool is_pre_execute_; bool is_prepare_stage_; bool is_dynamic_sql_; bool is_dbms_sql_; bool is_cursor_; bool is_remote_sql_; uint64_t statement_id_; common::ObString cur_sql_; stmt::StmtType stmt_type_; common::ObFixedArray partition_infos_; bool is_restore_; common::ObFixedArray related_user_var_names_; //use for plan cache support dist plan // 基表location约束,包括TABLE_SCAN算子上的基表和INSERT算子上的基表 common::ObFixedArray base_constraints_; // 严格partition wise join约束,要求同一个分组内的基表分区逻辑上和物理上都相等。 // 每个分组是一个array,保存了对应基表在base_table_constraints_中的偏移 common::ObFixedArray strict_constraints_; // 严格partition wise join约束,要求用一个分组内的基表分区物理上相等。 // 每个分组是一个array,保存了对应基表在base_table_constraints_中的偏移 common::ObFixedArray non_strict_constraints_; // constraints for duplicate table's replica selection // if not found values in this array, just use local server's replica. common::ObFixedArray dup_table_replica_cons_; // wether need late compilation bool need_late_compile_; // 从resolver传递过来的常量约束 // all_possible_const_param_constraints_ 表示该sql中可能的全部常量约束 // all_plan_const_param_constraints_ 表示该sql中存在的全部常量约束 // 比如:create table t (a bigint, b bigint as (a + 1 + 2), c bigint as (a + 2 + 3), index idx_b(b), index idx_c(c)); // 对于:select * from t where a + 1 + 2 > 0; // 有:all_plan_const_param_constraints_ = {[1, 2]}, all_possible_const_param_constraints_ = {[1, 2], [2, 3]} // 对于:select * from t where a + 3 + 4 > 0; // 有:all_plan_const_param_constraints_ = {}, all_possible_const_param_constraints_ = {[1, 2], [2, 3]} common::ObIArray *all_plan_const_param_constraints_; common::ObIArray *all_possible_const_param_constraints_; common::ObIArray *all_equal_param_constraints_; common::ObDList *all_pre_calc_constraints_; common::ObIArray *all_expr_constraints_; common::ObIArray *all_priv_constraints_; bool need_match_all_params_; //only used for matching plans common::ObIArray *all_local_session_vars_; //store the old values of session vars which have changed after creating generated columns bool is_ddl_from_primary_;//备集群从主库同步过来需要处理的ddl sql语句 const sql::ObStmt *cur_stmt_; const ObPhysicalPlan *cur_plan_; bool can_reroute_sql_; // 是否可以重新路由 bool is_sensitive_; // 是否含有敏感信息,若有则不记入 sql_audit bool is_protocol_weak_read_; // record whether proxy set weak read for this request in protocol flag common::ObFixedArray multi_stmt_rowkey_pos_; ObRawExpr *flashback_query_expr_; ObSpmCacheCtx spm_ctx_; bool is_execute_call_stmt_; bool enable_sql_resource_manage_; uint64_t res_map_rule_id_; int64_t res_map_rule_param_idx_; uint64_t res_map_rule_version_; bool is_text_ps_mode_; uint64_t first_plan_hash_; common::ObString first_outline_data_; bool is_bulk_; ObInsertRewriteOptCtx ins_opt_ctx_; union { uint32_t flags_; struct { uint32_t enable_strict_defensive_check_: 1; //TRUE if the _enable_defensive_check is '2' uint32_t enable_user_defined_rewrite_ : 1;//TRUE if enable_user_defined_rewrite_rules is open uint32_t is_from_pl_ : 1; uint32_t reserved_ : 29; }; }; TO_STRING_KV(K(stmt_type_)); private: share::ObFeedbackRerouteInfo *reroute_info_; }; struct ObQueryCtx { public: ObQueryCtx() : question_marks_count_(0), calculable_items_(), ab_param_exprs_(), fetch_cur_time_(true), is_contain_virtual_table_(false), is_contain_inner_table_(false), is_contain_select_for_update_(false), has_dml_write_stmt_(false), ins_values_batch_opt_(false), available_tb_id_(common::OB_INVALID_ID - 1), stmt_count_(0), subquery_count_(0), temp_table_count_(0), anonymous_view_count_(0), all_user_variable_(), need_match_all_params_(false), has_udf_(false), disable_udf_parallel_(false), has_is_table_(false), reference_obj_tables_(), is_table_gen_col_with_udf_(false), query_hint_(), #ifdef OB_BUILD_SPM is_spm_evolution_(false), #endif literal_stmt_type_(stmt::T_NONE), sql_stmt_(), sql_stmt_coll_type_(CS_TYPE_INVALID), prepare_param_count_(0), is_prepare_stmt_(false), has_nested_sql_(false), tz_info_(NULL), res_map_rule_id_(common::OB_INVALID_ID), res_map_rule_param_idx_(common::OB_INVALID_INDEX), root_stmt_(NULL), optimizer_features_enable_version_(0), udf_flag_(0), has_dblink_(false) { } TO_STRING_KV(N_PARAM_NUM, question_marks_count_, N_FETCH_CUR_TIME, fetch_cur_time_, K_(calculable_items)); void reset() { question_marks_count_ = 0; calculable_items_.reset(); fetch_cur_time_ = true; is_contain_virtual_table_ = false; is_contain_inner_table_ = false; is_contain_select_for_update_ = false; has_dml_write_stmt_ = false; ins_values_batch_opt_ = false; available_tb_id_ = common::OB_INVALID_ID - 1; stmt_count_ = 0; subquery_count_ = 0; temp_table_count_ = 0; anonymous_view_count_ = 0; all_user_variable_.reset(); need_match_all_params_= false; has_udf_ = false; disable_udf_parallel_ = false; has_is_table_ = false; sql_schema_guard_.reset(); reference_obj_tables_.reset(); is_table_gen_col_with_udf_ = false; query_hint_.reset(); #ifdef OB_BUILD_SPM is_spm_evolution_ = false; #endif literal_stmt_type_ = stmt::T_NONE; sql_stmt_.reset(); sql_stmt_coll_type_ = CS_TYPE_INVALID; prepare_param_count_ = 0; is_prepare_stmt_ = false; has_nested_sql_ = false; tz_info_ = NULL; res_map_rule_id_ = common::OB_INVALID_ID; res_map_rule_param_idx_ = common::OB_INVALID_INDEX; root_stmt_ = NULL; udf_flag_ = 0; optimizer_features_enable_version_ = 0; has_dblink_ = false; } int64_t get_new_stmt_id() { return stmt_count_++; } int64_t get_new_subquery_id() { return ++subquery_count_; } int64_t get_temp_table_id() { return ++temp_table_count_; } int64_t get_anonymous_view_id() { return ++anonymous_view_count_; } ObQueryHint &get_query_hint_for_update() { return query_hint_; }; const ObQueryHint &get_query_hint() const { return query_hint_; }; const ObGlobalHint &get_global_hint() const { return query_hint_.get_global_hint(); } int get_qb_name(int64_t stmt_id, ObString &qb_name) const { return query_hint_.get_qb_name(stmt_id, qb_name); } void set_literal_stmt_type(const stmt::StmtType type) { literal_stmt_type_ = type; } stmt::StmtType get_literal_stmt_type() const { return literal_stmt_type_; } inline common::ObString &get_sql_stmt() { return sql_stmt_; } inline const common::ObString &get_sql_stmt() const { return sql_stmt_; } inline void set_sql_stmt(const char *sql, int32_t sql_len) { sql_stmt_.assign_ptr(sql, sql_len); } inline void set_sql_stmt(const common::ObString sql_stmt) { sql_stmt_ = sql_stmt; } void set_sql_stmt_coll_type(common::ObCollationType coll_type) { sql_stmt_coll_type_ = coll_type;} common::ObCollationType get_sql_stmt_coll_type() { return sql_stmt_coll_type_; } void set_prepare_param_count(const int64_t prepare_param_count) { prepare_param_count_ = prepare_param_count; } int64_t get_prepare_param_count() const { return prepare_param_count_; } bool is_prepare_stmt() const { return is_prepare_stmt_; } void set_is_prepare_stmt(bool is_prepare) { is_prepare_stmt_ = is_prepare; } bool has_nested_sql() const { return has_nested_sql_; } void set_has_nested_sql(bool has_nested_sql) { has_nested_sql_ = has_nested_sql; } bool has_dblink() const { return has_dblink_; } void set_has_dblink(bool v) { has_dblink_ = v; } void set_timezone_info(const common::ObTimeZoneInfo *tz_info) { tz_info_ = tz_info; } const common::ObTimeZoneInfo *get_timezone_info() const { return tz_info_; } int add_local_session_vars(ObIAllocator *alloc, const ObLocalSessionVar &local_session_var, int64_t &idx); public: static const int64_t CALCULABLE_EXPR_NUM = 1; typedef common::ObSEArray CalculableItems; public: int64_t question_marks_count_; CalculableItems calculable_items_; //array binding param exprs, mark the all array binding param expr in the batch stmt common::ObSEArray ab_param_exprs_; common::ObSArray global_dependency_tables_; bool fetch_cur_time_; bool is_contain_virtual_table_; bool is_contain_inner_table_; bool is_contain_select_for_update_; bool has_dml_write_stmt_; bool ins_values_batch_opt_; uint64_t available_tb_id_; int64_t stmt_count_; int64_t subquery_count_; int64_t temp_table_count_; int64_t anonymous_view_count_; // record all system variables or user variables in this statement common::ObSArray variables_; common::ObSArray all_plan_const_param_constraints_; common::ObSArray all_possible_const_param_constraints_; common::ObSArray all_equal_param_constraints_; common::ObSEArray var_init_exprs_; common::ObDList all_pre_calc_constraints_; common::ObSArray all_expr_constraints_; common::ObSArray all_priv_constraints_; common::ObSArray all_local_session_vars_; common::ObSArray all_user_variable_; common::hash::ObHashMap calculable_expr_results_; bool need_match_all_params_; //only used for matching plans bool has_udf_; bool disable_udf_parallel_; //used to deterministic pl udf parallel execute bool has_is_table_; // used to mark query has information schema table ObSqlSchemaGuard sql_schema_guard_; share::schema::ObReferenceObjTable reference_obj_tables_; bool is_table_gen_col_with_udf_; // for data consistent check ObQueryHint query_hint_; #ifdef OB_BUILD_SPM bool is_spm_evolution_; #endif stmt::StmtType literal_stmt_type_; common::ObString sql_stmt_; common::ObCollationType sql_stmt_coll_type_; int64_t prepare_param_count_; bool is_prepare_stmt_; bool has_nested_sql_; const common::ObTimeZoneInfo *tz_info_; uint64_t res_map_rule_id_; int64_t res_map_rule_param_idx_; ObDMLStmt *root_stmt_; uint64_t optimizer_features_enable_version_; union { int8_t udf_flag_; struct { int8_t has_pl_udf_ : 1; // used to mark sql contain pl udf int8_t udf_has_select_stmt_ : 1; // udf has select stmt, not contain other dml stmt int8_t udf_has_dml_stmt_ : 1; // udf has dml stmt int8_t has_dblink_udf_ : 1; // udf is dblink udf int8_t reserved_:4; }; }; bool has_dblink_; }; } /* ns sql*/ } /* ns oceanbase */ #endif //OCEANBASE_SQL_CONTEXT_