PostgreSQL Source Code  git master
statistics.h File Reference
#include "commands/vacuum.h"
#include "nodes/pathnodes.h"
Include dependency graph for statistics.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  MVNDistinctItem
 
struct  MVNDistinct
 
struct  MVDependency
 
struct  MVDependencies
 
struct  MCVItem
 
struct  MCVList
 

Macros

#define STATS_MAX_DIMENSIONS   8 /* max number of attributes */
 
#define STATS_NDISTINCT_MAGIC   0xA352BFA4 /* struct identifier */
 
#define STATS_NDISTINCT_TYPE_BASIC   1 /* struct version */
 
#define STATS_DEPS_MAGIC   0xB4549A2C /* marks serialized bytea */
 
#define STATS_DEPS_TYPE_BASIC   1 /* basic dependencies type */
 
#define STATS_MCV_MAGIC   0xE1A651C2 /* marks serialized bytea */
 
#define STATS_MCV_TYPE_BASIC   1 /* basic MCV list type */
 
#define STATS_MCVLIST_MAX_ITEMS   10000
 

Typedefs

typedef struct MVNDistinctItem MVNDistinctItem
 
typedef struct MVNDistinct MVNDistinct
 
typedef struct MVDependency MVDependency
 
typedef struct MVDependencies MVDependencies
 
typedef struct MCVItem MCVItem
 
typedef struct MCVList MCVList
 

Functions

MVNDistinctstatext_ndistinct_load (Oid mvoid)
 
MVDependenciesstatext_dependencies_load (Oid mvoid)
 
MCVListstatext_mcv_load (Oid mvoid)
 
void BuildRelationExtStatistics (Relation onerel, double totalrows, int numrows, HeapTuple *rows, int natts, VacAttrStats **vacattrstats)
 
int ComputeExtStatisticsRows (Relation onerel, int natts, VacAttrStats **stats)
 
bool statext_is_kind_built (HeapTuple htup, char kind)
 
Selectivity dependencies_clauselist_selectivity (PlannerInfo *root, List *clauses, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo, RelOptInfo *rel, Bitmapset **estimatedclauses)
 
Selectivity statext_clauselist_selectivity (PlannerInfo *root, List *clauses, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo, RelOptInfo *rel, Bitmapset **estimatedclauses)
 
bool has_stats_of_kind (List *stats, char requiredkind)
 
StatisticExtInfochoose_best_statistics (List *stats, char requiredkind, Bitmapset **clause_attnums, int nclauses)
 

Macro Definition Documentation

◆ STATS_DEPS_MAGIC

#define STATS_DEPS_MAGIC   0xB4549A2C /* marks serialized bytea */

Definition at line 42 of file statistics.h.

Referenced by statext_dependencies_build(), and statext_dependencies_deserialize().

◆ STATS_DEPS_TYPE_BASIC

#define STATS_DEPS_TYPE_BASIC   1 /* basic dependencies type */

Definition at line 43 of file statistics.h.

Referenced by statext_dependencies_build(), and statext_dependencies_deserialize().

◆ STATS_MAX_DIMENSIONS

#define STATS_MAX_DIMENSIONS   8 /* max number of attributes */

◆ STATS_MCV_MAGIC

#define STATS_MCV_MAGIC   0xE1A651C2 /* marks serialized bytea */

Definition at line 65 of file statistics.h.

Referenced by statext_mcv_build(), and statext_mcv_deserialize().

◆ STATS_MCV_TYPE_BASIC

#define STATS_MCV_TYPE_BASIC   1 /* basic MCV list type */

Definition at line 66 of file statistics.h.

Referenced by statext_mcv_build(), and statext_mcv_deserialize().

◆ STATS_MCVLIST_MAX_ITEMS

#define STATS_MCVLIST_MAX_ITEMS   10000

Definition at line 69 of file statistics.h.

Referenced by mcv_get_match_bitmap(), and statext_mcv_deserialize().

◆ STATS_NDISTINCT_MAGIC

#define STATS_NDISTINCT_MAGIC   0xA352BFA4 /* struct identifier */

◆ STATS_NDISTINCT_TYPE_BASIC

#define STATS_NDISTINCT_TYPE_BASIC   1 /* struct version */

Typedef Documentation

◆ MCVItem

typedef struct MCVItem MCVItem

◆ MCVList

typedef struct MCVList MCVList

◆ MVDependencies

