812 lines
30 KiB
C++
812 lines
30 KiB
C++
/**
|
|
* 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<ObTablePartitionInfo *> ObTablePartitionInfoArray;
|
|
//ObLocationConstraint如果只有一项, 则仅需要约束该location type是否一致;
|
|
// 如果有多项,则需要校验每一项location对应的物理分布是否一样
|
|
struct LocationConstraint;
|
|
typedef common::ObSEArray<LocationConstraint, 1, common::ModulePageAllocator, true> ObLocationConstraint;
|
|
typedef common::ObFixedArray<LocationConstraint, common::ObIAllocator> ObPlanLocationConstraint;
|
|
typedef common::ObSEArray<int64_t, 4, common::ModulePageAllocator, true> ObPwjConstraint;
|
|
typedef common::ObFixedArray<int64_t, common::ObIAllocator> 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<ObPwjConstraint *, 8, common::ModulePageAllocator, true> strict_constraints_;
|
|
// 严格partition wise join约束,要求用一个分组内的基表分区物理上相等。
|
|
// 每个分组是一个array,保存了对应基表在base_table_constraints_中的偏移
|
|
common::ObSEArray<ObPwjConstraint *, 8, common::ModulePageAllocator, true> 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<ObDupTabConstraint, 1, common::ModulePageAllocator, true> 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<ObString> *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<ObString> *get_queries() const { return batched_queries_; }
|
|
inline void set_batched_queries(const common::ObIArray<ObString> *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<ObString> *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_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_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<const share::schema::ObTableSchema *, 1> table_schemas_;
|
|
uint64_t next_link_table_id_;
|
|
// key is dblink_id, value is current scn.
|
|
common::hash::ObHashMap<uint64_t, uint64_t> 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<common::ObString> &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<int64_t> &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<ObTablePartitionInfo*, common::ObIAllocator> partition_infos_;
|
|
bool is_restore_;
|
|
common::ObFixedArray<common::ObString, common::ObIAllocator> related_user_var_names_;
|
|
//use for plan cache support dist plan
|
|
// 基表location约束,包括TABLE_SCAN算子上的基表和INSERT算子上的基表
|
|
common::ObFixedArray<LocationConstraint, common::ObIAllocator> base_constraints_;
|
|
// 严格partition wise join约束,要求同一个分组内的基表分区逻辑上和物理上都相等。
|
|
// 每个分组是一个array,保存了对应基表在base_table_constraints_中的偏移
|
|
common::ObFixedArray<ObPwjConstraint *, common::ObIAllocator> strict_constraints_;
|
|
// 严格partition wise join约束,要求用一个分组内的基表分区物理上相等。
|
|
// 每个分组是一个array,保存了对应基表在base_table_constraints_中的偏移
|
|
common::ObFixedArray<ObPwjConstraint *, common::ObIAllocator> 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<ObDupTabConstraint, common::ObIAllocator> 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<ObPCConstParamInfo> *all_plan_const_param_constraints_;
|
|
common::ObIArray<ObPCConstParamInfo> *all_possible_const_param_constraints_;
|
|
common::ObIArray<ObPCParamEqualInfo> *all_equal_param_constraints_;
|
|
common::ObDList<ObPreCalcExprConstraint> *all_pre_calc_constraints_;
|
|
common::ObIArray<ObExprConstraint> *all_expr_constraints_;
|
|
common::ObIArray<ObPCPrivInfo> *all_priv_constraints_;
|
|
bool need_match_all_params_; //only used for matching plans
|
|
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<int64_t, common::ObIAllocator> 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 reserved_ : 30;
|
|
};
|
|
};
|
|
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),
|
|
udf_has_select_stmt_(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_has_select_stmt_ = 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; }
|
|
void set_timezone_info(const common::ObTimeZoneInfo *tz_info) { tz_info_ = tz_info; }
|
|
const common::ObTimeZoneInfo *get_timezone_info() const { return tz_info_; }
|
|
|
|
public:
|
|
static const int64_t CALCULABLE_EXPR_NUM = 1;
|
|
typedef common::ObSEArray<ObHiddenColumnItem, CALCULABLE_EXPR_NUM, common::ModulePageAllocator, true> 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<ObRawExpr*, 4, common::ModulePageAllocator, true> ab_param_exprs_;
|
|
common::ObSArray<share::schema::ObSchemaObjVersion> 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<ObVarInfo, common::ModulePageAllocator, true> variables_;
|
|
common::ObSArray<ObPCConstParamInfo, common::ModulePageAllocator, true> all_plan_const_param_constraints_;
|
|
common::ObSArray<ObPCConstParamInfo, common::ModulePageAllocator, true> all_possible_const_param_constraints_;
|
|
common::ObSArray<ObPCParamEqualInfo, common::ModulePageAllocator, true> all_equal_param_constraints_;
|
|
common::ObDList<ObPreCalcExprConstraint> all_pre_calc_constraints_;
|
|
common::ObSArray<ObExprConstraint, common::ModulePageAllocator, true> all_expr_constraints_;
|
|
common::ObSArray<ObPCPrivInfo, common::ModulePageAllocator, true> all_priv_constraints_;
|
|
common::ObSArray<ObUserVarIdentRawExpr *, common::ModulePageAllocator, true> all_user_variable_;
|
|
common::hash::ObHashMap<uint64_t, ObObj, common::hash::NoPthreadDefendMode> 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_;
|
|
bool udf_has_select_stmt_; // udf has select stmt, not contain other dml stmt
|
|
};
|
|
} /* ns sql*/
|
|
} /* ns oceanbase */
|
|
#endif //OCEANBASE_SQL_CONTEXT_
|