[FEAT MERGE]4_1_sql_feature
Co-authored-by: leslieyuchen <leslieyuchen@gmail.com> Co-authored-by: Charles0429 <xiezhenjiang@gmail.com> Co-authored-by: raywill <hustos@gmail.com>
This commit is contained in:
@ -48,6 +48,8 @@ public:
|
||||
int foreach_alloc_cache_obj(_callback &callback) const;
|
||||
template<class _callback>
|
||||
int atomic_get_cache_obj(ObCacheObjID id, _callback &callback);
|
||||
template<class _callback>
|
||||
int atomic_get_alloc_cache_obj(ObCacheObjID id, _callback &callback);
|
||||
int erase_cache_obj(ObCacheObjID id, const CacheRefHandleID ref_handle);
|
||||
int add_cache_obj(ObILibCacheObject *obj);
|
||||
int64_t get_cache_obj_size() const { return cache_obj_map_.size(); }
|
||||
@ -120,6 +122,16 @@ int ObLCObjectManager::atomic_get_cache_obj(ObCacheObjID id, _callback &callback
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<class _callback>
|
||||
int ObLCObjectManager::atomic_get_alloc_cache_obj(ObCacheObjID id, _callback &callback)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_FAIL(alloc_cache_obj_map_.atomic_refactored(id, callback))) {
|
||||
OB_LOG(WARN, "failed to atomic get cache obj", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename ClassT>
|
||||
int ObLCObjectManager::alloc(lib::MemoryContext &mem_ctx,
|
||||
ObILibCacheObject *&cache_obj,
|
||||
|
||||
@ -109,13 +109,13 @@ int ObPCVSet::inner_get_cache_obj(ObILibCacheCtx &ctx,
|
||||
ObPlanCacheCtx &pc_ctx = static_cast<ObPlanCacheCtx&>(ctx);
|
||||
if (PC_PS_MODE == pc_ctx.mode_ || PC_PL_MODE == pc_ctx.mode_) {
|
||||
if (normal_parse_const_cnt_ != pc_ctx.fp_result_.parameterized_params_.count()) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("param num is not equal", K_(normal_parse_const_cnt),
|
||||
"parameterized_params_count", pc_ctx.fp_result_.parameterized_params_.count());
|
||||
}
|
||||
} else {
|
||||
if (normal_parse_const_cnt_ != pc_ctx.fp_result_.raw_params_.count()) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_PC_LOG(DEBUG, "const number of fast parse and normal parse is different",
|
||||
"fast_parse_const_num", pc_ctx.fp_result_.raw_params_.count(),
|
||||
K_(normal_parse_const_cnt),
|
||||
@ -218,7 +218,7 @@ int ObPCVSet::inner_add_cache_obj(ObILibCacheCtx &ctx,
|
||||
K(pc_ctx.sql_ctx_.session_info_));
|
||||
} else if (get_plan_num() >= MAX_PCV_SET_PLAN_NUM) {
|
||||
static const int64_t PRINT_PLAN_EXCEEDS_LOG_INTERVAL = 20 * 1000 * 1000; // 20s
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
if (REACH_TIME_INTERVAL(PRINT_PLAN_EXCEEDS_LOG_INTERVAL)) {
|
||||
LOG_INFO("number of plans in a single pcv_set reach limit", K(ret), K(get_plan_num()), K(pc_ctx));
|
||||
}
|
||||
|
||||
@ -630,7 +630,6 @@ int ObPlanCache::add_plan(ObPhysicalPlan *plan, ObPlanCacheCtx &pc_ctx)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int ObPlanCache::add_plan_cache(ObILibCacheCtx &ctx,
|
||||
ObILibCacheObject *cache_obj)
|
||||
{
|
||||
@ -1206,7 +1205,7 @@ int ObPlanCache::ref_cache_obj(const ObCacheObjID obj_id, ObCacheObjGuard& guard
|
||||
int ret = OB_SUCCESS;
|
||||
ObCacheObjAtomicOp op(guard.ref_handle_);
|
||||
ObGlobalReqTimeService::check_req_timeinfo();
|
||||
if (OB_FAIL(co_mgr_.atomic_get_cache_obj(obj_id, op))) {
|
||||
if (OB_FAIL(co_mgr_.atomic_get_alloc_cache_obj(obj_id, op))) {
|
||||
SQL_PC_LOG(WARN, "failed to get update plan statistic", K(obj_id), K(ret));
|
||||
} else {
|
||||
guard.cache_obj_ = op.get_value();
|
||||
|
||||
@ -78,7 +78,11 @@ int ObGetAllCacheIdOp::operator()(common::hash::HashMapPair<ObCacheObjID, ObILib
|
||||
SQL_PC_LOG(WARN, "invalid argument", K(ret));
|
||||
} else if (entry.second->get_ns() >= ObLibCacheNameSpace::NS_CRSR
|
||||
&& entry.second->get_ns() <= ObLibCacheNameSpace::NS_PKG) {
|
||||
if (OB_FAIL(key_array_->push_back(entry.first))) {
|
||||
if (OB_ISNULL(entry.second)) {
|
||||
// do nothing
|
||||
} else if (!entry.second->added_lc()) {
|
||||
// do nothing
|
||||
} else if (OB_FAIL(key_array_->push_back(entry.first))) {
|
||||
SQL_PC_LOG(WARN, "fail to push back plan_id", K(ret));
|
||||
}
|
||||
}
|
||||
@ -400,6 +404,9 @@ int ObConfigInfoInPC::load_influence_plan_config()
|
||||
rowsets_enabled_ = tenant_config->_rowsets_enabled;
|
||||
enable_px_batch_rescan_ = tenant_config->_enable_px_batch_rescan;
|
||||
bloom_filter_enabled_ = tenant_config->_bloom_filter_enabled;
|
||||
px_join_skew_handling_ = tenant_config->_px_join_skew_handling;
|
||||
px_join_skew_minfreq_ = static_cast<int8_t>(tenant_config->_px_join_skew_minfreq);
|
||||
min_cluster_version_ = GET_MIN_CLUSTER_VERSION();
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -430,6 +437,16 @@ int ObConfigInfoInPC::serialize_configs(char *buf, int buf_len, int64_t &pos)
|
||||
} else if (OB_FAIL(databuff_printf(buf, buf_len, pos,
|
||||
"%d,", enable_newsort_))) {
|
||||
SQL_PC_LOG(WARN, "failed to databuff_printf", K(ret), K(enable_newsort_));
|
||||
} else if (OB_FAIL(databuff_printf(buf, buf_len, pos,
|
||||
"%d,", px_join_skew_handling_))) {
|
||||
SQL_PC_LOG(WARN, "failed to databuff_printf", K(ret), K(px_join_skew_handling_));
|
||||
} else if (OB_FAIL(databuff_printf(buf, buf_len, pos,
|
||||
"%d,", px_join_skew_minfreq_))) {
|
||||
SQL_PC_LOG(WARN, "failed to databuff_printf", K(ret), K(px_join_skew_minfreq_));
|
||||
|
||||
} else if (OB_FAIL(databuff_printf(buf, buf_len, pos,
|
||||
"%lu", min_cluster_version_))) {
|
||||
SQL_PC_LOG(WARN, "failed to databuff_printf", K(ret), K(min_cluster_version_));
|
||||
} else {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@ -303,6 +303,27 @@ struct ObPCParamEqualInfo
|
||||
}
|
||||
};
|
||||
|
||||
struct ObPCPrivInfo
|
||||
{
|
||||
share::ObRawPriv sys_priv_;
|
||||
bool has_privilege_;
|
||||
TO_STRING_KV(K_(sys_priv), K_(has_privilege));
|
||||
ObPCPrivInfo() : sys_priv_(PRIV_ID_NONE), has_privilege_(false)
|
||||
{
|
||||
}
|
||||
int assign(const ObPCPrivInfo &other)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
sys_priv_ = other.sys_priv_;
|
||||
has_privilege_ = other.has_privilege_;
|
||||
return ret;
|
||||
}
|
||||
inline bool operator==(const ObPCPrivInfo &other) const
|
||||
{
|
||||
return sys_priv_ == other.sys_priv_ && has_privilege_ == other.has_privilege_;
|
||||
}
|
||||
};
|
||||
|
||||
struct ObOperatorStat
|
||||
{
|
||||
int64_t plan_id_;
|
||||
@ -941,6 +962,9 @@ public:
|
||||
enable_px_batch_rescan_(true),
|
||||
bloom_filter_enabled_(true),
|
||||
enable_newsort_(true),
|
||||
px_join_skew_handling_(true),
|
||||
px_join_skew_minfreq_(30),
|
||||
min_cluster_version_(0),
|
||||
cluster_config_version_(-1),
|
||||
tenant_config_version_(-1),
|
||||
tenant_id_(0)
|
||||
@ -977,6 +1001,9 @@ public:
|
||||
bool enable_px_ordered_coord_;
|
||||
bool bloom_filter_enabled_;
|
||||
bool enable_newsort_;
|
||||
bool px_join_skew_handling_;
|
||||
int8_t px_join_skew_minfreq_;
|
||||
uint64_t min_cluster_version_;
|
||||
|
||||
private:
|
||||
// current cluster config version_
|
||||
|
||||
@ -702,14 +702,14 @@ int ObPlanCacheValue::resolver_params(ObPlanCacheCtx &pc_ctx,
|
||||
} else if (lib::is_oracle_mode()
|
||||
&& (value.is_negative_number()
|
||||
|| (value.is_zero_number() && '-' == raw_param->str_value_[0]))) { // -0 is also counted as negative
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_DEBUG("param must be positive", K(ret), K(i), K(value));
|
||||
pc_ctx.should_add_plan_ = false; // 内部主动抛出not supported时候需要设置这个标志,以免新计划add plan导致锁冲突
|
||||
} else if (lib::is_mysql_mode()
|
||||
&& value.is_integer_type()
|
||||
&& (value.get_int() < 0
|
||||
|| (0 == value.get_int() && '-' == raw_param->str_value_[0]))) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_DEBUG("param must be positive", K(ret), K(i), K(value));
|
||||
pc_ctx.should_add_plan_ = false; // 内部主动抛出not supported时候需要设置这个标志,以免新计划add plan导致锁冲突
|
||||
} else {
|
||||
|
||||
@ -364,57 +364,35 @@ int ObPlanMatchHelper::check_inner_constraints(
|
||||
if (strict_cons.count() >0 || non_strict_cons.count() > 0) {
|
||||
const int64_t tbl_count = phy_tbl_infos.count();
|
||||
ObSEArray<PwjTable, 4> pwj_tables;
|
||||
SMART_VARS_2((ObPwjComparer, strict_pwj_comparer, true),
|
||||
(ObPwjComparer, non_strict_pwj_comparer, false)) {
|
||||
SMART_VARS_2((ObStrictPwjComparer, strict_pwj_comparer),
|
||||
(ObNonStrictPwjComparer, non_strict_pwj_comparer)) {
|
||||
if (OB_FAIL(pwj_tables.prepare_allocate(tbl_count))) {
|
||||
LOG_WARN("failed to prepare allocate pwj tables", K(ret));
|
||||
}
|
||||
|
||||
/**
|
||||
* 遍历严格pwj约束和非严格pwj约束,并生成可以做partition wise join的partition id的映射。
|
||||
* 因为可能存在如下形式的约束
|
||||
* strict_pwj_cons = [0,1], [2,3]
|
||||
* non_strict_pwj_cons = [0,2]
|
||||
* 如果先遍历strict_pwj_cons,再遍历non_strict_pwj_cons,就可能出现一种情况:
|
||||
* 遍历strict_pwj_cons后,pwj_map中设置了[part_array0,part_array1,part_array2,part_array3]的映射,
|
||||
* 但是遍历non_strict_pwj_cons时发现partition_array2需要调整,那么就要递归地调整所有与其相关的array,
|
||||
* 调整提来很复杂。
|
||||
* 按照基表的顺序在strict_pwj_cons和non_strict_pwj_cons中分别遍历则可以规避这种情况:
|
||||
* 遍历以0开头的所有约束,会在pwj_map中设置[part_array0,part_array1,part_array2]的映射;
|
||||
* 遍历以1开头的所有约束,发现没有相关的约束;
|
||||
* 遍历以2开头的所有约束,需要在pwj_map中设置part_array3,由于part_array2已经设置过了,因此
|
||||
* 按照part_array2生成的part_array3的映射不需要再做调整
|
||||
* 遍历以3开头的所有约束,发现没有相关的约束
|
||||
*/
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < tbl_count; ++i) {
|
||||
// 遍历严格约束中以i开始的约束
|
||||
for (int64_t j = 0; OB_SUCC(ret) && j < strict_cons.count(); ++j) {
|
||||
const ObPlanPwjConstraint &pwj_cons = strict_cons.at(j);
|
||||
if (OB_UNLIKELY(pwj_cons.count() <= 1)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get unexpected pwj constraint", K(ret), K(pwj_cons));
|
||||
} else if (pwj_cons.at(0) == i) {
|
||||
if (OB_FAIL(check_pwj_cons(pc_ctx, pwj_cons, phy_tbl_infos,
|
||||
pwj_tables, strict_pwj_comparer,
|
||||
pwj_map, is_same))) {
|
||||
LOG_WARN("failed to check pwj cons", K(ret));
|
||||
}
|
||||
}
|
||||
for (int64_t i = 0; OB_SUCC(ret) && is_same && i < strict_cons.count(); ++i) {
|
||||
const ObPlanPwjConstraint &pwj_cons = strict_cons.at(i);
|
||||
if (OB_UNLIKELY(pwj_cons.count() <= 1)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get unexpected pwj constraint", K(ret), K(pwj_cons));
|
||||
} else if (OB_FAIL(check_strict_pwj_cons(pc_ctx, pwj_cons, phy_tbl_infos,
|
||||
strict_pwj_comparer, pwj_map, is_same))) {
|
||||
LOG_WARN("failed to check strict pwj cons", K(ret));
|
||||
} else {
|
||||
LOG_DEBUG("succ to check strict pwj cons", K(is_same));
|
||||
}
|
||||
}
|
||||
|
||||
// 遍历非严格约束中以i开始的约束
|
||||
for (int64_t j = 0; OB_SUCC(ret) && j < non_strict_cons.count(); ++j) {
|
||||
const ObPlanPwjConstraint &pwj_cons = non_strict_cons.at(j);
|
||||
if (OB_UNLIKELY(pwj_cons.count() <= 1)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get unexpected pwj constraint", K(ret), K(pwj_cons));
|
||||
} else if (pwj_cons.at(0) == i) {
|
||||
if (OB_FAIL(check_pwj_cons(pc_ctx, pwj_cons, phy_tbl_infos,
|
||||
pwj_tables, non_strict_pwj_comparer,
|
||||
pwj_map, is_same))) {
|
||||
LOG_WARN("failed to check pwj cons", K(ret));
|
||||
}
|
||||
}
|
||||
for (int64_t i = 0; OB_SUCC(ret) && is_same && i < non_strict_cons.count(); ++i) {
|
||||
const ObPlanPwjConstraint &pwj_cons = non_strict_cons.at(i);
|
||||
if (OB_UNLIKELY(pwj_cons.count() <= 1)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get unexpected pwj constraint", K(ret), K(pwj_cons));
|
||||
} else if (OB_FAIL(check_non_strict_pwj_cons(pwj_cons, phy_tbl_infos,
|
||||
non_strict_pwj_comparer, is_same))) {
|
||||
LOG_WARN("failed to check non strict pwj cons", K(ret));
|
||||
} else {
|
||||
LOG_DEBUG("succ to check non strict pwj cons", K(is_same));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -425,12 +403,11 @@ int ObPlanMatchHelper::check_inner_constraints(
|
||||
return ret;
|
||||
}
|
||||
|
||||
int64_t ObPlanMatchHelper::check_pwj_cons(
|
||||
int ObPlanMatchHelper::check_strict_pwj_cons(
|
||||
const ObPlanCacheCtx &pc_ctx,
|
||||
const ObPlanPwjConstraint &pwj_cons,
|
||||
const common::ObIArray<ObCandiTableLoc> &phy_tbl_infos,
|
||||
ObIArray<PwjTable> &pwj_tables,
|
||||
ObPwjComparer &pwj_comparer,
|
||||
const ObIArray<ObCandiTableLoc> &phy_tbl_infos,
|
||||
ObStrictPwjComparer &pwj_comparer,
|
||||
PWJTabletIdMap &pwj_map,
|
||||
bool &is_same) const
|
||||
{
|
||||
@ -461,49 +438,53 @@ int64_t ObPlanMatchHelper::check_pwj_cons(
|
||||
const uint64_t tenant_id = GET_MY_SESSION(pc_ctx.exec_ctx_)->get_effective_tenant_id();
|
||||
for (int64_t i = 0; OB_SUCC(ret) && is_same && i < pwj_cons.count(); ++i) {
|
||||
const int64_t table_idx = pwj_cons.at(i);
|
||||
PwjTable &table = pwj_tables.at(table_idx);
|
||||
bool need_set_refactored = false;
|
||||
if (OB_INVALID_ID == table.ref_table_id_) {
|
||||
// pwj table no init
|
||||
need_set_refactored = true;
|
||||
const ObCandiTableLoc &phy_tbl_info = phy_tbl_infos.at(table_idx);
|
||||
share::schema::ObSchemaGetterGuard *schema_guard = pc_ctx.sql_ctx_.schema_guard_;
|
||||
const share::schema::ObTableSchema *table_schema = NULL;
|
||||
if (OB_ISNULL(schema_guard)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get unexpected null", K(ret));
|
||||
} else if (OB_FAIL(schema_guard->get_table_schema(
|
||||
tenant_id, phy_tbl_info.get_ref_table_id(), table_schema))) {
|
||||
LOG_WARN("failed to get table schema", K(ret), K(tenant_id), K(phy_tbl_info.get_ref_table_id()));
|
||||
} else if (OB_ISNULL(table_schema)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get unexpected null", K(ret));
|
||||
} else if (OB_FAIL(table.init(*table_schema, phy_tbl_info))) {
|
||||
LOG_WARN("failed to init pwj table with table schema", K(ret));
|
||||
}
|
||||
} else {
|
||||
// pwj table already init, table's ordered partition ids should use
|
||||
// partition id array in pwj map
|
||||
TabletIdArray tablet_id_array;
|
||||
if (OB_FAIL(pwj_map.get_refactored(table_idx, tablet_id_array))) {
|
||||
if (OB_HASH_NOT_EXIST == ret) {
|
||||
LOG_WARN("get refactored not find partition id array", K(ret));
|
||||
} else {
|
||||
LOG_WARN("failed to get refactored", K(ret));
|
||||
}
|
||||
} else if (OB_FAIL(table.ordered_tablet_ids_.assign(tablet_id_array))) {
|
||||
LOG_WARN("failed to assign partition id array", K(ret));
|
||||
}
|
||||
PwjTable pwj_table;
|
||||
const ObCandiTableLoc &phy_tbl_info = phy_tbl_infos.at(table_idx);
|
||||
share::schema::ObSchemaGetterGuard *schema_guard = pc_ctx.sql_ctx_.schema_guard_;
|
||||
const share::schema::ObTableSchema *table_schema = NULL;
|
||||
if (OB_ISNULL(schema_guard)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get unexpected null", K(ret));
|
||||
} else if (OB_FAIL(schema_guard->get_table_schema(
|
||||
tenant_id, phy_tbl_info.get_ref_table_id(), table_schema))) {
|
||||
LOG_WARN("failed to get table schema", K(ret), K(tenant_id), K(phy_tbl_info.get_ref_table_id()));
|
||||
} else if (OB_ISNULL(table_schema)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get unexpected null", K(ret));
|
||||
} else if (OB_FAIL(pwj_table.init(*table_schema, phy_tbl_info))) {
|
||||
LOG_WARN("failed to init pwj table with table schema", K(ret));
|
||||
} else if (OB_FAIL(pwj_comparer.add_table(pwj_table, is_same))) {
|
||||
LOG_WARN("failed to add table", K(ret));
|
||||
} else if (is_same &&
|
||||
OB_FAIL(pwj_map.set_refactored(table_idx, pwj_comparer.get_tablet_id_group().at(i)))) {
|
||||
LOG_WARN("failed to set refactored", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_FAIL(pwj_comparer.add_table(table, is_same))) {
|
||||
LOG_WARN("failed to add table", K(ret));
|
||||
} else if (is_same && need_set_refactored &&
|
||||
OB_FAIL(pwj_map.set_refactored(table_idx, pwj_comparer.get_tablet_id_group().at(i)))) {
|
||||
LOG_WARN("failed to set refactored", K(ret));
|
||||
}
|
||||
}
|
||||
int ObPlanMatchHelper::check_non_strict_pwj_cons(const ObPlanPwjConstraint &pwj_cons,
|
||||
const ObIArray<ObCandiTableLoc> &phy_tbl_infos,
|
||||
ObNonStrictPwjComparer &pwj_comparer,
|
||||
bool &is_same) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSEArray<common::ObAddr, 8> server_list;
|
||||
// non strict partition wise join constraint, request all tables in same group have at least
|
||||
// one partition on same server. Each table's partition count may be different.
|
||||
pwj_comparer.reset();
|
||||
for (int64_t i = 0; OB_SUCC(ret) && is_same && i < pwj_cons.count(); ++i) {
|
||||
const int64_t table_idx = pwj_cons.at(i);
|
||||
PwjTable pwj_table;
|
||||
server_list.reuse();
|
||||
const ObCandiTableLoc &table_loc = phy_tbl_infos.at(table_idx);
|
||||
if (OB_FAIL(table_loc.get_all_servers(server_list))) {
|
||||
LOG_WARN("failed to get all servers", K(ret));
|
||||
} else if (OB_FAIL(pwj_table.init(server_list))) {
|
||||
LOG_WARN("failed to init pwj table with table schema", K(ret));
|
||||
} else if (OB_FAIL(pwj_comparer.add_table(pwj_table, is_same))) {
|
||||
LOG_WARN("failed to add table", K(ret));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
||||
@ -106,16 +106,23 @@ private:
|
||||
PWJTabletIdMap &pwj_map,
|
||||
bool &is_same) const;
|
||||
/**
|
||||
* @brief Check if pwj constraints are satisfied
|
||||
* @brief Check if strict pwj constraints are satisfied
|
||||
*
|
||||
*/
|
||||
int64_t check_pwj_cons(const ObPlanCacheCtx &pc_ctx,
|
||||
const ObPlanPwjConstraint &pwj_cons,
|
||||
const common::ObIArray<ObCandiTableLoc> &phy_tbl_infos,
|
||||
ObIArray<PwjTable> &pwj_tables,
|
||||
ObPwjComparer &pwj_comparer,
|
||||
PWJTabletIdMap &pwj_map,
|
||||
bool &is_same) const;
|
||||
int check_strict_pwj_cons(const ObPlanCacheCtx &pc_ctx,
|
||||
const ObPlanPwjConstraint &pwj_cons,
|
||||
const ObIArray<ObCandiTableLoc> &phy_tbl_infos,
|
||||
ObStrictPwjComparer &pwj_comparer,
|
||||
PWJTabletIdMap &pwj_map,
|
||||
bool &is_same) const;
|
||||
/**
|
||||
* @brief Check if non-strict pwj constraints are satisfied
|
||||
*
|
||||
*/
|
||||
int check_non_strict_pwj_cons(const ObPlanPwjConstraint &pwj_cons,
|
||||
const ObIArray<ObCandiTableLoc> &phy_tbl_infos,
|
||||
ObNonStrictPwjComparer &pwj_comparer,
|
||||
bool &is_same) const;
|
||||
/**
|
||||
* @brief Check table partition location
|
||||
*
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
#include "sql/plan_cache/ob_plan_cache_value.h"
|
||||
#include "sql/plan_cache/ob_cache_object.h"
|
||||
#include "sql/plan_cache/ob_dist_plans.h"
|
||||
#include "sql/privilege_check/ob_ora_priv_check.h"
|
||||
#include "sql/optimizer/ob_log_plan.h"
|
||||
#include "sql/engine/ob_physical_plan.h"
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
@ -131,6 +132,13 @@ int ObPlanSet::match_params_info(const ParamStore *params,
|
||||
}
|
||||
}
|
||||
|
||||
// privilege
|
||||
if (OB_SUCC(ret) && is_same && all_priv_constraints_.count() > 0) {
|
||||
if (OB_FAIL(match_priv_cons(pc_ctx, is_same))) {
|
||||
LOG_WARN("failed to check privilege constraint", K(ret));
|
||||
}
|
||||
}
|
||||
|
||||
//pre calculate
|
||||
if (OB_SUCC(ret) && is_same) {
|
||||
ObPhysicalPlanCtx *plan_ctx = exec_ctx.get_physical_plan_ctx();
|
||||
@ -365,6 +373,42 @@ int ObPlanSet::match_multi_stmt_info(const ParamStore ¶ms,
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
int ObPlanSet::match_priv_cons(ObPlanCacheCtx &pc_ctx, bool &is_matched)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
is_matched = true;
|
||||
bool has_priv = false;
|
||||
ObSQLSessionInfo *session_info = pc_ctx.sql_ctx_.session_info_;
|
||||
ObSchemaGetterGuard *schema_guard = pc_ctx.sql_ctx_.schema_guard_;
|
||||
if (OB_ISNULL(session_info) || OB_ISNULL(schema_guard)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid argument", K(ret));
|
||||
}
|
||||
for (int64_t i = 0; OB_SUCC(ret) && is_matched && i < all_priv_constraints_.count(); ++i) {
|
||||
const ObPCPrivInfo &priv_info = all_priv_constraints_.at(i);
|
||||
bool has_priv = false;
|
||||
if (OB_FAIL(ObOraSysChecker::check_ora_user_sys_priv(*schema_guard,
|
||||
session_info->get_effective_tenant_id(),
|
||||
session_info->get_priv_user_id(),
|
||||
session_info->get_database_name(),
|
||||
priv_info.sys_priv_,
|
||||
session_info->get_enable_role_array()))) {
|
||||
if (OB_ERR_NO_PRIVILEGE == ret) {
|
||||
ret = OB_SUCCESS;
|
||||
LOG_DEBUG("lack sys privilege", "priv_type", all_priv_constraints_.at(i).sys_priv_);
|
||||
} else {
|
||||
LOG_WARN("failed to check ora user sys priv", K(ret));
|
||||
}
|
||||
} else {
|
||||
has_priv = true;
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
is_matched = priv_info.has_privilege_ == has_priv;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
//判断多组参数中同一列参数的是否均为true/false, 并返回第一个参数是true/false
|
||||
int ObPlanSet::check_vector_param_same_bool(const ObObjParam ¶m_obj,
|
||||
@ -529,6 +573,7 @@ void ObPlanSet::reset()
|
||||
all_plan_const_param_constraints_.reset();
|
||||
all_equal_param_constraints_.reset();
|
||||
all_pre_calc_constraints_.reset();
|
||||
all_priv_constraints_.reset();
|
||||
alloc_.reset();
|
||||
}
|
||||
|
||||
@ -654,16 +699,19 @@ int ObPlanSet::init_new_set(const ObPlanCacheCtx &pc_ctx,
|
||||
all_plan_const_param_constraints_.reset();
|
||||
all_equal_param_constraints_.reset();
|
||||
all_pre_calc_constraints_.reset();
|
||||
all_priv_constraints_.reset();
|
||||
} else if (PST_SQL_CRSR == ps_t) {
|
||||
// otherwise it should not be empty
|
||||
CK( OB_NOT_NULL(sql_ctx.all_plan_const_param_constraints_),
|
||||
OB_NOT_NULL(sql_ctx.all_possible_const_param_constraints_),
|
||||
OB_NOT_NULL(sql_ctx.all_equal_param_constraints_),
|
||||
OB_NOT_NULL(sql_ctx.all_pre_calc_constraints_));
|
||||
OB_NOT_NULL(sql_ctx.all_pre_calc_constraints_),
|
||||
OB_NOT_NULL(sql_ctx.all_priv_constraints_));
|
||||
OZ( (set_const_param_constraint)(*sql_ctx.all_plan_const_param_constraints_, false) );
|
||||
OZ( (set_const_param_constraint)(*sql_ctx.all_possible_const_param_constraints_, true) );
|
||||
OZ( (set_equal_param_constraint)(*sql_ctx.all_equal_param_constraints_) );
|
||||
OZ( (set_pre_calc_constraint(*sql_ctx.all_pre_calc_constraints_)));
|
||||
OZ( (set_priv_constraint(*sql_ctx.all_priv_constraints_)));
|
||||
} else {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get an unexpected plan set type", K(ps_t), K(plan.get_ns()));
|
||||
@ -792,6 +840,30 @@ int ObPlanSet::set_pre_calc_constraint(common::ObDList<ObPreCalcExprConstraint>
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// add priv constraint
|
||||
int ObPlanSet::set_priv_constraint(common::ObIArray<ObPCPrivInfo> &priv_constraint)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
all_priv_constraints_.reset();
|
||||
all_priv_constraints_.set_allocator(&alloc_);
|
||||
if (priv_constraint.empty()) {
|
||||
//do nothing
|
||||
} else if (OB_FAIL(all_priv_constraints_.init(priv_constraint.count()))) {
|
||||
LOG_WARN("failed to init privilege constraint array", K(ret));
|
||||
}
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < priv_constraint.count(); ++i) {
|
||||
const ObPCPrivInfo &priv_info = priv_constraint.at(i);
|
||||
if (OB_UNLIKELY(!(priv_info.sys_priv_ > PRIV_ID_NONE && priv_info.sys_priv_ < PRIV_ID_MAX))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("invalid priv type", K(priv_info), K(ret));
|
||||
} else if (OB_FAIL(all_priv_constraints_.push_back(priv_info))) {
|
||||
LOG_WARN("failed to push back priv info");
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// match actually constraint
|
||||
int ObPlanSet::match_cons(const ObPlanCacheCtx &pc_ctx, bool &is_matched)
|
||||
{
|
||||
@ -800,6 +872,7 @@ int ObPlanSet::match_cons(const ObPlanCacheCtx &pc_ctx, bool &is_matched)
|
||||
ObIArray<ObPCConstParamInfo> *possible_param_cons =
|
||||
pc_ctx.sql_ctx_.all_possible_const_param_constraints_;
|
||||
ObIArray<ObPCParamEqualInfo> *equal_cons = pc_ctx.sql_ctx_.all_equal_param_constraints_;
|
||||
ObIArray<ObPCPrivInfo> *priv_cons = pc_ctx.sql_ctx_.all_priv_constraints_;
|
||||
is_matched = true;
|
||||
|
||||
if (OB_ISNULL(param_cons) ||
|
||||
@ -810,7 +883,8 @@ int ObPlanSet::match_cons(const ObPlanCacheCtx &pc_ctx, bool &is_matched)
|
||||
LOG_WARN("invalid arugment", K(param_cons), K(possible_param_cons), K(equal_cons));
|
||||
} else if (param_cons->count() != all_plan_const_param_constraints_.count() ||
|
||||
possible_param_cons->count() != all_possible_const_param_constraints_.count() ||
|
||||
equal_cons->count() != all_equal_param_constraints_.count()) {
|
||||
equal_cons->count() != all_equal_param_constraints_.count() ||
|
||||
priv_cons->count() != all_priv_constraints_.count()) {
|
||||
is_matched = false;
|
||||
} else {
|
||||
for (int64_t i=0; is_matched && i < all_plan_const_param_constraints_.count(); i++) {
|
||||
@ -822,6 +896,9 @@ int ObPlanSet::match_cons(const ObPlanCacheCtx &pc_ctx, bool &is_matched)
|
||||
for (int64_t i=0; is_matched && i < all_equal_param_constraints_.count(); i++) {
|
||||
is_matched = (all_equal_param_constraints_.at(i)==equal_cons->at(i));
|
||||
}
|
||||
for (int64_t i=0; is_matched && i < all_priv_constraints_.count(); i++) {
|
||||
is_matched = (all_priv_constraints_.at(i)==priv_cons->at(i));
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -1042,6 +1119,7 @@ int ObSqlPlanSet::add_cache_obj(ObPlanCacheObject &cache_object,
|
||||
} else {
|
||||
ret = add_plan(static_cast<ObPhysicalPlan&>(cache_object), pc_ctx, ol_param_idx);
|
||||
}
|
||||
cache_object.get_pre_expr_ref_count();
|
||||
// ref_cnt++;
|
||||
if (OB_FAIL(ret)) {
|
||||
LOG_WARN("failed to add plan.", K(ret));
|
||||
@ -1232,6 +1310,7 @@ int ObSqlPlanSet::init_new_set(const ObPlanCacheCtx &pc_ctx,
|
||||
enable_inner_part_parallel_exec_ = sql_plan.get_px_dop() > 1;
|
||||
contain_index_location = sql_plan.contain_index_location();
|
||||
LOG_DEBUG("using px", K(enable_inner_part_parallel_exec_));
|
||||
plan.get_pre_expr_ref_count();
|
||||
}
|
||||
if (OB_SUCC(ret) && (!contain_index_location || is_multi_stmt_plan())) {
|
||||
const ObTablePartitionInfoArray &partition_infos = sql_ctx.partition_infos_;
|
||||
|
||||
@ -50,6 +50,7 @@ typedef ObFixedArray<common::ObObjMeta, common::ObIAllocator> UserSessionVarMeta
|
||||
typedef ObFixedArray<ObPCConstParamInfo, common::ObIAllocator> ConstParamConstraint;
|
||||
typedef ObFixedArray<ObPCParamEqualInfo, common::ObIAllocator> EqualParamConstraint;
|
||||
typedef ObDList<ObPreCalcExprConstraint> PreCalcExprConstraint;
|
||||
typedef ObFixedArray<ObPCPrivInfo, common::ObIAllocator> PrivConstraint;
|
||||
|
||||
enum ObPlanSetType
|
||||
{
|
||||
@ -108,6 +109,7 @@ public:
|
||||
all_possible_const_param_constraints_(alloc_),
|
||||
all_plan_const_param_constraints_(alloc_),
|
||||
all_pre_calc_constraints_(),
|
||||
all_priv_constraints_(),
|
||||
multi_stmt_rowkey_pos_(alloc_),
|
||||
pre_cal_expr_handler_(NULL),
|
||||
res_map_rule_id_(common::OB_INVALID_ID),
|
||||
@ -182,6 +184,8 @@ private:
|
||||
|
||||
int set_pre_calc_constraint(common::ObDList<ObPreCalcExprConstraint> &pre_calc_cons);
|
||||
|
||||
int set_priv_constraint(common::ObIArray<ObPCPrivInfo> &priv_constraint);
|
||||
|
||||
int match_cons(const ObPlanCacheCtx &pc_ctx, bool &is_matched);
|
||||
/**
|
||||
* @brief Match const param constraint.
|
||||
@ -198,6 +202,7 @@ private:
|
||||
|
||||
int pre_calc_exprs(ObExecContext &exec_ctx);
|
||||
|
||||
int match_priv_cons(ObPlanCacheCtx &pc_ctx, bool &is_matched);
|
||||
static int check_vector_param_same_bool(const ObObjParam ¶m_obj,
|
||||
bool &first_val,
|
||||
bool &is_same);
|
||||
@ -222,6 +227,7 @@ protected:
|
||||
ConstParamConstraint all_plan_const_param_constraints_;
|
||||
EqualParamConstraint all_equal_param_constraints_;
|
||||
PreCalcExprConstraint all_pre_calc_constraints_;
|
||||
PrivConstraint all_priv_constraints_;
|
||||
// maintain the rowkey position for multi_stmt
|
||||
common::ObFixedArray<int64_t, common::ObIAllocator> multi_stmt_rowkey_pos_;
|
||||
// pre calculable expression list handler.
|
||||
|
||||
@ -1578,6 +1578,13 @@ int ObSqlParameterization::mark_tree(ParseNode *tree ,SqlInfo &sql_info)
|
||||
if (OB_FAIL(mark_args(node[1], mark_arr, ARGS_NUMBER_TWO, sql_info))) {
|
||||
SQL_PC_LOG(WARN, "fail to mark arg", K(ret));
|
||||
}
|
||||
} else if ((0 == func_name.case_compare("name_const"))
|
||||
&& (2 == node[1]->num_child_)) {
|
||||
const int64_t ARGS_NUMBER_TWO = 2;
|
||||
bool mark_arr[ARGS_NUMBER_TWO] = {1, 0};
|
||||
if (OB_FAIL(mark_args(node[1], mark_arr, ARGS_NUMBER_TWO, sql_info))) {
|
||||
SQL_PC_LOG(WARN, "fail to mark arg", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (T_OP_LIKE == tree->type_) {
|
||||
|
||||
Reference in New Issue
Block a user