◆ MVDependency

typedef struct MVDependency MVDependency

◆ MVNDistinct

typedef struct MVNDistinct MVNDistinct

◆ MVNDistinctItem

Function Documentation

◆ BuildRelationExtStatistics()

void BuildRelationExtStatistics ( Relation  onerel,
double  totalrows,
int  numrows,
HeapTuple rows,
int  natts,
VacAttrStats **  vacattrstats 
)

Definition at line 89 of file extended_stats.c.

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, Assert, bms_num_members(), StatExtEntry::columns, CurrentMemoryContext, ereport, errcode(), errmsg(), errtable(), fetch_statentries_for_relation(), get_namespace_name(), IsAutoVacuumWorkerProcess(), lfirst, lfirst_int, list_length(), lookup_var_attr_stats(), MemoryContextDelete(), MemoryContextSwitchTo(), StatExtEntry::name, NIL, pgstat_progress_update_multi_param(), pgstat_progress_update_param(), PROGRESS_ANALYZE_EXT_STATS_COMPUTED, PROGRESS_ANALYZE_EXT_STATS_TOTAL, PROGRESS_ANALYZE_PHASE, PROGRESS_ANALYZE_PHASE_COMPUTE_EXT_STATS, RelationData::rd_rel, RelationGetRelationName, RelationGetRelid, RowExclusiveLock, StatExtEntry::schema, stat, statext_compute_stattarget(), statext_dependencies_build(), statext_mcv_build(), statext_ndistinct_build(), statext_store(), StatExtEntry::statOid, STATS_MAX_DIMENSIONS, StatExtEntry::stattarget, table_close(), table_open(), StatExtEntry::types, val, and WARNING.

Referenced by do_analyze_rel().

