init push

This commit is contained in:
oceanbase-admin
2021-05-31 22:56:52 +08:00
commit cea7de1475
7020 changed files with 5689869 additions and 0 deletions

790
src/sql/ob_sql_utils.h Normal file
View File

@ -0,0 +1,790 @@
/**
* 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_SQL_UTILS_H
#define _OCEANBASE_SQL_OB_SQL_UTILS_H
#include "common/ob_range.h"
#include "common/object/ob_object.h"
#include "lib/container/ob_vector.h"
#include "lib/container/ob_2d_array.h"
#include "share/partition_table/ob_partition_location.h"
#include "share/partition_table/ob_partition_location_cache.h"
#include "sql/ob_phy_table_location.h"
#include "sql/ob_sql_define.h"
#include "sql/parser/parse_node.h"
#include "sql/resolver/ob_stmt_type.h"
#include "sql/optimizer/ob_phy_table_location_info.h"
namespace oceanbase {
namespace common {
class ObStatManager;
}
namespace sql {
class RowDesc;
class ObSQLSessionInfo;
class ObRawExpr;
class ObRawExprPointer;
class ObStmt;
class ObDMLStmt;
class ObOpRawExpr;
class ObTaskExecutorCtx;
class ObTableLocation;
class ObPhyTableLocation;
class ObQueryRange;
class ObSqlExpression;
class ObPhysicalPlan;
class ObExprResType;
class ObStmtHint;
struct ObTransformerCtx;
typedef common::ObSEArray<common::ObNewRange*, 1, common::ModulePageAllocator, true> ObQueryRangeArray;
typedef common::ObSEArray<bool, 2, common::ModulePageAllocator, true> ObGetMethodArray;
typedef common::Ob2DArray<ObObjParam, common::OB_MALLOC_BIG_BLOCK_SIZE, common::ObWrapperAllocator, false> ParamStore;
struct EstimatedPartition {
common::ObPartitionKey pkey_;
common::ObAddr addr_;
int64_t row_count_;
EstimatedPartition() : pkey_(), addr_(), row_count_(0)
{}
bool is_valid() const
{
return pkey_.is_valid() && addr_.is_valid();
}
void reset()
{
pkey_.reset();
addr_.reset();
row_count_ = 0;
}
void set(const common::ObPartitionKey& key, const common::ObAddr& addr, const int64_t row_count)
{
pkey_ = key;
addr_ = addr;
row_count_ = row_count;
}
TO_STRING_KV(K_(pkey), K_(addr), K_(row_count));
};
struct ObHiddenColumnItem {
ObHiddenColumnItem()
{
expr_ = NULL;
hidden_idx_ = common::OB_INVALID_INDEX;
}
ObRawExpr* expr_;
int64_t hidden_idx_;
TO_STRING_KV(K_(hidden_idx));
};
class ObSQLUtils {
public:
const static int64_t WITHOUT_FUNC_REGEXP = 1;
const static int64_t WITHOUT_FUNC_ADDR_TO_PARTITION_ID = 2;
const static int64_t OB_MYSQL50_TABLE_NAME_PREFIX_LENGTH = 9;
const static int64_t NO_VALUES = -1;
const static int64_t VALUE_LIST_LEVEL = 0;
const static int64_t VALUE_VECTOR_LEVEL = 1;
static bool is_trans_commit_need_disconnect_err(int err);
static void check_if_need_disconnect_after_end_trans(
const int end_trans_err, const bool is_rollback, const bool is_explicit, bool& is_need_disconnect);
/**
* This function gets a list of partition ids from a list of ranges
* and a partition func.
*
* The range array is assumed to only contain single_value ranges and
* the partiton_ids will contain all the resulted partition ids without
* duplicates.
*/
static int calc_partition_ids(const common::ObIArray<common::ObNewRange*>& ranges,
const ObSqlExpression& partition_func, const uint64_t part_num, common::ObIArray<uint64_t>& partition_ids);
static int get_phy_plan_type(common::ObIArray<share::ObPartitionLocation>& part_location_set,
const common::ObAddr& my_address, ObPhyPlanType& plan_type);
static int has_local_leader_replica(const ObPartitionLocationIArray& part_array, const common::ObAddr& addr,
common::ObPartitionKey& key, bool& has_local);
static int has_local_replica(const ObPhyPartitionLocationInfoIArray& part_loc_info_array, const common::ObAddr& addr,
common::ObPartitionKey& key, bool& has_local);
static int find_all_local_replica(const ObPhyPartitionLocationInfoIArray& part_loc_info_array,
const common::ObAddr& addr, common::ObIArray<common::ObPartitionKey>& keys);
static int replace_questionmarks(ParseNode* tree, const ParamStore& params);
static int calc_const_or_calculable_expr(const stmt::StmtType stmt_type, ObSQLSessionInfo* session,
const ObRawExpr* raw_expr, common::ObObj& result, const ParamStore* params, common::ObIAllocator& allocator);
static int calc_simple_expr_without_row(const stmt::StmtType stmt_type, ObSQLSessionInfo* session,
const ObRawExpr* raw_expr, common::ObObj& result, const ParamStore* params, common::ObIAllocator& allocator);
static int calc_raw_expr_without_row(ObExecContext& exec_ctx, const ObRawExpr* raw_expr, ObObj& result,
const ParamStore* params, ObIAllocator& allocator);
static int calc_sql_expression_without_row(ObExecContext& exec_ctx, const ObISqlExpression& expr, ObObj& result);
static int calc_const_expr(const ObRawExpr* expr, const ParamStore* params, common::ObObj& result, bool& need_check);
static int get_param_value(
const common::ObObj& param, const ParamStore& params_array, ObObjParam& result, bool& need_check);
static int get_param_value(
const common::ObObj& param, const ParamStore& params_array, ObObj& result, bool& need_check);
template <class T>
static int get_param_value(const common::ObObj& param, const ParamStore& params_array, T& result, bool& need_check);
static int calc_calculable_expr(const stmt::StmtType stmt_type, ObSQLSessionInfo* session, const ObRawExpr* expr,
common::ObObj& result, common::ObIAllocator* allocator, const ParamStore& params_array);
static int calc_const_expr(const stmt::StmtType stmt_type, ObExecContext& exec_ctx, const ObRawExpr* expr,
common::ObObj& result, common::ObIAllocator* allocator, const ParamStore& params_array);
static int calc_const_expr(const stmt::StmtType stmt_type, ObSQLSessionInfo* session, const ObRawExpr& expr,
ObObj& result, ObIAllocator& allocator, const ParamStore& params_array, ObExecContext* exec_ctx = NULL);
static int calc_const_expr(ObSQLSessionInfo* session, const ObRawExpr* expr, const ParamStore& params,
ObIAllocator& allocator, common::ObObj& result);
static int convert_calculable_expr_to_question_mark(ObDMLStmt& stmt, ObRawExpr*& expr, ObTransformerCtx& ctx);
static int make_generated_expression_from_str(const common::ObString& expr_str,
const share::schema::ObTableSchema& schema, const share::schema::ObColumnSchemaV2& gen_col,
const common::ObIArray<share::schema::ObColDesc>& col_ids, common::ObIAllocator& allocator,
common::ObISqlExpression*& expression);
static int make_generated_expression_from_str(const common::ObString& expr_str, ObSQLSessionInfo& session,
const share::schema::ObTableSchema& schema, const share::schema::ObColumnSchemaV2& gen_col,
const common::ObIArray<share::schema::ObColDesc>& col_ids, common::ObIAllocator& allocator,
common::ObISqlExpression*& expression, const bool make_column_expression);
static int make_default_expr_context(ObIAllocator& allocator, ObExprCtx& expr_ctx);
static int calc_sql_expression(const ObISqlExpression* expr, const share::schema::ObTableSchema& schema,
const ObIArray<share::schema::ObColDesc>& col_ids, const ObNewRow& row, ObIAllocator& allocator,
ObExprCtx& expr_ctx, ObObj& result);
static void destruct_default_expr_context(ObExprCtx& expr_ctx);
static int64_t get_usec();
static int check_and_convert_db_name(
const common::ObCollationType cs_type, const bool perserver_lettercase, common::ObString& name);
static int cvt_db_name_to_org(
share::schema::ObSchemaGetterGuard& schema_guard, const ObSQLSessionInfo* session, common::ObString& name);
static int check_and_convert_table_name(const common::ObCollationType cs_type, const bool perserve_lettercase,
common::ObString& name, const stmt::StmtType stmt_type = stmt::T_NONE, const bool is_index_table = false);
static int check_index_name(const common::ObCollationType cs_type, common::ObString& name);
static int check_column_name(const common::ObCollationType cs_type, common::ObString& name);
static int check_and_copy_column_alias_name(const common::ObCollationType cs_type, const bool is_auto_gen,
common::ObIAllocator* allocator, common::ObString& name);
static bool cause_implicit_commit(ParseResult& result);
static bool is_end_trans_stmt(const ParseResult& result);
static bool is_commit_stmt(const ParseResult& result);
static bool is_modify_tenant_stmt(ParseResult& result);
static bool is_mysql_ps_not_support_stmt(const ParseResult& result);
static bool is_readonly_stmt(ParseResult& result);
static int make_field_name(const char* src, int64_t len, const common::ObCollationType cs_type,
common::ObIAllocator* allocator, common::ObString& name);
static int set_compatible_cast_mode(const ObSQLSessionInfo* session, ObCastMode& cast_mode);
static int get_default_cast_mode(
const stmt::StmtType& stmt_type, const ObSQLSessionInfo* session, common::ObCastMode& cast_mode);
static int get_default_cast_mode(
const ObPhysicalPlan* plan, const ObSQLSessionInfo* session, common::ObCastMode& cast_mode);
static int get_default_cast_mode(const ObSQLSessionInfo* session, common::ObCastMode& cast_mode);
// CM_EXPLICIT_CAST, CM_ZERO_FILL, CM_STRICT_MODE
static int get_default_cast_mode(const bool is_explicit_cast, const uint32_t result_flag,
const ObSQLSessionInfo* session, common::ObCastMode& cast_mode);
static int check_well_formed_str(const ObString& src_str, const ObCollationType cs_type, ObString& dst_str,
bool& is_null, const bool is_strict_mode, const bool ret_error = false);
static int check_well_formed_str(
const common::ObObj& src, common::ObObj& dest, const bool is_strict_mode, const bool ret_error = false);
static void set_insert_update_scope(common::ObCastMode& cast_mode);
static bool is_insert_update_scope(common::ObCastMode& cast_mode);
static int get_outline_key(common::ObIAllocator& allocator, const ObSQLSessionInfo* session,
const common::ObString& query_sql, common::ObString& outline_key,
share::schema::ObMaxConcurrentParam::FixParamStore& fixed_param_store, ParseMode mode,
bool& has_questionmark_in_sql);
static int md5(const common::ObString& stmt, char* sql_id, int32_t len);
static int filter_hint_in_query_sql(common::ObIAllocator& allocator, const ObSQLSessionInfo& session,
const common::ObString& sql, common::ObString& param_sql);
static int filter_head_space(ObString& sql);
static int construct_outline_sql(common::ObIAllocator& allocator, const ObSQLSessionInfo& session,
const common::ObString& outline_content, const common::ObString& orig_sql, bool is_need_filter_hint,
common::ObString& outline_sql);
static int reconstruct_sql(
ObIAllocator& allocator, const ObStmt* stmt, ObString& sql, ObObjPrintParams print_params = ObObjPrintParams());
static int wrap_expr_ctx(const stmt::StmtType& stmt_type, ObExecContext& exec_ctx, common::ObIAllocator& allocator,
common::ObExprCtx& expr_ctx);
static int get_partition_service(ObTaskExecutorCtx& executor_ctx, int64_t table_id, ObIDataAccessService*& das);
/*static int calculate_phy_table_location(ObExecContext &exec_ctx,
ObPartMgr *part_mgr,
const common::ObIArray<ObObjParam> &params,
share::ObIPartitionLocationCache &location_cache,
const common::ObTimeZoneInfo *tz_info,
ObTableLocation &table_location,
ObPhyTableLocation &phy_location);*/
// use get_tablet_ranges instead.
static int extract_pre_query_range(const ObQueryRange& pre_query_range, common::ObIAllocator& allocator,
const ParamStore& param_store, ObQueryRangeArray& key_ranges, ObGetMethodArray get_method,
const ObDataTypeCastParams& dtc_params, common::ObIArray<int64_t>* range_pos = NULL);
static bool is_same_type(const ObExprResType& type1, const ObExprResType& type2);
static bool is_same_type(
const ObObjMeta& meta1, const ObObjMeta& meta2, const ObAccuracy& accuracy1, const ObAccuracy& accuracy2);
static bool is_same_type_for_compare(const ObObjMeta& meta1, const ObObjMeta& meta2);
static int get_partition_range(ObObj* start_row_key, ObObj* end_row_key, ObObj* function_obj,
const share::schema::ObPartitionFuncType part_type, const ObSqlExpression& part_expr, int64_t range_key_count,
uint64_t table_id, ObExprCtx& expr_ctx, common::ObNewRange& partition_range);
static int get_partition_range(ObObj* start_row_key, ObObj* end_row_key, ObObj* function_obj,
const share::schema::ObPartitionFuncType part_type, const ObExpr* part_expr, int64_t range_key_count,
uint64_t table_id, ObEvalCtx& eval_ctx, common::ObNewRange& partition_range);
static int revise_hash_part_object(common::ObObj& obj, const ObNewRow& row, const bool calc_oracle_hash,
const share::schema::ObPartitionFuncType part_type);
static int choose_best_partition_for_estimation(const ObPhyPartitionLocationInfoIArray& part_loc_info_array,
const common::ObAddr& addr, common::ObPartitionKey& key, common::ObStatManager& stat_manager, bool& has_local);
static int choose_best_partition_for_estimation(const ObPhyPartitionLocationInfoIArray& part_loc_info_array,
const common::ObAddr& addr, common::ObPartitionKey& key, bool& has_local);
static int choose_best_partition_for_estimation(const ObPhyPartitionLocationInfoIArray& part_loc_info_array,
storage::ObPartitionService* partition_service, common::ObStatManager& stat_manager, const ObAddr& local_addr,
const common::ObIArray<ObAddr>& addrs_list, const bool no_use_remote, EstimatedPartition& best_partition);
static int choose_best_partition_replica_addr(const ObAddr& local_addr,
const ObPhyPartitionLocationInfo& phy_part_loc_info, storage::ObPartitionService* partition_service,
ObAddr& selected_addr);
static int has_global_index(share::schema::ObSchemaGetterGuard* schema_guard, const uint64_t table_id, bool& exists);
static int wrap_column_convert_ctx(const common::ObExprCtx& expr_ctx, common::ObCastCtx& column_conv_ctx);
static void init_type_ctx(const ObSQLSessionInfo* session, ObExprTypeCtx& type_ctx);
/**
* the px framework switch.
* if the sql don't give a use_px and parallel hint, we wanna open the px framework in default.
*/
static bool use_px(const ObStmtHint& hint, bool dist_table = true);
static bool is_oracle_sys_view(const ObString& table_name);
static int extend_checker_stmt(ObExecContext& ctx, uint64_t table_id, uint64_t ref_table_id,
const common::ObIArray<int64_t>& part_ids, const bool is_weak);
static int make_whole_range(
ObIAllocator& allocator, const uint64_t ref_table_id, const int64_t rowkey_count, ObNewRange*& whole_range);
static int make_whole_range(
ObIAllocator& allocator, const uint64_t ref_table_id, const int64_t rowkey_count, ObNewRange& whole_range);
static int ConvertFiledNameAttribute(common::ObIAllocator& allocator, const common::ObString& src,
common::ObString& dst, const uint16_t collation_type);
static int clear_evaluated_flag(const ObExprPtrIArray& calc_exprs, ObEvalCtx& eval_ctx);
static int copy_and_convert_string_charset(common::ObIAllocator& allocator, const common::ObString& src,
common::ObString& dst, common::ObCollationType src_coll, common::ObCollationType dst_coll);
static int update_session_last_schema_version(
share::schema::ObMultiVersionSchemaService& schema_service, ObSQLSessionInfo& session_info);
static int extract_calc_expr_idx(ObDMLStmt& stmt, ObRawExpr* expr, int64_t old_idx, int64_t old_pre_param_size,
common::ObIArray<int64_t>& calculable_expr_idx);
static int recursively_extract_calc_expr_idx(ObDMLStmt& stmt, ObRawExpr* expr, int64_t old_idx,
int64_t old_pre_param_size, common::ObIArray<ObRawExpr*>& record_exprs,
common::ObIArray<int64_t>& calculable_expr_idx);
static int extract_calc_exprs(ObDMLStmt& stmt, ObRawExpr* expr, int64_t old_idx, int64_t old_pre_param_size,
common::ObIArray<ObHiddenColumnItem>& calculable_exprs);
static int recursively_extract_calc_exprs(common::ObIArray<ObHiddenColumnItem>& stmt_calc_exprs, ObRawExpr* expr,
int64_t old_idx, int64_t old_pre_param_size, common::ObIArray<ObRawExpr*>& record_exprs, bool& is_need_adjust,
common::ObIArray<ObHiddenColumnItem>& calc_exprs);
static int generate_new_name_with_escape_character(
common::ObIAllocator& allocator, const common::ObString& src, common::ObString& dest, bool is_oracle_mode);
static int check_table_version(
bool& equal, const DependenyTableStore& dependency_tables, share::schema::ObSchemaGetterGuard& schema_guard);
static int generate_view_definition_for_resolve(common::ObIAllocator& allocator,
common::ObCollationType connection_collation, const share::schema::ObViewSchema& view_schema,
common::ObString& view_definition);
static bool is_oracle_empty_string(const common::ObObjParam& param);
static int handle_audit_record(
bool need_retry, const ObExecuteMode exec_mode, ObSQLSessionInfo& session, ObExecContext& exec_ctx);
static int convert_sql_text_from_schema_for_resolve(
common::ObIAllocator& allocator, const common::ObDataTypeCastParams& dtc_params, ObString& sql_text);
static int convert_sql_text_to_schema_for_storing(
common::ObIAllocator& allocator, const common::ObDataTypeCastParams& dtc_params, ObString& sql_text);
static int print_identifier(char* buf, const int64_t buf_len, int64_t& pos,
common::ObCollationType connection_collation, const common::ObString& identifier_name);
private:
static int check_ident_name(const common::ObCollationType cs_type, common::ObString& name,
const bool check_for_path_char, const int64_t max_ident_len);
static bool check_mysql50_prefix(common::ObString& db_name);
struct SessionInfoCtx {
common::ObCollationType collation_type_;
common::ObTimeZoneInfo tz_info_;
};
}; // end of ObSQLUtils
/* used for acs plan */
struct ObAcsIndexInfo {
ObAcsIndexInfo()
: index_id_(common::OB_INVALID_ID),
index_name_(),
is_index_back_(false),
is_whole_range_(false),
prefix_filter_sel_(1.0),
column_id_(),
query_range_(NULL),
allocator_(NULL)
{}
ObAcsIndexInfo(common::ObIAllocator* allocator)
: index_id_(common::OB_INVALID_ID),
index_name_(),
is_index_back_(false),
is_whole_range_(false),
prefix_filter_sel_(1.0),
column_id_(allocator),
query_range_(NULL),
allocator_(allocator)
{}
virtual ~ObAcsIndexInfo();
int deep_copy(const ObAcsIndexInfo& other);
TO_STRING_KV(
K_(index_id), K_(index_name), K_(is_index_back), K_(is_whole_range), K_(prefix_filter_sel), K_(column_id));
uint64_t index_id_;
common::ObString index_name_;
bool is_index_back_;
bool is_whole_range_;
double prefix_filter_sel_;
common::ObFixedArray<uint64_t, common::ObIAllocator> column_id_;
ObQueryRange* query_range_;
common::ObIAllocator* allocator_;
};
class RelExprCheckerBase {
public:
const static int32_t FIELD_LIST_SCOPE;
const static int32_t WHERE_SCOPE;
const static int32_t GROUP_SCOPE;
const static int32_t HAVING_SCOPE;
/* const static int32_t INSERT_SCOPE; */
/* const static int32_t UPDATE_SCOPE; */
/* const static int32_t AGG_SCOPE; */
/* const static int32_t VARIABLE_SCOPE; */
/* const static int32_t WHEN_SCOPE; */
const static int32_t ORDER_SCOPE;
// const static int32_t EXPIRE_SCOPE;
// const static int32_t PARTITION_SCOPE;
const static int32_t FROM_SCOPE;
const static int32_t LIMIT_SCOPE;
// const static int32_t PARTITION_RANGE_SCOPE;
// const static int32_t INTO_SCOPE;
const static int32_t START_WITH_SCOPE;
const static int32_t CONNECT_BY_SCOPE;
const static int32_t JOIN_CONDITION_SCOPE;
const static int32_t EXTRA_OUTPUT_SCOPE;
public:
RelExprCheckerBase() : duplicated_checker_(), ignore_scope_(0)
{}
RelExprCheckerBase(int32_t ignore_scope) : duplicated_checker_(), ignore_scope_(ignore_scope)
{}
virtual ~RelExprCheckerBase()
{
duplicated_checker_.destroy();
}
bool is_ignore(int32_t ignore_scope)
{
return ignore_scope & ignore_scope_;
}
virtual int init(int64_t bucket_num = CHECKER_BUCKET_NUM);
virtual int add_expr(ObRawExpr*& expr) = 0;
int add_exprs(common::ObIArray<ObRawExpr*>& exprs);
protected:
static const int64_t CHECKER_BUCKET_NUM = 1000;
common::hash::ObHashSet<uint64_t, common::hash::NoPthreadDefendMode> duplicated_checker_;
int32_t ignore_scope_;
};
class RelExprChecker : public RelExprCheckerBase {
public:
RelExprChecker(common::ObIArray<ObRawExpr*>& rel_array) : RelExprCheckerBase(), rel_array_(rel_array)
{}
RelExprChecker(common::ObIArray<ObRawExpr*>& rel_array, int32_t ignore_scope)
: RelExprCheckerBase(ignore_scope), rel_array_(rel_array)
{}
virtual ~RelExprChecker()
{}
int add_expr(ObRawExpr*& expr);
private:
common::ObIArray<ObRawExpr*>& rel_array_;
};
class FastRelExprChecker : public RelExprCheckerBase {
public:
FastRelExprChecker(common::ObIArray<ObRawExpr*>& rel_array);
FastRelExprChecker(common::ObIArray<ObRawExpr*>& rel_array, int32_t ignore_scope);
virtual ~FastRelExprChecker();
int add_expr(ObRawExpr*& expr);
int dedup();
private:
common::ObIArray<ObRawExpr*>& rel_array_;
int64_t init_size_;
};
class RelExprPointerChecker : public RelExprCheckerBase {
public:
RelExprPointerChecker(common::ObIArray<ObRawExprPointer>& rel_array)
: RelExprCheckerBase(), rel_array_(rel_array), expr_id_map_()
{}
RelExprPointerChecker(common::ObIArray<ObRawExprPointer>& rel_array, int32_t ignore_scope)
: RelExprCheckerBase(ignore_scope), rel_array_(rel_array), expr_id_map_()
{}
virtual ~RelExprPointerChecker()
{}
virtual int init(int64_t bucket_num = CHECKER_BUCKET_NUM) override;
int add_expr(ObRawExpr*& expr);
private:
common::ObIArray<ObRawExprPointer>& rel_array_;
common::hash::ObHashMap<uint64_t, uint64_t, common::hash::NoPthreadDefendMode> expr_id_map_;
};
class AllExprPointerCollector : public RelExprCheckerBase {
public:
AllExprPointerCollector(common::ObIArray<ObRawExpr**>& rel_array) : RelExprCheckerBase(), rel_array_(rel_array)
{}
AllExprPointerCollector(common::ObIArray<ObRawExpr**>& rel_array, int32_t ignore_scope)
: RelExprCheckerBase(ignore_scope), rel_array_(rel_array)
{}
virtual ~AllExprPointerCollector()
{}
int add_expr(ObRawExpr*& expr);
private:
common::ObIArray<ObRawExpr**>& rel_array_;
};
struct ObSqlTraits {
char sql_id_[common::OB_MAX_SQL_ID_LENGTH + 1];
bool is_readonly_stmt_;
bool is_modify_tenant_stmt_;
bool is_cause_implicit_commit_;
bool is_commit_stmt_;
ObItemType stmt_type_;
ObSqlTraits();
void reset()
{
sql_id_[common::OB_MAX_SQL_ID_LENGTH] = '\0';
is_readonly_stmt_ = false;
is_modify_tenant_stmt_ = false;
is_cause_implicit_commit_ = false;
is_commit_stmt_ = false;
stmt_type_ = T_INVALID;
}
TO_STRING_KV(
K(is_readonly_stmt_), K(is_modify_tenant_stmt_), K(is_cause_implicit_commit_), K(is_commit_stmt_), K(stmt_type_));
};
template <typename ValueType>
class ObValueChecker {
public:
ObValueChecker() = delete;
constexpr ObValueChecker(ValueType min_value, ValueType max_value, int err_ret_code)
: min_value_(min_value), max_value_(max_value), err_ret_code_(err_ret_code)
{}
constexpr inline int validate(const ValueType& value) const
{
return (value < min_value_ || value > max_value_) ? err_ret_code_ : common::OB_SUCCESS;
}
constexpr inline int validate_str_length(const common::ObString& value) const
{
return (value.length() < min_value_ || value.length() > max_value_) ? err_ret_code_ : common::OB_SUCCESS;
}
TO_STRING_KV(K_(min_value), K_(max_value), K_(err_ret_code));
private:
ValueType min_value_;
ValueType max_value_;
int err_ret_code_;
};
template <typename ValueType>
class ObPointerChecker {
public:
ObPointerChecker() = delete;
constexpr ObPointerChecker(int err_ret_code) : err_ret_code_(err_ret_code)
{}
constexpr inline int validate(const ValueType* value) const
{
return (nullptr == value) ? err_ret_code_ : common::OB_SUCCESS;
}
TO_STRING_KV(K_(err_ret_code));
private:
int err_ret_code_;
};
template <typename T>
class ObEnumBitSet {
static const int MAX_ENUM_VALUE = 64;
static_assert(std::is_enum<T>::value, "typename must be a enum type");
static_assert(static_cast<int>(T::MAX_VALUE) < MAX_ENUM_VALUE, "Please add MAX_VALUE in enum class");
public:
inline ObEnumBitSet() : flag_(0)
{}
inline ObEnumBitSet(T value)
{
set_bit(value);
}
inline void reset()
{
flag_ = 0;
}
inline void set_bit(T bit_pos)
{
flag_ |= bit2flag(static_cast<int>(bit_pos));
}
inline bool test_bit(T bit_pos) const
{
return !!((flag_)&bit2flag(static_cast<int>(bit_pos)));
}
inline bool contain(const ObEnumBitSet& other) const
{
return (this & other) == other;
}
ObEnumBitSet<T>& operator|=(ObEnumBitSet<T> other)
{
this->flag_ |= other.flag_;
return *this;
}
ObEnumBitSet<T>& operator&=(ObEnumBitSet<T> other)
{
this->flag_ &= other.flag_;
return *this;
}
ObEnumBitSet<T> operator|(ObEnumBitSet<T> other) const
{
return ObEnumBitSet<T>(this->flag_ | other.flag_);
}
ObEnumBitSet<T> operator&(ObEnumBitSet<T> other) const
{
return ObEnumBitSet<T>(this->flag_ & other.flag_);
}
TO_STRING_KV(K_(flag));
private:
inline uint64_t bit2flag(int bit) const
{
uint64_t v = 1;
return v << bit;
}
uint64_t flag_;
OB_UNIS_VERSION(1);
};
OB_SERIALIZE_MEMBER_TEMP(template <typename T>, ObEnumBitSet<T>, flag_);
struct ObImplicitCursorInfo {
OB_UNIS_VERSION(1);
public:
ObImplicitCursorInfo()
: stmt_id_(common::OB_INVALID_INDEX),
affected_rows_(0),
found_rows_(0),
matched_rows_(0),
duplicated_rows_(0),
deleted_rows_(0)
{}
int merge_cursor(const ObImplicitCursorInfo& other);
TO_STRING_KV(K_(stmt_id), K_(affected_rows), K_(found_rows), K_(matched_rows), K_(duplicated_rows), K_(deleted_rows));
int64_t stmt_id_;
int64_t affected_rows_;
int64_t found_rows_;
int64_t matched_rows_;
int64_t duplicated_rows_;
int64_t deleted_rows_;
};
struct ObParamPosIdx {
OB_UNIS_VERSION_V(1);
public:
ObParamPosIdx() : pos_(0), idx_(0)
{}
ObParamPosIdx(int32_t pos, int32_t idx) : pos_(pos), idx_(idx)
{}
virtual ~ObParamPosIdx()
{}
TO_STRING_KV(N_POS, pos_, N_IDX, idx_);
int32_t pos_;
int32_t idx_;
};
class ObVirtualTableResultConverter {
public:
ObVirtualTableResultConverter()
: key_alloc_(nullptr),
key_cast_ctx_(),
output_row_types_(nullptr),
key_types_(nullptr),
key_with_tenant_ids_(nullptr),
has_extra_tenant_ids_(nullptr),
output_row_alloc_(),
init_alloc_(nullptr),
inited_row_(false),
convert_row_(),
output_row_cast_ctx_(),
base_table_id_(UINT64_MAX),
cur_tenant_id_(UINT64_MAX),
table_schema_(nullptr),
output_column_ids_(nullptr),
cols_schema_(),
tenant_id_col_id_(UINT64_MAX),
max_col_cnt_(INT64_MAX),
use_real_tenant_id_(false),
has_tenant_id_col_(false)
{}
~ObVirtualTableResultConverter()
{
destroy();
}
void destroy();
int reset_and_init(ObIAllocator* key_alloc, sql::ObSQLSessionInfo* session,
const common::ObIArray<ObObjMeta>* output_row_types, const common::ObIArray<ObObjMeta>* key_types,
const common::ObIArray<bool>* key_with_tenant_ids, const common::ObIArray<bool>* extra_tenant_id,
ObIAllocator* init_alloc, const share::schema::ObTableSchema* table_schema,
const common::ObIArray<uint64_t>* output_column_ids, const bool use_real_tenant_id, const bool has_tenant_id_col,
const int64_t max_col_cnt = INT64_MAX);
int init_without_allocator(const common::ObIArray<const share::schema::ObColumnSchemaV2*>& col_schemas,
const common::ObIArray<bool>* key_with_tenant_ids, uint64_t cur_tenant_id, uint64_t tenant_id_col_id,
const bool use_real_tenant_id);
int convert_key_ranges(ObIArray<ObNewRange>& key_ranges);
int convert_output_row(ObNewRow*& src_row);
int convert_output_row(
ObEvalCtx& eval_ctx, const common::ObIArray<ObExpr*>& src_exprs, const common::ObIArray<ObExpr*>& dst_exprs);
int convert_column(ObObj& obj, uint64_t column_id, uint64_t idx);
private:
int process_tenant_id(const ObIArray<bool>* extract_tenant_ids, const int64_t nth_col, ObIAllocator& allocator,
bool decode, ObObj& obj);
int convert_key(const ObRowkey& src, ObRowkey& dst, bool is_start_key, int64_t pos);
bool need_process_tenant_id(int64_t nth_col, ObObj& obj);
int get_all_columns_schema();
int init_output_row(int64_t cell_cnt);
int get_need_convert_key_ranges_pos(ObNewRange& key_range, int64_t& pos);
public:
// the memory that allocated must be reset by caller
ObIAllocator* key_alloc_;
ObCastCtx key_cast_ctx_;
const common::ObIArray<ObObjMeta>* output_row_types_;
const common::ObIArray<ObObjMeta>* key_types_;
const common::ObIArray<bool>* key_with_tenant_ids_;
const common::ObIArray<bool>* has_extra_tenant_ids_;
// every row must be reset
common::ObArenaAllocator output_row_alloc_;
// for init output row, lifecycle is from open to close(called destroy)
common::ObIAllocator* init_alloc_;
bool inited_row_;
common::ObNewRow convert_row_;
ObCastCtx output_row_cast_ctx_;
uint64_t base_table_id_;
uint64_t cur_tenant_id_;
const share::schema::ObTableSchema* table_schema_;
const common::ObIArray<uint64_t>* output_column_ids_;
common::ObArray<const share::schema::ObColumnSchemaV2*> cols_schema_;
uint64_t tenant_id_col_id_;
int64_t max_col_cnt_;
common::ObTimeZoneInfoWrap tz_info_wrap_;
bool use_real_tenant_id_;
bool has_tenant_id_col_;
};
class ObLinkStmtParam {
public:
static int write(char* buf, int64_t buf_len, int64_t& pos, int64_t param_idx);
static int read_next(const char* buf, int64_t buf_len, int64_t& pos, int64_t& param_idx);
static int64_t get_param_len();
private:
static const int64_t PARAM_LEN;
};
class ObSqlFatalErrExtraInfoGuard : public common::ObFatalErrExtraInfoGuard {
public:
ObSqlFatalErrExtraInfoGuard()
{
reset();
}
~ObSqlFatalErrExtraInfoGuard(){};
void reset()
{
tenant_id_ = OB_INVALID_TENANT_ID;
cur_sql_.reset();
plan_ = nullptr;
exec_ctx_ = nullptr;
}
void set_tenant_id(uint64_t tenant_id)
{
tenant_id_ = tenant_id;
}
void set_cur_sql(const common::ObString& cur_sql)
{
cur_sql_ = cur_sql;
}
void set_cur_plan(const ObPhysicalPlan* plan)
{
plan_ = plan;
}
void set_exec_context(ObExecContext* exec_ctx)
{
exec_ctx_ = exec_ctx;
}
DECLARE_TO_STRING;
private:
uint64_t tenant_id_;
common::ObString cur_sql_;
const ObPhysicalPlan* plan_;
ObExecContext* exec_ctx_;
};
} // namespace sql
} // namespace oceanbase
#endif