diff options
Diffstat (limited to 'src/backend/statistics/extended_stats.c')
-rw-r--r-- | src/backend/statistics/extended_stats.c | 75 |
1 files changed, 33 insertions, 42 deletions
diff --git a/src/backend/statistics/extended_stats.c b/src/backend/statistics/extended_stats.c index 5762621673b..87fe82ed114 100644 --- a/src/backend/statistics/extended_stats.c +++ b/src/backend/statistics/extended_stats.c @@ -25,6 +25,7 @@ #include "catalog/pg_statistic_ext.h" #include "catalog/pg_statistic_ext_data.h" #include "executor/executor.h" +#include "commands/defrem.h" #include "commands/progress.h" #include "miscadmin.h" #include "nodes/nodeFuncs.h" @@ -78,7 +79,7 @@ typedef struct StatExtEntry static List *fetch_statentries_for_relation(Relation pg_statext, Oid relid); static VacAttrStats **lookup_var_attr_stats(Relation rel, Bitmapset *attrs, List *exprs, int nvacatts, VacAttrStats **vacatts); -static void statext_store(Oid statOid, +static void statext_store(Oid statOid, bool inh, MVNDistinct *ndistinct, MVDependencies *dependencies, MCVList *mcv, Datum exprs, VacAttrStats **stats); static int statext_compute_stattarget(int stattarget, @@ -111,7 +112,7 @@ static StatsBuildData *make_build_data(Relation onerel, StatExtEntry *stat, * requested stats, and serializes them back into the catalog. */ void -BuildRelationExtStatistics(Relation onerel, double totalrows, +BuildRelationExtStatistics(Relation onerel, bool inh, double totalrows, int numrows, HeapTuple *rows, int natts, VacAttrStats **vacattrstats) { @@ -231,7 +232,8 @@ BuildRelationExtStatistics(Relation onerel, double totalrows, } /* store the statistics in the catalog */ - statext_store(stat->statOid, ndistinct, dependencies, mcv, exprstats, stats); + statext_store(stat->statOid, inh, + ndistinct, dependencies, mcv, exprstats, stats); /* for reporting progress */ pgstat_progress_update_param(PROGRESS_ANALYZE_EXT_STATS_COMPUTED, @@ -782,23 +784,27 @@ lookup_var_attr_stats(Relation rel, Bitmapset *attrs, List *exprs, * tuple. */ static void -statext_store(Oid statOid, +statext_store(Oid statOid, bool inh, MVNDistinct *ndistinct, MVDependencies *dependencies, MCVList *mcv, Datum exprs, VacAttrStats **stats) { Relation pg_stextdata; - HeapTuple stup, - oldtup; + HeapTuple stup; Datum values[Natts_pg_statistic_ext_data]; bool nulls[Natts_pg_statistic_ext_data]; - bool replaces[Natts_pg_statistic_ext_data]; pg_stextdata = table_open(StatisticExtDataRelationId, RowExclusiveLock); memset(nulls, true, sizeof(nulls)); - memset(replaces, false, sizeof(replaces)); memset(values, 0, sizeof(values)); + /* basic info */ + values[Anum_pg_statistic_ext_data_stxoid - 1] = ObjectIdGetDatum(statOid); + nulls[Anum_pg_statistic_ext_data_stxoid - 1] = false; + + values[Anum_pg_statistic_ext_data_stxdinherit - 1] = BoolGetDatum(inh); + nulls[Anum_pg_statistic_ext_data_stxdinherit - 1] = false; + /* * Construct a new pg_statistic_ext_data tuple, replacing the calculated * stats. @@ -831,25 +837,15 @@ statext_store(Oid statOid, values[Anum_pg_statistic_ext_data_stxdexpr - 1] = exprs; } - /* always replace the value (either by bytea or NULL) */ - replaces[Anum_pg_statistic_ext_data_stxdndistinct - 1] = true; - replaces[Anum_pg_statistic_ext_data_stxddependencies - 1] = true; - replaces[Anum_pg_statistic_ext_data_stxdmcv - 1] = true; - replaces[Anum_pg_statistic_ext_data_stxdexpr - 1] = true; - - /* there should already be a pg_statistic_ext_data tuple */ - oldtup = SearchSysCache1(STATEXTDATASTXOID, ObjectIdGetDatum(statOid)); - if (!HeapTupleIsValid(oldtup)) - elog(ERROR, "cache lookup failed for statistics object %u", statOid); - - /* replace it */ - stup = heap_modify_tuple(oldtup, - RelationGetDescr(pg_stextdata), - values, - nulls, - replaces); - ReleaseSysCache(oldtup); - CatalogTupleUpdate(pg_stextdata, &stup->t_self, stup); + /* + * Delete the old tuple if it exists, and insert a new one. It's easier + * than trying to update or insert, based on various conditions. + */ + RemoveStatisticsDataById(statOid, inh); + + /* form and insert a new tuple */ + stup = heap_form_tuple(RelationGetDescr(pg_stextdata), values, nulls); + CatalogTupleInsert(pg_stextdata, stup); heap_freetuple(stup); @@ -1235,7 +1231,7 @@ stat_covers_expressions(StatisticExtInfo *stat, List *exprs, * further tiebreakers are needed. */ StatisticExtInfo * -choose_best_statistics(List *stats, char requiredkind, +choose_best_statistics(List *stats, char requiredkind, bool inh, Bitmapset **clause_attnums, List **clause_exprs, int nclauses) { @@ -1257,6 +1253,10 @@ choose_best_statistics(List *stats, char requiredkind, if (info->kind != requiredkind) continue; + /* skip statistics with mismatching inheritance flag */ + if (info->inherit != inh) + continue; + /* * Collect attributes and expressions in remaining (unestimated) * clauses fully covered by this statistic object. @@ -1697,16 +1697,6 @@ statext_mcv_clauselist_selectivity(PlannerInfo *root, List *clauses, int varReli Selectivity sel = (is_or) ? 0.0 : 1.0; RangeTblEntry *rte = planner_rt_fetch(rel->relid, root); - /* - * When dealing with regular inheritance trees, ignore extended stats - * (which were built without data from child rels, and thus do not - * represent them). For partitioned tables data there's no data in the - * non-leaf relations, so we build stats only for the inheritance tree. - * So for partitioned tables we do consider extended stats. - */ - if (rte->inh && rte->relkind != RELKIND_PARTITIONED_TABLE) - return sel; - /* check if there's any stats that might be useful for us. */ if (!has_stats_of_kind(rel->statlist, STATS_EXT_MCV)) return sel; @@ -1758,7 +1748,7 @@ statext_mcv_clauselist_selectivity(PlannerInfo *root, List *clauses, int varReli Bitmapset *simple_clauses; /* find the best suited statistics object for these attnums */ - stat = choose_best_statistics(rel->statlist, STATS_EXT_MCV, + stat = choose_best_statistics(rel->statlist, STATS_EXT_MCV, rte->inh, list_attnums, list_exprs, list_length(clauses)); @@ -1847,7 +1837,7 @@ statext_mcv_clauselist_selectivity(PlannerInfo *root, List *clauses, int varReli MCVList *mcv_list; /* Load the MCV list stored in the statistics object */ - mcv_list = statext_mcv_load(stat->statOid); + mcv_list = statext_mcv_load(stat->statOid, rte->inh); /* * Compute the selectivity of the ORed list of clauses covered by @@ -2408,7 +2398,7 @@ serialize_expr_stats(AnlExprData *exprdata, int nexprs) * identified by the supplied index. */ HeapTuple -statext_expressions_load(Oid stxoid, int idx) +statext_expressions_load(Oid stxoid, bool inh, int idx) { bool isnull; Datum value; @@ -2418,7 +2408,8 @@ statext_expressions_load(Oid stxoid, int idx) HeapTupleData tmptup; HeapTuple tup; - htup = SearchSysCache1(STATEXTDATASTXOID, ObjectIdGetDatum(stxoid)); + htup = SearchSysCache2(STATEXTDATASTXOID, + ObjectIdGetDatum(stxoid), BoolGetDatum(inh)); if (!HeapTupleIsValid(htup)) elog(ERROR, "cache lookup failed for statistics object %u", stxoid); |