92 {
93  Relation pg_stext;
94  ListCell *lc;
95  List *stats;
96  MemoryContext cxt;
97  MemoryContext oldcxt;
98  int64 ext_cnt;
99 
101  "BuildRelationExtStatistics",
103  oldcxt = MemoryContextSwitchTo(cxt);
104 
105  pg_stext = table_open(StatisticExtRelationId, RowExclusiveLock);
106  stats = fetch_statentries_for_relation(pg_stext, RelationGetRelid(onerel));
107 
108  /* report this phase */
109  if (stats != NIL)
110  {
111  const int index[] = {
114  };
115  const int64 val[] = {
117  list_length(stats)
118  };
119 
120  pgstat_progress_update_multi_param(2, index, val);
121  }
122 
123  ext_cnt = 0;
124  foreach(lc, stats)
125  {
127  MVNDistinct *ndistinct = NULL;
128  MVDependencies *dependencies = NULL;
129  MCVList *mcv = NULL;
130  VacAttrStats **stats;
131  ListCell *lc2;
132  int stattarget;
133 
134  /*
135  * Check if we can build these stats based on the column analyzed. If
136  * not, report this fact (except in autovacuum) and move on.
137  */
138  stats = lookup_var_attr_stats(onerel, stat->columns,
139  natts, vacattrstats);
140  if (!stats)
141  {
144  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
145  errmsg("statistics object \"%s.%s\" could not be computed for relation \"%s.%s\"",
146  stat->schema, stat->name,
147  get_namespace_name(onerel->rd_rel->relnamespace),
148  RelationGetRelationName(onerel)),
149  errtable(onerel)));
150  continue;
151  }
152 
153  /* check allowed number of dimensions */
154  Assert(bms_num_members(stat->columns) >= 2 &&
156 
157  /* compute statistics target for this statistics */
158  stattarget = statext_compute_stattarget(stat->stattarget,
159  bms_num_members(stat->columns),
160  stats);
161 
162  /*
163  * Don't rebuild statistics objects with statistics target set to 0
164  * (we just leave the existing values around, just like we do for
165  * regular per-column statistics).
166  */
167  if (stattarget == 0)
168  continue;
169 
170  /* compute statistic of each requested type */
171  foreach(lc2, stat->types)
172  {
173  char t = (char) lfirst_int(lc2);
174 
175  if (t == STATS_EXT_NDISTINCT)
176  ndistinct = statext_ndistinct_build(totalrows, numrows, rows,
177  stat->columns, stats);
178  else if (t == STATS_EXT_DEPENDENCIES)
179  dependencies = statext_dependencies_build(numrows, rows,
180  stat->columns, stats);
181  else if (t == STATS_EXT_MCV)
182  mcv = statext_mcv_build(numrows, rows, stat->columns, stats,
183  totalrows, stattarget);
184  }
185 
186  /* store the statistics in the catalog */
187  statext_store(stat->statOid, ndistinct, dependencies, mcv, stats);
188 
189  /* for reporting progress */
191  ++ext_cnt);
192  }
193 
194  table_close(pg_stext, RowExclusiveLock);
195 
196  MemoryContextSwitchTo(oldcxt);
197  MemoryContextDelete(cxt);
198 }
#define NIL
Definition: pg_list.h:65
MCVList * statext_mcv_build(int numrows, HeapTuple *rows, Bitmapset *attrs, VacAttrStats **stats, double totalrows, int stattarget)
Definition: mcv.c:183
#define PROGRESS_ANALYZE_EXT_STATS_COMPUTED
Definition: progress.h:42
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:211
#define AllocSetContextCreate
Definition: memutils.h:170
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
#define PROGRESS_ANALYZE_PHASE
Definition: progress.h:38
void pgstat_progress_update_param(int index, int64 val)
Definition: pgstat.c:3231
static int statext_compute_stattarget(int stattarget, int natts, VacAttrStats **stats)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
int errcode(int sqlerrcode)
Definition: elog.c:610
static List * fetch_statentries_for_relation(Relation pg_statext, Oid relid)
Form_pg_class rd_rel
Definition: rel.h:109
Bitmapset * columns
Definition: type.h:89
#define lfirst_int(lc)
Definition: pg_list.h:191
#define PROGRESS_ANALYZE_EXT_STATS_TOTAL
Definition: progress.h:41
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:192
int bms_num_members(const Bitmapset *a)
Definition: bitmapset.c:646
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3191
#define RowExclusiveLock
Definition: lockdefs.h:38
#define RelationGetRelationName(relation)
Definition: rel.h:490
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
bool IsAutoVacuumWorkerProcess(void)
Definition: autovacuum.c:3301
#define WARNING
Definition: elog.h:40
#define stat(a, b)
Definition: win32_port.h:255
MVDependencies * statext_dependencies_build(int numrows, HeapTuple *rows, Bitmapset *attrs, VacAttrStats **stats)
Definition: dependencies.c:363
#define ereport(elevel,...)
Definition: elog.h:144
MVNDistinct * statext_ndistinct_build(double totalrows, int numrows, HeapTuple *rows, Bitmapset *attrs, VacAttrStats **stats)
Definition: mvdistinct.c:86
#define PROGRESS_ANALYZE_PHASE_COMPUTE_EXT_STATS
Definition: progress.h:51
#define Assert(condition)
Definition: c.h:745
#define lfirst(lc)
Definition: pg_list.h:190
void pgstat_progress_update_multi_param(int nparam, const int *index, const int64 *val)
Definition: pgstat.c:3253
static int list_length(const List *l)
Definition: pg_list.h:169
static void statext_store(Oid relid, MVNDistinct *ndistinct, MVDependencies *dependencies, MCVList *mcv, VacAttrStats **stats)
#define STATS_MAX_DIMENSIONS
Definition: statistics.h:19
int errmsg(const char *fmt,...)
Definition: elog.c:824
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
Definition: pg_list.h:50
int errtable(Relation rel)
Definition: relcache.c:5490
static VacAttrStats ** lookup_var_attr_stats(Relation rel, Bitmapset *attrs, int nvacatts, VacAttrStats **vacatts)
#define RelationGetRelid(relation)
Definition: rel.h:456
long val
Definition: informix.c:664

◆ choose_best_statistics()

StatisticExtInfo* choose_best_statistics ( List stats,
char  requiredkind,
Bitmapset **  clause_attnums,
int  nclauses 
)

Definition at line 883 of file extended_stats.c.

References bms_add_members(), bms_free(), bms_is_subset(), bms_num_members(), i, StatisticExtInfo::keys, StatisticExtInfo::kind, lfirst, and STATS_MAX_DIMENSIONS.

Referenced by statext_mcv_clauselist_selectivity().

