[FEAT MERGE]implement user-defined rewrite rules
This commit is contained in:
@ -32,6 +32,7 @@
|
||||
#include "sql/engine/ob_physical_plan.h"
|
||||
#include "sql/plan_cache/ob_plan_cache_callback.h"
|
||||
#include "sql/plan_cache/ob_cache_object_factory.h"
|
||||
#include "sql/udr/ob_udr_mgr.h"
|
||||
#include "pl/ob_pl.h"
|
||||
#include "pl/ob_pl_package.h"
|
||||
#include "observer/ob_req_time_service.h"
|
||||
@ -389,13 +390,16 @@ int ObPlanCache::check_after_get_plan(int tmp_ret,
|
||||
ObPhysicalPlan *plan = NULL;
|
||||
bool need_late_compilation = false;
|
||||
ObJITEnableMode jit_mode = OFF;
|
||||
omt::ObTenantConfigGuard tenant_config(TENANT_CONF(MTL_ID()));
|
||||
ObPlanCacheCtx &pc_ctx = static_cast<ObPlanCacheCtx&>(ctx);
|
||||
|
||||
if (cache_obj != NULL && ObLibCacheNameSpace::NS_CRSR == cache_obj->get_ns()) {
|
||||
plan = static_cast<ObPhysicalPlan *>(cache_obj);
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_ISNULL(pc_ctx.sql_ctx_.session_info_)) {
|
||||
if (!tenant_config.is_valid()) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("tenant config is invalid", K(ret));
|
||||
} else if (OB_ISNULL(pc_ctx.sql_ctx_.session_info_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected null session info", K(ret));
|
||||
} else if (OB_FAIL(pc_ctx.sql_ctx_.session_info_->get_jit_enabled_mode(jit_mode))) {
|
||||
@ -404,17 +408,39 @@ int ObPlanCache::check_after_get_plan(int tmp_ret,
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) &&
|
||||
plan != NULL &&
|
||||
AUTO == jit_mode && // only use late compilation when jit_mode is auto
|
||||
OB_FAIL(need_late_compile(plan, need_late_compilation))) {
|
||||
LOG_WARN("failed to check for late compilation", K(ret));
|
||||
} else {
|
||||
// set context's need_late_compile_ for upper layer to proceed
|
||||
pc_ctx.sql_ctx_.need_late_compile_ = need_late_compilation;
|
||||
if (OB_SUCC(ret) && plan != NULL) {
|
||||
bool is_exists = false;
|
||||
sql::ObUDRMgr *rule_mgr = MTL(sql::ObUDRMgr*);
|
||||
// when the global rule version changes or enable_user_defined_rewrite_rules changes
|
||||
// it is necessary to check whether the physical plan are expired
|
||||
if ((plan->get_rule_version() != rule_mgr->get_rule_version()
|
||||
|| plan->is_enable_udr() != tenant_config->enable_user_defined_rewrite_rules)) {
|
||||
if (OB_FAIL(rule_mgr->fuzzy_check_by_pattern_digest(pc_ctx.get_normalized_pattern_digest(), is_exists))) {
|
||||
LOG_WARN("failed to fuzzy check by pattern digest", K(ret));
|
||||
} else if (is_exists || plan->is_rewrite_sql()) {
|
||||
ret = OB_OLD_SCHEMA_VERSION;
|
||||
LOG_TRACE("Obsolete user-defined rewrite rules require eviction plan", K(ret),
|
||||
K(is_exists), K(pc_ctx.raw_sql_), K(plan->is_enable_udr()), K(tenant_config->enable_user_defined_rewrite_rules),
|
||||
K(plan->is_rewrite_sql()), K(plan->get_rule_version()), K(rule_mgr->get_rule_version()));
|
||||
} else {
|
||||
plan->set_rule_version(rule_mgr->get_rule_version());
|
||||
plan->set_is_enable_udr(tenant_config->enable_user_defined_rewrite_rules);
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (AUTO == jit_mode && // only use late compilation when jit_mode is auto
|
||||
OB_FAIL(need_late_compile(plan, need_late_compilation))) {
|
||||
LOG_WARN("failed to check for late compilation", K(ret));
|
||||
} else {
|
||||
// set context's need_late_compile_ for upper layer to proceed
|
||||
pc_ctx.sql_ctx_.need_late_compile_ = need_late_compilation;
|
||||
}
|
||||
}
|
||||
}
|
||||
// if schema expired, update pcv set;
|
||||
if (OB_OLD_SCHEMA_VERSION == ret || (plan != NULL && plan->is_expired()) || need_late_compilation) {
|
||||
if (OB_OLD_SCHEMA_VERSION == ret
|
||||
|| (plan != NULL && plan->is_expired())
|
||||
|| need_late_compilation) {
|
||||
if (plan != NULL && plan->is_expired()) {
|
||||
LOG_INFO("the statistics of table is stale and evict plan.", K(plan->stat_));
|
||||
}
|
||||
@ -583,14 +609,17 @@ int ObPlanCache::construct_fast_parser_result(common::ObIAllocator &allocator,
|
||||
LOG_WARN("failed to construct plan cache key", K(ret));
|
||||
} else if (enable_exact_mode) {
|
||||
(void)fp_result.pc_key_.name_.assign_ptr(raw_sql.ptr(), raw_sql.length());
|
||||
} else if (OB_FAIL(ObSqlParameterization::fast_parser(allocator,
|
||||
sql_mode,
|
||||
conn_coll,
|
||||
raw_sql,
|
||||
pc_ctx.sql_ctx_.handle_batched_multi_stmt(),
|
||||
fp_result))) {
|
||||
LOG_WARN("failed to fast parser", K(ret), K(sql_mode), K(pc_ctx.raw_sql_));
|
||||
} else { /*do nothing*/ }
|
||||
} else {
|
||||
FPContext fp_ctx(conn_coll);
|
||||
fp_ctx.enable_batched_multi_stmt_ = pc_ctx.sql_ctx_.handle_batched_multi_stmt();
|
||||
fp_ctx.sql_mode_ = sql_mode;
|
||||
if (OB_FAIL(ObSqlParameterization::fast_parser(allocator,
|
||||
fp_ctx,
|
||||
raw_sql,
|
||||
fp_result))) {
|
||||
LOG_WARN("failed to fast parser", K(ret), K(sql_mode), K(pc_ctx.raw_sql_));
|
||||
} else { /*do nothing*/ }
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -1579,6 +1608,7 @@ int ObPlanCache::add_ps_plan(T *plan, ObPlanCacheCtx &pc_ctx)
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_PC_LOG(WARN, "pc_ctx.raw_sql_.ptr() is NULL, cannot add plan to plan cache by sql", K(ret));
|
||||
} else {
|
||||
pc_ctx.fp_result_.pc_key_.is_ps_mode_ = true;
|
||||
pc_ctx.fp_result_.pc_key_.name_ = pc_ctx.raw_sql_;
|
||||
uint64_t old_stmt_id = pc_ctx.fp_result_.pc_key_.key_id_;
|
||||
// the remote plan uses key_id is 0 to distinguish, so if key_id is 0, it cannot be set to OB_INVALID_ID
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
#include "sql/plan_cache/ob_i_lib_cache_context.h"
|
||||
#include "sql/ob_sql_utils.h"
|
||||
#include "sql/plan_cache/ob_plan_cache_util.h"
|
||||
#include "sql/udr/ob_udr_struct.h"
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
@ -180,6 +181,11 @@ struct NotParamInfo
|
||||
TO_STRING_KV(K_(idx), K_(raw_text));
|
||||
};
|
||||
|
||||
typedef common::ObSEArray<NotParamInfo, 4> NotParamInfoList;
|
||||
|
||||
// Template SQL Constant Constraints
|
||||
typedef common::ObSEArray<NotParamInfoList, 4> TplSqlConstCons;
|
||||
|
||||
struct PsNotParamInfo
|
||||
{
|
||||
int64_t idx_;
|
||||
@ -198,16 +204,28 @@ public:
|
||||
raw_params_(&inner_alloc_),
|
||||
ps_params_(&inner_alloc_),
|
||||
cache_params_(NULL)
|
||||
{}
|
||||
{
|
||||
reset_question_mark_ctx();
|
||||
}
|
||||
ObPlanCacheKey pc_key_; //plan cache key, parameterized by fast parser
|
||||
common::ObFixedArray<ObPCParam *, common::ObIAllocator> raw_params_;
|
||||
common::ObFixedArray<const common::ObObjParam *, common::ObIAllocator> ps_params_;
|
||||
ParamStore *cache_params_;
|
||||
ObQuestionMarkCtx question_mark_ctx_;
|
||||
void reset() {
|
||||
pc_key_.reset();
|
||||
raw_params_.reuse();
|
||||
ps_params_.reuse();
|
||||
cache_params_ = NULL;
|
||||
}
|
||||
void reset_question_mark_ctx()
|
||||
{
|
||||
question_mark_ctx_.name_ = NULL;
|
||||
question_mark_ctx_.count_ = 0;
|
||||
question_mark_ctx_.capacity_ = 0;
|
||||
question_mark_ctx_.by_ordinal_ = false;
|
||||
question_mark_ctx_.by_name_ = false;
|
||||
question_mark_ctx_.by_defined_name_ = false;
|
||||
}
|
||||
TO_STRING_KV(K(pc_key_), K(raw_params_), K(ps_params_), K(cache_params_));
|
||||
};
|
||||
@ -294,7 +312,13 @@ struct ObPlanCacheCtx : public ObILibCacheCtx
|
||||
need_add_obj_stat_(true),
|
||||
is_inner_sql_(false),
|
||||
is_original_ps_mode_(false),
|
||||
ab_params_(NULL)
|
||||
ab_params_(NULL),
|
||||
is_rewrite_sql_(false),
|
||||
rule_name_(),
|
||||
def_name_ctx_(NULL),
|
||||
fixed_param_info_list_(allocator),
|
||||
dynamic_param_info_list_(allocator),
|
||||
tpl_sql_const_cons_(allocator)
|
||||
{
|
||||
fp_result_.pc_key_.is_ps_mode_ = is_ps_mode_;
|
||||
}
|
||||
@ -329,6 +353,17 @@ struct ObPlanCacheCtx : public ObILibCacheCtx
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint64_t get_normalized_pattern_digest() const
|
||||
{
|
||||
common::ObString normalized_pattern;
|
||||
if (is_ps_mode_ || fp_result_.pc_key_.name_.empty()) {
|
||||
normalized_pattern = raw_sql_;
|
||||
} else {
|
||||
normalized_pattern = fp_result_.pc_key_.name_;
|
||||
}
|
||||
return normalized_pattern.hash();
|
||||
}
|
||||
|
||||
int is_retry(bool &v) const; //是否在重试之中
|
||||
int is_retry_for_dup_tbl(bool &v) const; //仅复制表原因的重试才会设置为true
|
||||
void set_begin_commit_stmt() { begin_commit_stmt_ = true; }
|
||||
@ -337,6 +372,8 @@ struct ObPlanCacheCtx : public ObILibCacheCtx
|
||||
bool is_ps_execute_stage() { return is_ps_execute_stage_; }
|
||||
void set_is_inner_sql(bool v) { is_inner_sql_ = v; };
|
||||
bool is_inner_sql() const { return is_inner_sql_; }
|
||||
void set_is_rewrite_sql(bool v) { is_rewrite_sql_ = v; }
|
||||
bool is_rewrite_sql() const { return is_rewrite_sql_; }
|
||||
TO_STRING_KV(
|
||||
K(is_ps_mode_),
|
||||
K(raw_sql_),
|
||||
@ -353,6 +390,12 @@ struct ObPlanCacheCtx : public ObILibCacheCtx
|
||||
K(fixed_param_idx_),
|
||||
K(need_add_obj_stat_),
|
||||
K(is_inner_sql_),
|
||||
K(is_rewrite_sql_),
|
||||
K(rule_name_),
|
||||
K(def_name_ctx_),
|
||||
K(fixed_param_info_list_),
|
||||
K(dynamic_param_info_list_),
|
||||
K(tpl_sql_const_cons_),
|
||||
K(is_original_ps_mode_)
|
||||
);
|
||||
bool is_ps_mode_; //control use which variables to do match
|
||||
@ -402,6 +445,15 @@ struct ObPlanCacheCtx : public ObILibCacheCtx
|
||||
bool is_inner_sql_;
|
||||
bool is_original_ps_mode_;
|
||||
ParamStore *ab_params_; // arraybinding batch parameters,
|
||||
|
||||
// ********** for rewrite rule **********
|
||||
bool is_rewrite_sql_;
|
||||
common::ObString rule_name_;
|
||||
QuestionMarkDefNameCtx *def_name_ctx_;
|
||||
common::ObFixedArray<FixedParamValue, common::ObIAllocator> fixed_param_info_list_;
|
||||
common::ObFixedArray<DynamicParamInfo, common::ObIAllocator> dynamic_param_info_list_;
|
||||
common::ObFixedArray<NotParamInfoList, common::ObIAllocator> tpl_sql_const_cons_;
|
||||
// ********** for rewrite end **********
|
||||
};
|
||||
|
||||
struct ObPlanCacheStat
|
||||
|
||||
@ -490,6 +490,10 @@ struct ObPlanStat
|
||||
common::ObString config_str_;
|
||||
common::ObString raw_sql_; //记录生成plan时的原始sql
|
||||
common::ObCollationType sql_cs_type_;
|
||||
common::ObString rule_name_;
|
||||
bool is_rewrite_sql_;
|
||||
int64_t rule_version_; // the rule version when query rewrite generates a plan
|
||||
bool enable_udr_;
|
||||
//******** for spm ******
|
||||
//该计划是否正在演进过程中
|
||||
bool is_evolution_;
|
||||
@ -589,6 +593,10 @@ struct ObPlanStat
|
||||
outline_id_(common::OB_INVALID_ID),
|
||||
is_last_exec_succ_(true),
|
||||
sql_cs_type_(common::CS_TYPE_INVALID),
|
||||
rule_name_(),
|
||||
is_rewrite_sql_(false),
|
||||
rule_version_(OB_INVALID_VERSION),
|
||||
enable_udr_(false),
|
||||
is_evolution_(false),
|
||||
db_id_(common::OB_INVALID_ID),
|
||||
constructed_sql_(),
|
||||
@ -660,6 +668,10 @@ struct ObPlanStat
|
||||
outline_id_(rhs.outline_id_),
|
||||
is_last_exec_succ_(rhs.is_last_exec_succ_),
|
||||
sql_cs_type_(rhs.sql_cs_type_),
|
||||
rule_name_(),
|
||||
is_rewrite_sql_(false),
|
||||
rule_version_(OB_INVALID_VERSION),
|
||||
enable_udr_(false),
|
||||
is_evolution_(rhs.is_evolution_),
|
||||
db_id_(rhs.db_id_),
|
||||
evolution_stat_(rhs.evolution_stat_),
|
||||
|
||||
@ -24,6 +24,8 @@
|
||||
#include "sql/plan_cache/ob_plan_cache.h"
|
||||
#include "sql/plan_cache/ob_plan_set.h"
|
||||
#include "sql/session/ob_sql_session_info.h"
|
||||
#include "sql/udr/ob_udr_mgr.h"
|
||||
#include "sql/udr/ob_udr_utils.h"
|
||||
#include "share/ob_duplicate_scope_define.h"
|
||||
#include "pl/ob_pl_stmt.h"
|
||||
using namespace oceanbase::share::schema;
|
||||
@ -154,6 +156,42 @@ ObPlanCacheValue::ObPlanCacheValue()
|
||||
MEMSET(sql_id_, 0, sizeof(sql_id_));
|
||||
}
|
||||
|
||||
int ObPlanCacheValue::assign_udr_infos(ObPlanCacheCtx &pc_ctx)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_FAIL(dynamic_param_list_.assign(pc_ctx.dynamic_param_info_list_))) {
|
||||
LOG_WARN("fail to assign dynamic param info list", K(ret));
|
||||
} else if (OB_FAIL(tpl_sql_const_cons_.assign(pc_ctx.tpl_sql_const_cons_))) {
|
||||
LOG_WARN("failed to assign tpl sql const cons", K(ret));
|
||||
} else {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < tpl_sql_const_cons_.count(); ++i) {
|
||||
NotParamInfoList ¬_param_list = tpl_sql_const_cons_.at(i);
|
||||
std::sort(not_param_list.begin(), not_param_list.end(),
|
||||
[](NotParamInfo &l, NotParamInfo &r) { return (l.idx_ < r.idx_); });
|
||||
for (int64_t j = 0; OB_SUCC(ret) && j < not_param_list.count(); ++j) {
|
||||
if (OB_FAIL(ob_write_string(*pc_alloc_,
|
||||
not_param_list.at(j).raw_text_,
|
||||
not_param_list.at(j).raw_text_))) {
|
||||
LOG_WARN("deep_copy_obj failed", K(i), K(not_param_list.at(j)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ObPlanCacheValue::reset_tpl_sql_const_cons()
|
||||
{
|
||||
for (int64_t i = 0; i < tpl_sql_const_cons_.count(); ++i) {
|
||||
NotParamInfoList ¬_param_list = tpl_sql_const_cons_.at(i);
|
||||
for (int64_t j = 0; j < not_param_list.count(); ++j) {
|
||||
pc_alloc_->free(not_param_list.at(j).raw_text_.ptr());
|
||||
not_param_list.at(j).raw_text_.reset();
|
||||
}
|
||||
}
|
||||
tpl_sql_const_cons_.reset();
|
||||
}
|
||||
|
||||
int ObPlanCacheValue::init(ObPCVSet *pcv_set, const ObILibCacheObject *cache_obj, ObPlanCacheCtx &pc_ctx)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
@ -207,6 +245,8 @@ int ObPlanCacheValue::init(ObPCVSet *pcv_set, const ObILibCacheObject *cache_obj
|
||||
pc_ctx.sql_ctx_.schema_guard_))) {
|
||||
LOG_WARN("failed to set stored schema objs",
|
||||
K(ret), K(plan->get_dependency_table()), K(pc_ctx.sql_ctx_.schema_guard_));
|
||||
} else if (OB_FAIL(assign_udr_infos(pc_ctx))) {
|
||||
LOG_WARN("failed to assign user-defined rule infos", K(ret));
|
||||
} else {
|
||||
//deep copy special param raw text
|
||||
if (pc_ctx.is_ps_mode_) {
|
||||
@ -230,6 +270,10 @@ int ObPlanCacheValue::init(ObPCVSet *pcv_set, const ObILibCacheObject *cache_obj
|
||||
LOG_WARN("fail to deep copy param raw text", K(ret));
|
||||
}
|
||||
} //for end
|
||||
if (OB_SUCC(ret)) {
|
||||
std::sort(not_param_info_.begin(), not_param_info_.end(),
|
||||
[](NotParamInfo &l, NotParamInfo &r) { return (l.idx_ < r.idx_); });
|
||||
}
|
||||
}
|
||||
//deep copy constructed sql
|
||||
if (OB_SUCC(ret)) {
|
||||
@ -430,6 +474,13 @@ int ObPlanCacheValue::choose_plan(ObPlanCacheCtx &pc_ctx,
|
||||
LOG_WARN("failed to resolver row params", K(ret));
|
||||
}
|
||||
}
|
||||
// cons user-defined rule param store
|
||||
if (OB_SUCC(ret)) {
|
||||
ParamStore param_store( (ObWrapperAllocator(pc_ctx.allocator_)) );
|
||||
if (OB_FAIL(ObUDRUtils::cons_udr_param_store(dynamic_param_list_, pc_ctx, param_store))) {
|
||||
LOG_WARN("failed to construct user-defined rule param store", K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
ObPhysicalPlanCtx *phy_ctx = pc_ctx.exec_ctx_.get_physical_plan_ctx();
|
||||
if (NULL != phy_ctx) {
|
||||
@ -792,6 +843,54 @@ int ObPlanCacheValue::check_not_param_value(const ObFastParserResult &fp_result
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPlanCacheValue::cmp_not_param_info(const NotParamInfoList &l_param_info_list,
|
||||
const NotParamInfoList &r_param_info_list,
|
||||
bool &is_equal)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
is_equal = true;
|
||||
if (l_param_info_list.count() != r_param_info_list.count()) {
|
||||
is_equal = false;
|
||||
} else {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && is_equal && i < l_param_info_list.count(); ++i) {
|
||||
const NotParamInfo &l_param_info = l_param_info_list.at(i);
|
||||
const NotParamInfo &r_param_info = r_param_info_list.at(i);
|
||||
if (l_param_info.idx_ != r_param_info.idx_) {
|
||||
is_equal = false;
|
||||
LOG_DEBUG("compare not param info", K(l_param_info), K(r_param_info));
|
||||
} else if (0 != l_param_info.raw_text_.compare(r_param_info.raw_text_)) {
|
||||
is_equal = false;
|
||||
LOG_DEBUG("compare not param info", K(l_param_info), K(r_param_info));
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPlanCacheValue::check_tpl_sql_const_cons(const ObFastParserResult &fp_result,
|
||||
const TplSqlConstCons &tpl_cst_cons_list,
|
||||
bool &is_same)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
is_same = false;
|
||||
bool is_match_tpl_cst_cons = false;
|
||||
for (int64_t i = 0; OB_SUCC(ret) && !is_match_tpl_cst_cons && i < tpl_cst_cons_list.count(); ++i) {
|
||||
const NotParamInfoList ¬_param_list = tpl_cst_cons_list.at(i);
|
||||
if (OB_FAIL(check_not_param_value(fp_result, not_param_list, is_match_tpl_cst_cons))) {
|
||||
LOG_WARN("failed to check not param value", K(ret));
|
||||
} else if (is_match_tpl_cst_cons
|
||||
&& OB_FAIL(cmp_not_param_info(not_param_list, not_param_info_, is_same))) {
|
||||
LOG_WARN("failed to cmp not param info", K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && !is_match_tpl_cst_cons && !is_same) {
|
||||
if (OB_FAIL(check_not_param_value(fp_result, not_param_info_, is_same))) {
|
||||
LOG_WARN("failed to check not param value", K(ret));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPlanCacheValue::get_outline_param_index(ObExecContext &exec_ctx, int64_t ¶m_idx) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
@ -1091,6 +1190,7 @@ void ObPlanCacheValue::reset()
|
||||
neg_param_index_.reset();
|
||||
param_charset_type_.reset();
|
||||
sql_traits_.reset();
|
||||
reset_tpl_sql_const_cons();
|
||||
|
||||
if (OB_SUCCESS != outline_params_wrapper_.destroy()) {
|
||||
LOG_ERROR("fail to destroy ObOutlineParamWrapper");
|
||||
@ -1338,10 +1438,10 @@ int ObPlanCacheValue::match(ObPlanCacheCtx &pc_ctx,
|
||||
LOG_DEBUG("match", K(not_param_var_[i].idx_), K(not_param_var_[i].ps_param_), KPC(ps_param));
|
||||
}
|
||||
} else {
|
||||
if (OB_FAIL(check_not_param_value(pc_ctx.fp_result_,
|
||||
not_param_info_,
|
||||
is_same))) {
|
||||
LOG_WARN("failed to check not param value", K(ret));
|
||||
if (OB_FAIL(check_tpl_sql_const_cons(pc_ctx.fp_result_,
|
||||
tpl_sql_const_cons_,
|
||||
is_same))) {
|
||||
LOG_WARN("failed to check tpl sql const cons", K(ret));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -332,6 +332,15 @@ private:
|
||||
|
||||
static int rm_space_for_neg_num(ParseNode *param_node, ObIAllocator &allocator);
|
||||
|
||||
int assign_udr_infos(ObPlanCacheCtx &pc_ctx);
|
||||
void reset_tpl_sql_const_cons();
|
||||
int check_tpl_sql_const_cons(const ObFastParserResult &fp_result,
|
||||
const TplSqlConstCons &tpl_cst_cons_list,
|
||||
bool &is_same);
|
||||
int cmp_not_param_info(const NotParamInfoList &l_param_info_list,
|
||||
const NotParamInfoList &r_param_info_list,
|
||||
bool &is_equal);
|
||||
|
||||
friend class ::test::TestPlanSet_basic_Test;
|
||||
friend class ::test::TestPlanCacheValue_basic_Test;
|
||||
private:
|
||||
@ -387,6 +396,35 @@ private:
|
||||
common::ObFixedArray<PCVSchemaObj *, common::ObIAllocator> stored_schema_objs_;
|
||||
common::ObBitSet<> must_be_positive_idx_;
|
||||
stmt::StmtType stmt_type_;
|
||||
//*********** for user-defined rules **************
|
||||
DynamicParamInfoArray dynamic_param_list_;
|
||||
/**
|
||||
* call dbms_udr.create_rule('select ?, 1 from dual', 'select ? + 1, 1 from dual');
|
||||
* call dbms_udr.create_rule('select ?, 2 from dual', 'select ? + 2, 1 from dual');
|
||||
*
|
||||
* template SQL: select ?, ? from dual has the following two constant constraints:
|
||||
* tpl_sql_const_cons_ : {{idx:1, raw_text:"1"}, {idx:1, raw_text:"2"}}
|
||||
*
|
||||
* The following constraints are generated when executing a SQL that does not hit any of the rules:
|
||||
* SQL: select 4, 5 from dual;
|
||||
* not_param_info_ : {}
|
||||
* tpl_sql_const_cons_ : {{idx:1, raw_text:"1"}, {idx:1, raw_text:"2"}}
|
||||
*
|
||||
* When executing a SQL that hits a rule, the following constraints are generated:
|
||||
* SQL: select 4, 1 from dual;
|
||||
* not_param_info_ : {idx:1, raw_text:"1"}
|
||||
* tpl_sql_const_cons_ : {{idx:1, raw_text:"1"}, {idx:1, raw_text:"2"}}
|
||||
*
|
||||
* So the constant constraint matching rules are as follows:
|
||||
* 1、First match tpl_sql_const_cons_constraint list
|
||||
* 2、If it hits, use the hit rule to compare it with not_param_info_, if it is the same
|
||||
* the match succeeds, otherwise it fails
|
||||
* 3、If there is no hit, match not_param_info_. if the match is successful
|
||||
* the result is successful, otherwise it fails
|
||||
*/
|
||||
TplSqlConstCons tpl_sql_const_cons_;
|
||||
//*********** end user-defined rules **************
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ObPlanCacheValue);
|
||||
};
|
||||
|
||||
|
||||
@ -292,6 +292,7 @@ ObPsStmtInfo::ObPsStmtInfo(ObIAllocator *inner_allocator)
|
||||
num_of_returning_into_(-1),
|
||||
no_param_sql_(),
|
||||
is_sensitive_sql_(false),
|
||||
raw_sql_(),
|
||||
raw_params_(inner_allocator),
|
||||
raw_params_idx_(inner_allocator)
|
||||
|
||||
@ -321,6 +322,7 @@ ObPsStmtInfo::ObPsStmtInfo(ObIAllocator *inner_allocator,
|
||||
num_of_returning_into_(-1),
|
||||
no_param_sql_(),
|
||||
is_sensitive_sql_(false),
|
||||
raw_sql_(),
|
||||
raw_params_(inner_allocator),
|
||||
raw_params_idx_(inner_allocator)
|
||||
{
|
||||
@ -343,6 +345,18 @@ int ObPsStmtInfo::assign_no_param_sql(const common::ObString &no_param_sql)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPsStmtInfo::assign_raw_sql(const common::ObString &raw_sql)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(allocator_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("allocator is invalid", K(ret));
|
||||
} else if (OB_FAIL(ObPsSqlUtils::deep_copy_str(*allocator_, raw_sql, raw_sql_))) {
|
||||
LOG_WARN("deep copy raw sql failed", K(raw_sql), K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPsStmtInfo::add_fixed_raw_param(const ObPCParam &node)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
@ -473,6 +487,9 @@ int ObPsStmtInfo::deep_copy(const ObPsStmtInfo &other)
|
||||
} else if (OB_FAIL(ObPsSqlUtils::deep_copy_str(*allocator_, other.get_no_param_sql(),
|
||||
no_param_sql_))) {
|
||||
LOG_WARN("deep copy str failed", K(other), K(ret));
|
||||
} else if (OB_FAIL(ObPsSqlUtils::deep_copy_str(*allocator_, other.get_raw_sql(),
|
||||
raw_sql_))) {
|
||||
LOG_WARN("deep copy str failed", K(other), K(ret));
|
||||
} else if (OB_FAIL(deep_copy_fixed_raw_params(other.raw_params_idx_, other.raw_params_))) {
|
||||
LOG_WARN("deep copy fixed raw params failed", K(other), K(ret));
|
||||
} else if (OB_FAIL(ps_sql_meta_.deep_copy(other.get_ps_sql_meta()))) {
|
||||
@ -507,6 +524,7 @@ int ObPsStmtInfo::get_convert_size(int64_t &cv_size) const
|
||||
int64_t convert_size = sizeof(ObPsStmtInfo);
|
||||
convert_size += ps_sql_.length() + 1;
|
||||
convert_size += no_param_sql_.length() + 1;
|
||||
convert_size += raw_sql_.length() + 1;
|
||||
int64_t meta_convert_size = 0;
|
||||
int64_t raw_params_size = 0;
|
||||
if (OB_FAIL(ps_sql_meta_.get_convert_size(meta_convert_size))) {
|
||||
|
||||
@ -166,6 +166,7 @@ public:
|
||||
inline int32_t get_num_of_returning_into() const { return num_of_returning_into_; }
|
||||
inline void set_is_sensitive_sql(const bool is_sensitive_sql) { is_sensitive_sql_ = is_sensitive_sql; }
|
||||
inline bool get_is_sensitive_sql() const { return is_sensitive_sql_; }
|
||||
inline const common::ObString &get_raw_sql() const { return raw_sql_; }
|
||||
|
||||
bool is_valid() const;
|
||||
bool check_erase_inc_ref_count();
|
||||
@ -174,6 +175,7 @@ public:
|
||||
int add_param_field(const common::ObField ¶m);
|
||||
int add_column_field(const common::ObField &column);
|
||||
int get_convert_size(int64_t &cv_size) const;
|
||||
int assign_raw_sql(const common::ObString &raw_sql);
|
||||
int assign_no_param_sql(const common::ObString &no_param_sql);
|
||||
int assign_fixed_raw_params(const common::ObIArray<int64_t> ¶m_idxs,
|
||||
const common::ObIArray<ObPCParam *> &raw_params);
|
||||
@ -248,6 +250,7 @@ private:
|
||||
int32_t num_of_returning_into_;
|
||||
common::ObString no_param_sql_;
|
||||
bool is_sensitive_sql_;
|
||||
common::ObString raw_sql_;
|
||||
// raw_params_ records constants other than question mark in raw prepare sql
|
||||
// raw_params_idx_ records the offset of the constants in raw_params_ in param_store
|
||||
// E.g: prepare stmt from 'select 3 + ? + 2 from dual';
|
||||
@ -400,6 +403,41 @@ private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObPsStmtInfoGuard);
|
||||
};
|
||||
|
||||
struct PsCacheInfoCtx
|
||||
{
|
||||
PsCacheInfoCtx()
|
||||
: param_cnt_(0),
|
||||
num_of_returning_into_(-1),
|
||||
is_inner_sql_(false),
|
||||
is_sensitive_sql_(false),
|
||||
normalized_sql_(),
|
||||
raw_sql_(),
|
||||
no_param_sql_(),
|
||||
raw_params_(NULL),
|
||||
fixed_param_idx_(NULL),
|
||||
stmt_type_(stmt::T_NONE) {}
|
||||
|
||||
|
||||
TO_STRING_KV(K_(param_cnt),
|
||||
K_(num_of_returning_into),
|
||||
K_(is_inner_sql),
|
||||
K_(is_sensitive_sql),
|
||||
K_(normalized_sql),
|
||||
K_(raw_sql),
|
||||
K_(no_param_sql),
|
||||
K_(stmt_type));
|
||||
|
||||
int64_t param_cnt_;
|
||||
int32_t num_of_returning_into_;
|
||||
bool is_inner_sql_;
|
||||
bool is_sensitive_sql_;
|
||||
common::ObString normalized_sql_;
|
||||
common::ObString raw_sql_;
|
||||
common::ObString no_param_sql_;
|
||||
common::ObIArray<ObPCParam*> *raw_params_;
|
||||
common::ObIArray<int64_t> *fixed_param_idx_;
|
||||
stmt::StmtType stmt_type_;
|
||||
};
|
||||
|
||||
} //end of namespace sql
|
||||
} //end of namespace oceanbase
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
#include "sql/plan_cache/ob_ps_sql_utils.h"
|
||||
#include "sql/plan_cache/ob_ps_cache_callback.h"
|
||||
#include "sql/resolver/cmd/ob_call_procedure_stmt.h"
|
||||
#include "sql/udr/ob_udr_mgr.h"
|
||||
#include "share/schema/ob_schema_getter_guard.h"
|
||||
|
||||
namespace oceanbase
|
||||
@ -381,25 +382,22 @@ int ObPsCache::ref_stmt_item(const uint64_t db_id,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPsCache::get_or_add_stmt_info(const ObResultSet &result,
|
||||
const ObString &origin_sql,
|
||||
const ObString &no_param_sql,
|
||||
const ObIArray<ObPCParam*> &raw_params,
|
||||
const common::ObIArray<int64_t> &raw_params_idx,
|
||||
int64_t param_cnt,
|
||||
int ObPsCache::get_or_add_stmt_info(const PsCacheInfoCtx &info_ctx,
|
||||
const ObResultSet &result,
|
||||
ObSchemaGetterGuard &schema_guard,
|
||||
stmt::StmtType stmt_type,
|
||||
ObPsStmtItem *ps_item,
|
||||
ObPsStmtInfo *&ref_ps_info,
|
||||
int32_t returning_into_parm_num)
|
||||
ObPsStmtInfo *&ref_ps_info)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(ps_item)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid argument", K(ret), K(ps_item));
|
||||
} else if (OB_ISNULL(origin_sql.ptr())) {
|
||||
} else if (OB_ISNULL(info_ctx.normalized_sql_.ptr())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("origin_sql is null", K(ret), K(ps_item));
|
||||
LOG_WARN("normalized sql is null", K(ret), K(ps_item));
|
||||
} else if (OB_ISNULL(info_ctx.raw_params_) || OB_ISNULL(info_ctx.fixed_param_idx_)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("param is null", K(ret));
|
||||
} else if (OB_FAIL(ref_stmt_info(ps_item->get_ps_stmt_id(), ref_ps_info))) {
|
||||
if (OB_HASH_NOT_EXIST == ret) {
|
||||
ret = OB_SUCCESS;
|
||||
@ -407,21 +405,25 @@ int ObPsCache::get_or_add_stmt_info(const ObResultSet &result,
|
||||
ObArenaAllocator allocator;
|
||||
ObPsStmtInfo tmp_stmt_info(&allocator);
|
||||
tmp_stmt_info.assign_sql_key(*ps_item);
|
||||
tmp_stmt_info.set_stmt_type(stmt_type);
|
||||
tmp_stmt_info.set_stmt_type(info_ctx.stmt_type_);
|
||||
tmp_stmt_info.set_ps_item(ps_item);
|
||||
// calc check_sum with origin_sql
|
||||
uint64_t ps_stmt_checksum = ob_crc64(origin_sql.ptr(),
|
||||
origin_sql.length()); // actual is crc32
|
||||
// calc check_sum with normalized sql
|
||||
uint64_t ps_stmt_checksum = ob_crc64(info_ctx.normalized_sql_.ptr(),
|
||||
info_ctx.normalized_sql_.length()); // actual is crc32
|
||||
tmp_stmt_info.set_ps_stmt_checksum(ps_stmt_checksum);
|
||||
if (OB_FAIL(schema_guard.get_schema_version(tenant_id_, tenant_version))) {
|
||||
LOG_WARN("fail to get tenant version", K(ret), K(tenant_id_));
|
||||
} else if (FALSE_IT(tmp_stmt_info.set_tenant_version(tenant_version))) {
|
||||
// do nothing
|
||||
} else if (OB_FAIL(tmp_stmt_info.assign_no_param_sql(no_param_sql))) {
|
||||
LOG_WARN("fail to assign no param sql", K(ret), K(no_param_sql));
|
||||
} else if (OB_FAIL(tmp_stmt_info.assign_fixed_raw_params(raw_params_idx, raw_params))) {
|
||||
LOG_WARN("fail to assign raw params failed", K(raw_params_idx), K(ret));
|
||||
} else if (OB_FAIL(fill_ps_stmt_info(result, param_cnt, tmp_stmt_info, returning_into_parm_num))) {
|
||||
} else if (OB_FAIL(tmp_stmt_info.assign_no_param_sql(info_ctx.no_param_sql_))) {
|
||||
LOG_WARN("fail to assign no param sql", K(ret), K(info_ctx.no_param_sql_));
|
||||
} else if (OB_FAIL(tmp_stmt_info.assign_raw_sql(info_ctx.raw_sql_))) {
|
||||
LOG_WARN("fail to assign rule name", K(ret), K(info_ctx.raw_sql_));
|
||||
} else if (OB_FAIL(tmp_stmt_info.assign_fixed_raw_params(*info_ctx.fixed_param_idx_,
|
||||
*info_ctx.raw_params_))) {
|
||||
LOG_WARN("fail to assign raw params failed", KPC(info_ctx.fixed_param_idx_), K(ret));
|
||||
} else if (OB_FAIL(fill_ps_stmt_info(result, info_ctx.param_cnt_,
|
||||
tmp_stmt_info, info_ctx.num_of_returning_into_))) {
|
||||
LOG_WARN("fill ps stmt info failed", K(ret));
|
||||
} else if (OB_FAIL(add_stmt_info(*ps_item, tmp_stmt_info, ref_ps_info))) {
|
||||
LOG_WARN("add stmt info failed", K(ret), K(*ps_item), K(tmp_stmt_info));
|
||||
|
||||
@ -84,17 +84,11 @@ public:
|
||||
int get_or_add_stmt_item(const uint64_t db_id,
|
||||
const common::ObString &ps_sql,
|
||||
ObPsStmtItem *&ps_item_value);
|
||||
int get_or_add_stmt_info(const ObResultSet &result,
|
||||
const ObString &origin_sql,
|
||||
const common::ObString &no_param_sql,
|
||||
const ObIArray<ObPCParam*> &raw_params,
|
||||
const common::ObIArray<int64_t> &raw_params_idx,
|
||||
int64_t param_cnt,
|
||||
int get_or_add_stmt_info(const PsCacheInfoCtx &info_ctx,
|
||||
const ObResultSet &result,
|
||||
ObSchemaGetterGuard &schema_guard,
|
||||
stmt::StmtType stmt_type,
|
||||
ObPsStmtItem *ps_item,
|
||||
ObPsStmtInfo *&ref_ps_info,
|
||||
int32_t returning_into_parm_num);
|
||||
ObPsStmtInfo *&ref_ps_info);
|
||||
|
||||
int cache_evict();
|
||||
int cache_evict_all_ps();
|
||||
|
||||
@ -63,6 +63,7 @@ struct TransformTreeCtx
|
||||
SQL_EXECUTION_MODE mode_;
|
||||
bool is_project_list_scope_;
|
||||
int64_t assign_father_level_;
|
||||
const ObIArray<FixedParamValue> *udr_fixed_params_;
|
||||
bool ignore_scale_check_;
|
||||
TransformTreeCtx();
|
||||
};
|
||||
@ -123,6 +124,7 @@ TransformTreeCtx::TransformTreeCtx() :
|
||||
mode_(INVALID_MODE),
|
||||
is_project_list_scope_(false),
|
||||
assign_father_level_(ObSqlParameterization::NO_VALUES),
|
||||
udr_fixed_params_(NULL),
|
||||
ignore_scale_check_(false)
|
||||
{
|
||||
}
|
||||
@ -138,7 +140,8 @@ int ObSqlParameterization::transform_syntax_tree(ObIAllocator &allocator,
|
||||
SelectItemParamInfoArray *select_item_param_infos,
|
||||
ObMaxConcurrentParam::FixParamStore &fixed_param_store,
|
||||
bool is_transform_outline,
|
||||
SQL_EXECUTION_MODE execution_mode)
|
||||
SQL_EXECUTION_MODE execution_mode,
|
||||
const ObIArray<FixedParamValue> *udr_fixed_params)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObCollationType collation_connection = CS_TYPE_INVALID;
|
||||
@ -173,6 +176,7 @@ int ObSqlParameterization::transform_syntax_tree(ObIAllocator &allocator,
|
||||
ctx.paramlized_questionmask_count_ = 0;//used for outline sql限流,
|
||||
ctx.is_transform_outline_ = is_transform_outline;//used for outline sql限流
|
||||
ctx.raw_params_ = raw_params;
|
||||
ctx.udr_fixed_params_ = udr_fixed_params;
|
||||
ctx.is_project_list_scope_ = false;
|
||||
ctx.mode_ = execution_mode;
|
||||
ctx.assign_father_level_ = NO_VALUES;
|
||||
@ -255,6 +259,23 @@ int ObSqlParameterization::is_fast_parse_const(TransformTreeCtx &ctx)
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ObSqlParameterization::is_udr_not_param(TransformTreeCtx &ctx)
|
||||
{
|
||||
bool b_ret = false;
|
||||
if (OB_ISNULL(ctx.tree_) || (NULL == ctx.udr_fixed_params_)) {
|
||||
b_ret = false;
|
||||
} else {
|
||||
for (int64_t i = 0; !b_ret && i < ctx.udr_fixed_params_->count(); ++i) {
|
||||
const FixedParamValue &fixed_param = ctx.udr_fixed_params_->at(i);
|
||||
if (fixed_param.idx_ == ctx.tree_->raw_param_idx_) {
|
||||
b_ret = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return b_ret;
|
||||
}
|
||||
|
||||
//判断该node是否为不能参数化的node
|
||||
bool ObSqlParameterization::is_node_not_param(TransformTreeCtx &ctx)
|
||||
{
|
||||
@ -598,9 +619,11 @@ int ObSqlParameterization::transform_tree(TransformTreeCtx &ctx,
|
||||
//do nothing
|
||||
} else if (!is_execute_mode(ctx.mode_) && OB_FAIL(ctx.params_->push_back(value))) {
|
||||
SQL_PC_LOG(WARN, "fail to push into params", K(ret));
|
||||
} else if (is_udr_not_param(ctx) && OB_FAIL(add_not_param_flag(ctx.tree_, *ctx.sql_info_))) {
|
||||
SQL_PC_LOG(WARN, "fail to add not param flag", K(ret));
|
||||
}
|
||||
}
|
||||
} else if (add_not_param_flag(ctx.tree_, *ctx.sql_info_)) { //not param
|
||||
} else if (OB_FAIL(add_not_param_flag(ctx.tree_, *ctx.sql_info_))) { //not param
|
||||
SQL_PC_LOG(WARN, "fail to add not param flag", K(ret));
|
||||
}
|
||||
} //if is_fast_parse_const end
|
||||
@ -906,11 +929,14 @@ int ObSqlParameterization::parameterize_syntax_tree(common::ObIAllocator &alloca
|
||||
// if so, faster parser is needed
|
||||
// otherwise, fast parser has been done before
|
||||
pc_ctx.fp_result_.reset();
|
||||
FPContext fp_ctx(cs_type);
|
||||
fp_ctx.enable_batched_multi_stmt_ = pc_ctx.sql_ctx_.handle_batched_multi_stmt();
|
||||
fp_ctx.sql_mode_ = session->get_sql_mode();
|
||||
fp_ctx.is_udr_mode_ = pc_ctx.is_rewrite_sql_;
|
||||
fp_ctx.def_name_ctx_ = pc_ctx.def_name_ctx_;
|
||||
if (OB_FAIL(fast_parser(allocator,
|
||||
session->get_sql_mode(),
|
||||
cs_type,
|
||||
fp_ctx,
|
||||
pc_ctx.raw_sql_,
|
||||
pc_ctx.sql_ctx_.handle_batched_multi_stmt(),
|
||||
pc_ctx.fp_result_))) {
|
||||
SQL_PC_LOG(WARN, "fail to fast parser", K(ret));
|
||||
}
|
||||
@ -925,14 +951,15 @@ int ObSqlParameterization::parameterize_syntax_tree(common::ObIAllocator &alloca
|
||||
LOG_WARN("failed to reserve array", K(ret));
|
||||
} else if (OB_FAIL(transform_syntax_tree(allocator,
|
||||
*session,
|
||||
&pc_ctx.fp_result_.raw_params_,
|
||||
is_execute_mode(mode) ? NULL : &pc_ctx.fp_result_.raw_params_,
|
||||
tree,
|
||||
sql_info,
|
||||
params,
|
||||
is_prepare_mode(mode) ? NULL : &pc_ctx.select_item_param_infos_,
|
||||
fix_param_store,
|
||||
is_transform_outline,
|
||||
mode))) {
|
||||
mode,
|
||||
&pc_ctx.fixed_param_info_list_))) {
|
||||
if (OB_NOT_SUPPORTED != ret) {
|
||||
SQL_PC_LOG(WARN, "fail to normal parameterized parser tree", K(ret));
|
||||
}
|
||||
@ -1224,10 +1251,8 @@ bool ObSqlParameterization::need_fast_parser(const ObString &sql)
|
||||
}
|
||||
|
||||
int ObSqlParameterization::fast_parser(ObIAllocator &allocator,
|
||||
ObSQLMode sql_mode,
|
||||
ObCollationType connection_collation,
|
||||
const FPContext &fp_ctx,
|
||||
const ObString &sql,
|
||||
const bool enable_batched_multi_stmt,
|
||||
ObFastParserResult &fp_result)
|
||||
{
|
||||
//UNUSED(sql_mode);
|
||||
@ -1242,8 +1267,8 @@ int ObSqlParameterization::fast_parser(ObIAllocator &allocator,
|
||||
|| (ObParser::is_pl_stmt(sql, nullptr, &is_call_procedure) && !is_call_procedure))) {
|
||||
(void)fp_result.pc_key_.name_.assign_ptr(sql.ptr(), sql.length());
|
||||
} else if (GCONF._ob_enable_fast_parser) {
|
||||
if (OB_FAIL(ObFastParser::parse(sql, enable_batched_multi_stmt, no_param_sql_ptr,
|
||||
no_param_sql_len, p_list, param_num, connection_collation, allocator, sql_mode))) {
|
||||
if (OB_FAIL(ObFastParser::parse(sql, fp_ctx, allocator, no_param_sql_ptr,
|
||||
no_param_sql_len, p_list, param_num, fp_result.question_mark_ctx_))) {
|
||||
LOG_WARN("fast parse error", K(param_num),
|
||||
K(ObString(no_param_sql_len, no_param_sql_ptr)), K(sql));
|
||||
}
|
||||
@ -1252,6 +1277,7 @@ int ObSqlParameterization::fast_parser(ObIAllocator &allocator,
|
||||
if (param_num > 0) {
|
||||
ObPCParam *pc_param = NULL;
|
||||
char *ptr = (char *)allocator.alloc(param_num * sizeof(ObPCParam));
|
||||
fp_result.raw_params_.reset();
|
||||
fp_result.raw_params_.set_allocator(&allocator);
|
||||
fp_result.raw_params_.set_capacity(param_num);
|
||||
if (OB_ISNULL(ptr)) {
|
||||
@ -1271,9 +1297,9 @@ int ObSqlParameterization::fast_parser(ObIAllocator &allocator,
|
||||
} else { /*do nothing*/}
|
||||
}
|
||||
} else {
|
||||
ObParser parser(allocator, sql_mode, connection_collation);
|
||||
ObParser parser(allocator, fp_ctx.sql_mode_, fp_ctx.conn_coll_);
|
||||
SMART_VAR(ParseResult, parse_result) {
|
||||
if (OB_FAIL(parser.parse(sql, parse_result, FP_MODE, enable_batched_multi_stmt))) {
|
||||
if (OB_FAIL(parser.parse(sql, parse_result, FP_MODE, fp_ctx.enable_batched_multi_stmt_))) {
|
||||
SQL_PC_LOG(WARN, "fail to fast parser", K(sql), K(ret));
|
||||
} else {
|
||||
(void)fp_result.pc_key_.name_.assign_ptr(parse_result.no_param_sql_, parse_result.no_param_sql_len_);
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
#include "lib/utility/ob_print_utils.h"
|
||||
#include "common/object/ob_object.h"
|
||||
#include "sql/parser/ob_parser.h"
|
||||
#include "sql/parser/ob_fast_parser.h"
|
||||
#include "sql/session/ob_sql_session_info.h"
|
||||
#include "sql/plan_cache/ob_id_manager_allocator.h"
|
||||
#include "sql/plan_cache/ob_plan_cache_util.h"
|
||||
@ -115,10 +116,8 @@ public:
|
||||
ObSqlParameterization() {}
|
||||
virtual ~ObSqlParameterization() {}
|
||||
static int fast_parser(common::ObIAllocator &allocator,
|
||||
ObSQLMode sql_mode,
|
||||
common::ObCollationType connection_collation,
|
||||
const FPContext &fp_ctx,
|
||||
const common::ObString &sql,
|
||||
const bool enable_batched_multi_stmt,
|
||||
ObFastParserResult &fp_result);
|
||||
|
||||
static int transform_syntax_tree(common::ObIAllocator &allocator,
|
||||
@ -130,7 +129,8 @@ public:
|
||||
SelectItemParamInfoArray *select_item_param_infos,
|
||||
share::schema::ObMaxConcurrentParam::FixParamStore &fixed_param_store,
|
||||
bool is_transform_outline,
|
||||
SQL_EXECUTION_MODE execution_mode = INVALID_MODE);
|
||||
SQL_EXECUTION_MODE execution_mode = INVALID_MODE,
|
||||
const ObIArray<FixedParamValue> *udr_fixed_params = NULL);
|
||||
static int raw_fast_parameterize_sql(common::ObIAllocator &allocator,
|
||||
const ObSQLSessionInfo &session,
|
||||
const common::ObString &sql,
|
||||
@ -170,6 +170,7 @@ private:
|
||||
static int is_fast_parse_const(TransformTreeCtx &ctx);
|
||||
|
||||
static bool is_node_not_param(TransformTreeCtx &ctx);
|
||||
static bool is_udr_not_param(TransformTreeCtx &ctx);
|
||||
static int transform_tree(TransformTreeCtx &ctx, const ObSQLSessionInfo &session_info);
|
||||
static int add_param_flag(const ParseNode *node, SqlInfo &sql_info);
|
||||
static int add_not_param_flag(const ParseNode *node, SqlInfo &sql_info);
|
||||
|
||||
Reference in New Issue
Block a user