[opt_stats]: Fix online_osg bugs
This commit is contained in:
@ -100,7 +100,6 @@ void ObOptimizerStatsGatheringOp::reset() {
|
||||
}
|
||||
|
||||
void ObOptimizerStatsGatheringOp::reuse_stats() {
|
||||
// call each column stat's reset to free memory allocated by inner_max_alloc and inner_min_alloc
|
||||
FOREACH(it, column_stats_map_) {
|
||||
if (OB_NOT_NULL(it->second)) {
|
||||
it->second->reset();
|
||||
@ -489,9 +488,18 @@ void ObOptimizerStatsGatheringOp::set_col_stats_avg_len(StatItems &all_stats, in
|
||||
int ObOptimizerStatsGatheringOp::set_col_stats(StatItems &all_stats, ObObj &obj)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const ObObj *tmp_obj;
|
||||
if (OB_FAIL(ObOptimizerUtil::truncate_string_for_opt_stats(&obj, arena_, tmp_obj))) {
|
||||
LOG_WARN("fail to truncate string", K(ret));
|
||||
} else {
|
||||
obj = *tmp_obj;
|
||||
}
|
||||
|
||||
all_stats.global_col_stat_->set_stat_level(StatLevel::TABLE_LEVEL);
|
||||
if (OB_FAIL(all_stats.global_col_stat_->merge_obj(obj))) {
|
||||
LOG_WARN("fail to set global column stat", K(ret), K(obj));
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_FAIL(all_stats.global_col_stat_->merge_obj(obj))) {
|
||||
LOG_WARN("fail to set global column stat", K(ret), K(obj));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && MY_SPEC.is_part_table()) {
|
||||
all_stats.part_col_stat_->set_stat_level(StatLevel::PARTITION_LEVEL);
|
||||
@ -583,10 +591,8 @@ int ObOptimizerStatsGatheringOp::merge_col_stat(ObOptColumnStat *src_col_stat)
|
||||
} else {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (OB_FAIL(col_stat->merge_column_stat(*src_col_stat))) {
|
||||
LOG_WARN("fail to merge two table stats", K(ret), K(col_stat), K(src_col_stat));
|
||||
}
|
||||
} else if (OB_FAIL(col_stat->merge_column_stat(*src_col_stat))) {
|
||||
LOG_WARN("fail to merge two table stats", K(ret), K(col_stat), K(src_col_stat));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -166,7 +166,8 @@ int ObInsertLogPlan::check_need_online_stats_gather(bool &need_osg)
|
||||
LOG_WARN("get unexpected null pointer", K(ret), K(insert_stmt->get_insert_table_info()));
|
||||
} else if (OB_UNLIKELY(ins_table->is_system_table_ || ins_table->is_index_table_)
|
||||
|| insert_stmt->is_insert_up()
|
||||
|| !get_optimizer_context().get_session_info()->is_user_session()) {
|
||||
|| insert_stmt->value_from_select()
|
||||
|| (!get_optimizer_context().get_session_info()->is_user_session())) {
|
||||
need_gathering = false;
|
||||
}
|
||||
|
||||
@ -184,7 +185,7 @@ int ObInsertLogPlan::check_need_online_stats_gather(bool &need_osg)
|
||||
&& online_sys_var
|
||||
&& ((get_optimizer_context().get_query_ctx()->get_global_hint().should_generate_osg_operator())
|
||||
|| (get_optimizer_context().use_pdml()));
|
||||
LOG_TRACE("online insert stat", K(online_sys_var), K(need_osg));
|
||||
LOG_TRACE("online insert stat", K(online_sys_var), K(need_osg), K(need_gathering));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -4103,40 +4103,10 @@ int ObOptSelectivity::convert_valid_obj_for_opt_stats(const ObObj *old_obj,
|
||||
const ObObj *&new_obj)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObObj tmp_obj;
|
||||
if (OB_ISNULL(old_obj)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get unexpected null", K(ret), K(old_obj));
|
||||
} else if (old_obj->is_string_type()) {
|
||||
ObString str;
|
||||
if (OB_FAIL(old_obj->get_string(str))) {
|
||||
LOG_WARN("failed to get string", K(ret), K(str));
|
||||
} else {
|
||||
int64_t mb_len = ObCharset::strlen_char(old_obj->get_collation_type(), str.ptr(), str.length());
|
||||
if (mb_len <= OPT_STATS_MAX_VALUE_CAHR_LEN) {
|
||||
new_obj = old_obj;
|
||||
} else {
|
||||
//need truncate string, because the opt stats is gathered after truncate string, such as: max_value、min_value、histogram.
|
||||
ObObj *tmp_obj = NULL;
|
||||
if (OB_ISNULL(tmp_obj = static_cast<ObObj*>(alloc.alloc(sizeof(ObObj))))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to alloc buf", K(ret));
|
||||
} else {
|
||||
int64_t valid_len = ObCharset::charpos(old_obj->get_collation_type(), str.ptr(),
|
||||
str.length(), OPT_STATS_MAX_VALUE_CAHR_LEN);
|
||||
if (OB_UNLIKELY(valid_len <= 0)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get unexpected error", K(ret), K(valid_len), K(str), K(OPT_STATS_MAX_VALUE_CAHR_LEN));
|
||||
} else {
|
||||
tmp_obj->set_varchar(str.ptr(), valid_len);
|
||||
tmp_obj->set_meta_type(old_obj->get_meta());
|
||||
new_obj = tmp_obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
new_obj = old_obj;
|
||||
if (OB_FAIL(ObOptimizerUtil::truncate_string_for_opt_stats(old_obj,
|
||||
alloc,
|
||||
new_obj))) {
|
||||
LOG_WARN("fail to truncated string", K(ret));
|
||||
}
|
||||
LOG_TRACE("Succeed to convert valid obj for opt stats", KPC(old_obj), KPC(new_obj));
|
||||
return ret;
|
||||
|
||||
@ -8611,3 +8611,44 @@ int ObOptimizerUtil::replace_gen_column(ObLogPlan *log_plan, ObRawExpr *part_exp
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObOptimizerUtil::truncate_string_for_opt_stats(const ObObj *old_obj,
|
||||
ObIAllocator &alloc,
|
||||
const ObObj *&new_obj)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
bool is_truncated = false;
|
||||
if (old_obj->is_string_type()) {
|
||||
ObString str;
|
||||
if (OB_FAIL(old_obj->get_string(str))) {
|
||||
LOG_WARN("failed to get string", K(ret), K(str));
|
||||
} else {
|
||||
int64_t mb_len = ObCharset::strlen_char(old_obj->get_collation_type(), str.ptr(), str.length());
|
||||
if (mb_len <= OPT_STATS_MAX_VALUE_CHAR_LEN) {
|
||||
} else {
|
||||
//need truncate string, because the opt stats is gathered after truncate string, such as: max_value、min_value、histogram.
|
||||
ObObj *tmp_obj = NULL;
|
||||
if (OB_ISNULL(tmp_obj = static_cast<ObObj*>(alloc.alloc(sizeof(ObObj))))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to alloc buf", K(ret));
|
||||
} else {
|
||||
int64_t valid_len = ObCharset::charpos(old_obj->get_collation_type(), str.ptr(),
|
||||
str.length(), OPT_STATS_MAX_VALUE_CHAR_LEN);
|
||||
if (OB_UNLIKELY(valid_len <= 0)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get unexpected error", K(ret), K(valid_len), K(str), K(OPT_STATS_MAX_VALUE_CHAR_LEN));
|
||||
} else {
|
||||
tmp_obj->set_varchar(str.ptr(), valid_len);
|
||||
tmp_obj->set_meta_type(old_obj->get_meta());
|
||||
new_obj = tmp_obj;
|
||||
is_truncated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && !is_truncated) {
|
||||
new_obj = old_obj;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1436,6 +1436,10 @@ public:
|
||||
|
||||
static int check_contain_my_exec_param(ObRawExpr* expr, const common::ObIArray<ObExecParamRawExpr*> & my_exec_params, bool &contain);
|
||||
|
||||
static int truncate_string_for_opt_stats(const ObObj *old_obj,
|
||||
ObIAllocator &alloc,
|
||||
const ObObj *&new_obj);
|
||||
|
||||
private:
|
||||
//disallow construct
|
||||
ObOptimizerUtil();
|
||||
|
||||
Reference in New Issue
Block a user