init push
This commit is contained in:
329
src/sql/ob_sql.h
Normal file
329
src/sql/ob_sql.h
Normal file
@ -0,0 +1,329 @@
|
||||
/**
|
||||
* 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_
|
||||
#define OCEANBASE_SQL_OB_SQL_
|
||||
|
||||
#include "lib/string/ob_string.h"
|
||||
#include "lib/net/ob_addr.h"
|
||||
#include "share/partition_table/ob_partition_location_cache.h"
|
||||
#include "share/schema/ob_schema_struct.h"
|
||||
#include "sql/ob_sql_context.h"
|
||||
#include "sql/resolver/prepare/ob_execute_stmt.h"
|
||||
#include "sql/resolver/prepare/ob_deallocate_stmt.h"
|
||||
#include "sql/plan_cache/ob_plan_cache.h"
|
||||
#include "sql/plan_cache/ob_plan_cache_manager.h"
|
||||
#include "sql/code_generator/ob_code_generator_impl.h"
|
||||
#include "sql/monitor/ob_monitor_info_manager.h"
|
||||
|
||||
namespace test {
|
||||
class TestOptimizerUtils;
|
||||
}
|
||||
|
||||
namespace oceanbase {
|
||||
|
||||
namespace share {
|
||||
class ObRsMgr;
|
||||
} // end of namespace share
|
||||
namespace share {
|
||||
namespace schema {
|
||||
class ObMaxConcurrentParam;
|
||||
class ObOutlineInfo;
|
||||
} // namespace schema
|
||||
} // namespace share
|
||||
namespace common {
|
||||
class ObOptStatManager;
|
||||
}
|
||||
namespace sql {
|
||||
struct ObStmtPrepareResult;
|
||||
class ObIVirtualTableIteratorFactory;
|
||||
class ObSqlCtx;
|
||||
class ObResultSet;
|
||||
|
||||
// this class is the main interface for sql module
|
||||
class ObSql {
|
||||
|
||||
static const int64_t max_error_length;
|
||||
static const int64_t SQL_MEM_SIZE_LIMIT;
|
||||
|
||||
public:
|
||||
/// init SQL module
|
||||
int init(common::ObStatManager* stat_mgr, common::ObOptStatManager* opt_stat_mgr,
|
||||
rpc::frame::ObReqTransport* transport, storage::ObPartitionService* partition_service,
|
||||
common::ObIDataAccessService* vt_partition_service, share::ObIPartitionLocationCache* partition_loc_cache,
|
||||
common::ObAddr& addr, share::ObRsMgr& rs_mgr);
|
||||
void destroy();
|
||||
|
||||
public:
|
||||
/// print statatistics of SQL module
|
||||
void stat();
|
||||
|
||||
public:
|
||||
// These interface are one one mapping whit MySQL request type currently
|
||||
|
||||
// Interface of SQL Engine for OB_MYSQL_COM_QUERY request
|
||||
//
|
||||
// Handle all OB_MYSQL_COM_QUERY request from mysqlclient
|
||||
// There are two kinds of OB_MYSQL_COM_QUERY request
|
||||
// 1. general query such as "select * from table_test"
|
||||
// 2. text prepare such as "prepare stmt from select * from table_test"
|
||||
//
|
||||
// @param stmt[in] input sql string
|
||||
// @param context[in] sql context
|
||||
// @param result[out]
|
||||
//
|
||||
// @return oceanbase error code defined in lib/ob_errno.def
|
||||
virtual int stmt_query(const common::ObString& stmt, ObSqlCtx& context, ObResultSet& result);
|
||||
int handle_remote_query(const ObRemoteSqlInfo& remote_sql_info, ObSqlCtx& context, ObExecContext& exec_ctx,
|
||||
ObPhysicalPlan*& plan, CacheRefHandleID& ref_handle_id);
|
||||
int handle_batch_req(const int type, const ObReqTimestamp& req_ts, const char* buf, int32_t size);
|
||||
virtual int stmt_prepare(
|
||||
const common::ObString& stmt, ObSqlCtx& context, ObResultSet& result, bool is_inner_sql = true);
|
||||
// is_inner_sql: Determine whether the call is an external request preparation,
|
||||
// or internal sql or pl internal sql
|
||||
|
||||
/** Interface of SQL Engine for COM_
|
||||
* @param stmt_id [in]
|
||||
* @param params [in]
|
||||
* @param context [in]
|
||||
* @param result [out]
|
||||
*/
|
||||
virtual int stmt_execute(const ObPsStmtId stmt_id, const stmt::StmtType stmt_type, const ParamStore& params,
|
||||
ObSqlCtx& context, ObResultSet& result, bool is_inner_sql);
|
||||
|
||||
// Interface of SQL Engine for OB_MYSQL_COM_FIELD_LIST request
|
||||
//
|
||||
// @brief: list fields of the specific table with some condition
|
||||
//
|
||||
// @param table_name [in]
|
||||
// @param wild_str[in]
|
||||
// @param context [in]
|
||||
// @param result [out]
|
||||
//
|
||||
// @return oceanbase error code defined in share/ob_errno.h
|
||||
int stmt_list_field(
|
||||
const common::ObString& table_name, const common::ObString& wild_str, ObSqlCtx& context, ObResultSet& result);
|
||||
// Get plan cache by tenant id
|
||||
// if not exist, create a new plan cacha object
|
||||
//
|
||||
// @param tenant_id [in]
|
||||
//
|
||||
// @return Return ObPlanCache if get/create success, else return NULL
|
||||
ObPlanCache* get_plan_cache(uint64_t tenant_id, const ObPCMemPctConf& pc_mem_conf);
|
||||
ObPsCache* get_ps_cache(const uint64_t tenant_id, const ObPCMemPctConf& pc_mem_conf);
|
||||
|
||||
int revert_plan_cache(uint64_t tenant_id);
|
||||
|
||||
ObPlanCacheManager* get_plan_cache_manager()
|
||||
{
|
||||
return &plan_cache_manager_;
|
||||
}
|
||||
|
||||
int64_t get_execution_id()
|
||||
{
|
||||
return ATOMIC_AAF(&execution_id_, 1);
|
||||
}
|
||||
int64_t get_px_sequence_id()
|
||||
{
|
||||
return ATOMIC_AAF(&px_sequence_id_, 1);
|
||||
}
|
||||
// calculate calculable expr
|
||||
static int calc_pre_calculable_exprs(ObExecContext& exec_ctx, ObDMLStmt& stmt, ObPhysicalPlan& phy_plan);
|
||||
|
||||
static int calc_pre_calculable_exprs(common::ObIArray<ObHiddenColumnItem>& calculable_exprs, ObExecContext& exec_ctx,
|
||||
ObDMLStmt& stmt, ObPhysicalPlan& phy_plan);
|
||||
|
||||
static int calc_pre_calculable_exprs(const ObDMLStmt& stmt,
|
||||
const common::ObIArray<ObHiddenColumnItem>& calculable_exprs, const bool is_ignore_stmt, ObExecContext& exec_ctx,
|
||||
ObPhysicalPlan& phy_plan);
|
||||
|
||||
// simplyfy and rewrite stmt
|
||||
static int transform_stmt(ObSqlSchemaGuard* sql_schema_guard,
|
||||
share::ObIPartitionLocationCache* partition_location_cache, storage::ObPartitionService* partition_service,
|
||||
common::ObStatManager* stat_mgr, common::ObOptStatManager* opt_stat_mgr, common::ObAddr* self_addr,
|
||||
int64_t merged_version, ObPhysicalPlan* phy_plan, ObExecContext& exec_ctx, ObDMLStmt*& stmt);
|
||||
|
||||
// optimize stmt, generate logical_plan
|
||||
static int optimize_stmt(
|
||||
ObOptimizer& optimizer, const ObSQLSessionInfo& session_info, ObDMLStmt& stmt, ObLogPlan*& logical_plan);
|
||||
|
||||
static int analyze_table_stat_version(
|
||||
share::schema::ObSchemaGetterGuard* schema_guard, common::ObOptStatManager* opt_stat_manager, ObDMLStmt& stmt);
|
||||
|
||||
const common::ObAddr& get_addr() const
|
||||
{
|
||||
return self_addr_;
|
||||
}
|
||||
|
||||
int init_result_set(ObSqlCtx& context, ObResultSet& result_set);
|
||||
|
||||
public:
|
||||
// for sql test only
|
||||
friend bool compare_stmt(const char* schema_file, const char* str1, const char* str2);
|
||||
int fill_result_set(const ObPsStmtId stmt_id, const ObPsStmtInfo& stmt_info, ObResultSet& result);
|
||||
|
||||
public:
|
||||
ObSql()
|
||||
: inited_(false),
|
||||
stat_mgr_(NULL),
|
||||
opt_stat_mgr_(NULL),
|
||||
transport_(NULL),
|
||||
partition_service_(NULL),
|
||||
vt_partition_service_(NULL),
|
||||
rs_mgr_(NULL),
|
||||
execution_id_(0),
|
||||
px_sequence_id_(0)
|
||||
{}
|
||||
|
||||
virtual ~ObSql()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
static int construct_not_paramalize(
|
||||
const ObIArray<int64_t>& offsets, const ParamStore& param_store, ObPlanCacheCtx& plan_ctx);
|
||||
static int construct_no_check_type_params(const ObIArray<int64_t>& offsets, ParamStore& param_store);
|
||||
static int construct_ps_param(const ParamStore& params, ObPlanCacheCtx& phy_ctx);
|
||||
|
||||
storage::ObPartitionService* get_partition_service() const
|
||||
{
|
||||
return partition_service_;
|
||||
}
|
||||
|
||||
private:
|
||||
// disallow copy
|
||||
ObSql(const ObSql& other);
|
||||
ObSql& operator=(const ObSql& other);
|
||||
|
||||
private:
|
||||
int construct_param_store(const ParamStore& params, ParamStore& param_store);
|
||||
int do_real_prepare(const ObString& stmt, ObSqlCtx& context, ObResultSet& result, bool is_inner_sql);
|
||||
|
||||
int do_add_ps_cache(const ObString& sql, int64_t param_cnt, share::schema::ObSchemaGetterGuard& schema_guard,
|
||||
stmt::StmtType stmt_type, ObResultSet& result, bool is_inner_sql);
|
||||
|
||||
int fill_result_set(ObResultSet& result, ObSqlCtx* context, const bool is_ps_mode, ObStmt& stmt);
|
||||
|
||||
int handle_ps_prepare(const common::ObString& stmt, ObSqlCtx& context, ObResultSet& result, bool is_inner_sql);
|
||||
|
||||
int handle_ps_execute(const ObPsStmtId stmt_id, const stmt::StmtType stmt_type, const ParamStore& params,
|
||||
ObSqlCtx& context, ObResultSet& result, bool is_inner_sql);
|
||||
|
||||
int handle_text_query(const common::ObString& stmt, ObSqlCtx& context, ObResultSet& result);
|
||||
int handle_physical_plan(const common::ObString& trimed_stmt, ObSqlCtx& context, ObResultSet& result,
|
||||
ObPlanCacheCtx& pc_ctx, const int get_plan_err);
|
||||
// @brief Generate 'stmt' from syntax tree
|
||||
// @param parse_result[in] syntax tree
|
||||
// @param select_item_param_infos select_item_param_infos from fast parser
|
||||
// @param context[in] sql context
|
||||
// @param allocator[in] memory allocator
|
||||
// @param result_plan[out]
|
||||
// @param result[out] - the id of the explain plan text column
|
||||
// @retval OB_SUCCESS execute success
|
||||
// @retval OB_SOME_ERROR special errno need to handle
|
||||
int generate_stmt(ParseResult& parse_result, ObPlanCacheCtx* pc_ctx, ObSqlCtx& context, ObIAllocator& allocator,
|
||||
ObResultSet& result, ObStmt*& basic_stmt);
|
||||
|
||||
// Generate Physical Plan for given syntax tree
|
||||
// called by handle_text_query
|
||||
// && stmt_prepare && stmt_execute when necessary
|
||||
//
|
||||
// @param parse_result[in] syntax tree
|
||||
// @param select_item_param_infos[in] select_item_param_infos from fast parser
|
||||
// @param context[in] sql context
|
||||
// @param allocator[in] memory allocator
|
||||
// @param result[out] result set include physical plan generated
|
||||
int generate_physical_plan(ParseResult& parse_result, ObPlanCacheCtx* pc_ctx, ObSqlCtx& context, ObResultSet& result,
|
||||
const bool is_ps_mode = false);
|
||||
|
||||
int init_baseline_info(const ObPlanCacheCtx& pc_ctx, ObPhysicalPlan* plan);
|
||||
|
||||
int check_baseline(ObPhysicalPlan* plan, ObPlanCacheCtx& pc_ctx);
|
||||
|
||||
// generate physical_plan
|
||||
static int code_generate(ObSqlCtx& sql_ctx, ObResultSet& result, ObDMLStmt* stmt,
|
||||
share::schema::ObStmtNeedPrivs& stmt_need_privs, share::schema::ObStmtOraNeedPrivs& stmt_ora_need_privs,
|
||||
ObLogPlan* logical_plan, ObPhysicalPlan*& phy_plan);
|
||||
|
||||
int sanity_check(ObSqlCtx& context);
|
||||
|
||||
int init_exec_context(const ObSqlCtx& context, ObExecutorRpcImpl& exec_rpc, obrpc::ObCommonRpcProxy& rs_proxy,
|
||||
obrpc::ObSrvRpcProxy& srv_proxy, const ObVirtualTableCtx& vt_ctx, ObExecContext& exec_ctx);
|
||||
|
||||
//@brief replace and mark bool filter('1+1 and c1 = 1', '0 or c1 =1', 1+1 and 0 are considered
|
||||
// as bool filters) in stmt filters, filters include where conditions, join conditions and
|
||||
// having filters. This is used for distinguish true/false filter in plan.
|
||||
static int replace_stmt_bool_filter(ObExecContext& ctx, ObDMLStmt* stmt);
|
||||
|
||||
//@brief replace bool filter in expr. Only search 'T_OP_AND' and 'T_OP_OR' expr type, and
|
||||
// replace const expr to bool(tinyint) value.
|
||||
static int replace_expr_bool_filter(ObSQLSessionInfo* session, ObRawExpr* expr, ParamStore& params);
|
||||
static int replace_joined_table_bool_filter(ObSQLSessionInfo* session, JoinedTable& joined_table, ParamStore& params);
|
||||
int transform_stmt_with_outline(ObPlanCacheCtx& pc_ctx, ObOutlineState& outline_state, common::ObString& rewrite_sql);
|
||||
int get_outline_info(ObPlanCacheCtx& pc_ctx, const ObString& outline_key,
|
||||
const share::schema::ObOutlineInfo*& outline_info, bool& outline_with_sql_id);
|
||||
int handle_large_query(int tmp_ret, ObResultSet& result, bool& need_disconnect, ObExecContext& exec_ctx);
|
||||
int handle_parallel_query(ObResultSet& result, bool& need_disconnect);
|
||||
int pc_get_plan_and_fill_result(
|
||||
ObPlanCacheCtx& pc_ctx, ObResultSet& result_set, int& get_plan_err, bool& need_disconnect);
|
||||
int pc_get_plan(ObPlanCacheCtx& pc_ctx, ObPhysicalPlan*& plan, int& get_plan_err, bool& need_disconnect);
|
||||
|
||||
// Add a hint to the original sql, the hint comes from the outline or spm
|
||||
int rewrite_query_sql(ObPlanCacheCtx& pc_ctx, ObOutlineState& outline_state, common::ObString& rewrite_sql);
|
||||
|
||||
int parser_and_check(const ObString& outlined_stmt, ObExecContext& exec_ctx, ObPlanCacheCtx& pc_ctx,
|
||||
ParseResult& parse_result, int get_plan_err, bool& add_plan_to_pc, bool& is_enable_transform_tree);
|
||||
int handle_parser(const ObString& outlined_stmt, ObExecContext& exec_ctx, ObPlanCacheCtx& pc_ctx,
|
||||
ParseResult& parse_result, int get_plan_err, bool& add_plan_to_pc, bool& is_enable_transform_tree);
|
||||
|
||||
int check_batched_multi_stmt_after_parser(
|
||||
ObPlanCacheCtx& pc_ctx, ParseResult& parse_result, bool add_plan_to_pc, bool& is_valid);
|
||||
int check_batched_multi_stmt_after_resolver(ObPlanCacheCtx& pc_ctx, const ObStmt& stmt, bool& is_valid);
|
||||
|
||||
int replace_const_expr(common::ObIArray<ObRawExpr*>& raw_exprs, ParamStore& param_store);
|
||||
int replace_const_expr(ObRawExpr* raw_expr, ParamStore& param_store);
|
||||
int generate_sql_id(ObPlanCacheCtx& pc_ctx, bool add_plan_to_pc);
|
||||
int pc_add_plan(ObPlanCacheCtx& pc_ctx, ObResultSet& result, ObOutlineState& outline_state, ObPlanCache* plan_cache);
|
||||
// Check whether the parameterized template SQL can be prepared
|
||||
void check_template_sql_can_be_prepare(ObPlanCacheCtx& pc_ctx, ObPhysicalPlan& plan);
|
||||
int execute_get_plan(ObPlanCache& plan_cache, ObPlanCacheCtx& pc_ctx, ObPhysicalPlan*& plan);
|
||||
int after_get_plan(ObPlanCacheCtx& pc_ctx, ObSQLSessionInfo& session, ObPhysicalPlan* plan, bool from_plan_cache,
|
||||
const ParamStore* ps_params);
|
||||
int need_check_baseline(const ObPlanCacheCtx& pc_ctx, const ObPhysicalPlan& plan, bool& need_check);
|
||||
int need_add_plan(const ObPlanCacheCtx& ctx, ObResultSet& result, bool is_enable_pc, bool& need_add_plan);
|
||||
|
||||
template <typename ProcessorT>
|
||||
int handle_remote_batch_req(const ObReqTimestamp& req_ts, const char* buf, int32_t size);
|
||||
|
||||
typedef hash::ObHashMap<uint64_t, ObPlanCache*> PlanCacheMap;
|
||||
friend class ::test::TestOptimizerUtils;
|
||||
|
||||
private:
|
||||
bool inited_;
|
||||
// BEGIN Global singleton dependent interface
|
||||
common::ObStatManager* stat_mgr_;
|
||||
common::ObOptStatManager* opt_stat_mgr_;
|
||||
rpc::frame::ObReqTransport* transport_;
|
||||
storage::ObPartitionService* partition_service_;
|
||||
common::ObIDataAccessService* vt_partition_service_;
|
||||
// END Global singleton dependent interface
|
||||
|
||||
ObPlanCacheManager plan_cache_manager_;
|
||||
common::ObAddr self_addr_;
|
||||
share::ObRsMgr* rs_mgr_;
|
||||
volatile int64_t execution_id_;
|
||||
volatile uint64_t px_sequence_id_;
|
||||
};
|
||||
} // end namespace sql
|
||||
} // end namespace oceanbase
|
||||
|
||||
#endif // OCEANBASE_SQL_OB_SQL_
|
||||
Reference in New Issue
Block a user