885 {
886  ListCell *lc;
887  StatisticExtInfo *best_match = NULL;
888  int best_num_matched = 2; /* goal #1: maximize */
889  int best_match_keys = (STATS_MAX_DIMENSIONS + 1); /* goal #2: minimize */
890 
891  foreach(lc, stats)
892  {
893  int i;
894  StatisticExtInfo *info = (StatisticExtInfo *) lfirst(lc);
895  Bitmapset *matched = NULL;
896  int num_matched;
897  int numkeys;
898 
899  /* skip statistics that are not of the correct type */
900  if (info->kind != requiredkind)
901  continue;
902 
903  /*
904  * Collect attributes in remaining (unestimated) clauses fully covered
905  * by this statistic object.
906  */
907  for (i = 0; i < nclauses; i++)
908  {
909  /* ignore incompatible/estimated clauses */
910  if (!clause_attnums[i])
911  continue;
912 
913  /* ignore clauses that are not covered by this object */
914  if (!bms_is_subset(clause_attnums[i], info->keys))
915  continue;
916 
917  matched = bms_add_members(matched, clause_attnums[i]);
918  }
919 
920  num_matched = bms_num_members(matched);
921  bms_free(matched);
922 
923  /*
924  * save the actual number of keys in the stats so that we can choose
925  * the narrowest stats with the most matching keys.
926  */
927  numkeys = bms_num_members(info->keys);
928 
929  /*
930  * Use this object when it increases the number of matched clauses or
931  * when it matches the same number of attributes but these stats have
932  * fewer keys than any previous match.
933  */
934  if (num_matched > best_num_matched ||
935  (num_matched == best_num_matched && numkeys < best_match_keys))
936  {
937  best_match = info;
938  best_num_matched = num_matched;
939  best_match_keys = numkeys;
940  }
941  }
942 
943  return best_match;
944 }
bool bms_is_subset(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:315
int bms_num_members(const Bitmapset *a)
Definition: bitmapset.c:646
void bms_free(Bitmapset *a)
Definition: bitmapset.c:208
#define lfirst(lc)
Definition: pg_list.h:190
Bitmapset * keys
Definition: pathnodes.h:915
#define STATS_MAX_DIMENSIONS
Definition: statistics.h:19
int i
Bitmapset * bms_add_members(Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:793

◆ ComputeExtStatisticsRows()

int ComputeExtStatisticsRows ( Relation  onerel,
int  natts,
VacAttrStats **  stats 
)

Definition at line 214 of file extended_stats.c.

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, bms_num_members(), StatExtEntry::columns, CurrentMemoryContext, fetch_statentries_for_relation(), lfirst, lookup_var_attr_stats(), MemoryContextDelete(), MemoryContextSwitchTo(), RelationGetRelid, RowExclusiveLock, stat, statext_compute_stattarget(), StatExtEntry::stattarget, table_close(), and table_open().

Referenced by do_analyze_rel().

216 {
217  Relation pg_stext;
218  ListCell *lc;
219  List *lstats;
220  MemoryContext cxt;
221  MemoryContext oldcxt;
222  int result = 0;
223 
225  "ComputeExtStatisticsRows",
227  oldcxt = MemoryContextSwitchTo(cxt);
228 
229  pg_stext = table_open(StatisticExtRelationId, RowExclusiveLock);
230  lstats = fetch_statentries_for_relation(pg_stext, RelationGetRelid(onerel));
231 
232  foreach(lc, lstats)
233  {
235  int stattarget = stat->stattarget;
236  VacAttrStats **stats;
237  int nattrs = bms_num_members(stat->columns);
238 
239  /*
240  * Check if we can build this statistics object based on the columns
241  * analyzed. If not, ignore it (don't report anything, we'll do that
242  * during the actual build BuildRelationExtStatistics).
243  */
244  stats = lookup_var_attr_stats(onerel, stat->columns,
245  natts, vacattrstats);
246 
247  if (!stats)
248  continue;
249 
250  /*
251  * Compute statistics target, based on what's set for the statistic
252  * object itself, and for its attributes.
253  */
254  stattarget = statext_compute_stattarget(stat->stattarget,
255  nattrs, stats);
256 
257  /* Use the largest value for all statistics objects. */
258  if (stattarget > result)
259  result = stattarget;
260  }
261 
262  table_close(pg_stext, RowExclusiveLock);
263 
264  MemoryContextSwitchTo(oldcxt);
265  MemoryContextDelete(cxt);
266 
267  /* compute sample size based on the statistics target */
268  return (300 * result);
269 }
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:211
#define AllocSetContextCreate
Definition: memutils.h:170
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
static int statext_compute_stattarget(int stattarget, int natts, VacAttrStats **stats)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
static List * fetch_statentries_for_relation(Relation pg_statext, Oid relid)
Bitmapset * columns
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:192
int bms_num_members(const Bitmapset *a)
Definition: bitmapset.c:646
#define RowExclusiveLock
Definition: lockdefs.h:38
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
#define stat(a, b)
Definition: win32_port.h:255
#define lfirst(lc)
Definition: pg_list.h:190
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
Definition: pg_list.h:50
static VacAttrStats ** lookup_var_attr_stats(Relation rel, Bitmapset *attrs, int nvacatts, VacAttrStats **vacatts)
#define RelationGetRelid(relation)
Definition: rel.h:456

◆ dependencies_clauselist_selectivity()

Selectivity dependencies_clauselist_selectivity ( PlannerInfo root,
List clauses,
int  varRelid,
JoinType  jointype,
SpecialJoinInfo sjinfo,
RelOptInfo rel,
Bitmapset **  estimatedclauses 
)

Definition at line 1188 of file dependencies.c.

References attnum, MVDependency::attributes, bms_add_member(), bms_del_member(), bms_free(), bms_intersect(), bms_is_member(), bms_num_members(), clauselist_apply_dependencies(), DependencyGeneratorData::dependencies, dependency_is_compatible_clause(), find_strongest_dependency(), has_stats_of_kind(), i, InvalidAttrNumber, StatisticExtInfo::keys, StatisticExtInfo::kind, lfirst, list_length(), MVDependency::nattributes, DependencyGeneratorData::ndependencies, MVDependencies::ndeps, palloc(), pfree(), RelOptInfo::relid, s1, stat, statext_dependencies_load(), RelOptInfo::statlist, and StatisticExtInfo::statOid.

Referenced by statext_clauselist_selectivity().

1195 {
1196  Selectivity s1 = 1.0;
1197  ListCell *l;
1198  Bitmapset *clauses_attnums = NULL;
1199  AttrNumber *list_attnums;
1200  int listidx;
1201  MVDependencies **func_dependencies;
1202  int nfunc_dependencies;
1203  int total_ndeps;
1204  MVDependency **dependencies;
1205  int ndependencies;
1206  int i;
1207 
1208  /* check if there's any stats that might be useful for us. */
1209  if (!has_stats_of_kind(rel->statlist, STATS_EXT_DEPENDENCIES))
1210  return 1.0;
1211 
1212  list_attnums = (AttrNumber *) palloc(sizeof(AttrNumber) *
1213  list_length(clauses));
1214 
1215  /*
1216  * Pre-process the clauses list to extract the attnums seen in each item.
1217  * We need to determine if there's any clauses which will be useful for
1218  * dependency selectivity estimations. Along the way we'll record all of
1219  * the attnums for each clause in a list which we'll reference later so we
1220  * don't need to repeat the same work again. We'll also keep track of all
1221  * attnums seen.
1222  *
1223  * We also skip clauses that we already estimated using different types of
1224  * statistics (we treat them as incompatible).
1225  */
1226  listidx = 0;
1227  foreach(l, clauses)
1228  {
1229  Node *clause = (Node *) lfirst(l);
1231 
1232  if (!bms_is_member(listidx, *estimatedclauses) &&
1233  dependency_is_compatible_clause(clause, rel->relid, &attnum))
1234  {
1235  list_attnums[listidx] = attnum;
1236  clauses_attnums = bms_add_member(clauses_attnums, attnum);
1237  }
1238  else
1239  list_attnums[listidx] = InvalidAttrNumber;
1240 
1241  listidx++;
1242  }
1243 
1244  /*
1245  * If there's not at least two distinct attnums then reject the whole list
1246  * of clauses. We must return 1.0 so the calling function's selectivity is
1247  * unaffected.
1248  */
1249  if (bms_num_members(clauses_attnums) < 2)
1250  {
1251  bms_free(clauses_attnums);
1252  pfree(list_attnums);
1253  return 1.0;
1254  }
1255 
1256  /*
1257  * Load all functional dependencies matching at least two parameters. We
1258  * can simply consider all dependencies at once, without having to search
1259  * for the best statistics object.
1260  *
1261  * To not waste cycles and memory, we deserialize dependencies only for
1262  * statistics that match at least two attributes. The array is allocated
1263  * with the assumption that all objects match - we could grow the array to
1264  * make it just the right size, but it's likely wasteful anyway thanks to
1265  * moving the freed chunks to freelists etc.
1266  */
1267  func_dependencies = (MVDependencies **) palloc(sizeof(MVDependencies *) *
1268  list_length(rel->statlist));
1269  nfunc_dependencies = 0;
1270  total_ndeps = 0;
1271 
1272  foreach(l, rel->statlist)
1273  {
1275  Bitmapset *matched;
1276  int num_matched;
1277 
1278  /* skip statistics that are not of the correct type */
1279  if (stat->kind != STATS_EXT_DEPENDENCIES)
1280  continue;
1281 
1282  matched = bms_intersect(clauses_attnums, stat->keys);
1283  num_matched = bms_num_members(matched);
1284  bms_free(matched);
1285 
1286  /* skip objects matching fewer than two attributes from clauses */
1287  if (num_matched < 2)
1288  continue;
1289 
1290  func_dependencies[nfunc_dependencies]
1292 
1293  total_ndeps += func_dependencies[nfunc_dependencies]->ndeps;
1294  nfunc_dependencies++;
1295  }
1296 
1297  /* if no matching stats could be found then we've nothing to do */
1298  if (nfunc_dependencies == 0)
1299  {
1300  pfree(func_dependencies);
1301  bms_free(clauses_attnums);
1302  pfree(list_attnums);
1303  return 1.0;
1304  }
1305 
1306  /*
1307  * Work out which dependencies we can apply, starting with the
1308  * widest/stongest ones, and proceeding to smaller/weaker ones.
1309  */
1310  dependencies = (MVDependency **) palloc(sizeof(MVDependency *) *
1311  total_ndeps);
1312  ndependencies = 0;
1313 
1314  while (true)
1315  {
1316  MVDependency *dependency;
1318 
1319  /* the widest/strongest dependency, fully matched by clauses */
1320  dependency = find_strongest_dependency(func_dependencies,
1321  nfunc_dependencies,
1322  clauses_attnums);
1323  if (!dependency)
1324  break;
1325 
1326  dependencies[ndependencies++] = dependency;
1327 
1328  /* Ignore dependencies using this implied attribute in later loops */
1329  attnum = dependency->attributes[dependency->nattributes - 1];
1330  clauses_attnums = bms_del_member(clauses_attnums, attnum);
1331  }
1332 
1333  /*
1334  * If we found applicable dependencies, use them to estimate all
1335  * compatible clauses on attributes that they refer to.
1336  */
1337  if (ndependencies != 0)
1338  s1 = clauselist_apply_dependencies(root, clauses, varRelid, jointype,
1339  sjinfo, dependencies, ndependencies,
1340  list_attnums, estimatedclauses);
1341 
1342  /* free deserialized functional dependencies (and then the array) */
1343  for (i = 0; i < nfunc_dependencies; i++)
1344  pfree(func_dependencies[i]);
1345 
1346  pfree(dependencies);
1347  pfree(func_dependencies);
1348  bms_free(clauses_attnums);
1349  pfree(list_attnums);
1350 
1351  return s1;
1352 }
AttrNumber attributes[FLEXIBLE_ARRAY_MEMBER]
Definition: statistics.h:53
List * statlist
Definition: pathnodes.h:703
MVDependencies * statext_dependencies_load(Oid mvoid)
Definition: dependencies.c:627
Definition: nodes.h:529
double Selectivity
Definition: nodes.h:662
AttrNumber nattributes
Definition: statistics.h:52
static Selectivity clauselist_apply_dependencies(PlannerInfo *root, List *clauses, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo, MVDependency **dependencies, int ndependencies, AttrNumber *list_attnums, Bitmapset **estimatedclauses)
void pfree(void *pointer)
Definition: mcxt.c:1056
char * s1
int bms_num_members(const Bitmapset *a)
Definition: bitmapset.c:646
Index relid
Definition: pathnodes.h:693
#define stat(a, b)
Definition: win32_port.h:255
static MVDependency * find_strongest_dependency(MVDependencies **dependencies, int ndependencies, Bitmapset *attnums)
Definition: dependencies.c:930
Bitmapset * bms_intersect(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:259
int16 attnum
Definition: pg_attribute.h:79
void bms_free(Bitmapset *a)
Definition: bitmapset.c:208
uint32 ndeps
Definition: statistics.h:60
#define lfirst(lc)
Definition: pg_list.h:190
static int list_length(const List *l)
Definition: pg_list.h:169
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:736
#define InvalidAttrNumber
Definition: attnum.h:23
Bitmapset * keys
Definition: pathnodes.h:915
void * palloc(Size size)
Definition: mcxt.c:949
int i
int l
Definition: api.h:16
Bitmapset * bms_del_member(Bitmapset *a, int x)
Definition: bitmapset.c:773
bool bms_is_member(int x, const Bitmapset *a)
Definition: bitmapset.c:427
bool has_stats_of_kind(List *stats, char requiredkind)
int16 AttrNumber
Definition: attnum.h:21
static bool dependency_is_compatible_clause(Node *clause, Index relid, AttrNumber *attnum)
Definition: dependencies.c:747

◆ has_stats_of_kind()

bool has_stats_of_kind ( List stats,
char  requiredkind 
)

Definition at line 849 of file extended_stats.c.

References StatisticExtInfo::kind, lfirst, and stat.

Referenced by dependencies_clauselist_selectivity(), and statext_mcv_clauselist_selectivity().

850 {
851  ListCell *l;
852 
853  foreach(l, stats)
854  {
856 
857  if (stat->kind == requiredkind)
858  return true;
859  }
860 
861  return false;
862 }
#define stat(a, b)
Definition: win32_port.h:255
#define lfirst(lc)
Definition: pg_list.h:190
int l
Definition: api.h:16

◆ statext_clauselist_selectivity()

Selectivity statext_clauselist_selectivity ( PlannerInfo root,
List clauses,
int  varRelid,
JoinType  jointype,
SpecialJoinInfo sjinfo,
RelOptInfo rel,
Bitmapset **  estimatedclauses 
)

Definition at line 1418 of file extended_stats.c.

References dependencies_clauselist_selectivity(), and statext_mcv_clauselist_selectivity().

Referenced by clauselist_selectivity().

1421 {
1422  Selectivity sel;
1423 
1424  /* First, try estimating clauses using a multivariate MCV list. */
1425  sel = statext_mcv_clauselist_selectivity(root, clauses, varRelid, jointype,
1426  sjinfo, rel, estimatedclauses);
1427 
1428  /*
1429  * Then, apply functional dependencies on the remaining clauses by calling
1430  * dependencies_clauselist_selectivity. Pass 'estimatedclauses' so the
1431  * function can properly skip clauses already estimated above.
1432  *
1433  * The reasoning for applying dependencies last is that the more complex
1434  * stats can track more complex correlations between the attributes, and
1435  * so may be considered more reliable.
1436  *
1437  * For example, MCV list can give us an exact selectivity for values in
1438  * two columns, while functional dependencies can only provide information
1439  * about the overall strength of the dependency.
1440  */
1441  sel *= dependencies_clauselist_selectivity(root, clauses, varRelid,
1442  jointype, sjinfo, rel,
1443  estimatedclauses);
1444 
1445  return sel;
1446 }
Selectivity dependencies_clauselist_selectivity(PlannerInfo *root, List *clauses, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo, RelOptInfo *rel, Bitmapset **estimatedclauses)
double Selectivity
Definition: nodes.h:662
static Selectivity statext_mcv_clauselist_selectivity(PlannerInfo *root, List *clauses, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo, RelOptInfo *rel, Bitmapset **estimatedclauses)

◆ statext_dependencies_load()

MVDependencies* statext_dependencies_load ( Oid  mvoid)

Definition at line 627 of file dependencies.c.

References DatumGetByteaPP, elog, ERROR, HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1(), statext_dependencies_deserialize(), STATEXTDATASTXOID, and SysCacheGetAttr().

Referenced by dependencies_clauselist_selectivity().

628 {
629  MVDependencies *result;
630  bool isnull;
631  Datum deps;
632  HeapTuple htup;
633 
635  if (!HeapTupleIsValid(htup))
636  elog(ERROR, "cache lookup failed for statistics object %u", mvoid);
637 
638  deps = SysCacheGetAttr(STATEXTDATASTXOID, htup,
639  Anum_pg_statistic_ext_data_stxddependencies, &isnull);
640  if (isnull)
641  elog(ERROR,
642  "requested statistic kind \"%c\" is not yet built for statistics object %u",
643  STATS_EXT_DEPENDENCIES, mvoid);
644 
646 
647  ReleaseSysCache(htup);
648 
649  return result;
650 }
#define DatumGetByteaPP(X)
Definition: fmgr.h:290
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
uintptr_t Datum
Definition: postgres.h:367
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1377
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define elog(elevel,...)
Definition: elog.h:214
MVDependencies * statext_dependencies_deserialize(bytea *data)
Definition: dependencies.c:507

◆ statext_is_kind_built()

bool statext_is_kind_built ( HeapTuple  htup,
char  kind 
)

Definition at line 334 of file extended_stats.c.

References attnum, elog, ERROR, and heap_attisnull().

Referenced by get_relation_statistics(), and UpdateStatisticsForTypeChange().

335 {
337 
338  switch (type)
339  {
340  case STATS_EXT_NDISTINCT:
341  attnum = Anum_pg_statistic_ext_data_stxdndistinct;
342  break;
343 
344  case STATS_EXT_DEPENDENCIES:
345  attnum = Anum_pg_statistic_ext_data_stxddependencies;
346  break;
347 
348  case STATS_EXT_MCV:
349  attnum = Anum_pg_statistic_ext_data_stxdmcv;
350  break;
351 
352  default:
353  elog(ERROR, "unexpected statistics type requested: %d", type);
354  }
355 
356  return !heap_attisnull(htup, attnum, NULL);
357 }
bool heap_attisnull(HeapTuple tup, int attnum, TupleDesc tupleDesc)
Definition: heaptuple.c:359
#define ERROR
Definition: elog.h:43
int16 attnum
Definition: pg_attribute.h:79
#define elog(elevel,...)
Definition: elog.h:214
int16 AttrNumber
Definition: attnum.h:21

◆ statext_mcv_load()

MCVList* statext_mcv_load ( Oid  mvoid)

Definition at line 557 of file mcv.c.

References DatumGetByteaP, elog, ERROR, HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1(), statext_mcv_deserialize(), STATEXTDATASTXOID, and SysCacheGetAttr().

Referenced by mcv_clauselist_selectivity().

558 {
559  MCVList *result;
560  bool isnull;
561  Datum mcvlist;
563 
564  if (!HeapTupleIsValid(htup))
565  elog(ERROR, "cache lookup failed for statistics object %u", mvoid);
566 
567  mcvlist = SysCacheGetAttr(STATEXTDATASTXOID, htup,
568  Anum_pg_statistic_ext_data_stxdmcv, &isnull);
569 
570  if (isnull)
571  elog(ERROR,
572  "requested statistic kind \"%c\" is not yet built for statistics object %u",
573  STATS_EXT_DEPENDENCIES, mvoid);
574 
575  result = statext_mcv_deserialize(DatumGetByteaP(mcvlist));
576 
577  ReleaseSysCache(htup);
578 
579  return result;
580 }
MCVList * statext_mcv_deserialize(bytea *data)
Definition: mcv.c:993
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define DatumGetByteaP(X)
Definition: fmgr.h:330
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
uintptr_t Datum
Definition: postgres.h:367
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1377
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define elog(elevel,...)
Definition: elog.h:214

◆ statext_ndistinct_load()

MVNDistinct* statext_ndistinct_load ( Oid  mvoid)

Definition at line 141 of file mvdistinct.c.

References DatumGetByteaPP, elog, ERROR, HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1(), statext_ndistinct_deserialize(), STATEXTDATASTXOID, and SysCacheGetAttr().

Referenced by estimate_multivariate_ndistinct().

142 {
143  MVNDistinct *result;
144  bool isnull;
145  Datum ndist;
146  HeapTuple htup;
147 
149  if (!HeapTupleIsValid(htup))
150  elog(ERROR, "cache lookup failed for statistics object %u", mvoid);
151 
152  ndist = SysCacheGetAttr(STATEXTDATASTXOID, htup,
153  Anum_pg_statistic_ext_data_stxdndistinct, &isnull);
154  if (isnull)
155  elog(ERROR,
156  "requested statistic kind \"%c\" is not yet built for statistics object %u",
157  STATS_EXT_NDISTINCT, mvoid);
158 
160 
161  ReleaseSysCache(htup);
162 
163  return result;
164 }
MVNDistinct * statext_ndistinct_deserialize(bytea *data)
Definition: mvdistinct.c:249
#define DatumGetByteaPP(X)
Definition: fmgr.h:290
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
uintptr_t Datum
Definition: postgres.h:367
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1377
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define elog(elevel,...)
Definition: elog.h:214