diff --git a/src/pl/sys_package/ob_dbms_stats.cpp b/src/pl/sys_package/ob_dbms_stats.cpp index 0bc93bb74e88df13c63a241e0dbcc0da80e916e4..7b1c29ff2347c4828f0f6f136b03a72ca7fb79de 100644 --- a/src/pl/sys_package/ob_dbms_stats.cpp +++ b/src/pl/sys_package/ob_dbms_stats.cpp @@ -3738,7 +3738,7 @@ int ObDbmsStats::parse_gather_stat_options(ObExecContext &ctx, { int ret = OB_SUCCESS; UNUSED(ctx); - int64_t stat_options = StatOptionFlags::OPT_APPROXIMATE_NDV; + int64_t stat_options = StatOptionFlags::OPT_APPROXIMATE_NDV | StatOptionFlags::OPT_ESTIMATE_BLOCK; number::ObNumber num_est_percent; number::ObNumber num_degree; double percent = 0.0; @@ -3935,6 +3935,14 @@ int ObDbmsStats::get_default_stat_options(ObExecContext &ctx, LOG_WARN("failed to push back", K(ret)); } } + if (OB_SUCC(ret) && stat_options & StatOptionFlags::OPT_ESTIMATE_BLOCK) { + ObEstimateBlockPrefs *tmp_pref = NULL; + if (OB_FAIL(new_stat_prefs(ctx.get_allocator(), ctx.get_my_session(), ObString(), tmp_pref))) { + LOG_WARN("failed to new stat prefs", K(ret)); + } else if (OB_FAIL(stat_prefs.push_back(tmp_pref))) { + LOG_WARN("failed to push back", K(ret)); + } + } if (OB_SUCC(ret)) { if (OB_FAIL(ObDbmsStatsPreferences::get_sys_default_stat_options(ctx, stat_prefs, param))) { LOG_WARN("failed to get sys default stat options", K(ret)); @@ -5588,6 +5596,7 @@ int ObDbmsStats::gather_table_stats_with_default_param(ObExecContext &ctx, * CONCURRENT, DEBUG, ENABLE_HYBRID_HISTOGRAMS, INCREMENTAL_INTERNAL_CONTROL, JOB_OVERHEAD, * JOB_OVERHEAD_PERC, PREFERENCE_OVERRIDES_PARAMETER, SCAN_RATE, STAT_CATEGORY, SYS_FLAGS, * TRACE, WAIT_TIME_TO_UPDATE_STATS + * add new prefs for OceanBase: ESTIMATE_BLOCK https://docs.oracle.com/database/121/ARPLS/d_stats.htm#ARPLS68674 */ int ObDbmsStats::get_new_stat_pref(ObExecContext &ctx, @@ -5676,13 +5685,20 @@ int ObDbmsStats::get_new_stat_pref(ObExecContext &ctx, } else { stat_pref = tmp_pref; } + } else if (is_global_prefs && 0 == opt_name.case_compare("ESTIMATE_BLOCK")) { + ObEstimateBlockPrefs *tmp_pref = NULL; + if (OB_FAIL(new_stat_prefs(ctx.get_allocator(), ctx.get_my_session(), opt_value, tmp_pref))) { + LOG_WARN("failed to new stat prefs", K(ret)); + } else { + stat_pref = tmp_pref; + } } else { ret = OB_ERR_DBMS_STATS_PL; LOG_WARN("Invalid input values for pname", K(ret), K(opt_name)); LOG_USER_ERROR(OB_ERR_DBMS_STATS_PL, "Invalid input values for pname, Only Support CASCADE |"\ "DEGREE | ESTIMATE_PERCENT | GRANULARITY | INCREMENTAL |"\ "INCREMENTAL_LEVEL | METHOD_OPT | NO_INVALIDATE | OPTIONS"\ - "STALE_PERCENT | APPROXIMATE_NDV(global prefs unique) prefs"); + "STALE_PERCENT | ESTIMATE_BLOCK | APPROXIMATE_NDV(global prefs unique) prefs"); } return ret; } diff --git a/src/share/stat/ob_dbms_stats_executor.cpp b/src/share/stat/ob_dbms_stats_executor.cpp index 6de862957f84cf91eda253ed4d04e068cb5ce4b9..c855c0e063b105932107ad88b45577b04f26108a 100644 --- a/src/share/stat/ob_dbms_stats_executor.cpp +++ b/src/share/stat/ob_dbms_stats_executor.cpp @@ -45,7 +45,8 @@ int ObDbmsStatsExecutor::gather_table_stats(ObExecContext &ctx, ObModIds::OB_HASH_BUCKET_TABLE_STATISTICS, param.tenant_id_))) { LOG_WARN("failed to create hash map", K(ret)); - } else if (OB_FAIL(ObBasicStatsEstimator::estimate_block_count(ctx, param, + } else if (param.need_estimate_block_ && + OB_FAIL(ObBasicStatsEstimator::estimate_block_count(ctx, param, extra.partition_id_block_map_))) { LOG_WARN("failed to estimate block count", K(ret)); } diff --git a/src/share/stat/ob_dbms_stats_preferences.cpp b/src/share/stat/ob_dbms_stats_preferences.cpp index a5489d8d674ca15c1b535737c79ab590d6b8d155..aac69be0ead6be9e6bee9379c455ab5d2c6bb617 100644 --- a/src/share/stat/ob_dbms_stats_preferences.cpp +++ b/src/share/stat/ob_dbms_stats_preferences.cpp @@ -529,7 +529,23 @@ int ObDbmsStatsPreferences::gen_init_global_prefs_sql(ObSqlString &raw_sql, ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected error", K(ret), K(prefs.get_stat_pref_name()), K(prefs.get_stat_pref_default_value())); - } else if (OB_FAIL(value_str.append_fmt("('%s', %s, %s, '%s')", + } else if (OB_FAIL(value_str.append_fmt("('%s', %s, %s, '%s'),", + prefs.get_stat_pref_name(), + null_str, + time_str, + prefs.get_stat_pref_default_value()))) { + LOG_WARN("failed to append", K(ret)); + } else { + ++ total_rows; + } + } + if (OB_SUCC(ret)) {//init estimate_block + ObEstimateBlockPrefs prefs; + if (OB_ISNULL(prefs.get_stat_pref_name()) || OB_ISNULL(prefs.get_stat_pref_default_value())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get unexpected error", K(ret), K(prefs.get_stat_pref_name()), + K(prefs.get_stat_pref_default_value())); + } else if (OB_FAIL(value_str.append_fmt("('%s', %s, %s, '%s');", prefs.get_stat_pref_name(), null_str, time_str, @@ -1032,6 +1048,26 @@ int ObApproximateNdvPrefs::check_pref_value_validity(ObTableStatParam *param/*de return ret; } +int ObEstimateBlockPrefs::check_pref_value_validity(ObTableStatParam *param/*default null*/) +{ + int ret = OB_SUCCESS; + if (pvalue_.empty() || + 0 == pvalue_.case_compare("TRUE")) { + if (param != NULL) { + param->need_estimate_block_ = true; + } + } else if (0 == pvalue_.case_compare("FALSE")) { + if (param != NULL) { + param->need_estimate_block_ = false; + } + } else { + ret = OB_ERR_DBMS_STATS_PL; + LOG_WARN("Illegal value for ESTIMATE_BLOCK", K(ret), K(pvalue_)); + LOG_USER_ERROR(OB_ERR_DBMS_STATS_PL,"Illegal value for ESTIMATE_BLOCK: must be {TRUE, FALSE}"); + } + return ret; +} + #define ISSPACE(c) ((c) == ' ' || (c) == '\n' || (c) == '\r' || (c) == '\t' || (c) == '\f' || (c) == '\v') //compatible oracle, global prefs/schema prefs just only can set "for all columns...." diff --git a/src/share/stat/ob_dbms_stats_preferences.h b/src/share/stat/ob_dbms_stats_preferences.h index 6e9ae51c4d78c2c088d15aaa16e8a2f24b538aad..2303fcd6f9b5a3aacff8b8aa0a6d3c2f52132ce3 100644 --- a/src/share/stat/ob_dbms_stats_preferences.h +++ b/src/share/stat/ob_dbms_stats_preferences.h @@ -201,6 +201,19 @@ class ObApproximateNdvPrefs : public ObStatPrefs virtual const char* get_stat_pref_default_value() const { return "TRUE"; } }; +class ObEstimateBlockPrefs : public ObStatPrefs +{ + public: + ObEstimateBlockPrefs() : ObStatPrefs() {} + ObEstimateBlockPrefs(ObIAllocator *alloc, + ObSQLSessionInfo *session_info, + const ObString &pvalue) : + ObStatPrefs(alloc, session_info, pvalue) {} + virtual int check_pref_value_validity(ObTableStatParam *param = NULL) override; + virtual const char* get_stat_pref_name() const { return "ESTIMATE_BLOCK"; } + virtual const char* get_stat_pref_default_value() const { return "TRUE"; } +}; + template static int new_stat_prefs(ObIAllocator &allocator, ObSQLSessionInfo *session_info, const ObString &opt_value, T *&src) diff --git a/src/share/stat/ob_index_stats_estimator.cpp b/src/share/stat/ob_index_stats_estimator.cpp index 0fea173abb21912340661fb2e92258673d51140c..94922a90ae993e340fcdc2b6adba3a8946ee8760 100644 --- a/src/share/stat/ob_index_stats_estimator.cpp +++ b/src/share/stat/ob_index_stats_estimator.cpp @@ -258,7 +258,8 @@ int ObIndexStatsEstimator::fast_gather_index_stats(ObExecContext &ctx, LOG_WARN("get unexpected error", K(index_param.is_global_index_), K(gather_part_ids.count())); } else if (mgr.get_table_stat(data_param.tenant_id_, data_param.table_id_, gather_part_ids, data_table_stats)) { LOG_WARN("failed to get table stat", K(ret)); - } else if (OB_FAIL(partition_id_block_map.create(10000, + } else if (index_param.need_estimate_block_ && + OB_FAIL(partition_id_block_map.create(10000, ObModIds::OB_HASH_BUCKET_TABLE_STATISTICS, ObModIds::OB_HASH_BUCKET_TABLE_STATISTICS, index_param.tenant_id_))) { diff --git a/src/share/stat/ob_stat_define.cpp b/src/share/stat/ob_stat_define.cpp index 395af49ca780d0bba75fff17bc5e3d6292583741..89ed264b7b85787524a84e5c63ccc304ec8f72b5 100644 --- a/src/share/stat/ob_stat_define.cpp +++ b/src/share/stat/ob_stat_define.cpp @@ -115,6 +115,7 @@ int ObTableStatParam::assign(const ObTableStatParam &other) global_tablet_id_ = other.global_tablet_id_; global_data_part_id_ = other.global_data_part_id_; data_table_id_ = other.data_table_id_; + need_estimate_block_ = other.need_estimate_block_; if (OB_FAIL(part_infos_.assign(other.part_infos_))) { LOG_WARN("failed to assign", K(ret)); } else if (OB_FAIL(subpart_infos_.assign(other.subpart_infos_))) { diff --git a/src/share/stat/ob_stat_define.h b/src/share/stat/ob_stat_define.h index d2585b7c2fd9d42c044dd2d016179b4234ec6ae3..d6c93d5db5e344622eeb2784f379ec99279e5bd2 100644 --- a/src/share/stat/ob_stat_define.h +++ b/src/share/stat/ob_stat_define.h @@ -44,7 +44,8 @@ enum StatOptionFlags OPT_STATTYPE = 1 << 10, OPT_FORCE = 1 << 11, OPT_APPROXIMATE_NDV = 1 << 12, - OPT_STAT_OPTION_ALL = (1 << 13) -1 + OPT_ESTIMATE_BLOCK = 1 << 13, + OPT_STAT_OPTION_ALL = (1 << 14) -1 }; const static double OPT_DEFAULT_STALE_PERCENT = 0.1; const static int64_t OPT_DEFAULT_STATS_RETENTION = 31; @@ -289,7 +290,8 @@ struct ObTableStatParam { duration_time_(-1), global_tablet_id_(0), global_data_part_id_(INVALID_GLOBAL_PART_ID), - data_table_id_(INVALID_GLOBAL_PART_ID) + data_table_id_(INVALID_GLOBAL_PART_ID), + need_estimate_block_(true) {} int assign(const ObTableStatParam &other); @@ -360,6 +362,7 @@ struct ObTableStatParam { uint64_t global_tablet_id_; int64_t global_data_part_id_; // used to check wether table is locked, while gathering index stats. int64_t data_table_id_; // the data table id for index schema + bool need_estimate_block_;//need estimate macro/micro block count TO_STRING_KV(K(tenant_id_), K(db_name_), @@ -402,7 +405,8 @@ struct ObTableStatParam { K(duration_time_), K(global_tablet_id_), K(global_data_part_id_), - K(data_table_id_)); + K(data_table_id_), + K(need_estimate_block_)); }; struct ObOptStat diff --git a/src/sql/resolver/expr/ob_raw_expr_resolver_impl.cpp b/src/sql/resolver/expr/ob_raw_expr_resolver_impl.cpp index bbd36e7c02b21d9f09de4f0fa2c46fd7f1f49cab..2930e014d2df1697cf636aa57eb2e93289d14fdd 100644 --- a/src/sql/resolver/expr/ob_raw_expr_resolver_impl.cpp +++ b/src/sql/resolver/expr/ob_raw_expr_resolver_impl.cpp @@ -6486,6 +6486,7 @@ int ObRawExprResolverImpl::process_odbc_time_literals(const ObItemType dst_time_ tmp_node.num_child_ = 0; tmp_node.str_len_ = time_str.length(); tmp_node.str_value_ = time_str.ptr(); + tmp_node.is_date_unit_ = false; if (OB_FAIL(process_datatype_or_questionmark(tmp_node, expr))) { if (ret == OB_ERR_WRONG_VALUE) {//invalid time str, go back default way like Mysql. ret = OB_SUCCESS;