1 /*-------------------------------------------------------------------------
2 *
3 * plancat.c
4 * routines for accessing the system catalogs
5 *
6 *
7 * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
9 *
10 *
11 * IDENTIFICATION
12 * src/backend/optimizer/util/plancat.c
13 *
14 *-------------------------------------------------------------------------
15 */
16 #include "postgres.h"
17
18 #include <math.h>
19
20 #include "access/genam.h"
21 #include "access/htup_details.h"
22 #include "access/nbtree.h"
23 #include "access/sysattr.h"
24 #include "access/table.h"
25 #include "access/tableam.h"
26 #include "access/transam.h"
27 #include "access/xlog.h"
28 #include "catalog/catalog.h"
29 #include "catalog/dependency.h"
30 #include "catalog/heap.h"
31 #include "catalog/pg_am.h"
32 #include "catalog/pg_proc.h"
33 #include "catalog/pg_statistic_ext.h"
34 #include "foreign/fdwapi.h"
35 #include "miscadmin.h"
36 #include "nodes/makefuncs.h"
37 #include "nodes/supportnodes.h"
38 #include "optimizer/clauses.h"
39 #include "optimizer/cost.h"
40 #include "optimizer/optimizer.h"
41 #include "optimizer/plancat.h"
42 #include "optimizer/prep.h"
43 #include "parser/parse_relation.h"
44 #include "parser/parsetree.h"
45 #include "partitioning/partdesc.h"
46 #include "rewrite/rewriteManip.h"
47 #include "statistics/statistics.h"
48 #include "storage/bufmgr.h"
49 #include "utils/builtins.h"
50 #include "utils/lsyscache.h"
51 #include "utils/partcache.h"
52 #include "utils/rel.h"
53 #include "utils/snapmgr.h"
54 #include "utils/syscache.h"
55
56 /* GUC parameter */
57 int constraint_exclusion = CONSTRAINT_EXCLUSION_PARTITION;
58
59 /* Hook for plugins to get control in get_relation_info() */
60 get_relation_info_hook_type get_relation_info_hook = NULL;
61
62
63 static void get_relation_foreign_keys(PlannerInfo *root, RelOptInfo *rel,
64 Relation relation, bool inhparent);
65 static bool infer_collation_opclass_match(InferenceElem *elem, Relation idxRel,
66 List *idxExprs);
67 static List *get_relation_constraints(PlannerInfo *root,
68 Oid relationObjectId, RelOptInfo *rel,
69 bool include_noinherit,
70 bool include_notnull,
71 bool include_partition);
72 static List *build_index_tlist(PlannerInfo *root, IndexOptInfo *index,
73 Relation heapRelation);
74 static List *get_relation_statistics(RelOptInfo *rel, Relation relation);
75 static void set_relation_partition_info(PlannerInfo *root, RelOptInfo *rel,
76 Relation relation);
77 static PartitionScheme find_partition_scheme(PlannerInfo *root, Relation rel);
78 static void set_baserel_partition_key_exprs(Relation relation,
79 RelOptInfo *rel);
80 static void set_baserel_partition_constraint(Relation relation,
81 RelOptInfo *rel);
82
83
84 /*
85 * get_relation_info -
86 * Retrieves catalog information for a given relation.
87 *
88 * Given the Oid of the relation, return the following info into fields
89 * of the RelOptInfo struct:
90 *
91 * min_attr lowest valid AttrNumber
92 * max_attr highest valid AttrNumber
93 * indexlist list of IndexOptInfos for relation's indexes
94 * statlist list of StatisticExtInfo for relation's statistic objects
95 * serverid if it's a foreign table, the server OID
96 * fdwroutine if it's a foreign table, the FDW function pointers
97 * pages number of pages
98 * tuples number of tuples
99 * rel_parallel_workers user-defined number of parallel workers
100 *
101 * Also, add information about the relation's foreign keys to root->fkey_list.
102 *
103 * Also, initialize the attr_needed[] and attr_widths[] arrays. In most
104 * cases these are left as zeroes, but sometimes we need to compute attr
105 * widths here, and we may as well cache the results for costsize.c.
106 *
107 * If inhparent is true, all we need to do is set up the attr arrays:
108 * the RelOptInfo actually represents the appendrel formed by an inheritance
109 * tree, and so the parent rel's physical size and index information isn't
110 * important for it.
111 */
112 void
get_relation_info(PlannerInfo * root,Oid relationObjectId,bool inhparent,RelOptInfo * rel)113 get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
114 RelOptInfo *rel)
115 {
116 Index varno = rel->relid;
117 Relation relation;
118 bool hasindex;
119 List *indexinfos = NIL;
120
121 /*
122 * We need not lock the relation since it was already locked, either by
123 * the rewriter or when expand_inherited_rtentry() added it to the query's
124 * rangetable.
125 */
126 relation = table_open(relationObjectId, NoLock);
127
128 /* Temporary and unlogged relations are inaccessible during recovery. */
129 if (relation->rd_rel->relpersistence != RELPERSISTENCE_PERMANENT &&
130 RecoveryInProgress())
131 ereport(ERROR,
132 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
133 errmsg("cannot access temporary or unlogged relations during recovery")));
134
135 rel->min_attr = FirstLowInvalidHeapAttributeNumber + 1;
136 rel->max_attr = RelationGetNumberOfAttributes(relation);
137 rel->reltablespace = RelationGetForm(relation)->reltablespace;
138
139 Assert(rel->max_attr >= rel->min_attr);
140 rel->attr_needed = (Relids *)
141 palloc0((rel->max_attr - rel->min_attr + 1) * sizeof(Relids));
142 rel->attr_widths = (int32 *)
143 palloc0((rel->max_attr - rel->min_attr + 1) * sizeof(int32));
144
145 /*
146 * Estimate relation size --- unless it's an inheritance parent, in which
147 * case the size we want is not the rel's own size but the size of its
148 * inheritance tree. That will be computed in set_append_rel_size().
149 */
150 if (!inhparent)
151 estimate_rel_size(relation, rel->attr_widths - rel->min_attr,
152 &rel->pages, &rel->tuples, &rel->allvisfrac);
153
154 /* Retrieve the parallel_workers reloption, or -1 if not set. */
155 rel->rel_parallel_workers = RelationGetParallelWorkers(relation, -1);
156
157 /*
158 * Make list of indexes. Ignore indexes on system catalogs if told to.
159 * Don't bother with indexes for an inheritance parent, either.
160 */
161 if (inhparent ||
162 (IgnoreSystemIndexes && IsSystemRelation(relation)))
163 hasindex = false;
164 else
165 hasindex = relation->rd_rel->relhasindex;
166
167 if (hasindex)
168 {
169 List *indexoidlist;
170 LOCKMODE lmode;
171 ListCell *l;
172
173 indexoidlist = RelationGetIndexList(relation);
174
175 /*
176 * For each index, we get the same type of lock that the executor will
177 * need, and do not release it. This saves a couple of trips to the
178 * shared lock manager while not creating any real loss of
179 * concurrency, because no schema changes could be happening on the
180 * index while we hold lock on the parent rel, and no lock type used
181 * for queries blocks any other kind of index operation.
182 */
183 lmode = root->simple_rte_array[varno]->rellockmode;
184
185 foreach(l, indexoidlist)
186 {
187 Oid indexoid = lfirst_oid(l);
188 Relation indexRelation;
189 Form_pg_index index;
190 IndexAmRoutine *amroutine;
191 IndexOptInfo *info;
192 int ncolumns,
193 nkeycolumns;
194 int i;
195
196 /*
197 * Extract info from the relation descriptor for the index.
198 */
199 indexRelation = index_open(indexoid, lmode);
200 index = indexRelation->rd_index;
201
202 /*
203 * Ignore invalid indexes, since they can't safely be used for
204 * queries. Note that this is OK because the data structure we
205 * are constructing is only used by the planner --- the executor
206 * still needs to insert into "invalid" indexes, if they're marked
207 * indisready.
208 */
209 if (!index->indisvalid)
210 {
211 index_close(indexRelation, NoLock);
212 continue;
213 }
214
215 /*
216 * Ignore partitioned indexes, since they are not usable for
217 * queries.
218 */
219 if (indexRelation->rd_rel->relkind == RELKIND_PARTITIONED_INDEX)
220 {
221 index_close(indexRelation, NoLock);
222 continue;
223 }
224
225 /*
226 * If the index is valid, but cannot yet be used, ignore it; but
227 * mark the plan we are generating as transient. See
228 * src/backend/access/heap/README.HOT for discussion.
229 */
230 if (index->indcheckxmin &&
231 !TransactionIdPrecedes(HeapTupleHeaderGetXmin(indexRelation->rd_indextuple->t_data),
232 TransactionXmin))
233 {
234 root->glob->transientPlan = true;
235 index_close(indexRelation, NoLock);
236 continue;
237 }
238
239 info = makeNode(IndexOptInfo);
240
241 info->indexoid = index->indexrelid;
242 info->reltablespace =
243 RelationGetForm(indexRelation)->reltablespace;
244 info->rel = rel;
245 info->ncolumns = ncolumns = index->indnatts;
246 info->nkeycolumns = nkeycolumns = index->indnkeyatts;
247
248 info->indexkeys = (int *) palloc(sizeof(int) * ncolumns);
249 info->indexcollations = (Oid *) palloc(sizeof(Oid) * nkeycolumns);
250 info->opfamily = (Oid *) palloc(sizeof(Oid) * nkeycolumns);
251 info->opcintype = (Oid *) palloc(sizeof(Oid) * nkeycolumns);
252 info->canreturn = (bool *) palloc(sizeof(bool) * ncolumns);
253
254 for (i = 0; i < ncolumns; i++)
255 {
256 info->indexkeys[i] = index->indkey.values[i];
257 info->canreturn[i] = index_can_return(indexRelation, i + 1);
258 }
259
260 for (i = 0; i < nkeycolumns; i++)
261 {
262 info->opfamily[i] = indexRelation->rd_opfamily[i];
263 info->opcintype[i] = indexRelation->rd_opcintype[i];
264 info->indexcollations[i] = indexRelation->rd_indcollation[i];
265 }
266
267 info->relam = indexRelation->rd_rel->relam;
268
269 /* We copy just the fields we need, not all of rd_indam */
270 amroutine = indexRelation->rd_indam;
271 info->amcanorderbyop = amroutine->amcanorderbyop;
272 info->amoptionalkey = amroutine->amoptionalkey;
273 info->amsearcharray = amroutine->amsearcharray;
274 info->amsearchnulls = amroutine->amsearchnulls;
275 info->amcanparallel = amroutine->amcanparallel;
276 info->amhasgettuple = (amroutine->amgettuple != NULL);
277 info->amhasgetbitmap = amroutine->amgetbitmap != NULL &&
278 relation->rd_tableam->scan_bitmap_next_block != NULL;
279 info->amcanmarkpos = (amroutine->ammarkpos != NULL &&
280 amroutine->amrestrpos != NULL);
281 info->amcostestimate = amroutine->amcostestimate;
282 Assert(info->amcostestimate != NULL);
283
284 /* Fetch index opclass options */
285 info->opclassoptions = RelationGetIndexAttOptions(indexRelation, true);
286
287 /*
288 * Fetch the ordering information for the index, if any.
289 */
290 if (info->relam == BTREE_AM_OID)
291 {
292 /*
293 * If it's a btree index, we can use its opfamily OIDs
294 * directly as the sort ordering opfamily OIDs.
295 */
296 Assert(amroutine->amcanorder);
297
298 info->sortopfamily = info->opfamily;
299 info->reverse_sort = (bool *) palloc(sizeof(bool) * nkeycolumns);
300 info->nulls_first = (bool *) palloc(sizeof(bool) * nkeycolumns);
301
302 for (i = 0; i < nkeycolumns; i++)
303 {
304 int16 opt = indexRelation->rd_indoption[i];
305
306 info->reverse_sort[i] = (opt & INDOPTION_DESC) != 0;
307 info->nulls_first[i] = (opt & INDOPTION_NULLS_FIRST) != 0;
308 }
309 }
310 else if (amroutine->amcanorder)
311 {
312 /*
313 * Otherwise, identify the corresponding btree opfamilies by
314 * trying to map this index's "<" operators into btree. Since
315 * "<" uniquely defines the behavior of a sort order, this is
316 * a sufficient test.
317 *
318 * XXX This method is rather slow and also requires the
319 * undesirable assumption that the other index AM numbers its
320 * strategies the same as btree. It'd be better to have a way
321 * to explicitly declare the corresponding btree opfamily for
322 * each opfamily of the other index type. But given the lack
323 * of current or foreseeable amcanorder index types, it's not
324 * worth expending more effort on now.
325 */
326 info->sortopfamily = (Oid *) palloc(sizeof(Oid) * nkeycolumns);
327 info->reverse_sort = (bool *) palloc(sizeof(bool) * nkeycolumns);
328 info->nulls_first = (bool *) palloc(sizeof(bool) * nkeycolumns);
329
330 for (i = 0; i < nkeycolumns; i++)
331 {
332 int16 opt = indexRelation->rd_indoption[i];
333 Oid ltopr;
334 Oid btopfamily;
335 Oid btopcintype;
336 int16 btstrategy;
337
338 info->reverse_sort[i] = (opt & INDOPTION_DESC) != 0;
339 info->nulls_first[i] = (opt & INDOPTION_NULLS_FIRST) != 0;
340
341 ltopr = get_opfamily_member(info->opfamily[i],
342 info->opcintype[i],
343 info->opcintype[i],
344 BTLessStrategyNumber);
345 if (OidIsValid(ltopr) &&
346 get_ordering_op_properties(ltopr,
347 &btopfamily,
348 &btopcintype,
349 &btstrategy) &&
350 btopcintype == info->opcintype[i] &&
351 btstrategy == BTLessStrategyNumber)
352 {
353 /* Successful mapping */
354 info->sortopfamily[i] = btopfamily;
355 }
356 else
357 {
358 /* Fail ... quietly treat index as unordered */
359 info->sortopfamily = NULL;
360 info->reverse_sort = NULL;
361 info->nulls_first = NULL;
362 break;
363 }
364 }
365 }
366 else
367 {
368 info->sortopfamily = NULL;
369 info->reverse_sort = NULL;
370 info->nulls_first = NULL;
371 }
372
373 /*
374 * Fetch the index expressions and predicate, if any. We must
375 * modify the copies we obtain from the relcache to have the
376 * correct varno for the parent relation, so that they match up
377 * correctly against qual clauses.
378 */
379 info->indexprs = RelationGetIndexExpressions(indexRelation);
380 info->indpred = RelationGetIndexPredicate(indexRelation);
381 if (info->indexprs && varno != 1)
382 ChangeVarNodes((Node *) info->indexprs, 1, varno, 0);
383 if (info->indpred && varno != 1)
384 ChangeVarNodes((Node *) info->indpred, 1, varno, 0);
385
386 /* Build targetlist using the completed indexprs data */
387 info->indextlist = build_index_tlist(root, info, relation);
388
389 info->indrestrictinfo = NIL; /* set later, in indxpath.c */
390 info->predOK = false; /* set later, in indxpath.c */
391 info->unique = index->indisunique;
392 info->immediate = index->indimmediate;
393 info->hypothetical = false;
394
395 /*
396 * Estimate the index size. If it's not a partial index, we lock
397 * the number-of-tuples estimate to equal the parent table; if it
398 * is partial then we have to use the same methods as we would for
399 * a table, except we can be sure that the index is not larger
400 * than the table.
401 */
402 if (info->indpred == NIL)
403 {
404 info->pages = RelationGetNumberOfBlocks(indexRelation);
405 info->tuples = rel->tuples;
406 }
407 else
408 {
409 double allvisfrac; /* dummy */
410
411 estimate_rel_size(indexRelation, NULL,
412 &info->pages, &info->tuples, &allvisfrac);
413 if (info->tuples > rel->tuples)
414 info->tuples = rel->tuples;
415 }
416
417 if (info->relam == BTREE_AM_OID)
418 {
419 /* For btrees, get tree height while we have the index open */
420 info->tree_height = _bt_getrootheight(indexRelation);
421 }
422 else
423 {
424 /* For other index types, just set it to "unknown" for now */
425 info->tree_height = -1;
426 }
427
428 index_close(indexRelation, NoLock);
429
430 /*
431 * We've historically used lcons() here. It'd make more sense to
432 * use lappend(), but that causes the planner to change behavior
433 * in cases where two indexes seem equally attractive. For now,
434 * stick with lcons() --- few tables should have so many indexes
435 * that the O(N^2) behavior of lcons() is really a problem.
436 */
437 indexinfos = lcons(info, indexinfos);
438 }
439
440 list_free(indexoidlist);
441 }
442
443 rel->indexlist = indexinfos;
444
445 rel->statlist = get_relation_statistics(rel, relation);
446
447 /* Grab foreign-table info using the relcache, while we have it */
448 if (relation->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
449 {
450 rel->serverid = GetForeignServerIdByRelId(RelationGetRelid(relation));
451 rel->fdwroutine = GetFdwRoutineForRelation(relation, true);
452 }
453 else
454 {
455 rel->serverid = InvalidOid;
456 rel->fdwroutine = NULL;
457 }
458
459 /* Collect info about relation's foreign keys, if relevant */
460 get_relation_foreign_keys(root, rel, relation, inhparent);
461
462 /*
463 * Collect info about relation's partitioning scheme, if any. Only
464 * inheritance parents may be partitioned.
465 */
466 if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
467 set_relation_partition_info(root, rel, relation);
468
469 table_close(relation, NoLock);
470
471 /*
472 * Allow a plugin to editorialize on the info we obtained from the
473 * catalogs. Actions might include altering the assumed relation size,
474 * removing an index, or adding a hypothetical index to the indexlist.
475 */
476 if (get_relation_info_hook)
477 (*get_relation_info_hook) (root, relationObjectId, inhparent, rel);
478 }
479
480 /*
481 * get_relation_foreign_keys -
482 * Retrieves foreign key information for a given relation.
483 *
484 * ForeignKeyOptInfos for relevant foreign keys are created and added to
485 * root->fkey_list. We do this now while we have the relcache entry open.
486 * We could sometimes avoid making useless ForeignKeyOptInfos if we waited
487 * until all RelOptInfos have been built, but the cost of re-opening the
488 * relcache entries would probably exceed any savings.
489 */
490 static void
get_relation_foreign_keys(PlannerInfo * root,RelOptInfo * rel,Relation relation,bool inhparent)491 get_relation_foreign_keys(PlannerInfo *root, RelOptInfo *rel,
492 Relation relation, bool inhparent)
493 {
494 List *rtable = root->parse->rtable;
495 List *cachedfkeys;
496 ListCell *lc;
497
498 /*
499 * If it's not a baserel, we don't care about its FKs. Also, if the query
500 * references only a single relation, we can skip the lookup since no FKs
501 * could satisfy the requirements below.
502 */
503 if (rel->reloptkind != RELOPT_BASEREL ||
504 list_length(rtable) < 2)
505 return;
506
507 /*
508 * If it's the parent of an inheritance tree, ignore its FKs. We could
509 * make useful FK-based deductions if we found that all members of the
510 * inheritance tree have equivalent FK constraints, but detecting that
511 * would require code that hasn't been written.
512 */
513 if (inhparent)
514 return;
515
516 /*
517 * Extract data about relation's FKs from the relcache. Note that this
518 * list belongs to the relcache and might disappear in a cache flush, so
519 * we must not do any further catalog access within this function.
520 */
521 cachedfkeys = RelationGetFKeyList(relation);
522
523 /*
524 * Figure out which FKs are of interest for this query, and create
525 * ForeignKeyOptInfos for them. We want only FKs that reference some
526 * other RTE of the current query. In queries containing self-joins,
527 * there might be more than one other RTE for a referenced table, and we
528 * should make a ForeignKeyOptInfo for each occurrence.
529 *
530 * Ideally, we would ignore RTEs that correspond to non-baserels, but it's
531 * too hard to identify those here, so we might end up making some useless
532 * ForeignKeyOptInfos. If so, match_foreign_keys_to_quals() will remove
533 * them again.
534 */
535 foreach(lc, cachedfkeys)
536 {
537 ForeignKeyCacheInfo *cachedfk = (ForeignKeyCacheInfo *) lfirst(lc);
538 Index rti;
539 ListCell *lc2;
540
541 /* conrelid should always be that of the table we're considering */
542 Assert(cachedfk->conrelid == RelationGetRelid(relation));
543
544 /* Scan to find other RTEs matching confrelid */
545 rti = 0;
546 foreach(lc2, rtable)
547 {
548 RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc2);
549 ForeignKeyOptInfo *info;
550
551 rti++;
552 /* Ignore if not the correct table */
553 if (rte->rtekind != RTE_RELATION ||
554 rte->relid != cachedfk->confrelid)
555 continue;
556 /* Ignore if it's an inheritance parent; doesn't really match */
557 if (rte->inh)
558 continue;
559 /* Ignore self-referential FKs; we only care about joins */
560 if (rti == rel->relid)
561 continue;
562
563 /* OK, let's make an entry */
564 info = makeNode(ForeignKeyOptInfo);
565 info->con_relid = rel->relid;
566 info->ref_relid = rti;
567 info->nkeys = cachedfk->nkeys;
568 memcpy(info->conkey, cachedfk->conkey, sizeof(info->conkey));
569 memcpy(info->confkey, cachedfk->confkey, sizeof(info->confkey));
570 memcpy(info->conpfeqop, cachedfk->conpfeqop, sizeof(info->conpfeqop));
571 /* zero out fields to be filled by match_foreign_keys_to_quals */
572 info->nmatched_ec = 0;
573 info->nmatched_rcols = 0;
574 info->nmatched_ri = 0;
575 memset(info->eclass, 0, sizeof(info->eclass));
576 memset(info->rinfos, 0, sizeof(info->rinfos));
577
578 root->fkey_list = lappend(root->fkey_list, info);
579 }
580 }
581 }
582
583 /*
584 * infer_arbiter_indexes -
585 * Determine the unique indexes used to arbitrate speculative insertion.
586 *
587 * Uses user-supplied inference clause expressions and predicate to match a
588 * unique index from those defined and ready on the heap relation (target).
589 * An exact match is required on columns/expressions (although they can appear
590 * in any order). However, the predicate given by the user need only restrict
591 * insertion to a subset of some part of the table covered by some particular
592 * unique index (in particular, a partial unique index) in order to be
593 * inferred.
594 *
595 * The implementation does not consider which B-Tree operator class any
596 * particular available unique index attribute uses, unless one was specified
597 * in the inference specification. The same is true of collations. In
598 * particular, there is no system dependency on the default operator class for
599 * the purposes of inference. If no opclass (or collation) is specified, then
600 * all matching indexes (that may or may not match the default in terms of
601 * each attribute opclass/collation) are used for inference.
602 */
603 List *
infer_arbiter_indexes(PlannerInfo * root)604 infer_arbiter_indexes(PlannerInfo *root)
605 {
606 OnConflictExpr *onconflict = root->parse->onConflict;
607
608 /* Iteration state */
609 RangeTblEntry *rte;
610 Relation relation;
611 Oid indexOidFromConstraint = InvalidOid;
612 List *indexList;
613 ListCell *l;
614
615 /* Normalized inference attributes and inference expressions: */
616 Bitmapset *inferAttrs = NULL;
617 List *inferElems = NIL;
618
619 /* Results */
620 List *results = NIL;
621
622 /*
623 * Quickly return NIL for ON CONFLICT DO NOTHING without an inference
624 * specification or named constraint. ON CONFLICT DO UPDATE statements
625 * must always provide one or the other (but parser ought to have caught
626 * that already).
627 */
628 if (onconflict->arbiterElems == NIL &&
629 onconflict->constraint == InvalidOid)
630 return NIL;
631
632 /*
633 * We need not lock the relation since it was already locked, either by
634 * the rewriter or when expand_inherited_rtentry() added it to the query's
635 * rangetable.
636 */
637 rte = rt_fetch(root->parse->resultRelation, root->parse->rtable);
638
639 relation = table_open(rte->relid, NoLock);
640
641 /*
642 * Build normalized/BMS representation of plain indexed attributes, as
643 * well as a separate list of expression items. This simplifies matching
644 * the cataloged definition of indexes.
645 */
646 foreach(l, onconflict->arbiterElems)
647 {
648 InferenceElem *elem = (InferenceElem *) lfirst(l);
649 Var *var;
650 int attno;
651
652 if (!IsA(elem->expr, Var))
653 {
654 /* If not a plain Var, just shove it in inferElems for now */
655 inferElems = lappend(inferElems, elem->expr);
656 continue;
657 }
658
659 var = (Var *) elem->expr;
660 attno = var->varattno;
661
662 if (attno == 0)
663 ereport(ERROR,
664 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
665 errmsg("whole row unique index inference specifications are not supported")));
666
667 inferAttrs = bms_add_member(inferAttrs,
668 attno - FirstLowInvalidHeapAttributeNumber);
669 }
670
671 /*
672 * Lookup named constraint's index. This is not immediately returned
673 * because some additional sanity checks are required.
674 */
675 if (onconflict->constraint != InvalidOid)
676 {
677 indexOidFromConstraint = get_constraint_index(onconflict->constraint);
678
679 if (indexOidFromConstraint == InvalidOid)
680 ereport(ERROR,
681 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
682 errmsg("constraint in ON CONFLICT clause has no associated index")));
683 }
684
685 /*
686 * Using that representation, iterate through the list of indexes on the
687 * target relation to try and find a match
688 */
689 indexList = RelationGetIndexList(relation);
690
691 foreach(l, indexList)
692 {
693 Oid indexoid = lfirst_oid(l);
694 Relation idxRel;
695 Form_pg_index idxForm;
696 Bitmapset *indexedAttrs;
697 List *idxExprs;
698 List *predExprs;
699 AttrNumber natt;
700 ListCell *el;
701
702 /*
703 * Extract info from the relation descriptor for the index. Obtain
704 * the same lock type that the executor will ultimately use.
705 *
706 * Let executor complain about !indimmediate case directly, because
707 * enforcement needs to occur there anyway when an inference clause is
708 * omitted.
709 */
710 idxRel = index_open(indexoid, rte->rellockmode);
711 idxForm = idxRel->rd_index;
712
713 if (!idxForm->indisvalid)
714 goto next;
715
716 /*
717 * Note that we do not perform a check against indcheckxmin (like e.g.
718 * get_relation_info()) here to eliminate candidates, because
719 * uniqueness checking only cares about the most recently committed
720 * tuple versions.
721 */
722
723 /*
724 * Look for match on "ON constraint_name" variant, which may not be
725 * unique constraint. This can only be a constraint name.
726 */
727 if (indexOidFromConstraint == idxForm->indexrelid)
728 {
729 if (!idxForm->indisunique && onconflict->action == ONCONFLICT_UPDATE)
730 ereport(ERROR,
731 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
732 errmsg("ON CONFLICT DO UPDATE not supported with exclusion constraints")));
733
734 results = lappend_oid(results, idxForm->indexrelid);
735 list_free(indexList);
736 index_close(idxRel, NoLock);
737 table_close(relation, NoLock);
738 return results;
739 }
740 else if (indexOidFromConstraint != InvalidOid)
741 {
742 /* No point in further work for index in named constraint case */
743 goto next;
744 }
745
746 /*
747 * Only considering conventional inference at this point (not named
748 * constraints), so index under consideration can be immediately
749 * skipped if it's not unique
750 */
751 if (!idxForm->indisunique)
752 goto next;
753
754 /* Build BMS representation of plain (non expression) index attrs */
755 indexedAttrs = NULL;
756 for (natt = 0; natt < idxForm->indnkeyatts; natt++)
757 {
758 int attno = idxRel->rd_index->indkey.values[natt];
759
760 if (attno != 0)
761 indexedAttrs = bms_add_member(indexedAttrs,
762 attno - FirstLowInvalidHeapAttributeNumber);
763 }
764
765 /* Non-expression attributes (if any) must match */
766 if (!bms_equal(indexedAttrs, inferAttrs))
767 goto next;
768
769 /* Expression attributes (if any) must match */
770 idxExprs = RelationGetIndexExpressions(idxRel);
771 foreach(el, onconflict->arbiterElems)
772 {
773 InferenceElem *elem = (InferenceElem *) lfirst(el);
774
775 /*
776 * Ensure that collation/opclass aspects of inference expression
777 * element match. Even though this loop is primarily concerned
778 * with matching expressions, it is a convenient point to check
779 * this for both expressions and ordinary (non-expression)
780 * attributes appearing as inference elements.
781 */
782 if (!infer_collation_opclass_match(elem, idxRel, idxExprs))
783 goto next;
784
785 /*
786 * Plain Vars don't factor into count of expression elements, and
787 * the question of whether or not they satisfy the index
788 * definition has already been considered (they must).
789 */
790 if (IsA(elem->expr, Var))
791 continue;
792
793 /*
794 * Might as well avoid redundant check in the rare cases where
795 * infer_collation_opclass_match() is required to do real work.
796 * Otherwise, check that element expression appears in cataloged
797 * index definition.
798 */
799 if (elem->infercollid != InvalidOid ||
800 elem->inferopclass != InvalidOid ||
801 list_member(idxExprs, elem->expr))
802 continue;
803
804 goto next;
805 }
806
807 /*
808 * Now that all inference elements were matched, ensure that the
809 * expression elements from inference clause are not missing any
810 * cataloged expressions. This does the right thing when unique
811 * indexes redundantly repeat the same attribute, or if attributes
812 * redundantly appear multiple times within an inference clause.
813 */
814 if (list_difference(idxExprs, inferElems) != NIL)
815 goto next;
816
817 /*
818 * If it's a partial index, its predicate must be implied by the ON
819 * CONFLICT's WHERE clause.
820 */
821 predExprs = RelationGetIndexPredicate(idxRel);
822
823 if (!predicate_implied_by(predExprs, (List *) onconflict->arbiterWhere, false))
824 goto next;
825
826 results = lappend_oid(results, idxForm->indexrelid);
827 next:
828 index_close(idxRel, NoLock);
829 }
830
831 list_free(indexList);
832 table_close(relation, NoLock);
833
834 if (results == NIL)
835 ereport(ERROR,
836 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
837 errmsg("there is no unique or exclusion constraint matching the ON CONFLICT specification")));
838
839 return results;
840 }
841
842 /*
843 * infer_collation_opclass_match - ensure infer element opclass/collation match
844 *
845 * Given unique index inference element from inference specification, if
846 * collation was specified, or if opclass was specified, verify that there is
847 * at least one matching indexed attribute (occasionally, there may be more).
848 * Skip this in the common case where inference specification does not include
849 * collation or opclass (instead matching everything, regardless of cataloged
850 * collation/opclass of indexed attribute).
851 *
852 * At least historically, Postgres has not offered collations or opclasses
853 * with alternative-to-default notions of equality, so these additional
854 * criteria should only be required infrequently.
855 *
856 * Don't give up immediately when an inference element matches some attribute
857 * cataloged as indexed but not matching additional opclass/collation
858 * criteria. This is done so that the implementation is as forgiving as
859 * possible of redundancy within cataloged index attributes (or, less
860 * usefully, within inference specification elements). If collations actually
861 * differ between apparently redundantly indexed attributes (redundant within
862 * or across indexes), then there really is no redundancy as such.
863 *
864 * Note that if an inference element specifies an opclass and a collation at
865 * once, both must match in at least one particular attribute within index
866 * catalog definition in order for that inference element to be considered
867 * inferred/satisfied.
868 */
869 static bool
infer_collation_opclass_match(InferenceElem * elem,Relation idxRel,List * idxExprs)870 infer_collation_opclass_match(InferenceElem *elem, Relation idxRel,
871 List *idxExprs)
872 {
873 AttrNumber natt;
874 Oid inferopfamily = InvalidOid; /* OID of opclass opfamily */
875 Oid inferopcinputtype = InvalidOid; /* OID of opclass input type */
876 int nplain = 0; /* # plain attrs observed */
877
878 /*
879 * If inference specification element lacks collation/opclass, then no
880 * need to check for exact match.
881 */
882 if (elem->infercollid == InvalidOid && elem->inferopclass == InvalidOid)
883 return true;
884
885 /*
886 * Lookup opfamily and input type, for matching indexes
887 */
888 if (elem->inferopclass)
889 {
890 inferopfamily = get_opclass_family(elem->inferopclass);
891 inferopcinputtype = get_opclass_input_type(elem->inferopclass);
892 }
893
894 for (natt = 1; natt <= idxRel->rd_att->natts; natt++)
895 {
896 Oid opfamily = idxRel->rd_opfamily[natt - 1];
897 Oid opcinputtype = idxRel->rd_opcintype[natt - 1];
898 Oid collation = idxRel->rd_indcollation[natt - 1];
899 int attno = idxRel->rd_index->indkey.values[natt - 1];
900
901 if (attno != 0)
902 nplain++;
903
904 if (elem->inferopclass != InvalidOid &&
905 (inferopfamily != opfamily || inferopcinputtype != opcinputtype))
906 {
907 /* Attribute needed to match opclass, but didn't */
908 continue;
909 }
910
911 if (elem->infercollid != InvalidOid &&
912 elem->infercollid != collation)
913 {
914 /* Attribute needed to match collation, but didn't */
915 continue;
916 }
917
918 /* If one matching index att found, good enough -- return true */
919 if (IsA(elem->expr, Var))
920 {
921 if (((Var *) elem->expr)->varattno == attno)
922 return true;
923 }
924 else if (attno == 0)
925 {
926 Node *nattExpr = list_nth(idxExprs, (natt - 1) - nplain);
927
928 /*
929 * Note that unlike routines like match_index_to_operand() we
930 * don't need to care about RelabelType. Neither the index
931 * definition nor the inference clause should contain them.
932 */
933 if (equal(elem->expr, nattExpr))
934 return true;
935 }
936 }
937
938 return false;
939 }
940
941 /*
942 * estimate_rel_size - estimate # pages and # tuples in a table or index
943 *
944 * We also estimate the fraction of the pages that are marked all-visible in
945 * the visibility map, for use in estimation of index-only scans.
946 *
947 * If attr_widths isn't NULL, it points to the zero-index entry of the
948 * relation's attr_widths[] cache; we fill this in if we have need to compute
949 * the attribute widths for estimation purposes.
950 */
951 void
estimate_rel_size(Relation rel,int32 * attr_widths,BlockNumber * pages,double * tuples,double * allvisfrac)952 estimate_rel_size(Relation rel, int32 *attr_widths,
953 BlockNumber *pages, double *tuples, double *allvisfrac)
954 {
955 BlockNumber curpages;
956 BlockNumber relpages;
957 double reltuples;
958 BlockNumber relallvisible;
959 double density;
960
961 switch (rel->rd_rel->relkind)
962 {
963 case RELKIND_RELATION:
964 case RELKIND_MATVIEW:
965 case RELKIND_TOASTVALUE:
966 table_relation_estimate_size(rel, attr_widths, pages, tuples,
967 allvisfrac);
968 break;
969
970 case RELKIND_INDEX:
971
972 /*
973 * XXX: It'd probably be good to move this into a callback,
974 * individual index types e.g. know if they have a metapage.
975 */
976
977 /* it has storage, ok to call the smgr */
978 curpages = RelationGetNumberOfBlocks(rel);
979
980 /* coerce values in pg_class to more desirable types */
981 relpages = (BlockNumber) rel->rd_rel->relpages;
982 reltuples = (double) rel->rd_rel->reltuples;
983 relallvisible = (BlockNumber) rel->rd_rel->relallvisible;
984
985 /* report estimated # pages */
986 *pages = curpages;
987 /* quick exit if rel is clearly empty */
988 if (curpages == 0)
989 {
990 *tuples = 0;
991 *allvisfrac = 0;
992 break;
993 }
994 /* coerce values in pg_class to more desirable types */
995 relpages = (BlockNumber) rel->rd_rel->relpages;
996 reltuples = (double) rel->rd_rel->reltuples;
997 relallvisible = (BlockNumber) rel->rd_rel->relallvisible;
998
999 /*
1000 * Discount the metapage while estimating the number of tuples.
1001 * This is a kluge because it assumes more than it ought to about
1002 * index structure. Currently it's OK for btree, hash, and GIN
1003 * indexes but suspect for GiST indexes.
1004 */
1005 if (relpages > 0)
1006 {
1007 curpages--;
1008 relpages--;
1009 }
1010
1011 /* estimate number of tuples from previous tuple density */
1012 if (relpages > 0)
1013 density = reltuples / (double) relpages;
1014 else
1015 {
1016 /*
1017 * When we have no data because the relation was truncated,
1018 * estimate tuple width from attribute datatypes. We assume
1019 * here that the pages are completely full, which is OK for
1020 * tables (since they've presumably not been VACUUMed yet) but
1021 * is probably an overestimate for indexes. Fortunately
1022 * get_relation_info() can clamp the overestimate to the
1023 * parent table's size.
1024 *
1025 * Note: this code intentionally disregards alignment
1026 * considerations, because (a) that would be gilding the lily
1027 * considering how crude the estimate is, and (b) it creates
1028 * platform dependencies in the default plans which are kind
1029 * of a headache for regression testing.
1030 *
1031 * XXX: Should this logic be more index specific?
1032 */
1033 int32 tuple_width;
1034
1035 tuple_width = get_rel_data_width(rel, attr_widths);
1036 tuple_width += MAXALIGN(SizeofHeapTupleHeader);
1037 tuple_width += sizeof(ItemIdData);
1038 /* note: integer division is intentional here */
1039 density = (BLCKSZ - SizeOfPageHeaderData) / tuple_width;
1040 }
1041 *tuples = rint(density * (double) curpages);
1042
1043 /*
1044 * We use relallvisible as-is, rather than scaling it up like we
1045 * do for the pages and tuples counts, on the theory that any
1046 * pages added since the last VACUUM are most likely not marked
1047 * all-visible. But costsize.c wants it converted to a fraction.
1048 */
1049 if (relallvisible == 0 || curpages <= 0)
1050 *allvisfrac = 0;
1051 else if ((double) relallvisible >= curpages)
1052 *allvisfrac = 1;
1053 else
1054 *allvisfrac = (double) relallvisible / curpages;
1055 break;
1056
1057 case RELKIND_SEQUENCE:
1058 /* Sequences always have a known size */
1059 *pages = 1;
1060 *tuples = 1;
1061 *allvisfrac = 0;
1062 break;
1063 case RELKIND_FOREIGN_TABLE:
1064 /* Just use whatever's in pg_class */
1065 *pages = rel->rd_rel->relpages;
1066 *tuples = rel->rd_rel->reltuples;
1067 *allvisfrac = 0;
1068 break;
1069 default:
1070 /* else it has no disk storage; probably shouldn't get here? */
1071 *pages = 0;
1072 *tuples = 0;
1073 *allvisfrac = 0;
1074 break;
1075 }
1076 }
1077
1078
1079 /*
1080 * get_rel_data_width
1081 *
1082 * Estimate the average width of (the data part of) the relation's tuples.
1083 *
1084 * If attr_widths isn't NULL, it points to the zero-index entry of the
1085 * relation's attr_widths[] cache; use and update that cache as appropriate.
1086 *
1087 * Currently we ignore dropped columns. Ideally those should be included
1088 * in the result, but we haven't got any way to get info about them; and
1089 * since they might be mostly NULLs, treating them as zero-width is not
1090 * necessarily the wrong thing anyway.
1091 */
1092 int32
get_rel_data_width(Relation rel,int32 * attr_widths)1093 get_rel_data_width(Relation rel, int32 *attr_widths)
1094 {
1095 int32 tuple_width = 0;
1096 int i;
1097
1098 for (i = 1; i <= RelationGetNumberOfAttributes(rel); i++)
1099 {
1100 Form_pg_attribute att = TupleDescAttr(rel->rd_att, i - 1);
1101 int32 item_width;
1102
1103 if (att->attisdropped)
1104 continue;
1105
1106 /* use previously cached data, if any */
1107 if (attr_widths != NULL && attr_widths[i] > 0)
1108 {
1109 tuple_width += attr_widths[i];
1110 continue;
1111 }
1112
1113 /* This should match set_rel_width() in costsize.c */
1114 item_width = get_attavgwidth(RelationGetRelid(rel), i);
1115 if (item_width <= 0)
1116 {
1117 item_width = get_typavgwidth(att->atttypid, att->atttypmod);
1118 Assert(item_width > 0);
1119 }
1120 if (attr_widths != NULL)
1121 attr_widths[i] = item_width;
1122 tuple_width += item_width;
1123 }
1124
1125 return tuple_width;
1126 }
1127
1128 /*
1129 * get_relation_data_width
1130 *
1131 * External API for get_rel_data_width: same behavior except we have to
1132 * open the relcache entry.
1133 */
1134 int32
get_relation_data_width(Oid relid,int32 * attr_widths)1135 get_relation_data_width(Oid relid, int32 *attr_widths)
1136 {
1137 int32 result;
1138 Relation relation;
1139
1140 /* As above, assume relation is already locked */
1141 relation = table_open(relid, NoLock);
1142
1143 result = get_rel_data_width(relation, attr_widths);
1144
1145 table_close(relation, NoLock);
1146
1147 return result;
1148 }
1149
1150
1151 /*
1152 * get_relation_constraints
1153 *
1154 * Retrieve the applicable constraint expressions of the given relation.
1155 *
1156 * Returns a List (possibly empty) of constraint expressions. Each one
1157 * has been canonicalized, and its Vars are changed to have the varno
1158 * indicated by rel->relid. This allows the expressions to be easily
1159 * compared to expressions taken from WHERE.
1160 *
1161 * If include_noinherit is true, it's okay to include constraints that
1162 * are marked NO INHERIT.
1163 *
1164 * If include_notnull is true, "col IS NOT NULL" expressions are generated
1165 * and added to the result for each column that's marked attnotnull.
1166 *
1167 * If include_partition is true, and the relation is a partition,
1168 * also include the partitioning constraints.
1169 *
1170 * Note: at present this is invoked at most once per relation per planner
1171 * run, and in many cases it won't be invoked at all, so there seems no
1172 * point in caching the data in RelOptInfo.
1173 */
1174 static List *
get_relation_constraints(PlannerInfo * root,Oid relationObjectId,RelOptInfo * rel,bool include_noinherit,bool include_notnull,bool include_partition)1175 get_relation_constraints(PlannerInfo *root,
1176 Oid relationObjectId, RelOptInfo *rel,
1177 bool include_noinherit,
1178 bool include_notnull,
1179 bool include_partition)
1180 {
1181 List *result = NIL;
1182 Index varno = rel->relid;
1183 Relation relation;
1184 TupleConstr *constr;
1185
1186 /*
1187 * We assume the relation has already been safely locked.
1188 */
1189 relation = table_open(relationObjectId, NoLock);
1190
1191 constr = relation->rd_att->constr;
1192 if (constr != NULL)
1193 {
1194 int num_check = constr->num_check;
1195 int i;
1196
1197 for (i = 0; i < num_check; i++)
1198 {
1199 Node *cexpr;
1200
1201 /*
1202 * If this constraint hasn't been fully validated yet, we must
1203 * ignore it here. Also ignore if NO INHERIT and we weren't told
1204 * that that's safe.
1205 */
1206 if (!constr->check[i].ccvalid)
1207 continue;
1208 if (constr->check[i].ccnoinherit && !include_noinherit)
1209 continue;
1210
1211 cexpr = stringToNode(constr->check[i].ccbin);
1212
1213 /*
1214 * Run each expression through const-simplification and
1215 * canonicalization. This is not just an optimization, but is
1216 * necessary, because we will be comparing it to
1217 * similarly-processed qual clauses, and may fail to detect valid
1218 * matches without this. This must match the processing done to
1219 * qual clauses in preprocess_expression()! (We can skip the
1220 * stuff involving subqueries, however, since we don't allow any
1221 * in check constraints.)
1222 */
1223 cexpr = eval_const_expressions(root, cexpr);
1224
1225 cexpr = (Node *) canonicalize_qual((Expr *) cexpr, true);
1226
1227 /* Fix Vars to have the desired varno */
1228 if (varno != 1)
1229 ChangeVarNodes(cexpr, 1, varno, 0);
1230
1231 /*
1232 * Finally, convert to implicit-AND format (that is, a List) and
1233 * append the resulting item(s) to our output list.
1234 */
1235 result = list_concat(result,
1236 make_ands_implicit((Expr *) cexpr));
1237 }
1238
1239 /* Add NOT NULL constraints in expression form, if requested */
1240 if (include_notnull && constr->has_not_null)
1241 {
1242 int natts = relation->rd_att->natts;
1243
1244 for (i = 1; i <= natts; i++)
1245 {
1246 Form_pg_attribute att = TupleDescAttr(relation->rd_att, i - 1);
1247
1248 if (att->attnotnull && !att->attisdropped)
1249 {
1250 NullTest *ntest = makeNode(NullTest);
1251
1252 ntest->arg = (Expr *) makeVar(varno,
1253 i,
1254 att->atttypid,
1255 att->atttypmod,
1256 att->attcollation,
1257 0);
1258 ntest->nulltesttype = IS_NOT_NULL;
1259
1260 /*
1261 * argisrow=false is correct even for a composite column,
1262 * because attnotnull does not represent a SQL-spec IS NOT
1263 * NULL test in such a case, just IS DISTINCT FROM NULL.
1264 */
1265 ntest->argisrow = false;
1266 ntest->location = -1;
1267 result = lappend(result, ntest);
1268 }
1269 }
1270 }
1271 }
1272
1273 /*
1274 * Add partitioning constraints, if requested.
1275 */
1276 if (include_partition && relation->rd_rel->relispartition)
1277 {
1278 /* make sure rel->partition_qual is set */
1279 set_baserel_partition_constraint(relation, rel);
1280 result = list_concat(result, rel->partition_qual);
1281 }
1282
1283 table_close(relation, NoLock);
1284
1285 return result;
1286 }
1287
1288 /*
1289 * get_relation_statistics
1290 * Retrieve extended statistics defined on the table.
1291 *
1292 * Returns a List (possibly empty) of StatisticExtInfo objects describing
1293 * the statistics. Note that this doesn't load the actual statistics data,
1294 * just the identifying metadata. Only stats actually built are considered.
1295 */
1296 static List *
get_relation_statistics(RelOptInfo * rel,Relation relation)1297 get_relation_statistics(RelOptInfo *rel, Relation relation)
1298 {
1299 List *statoidlist;
1300 List *stainfos = NIL;
1301 ListCell *l;
1302
1303 statoidlist = RelationGetStatExtList(relation);
1304
1305 foreach(l, statoidlist)
1306 {
1307 Oid statOid = lfirst_oid(l);
1308 Form_pg_statistic_ext staForm;
1309 HeapTuple htup;
1310 HeapTuple dtup;
1311 Bitmapset *keys = NULL;
1312 int i;
1313
1314 htup = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(statOid));
1315 if (!HeapTupleIsValid(htup))
1316 elog(ERROR, "cache lookup failed for statistics object %u", statOid);
1317 staForm = (Form_pg_statistic_ext) GETSTRUCT(htup);
1318
1319 dtup = SearchSysCache1(STATEXTDATASTXOID, ObjectIdGetDatum(statOid));
1320 if (!HeapTupleIsValid(dtup))
1321 elog(ERROR, "cache lookup failed for statistics object %u", statOid);
1322
1323 /*
1324 * First, build the array of columns covered. This is ultimately
1325 * wasted if no stats within the object have actually been built, but
1326 * it doesn't seem worth troubling over that case.
1327 */
1328 for (i = 0; i < staForm->stxkeys.dim1; i++)
1329 keys = bms_add_member(keys, staForm->stxkeys.values[i]);
1330
1331 /* add one StatisticExtInfo for each kind built */
1332 if (statext_is_kind_built(dtup, STATS_EXT_NDISTINCT))
1333 {
1334 StatisticExtInfo *info = makeNode(StatisticExtInfo);
1335
1336 info->statOid = statOid;
1337 info->rel = rel;
1338 info->kind = STATS_EXT_NDISTINCT;
1339 info->keys = bms_copy(keys);
1340
1341 stainfos = lappend(stainfos, info);
1342 }
1343
1344 if (statext_is_kind_built(dtup, STATS_EXT_DEPENDENCIES))
1345 {
1346 StatisticExtInfo *info = makeNode(StatisticExtInfo);
1347
1348 info->statOid = statOid;
1349 info->rel = rel;
1350 info->kind = STATS_EXT_DEPENDENCIES;
1351 info->keys = bms_copy(keys);
1352
1353 stainfos = lappend(stainfos, info);
1354 }
1355
1356 if (statext_is_kind_built(dtup, STATS_EXT_MCV))
1357 {
1358 StatisticExtInfo *info = makeNode(StatisticExtInfo);
1359
1360 info->statOid = statOid;
1361 info->rel = rel;
1362 info->kind = STATS_EXT_MCV;
1363 info->keys = bms_copy(keys);
1364
1365 stainfos = lappend(stainfos, info);
1366 }
1367
1368 ReleaseSysCache(htup);
1369 ReleaseSysCache(dtup);
1370 bms_free(keys);
1371 }
1372
1373 list_free(statoidlist);
1374
1375 return stainfos;
1376 }
1377
1378 /*
1379 * relation_excluded_by_constraints
1380 *
1381 * Detect whether the relation need not be scanned because it has either
1382 * self-inconsistent restrictions, or restrictions inconsistent with the
1383 * relation's applicable constraints.
1384 *
1385 * Note: this examines only rel->relid, rel->reloptkind, and
1386 * rel->baserestrictinfo; therefore it can be called before filling in
1387 * other fields of the RelOptInfo.
1388 */
1389 bool
relation_excluded_by_constraints(PlannerInfo * root,RelOptInfo * rel,RangeTblEntry * rte)1390 relation_excluded_by_constraints(PlannerInfo *root,
1391 RelOptInfo *rel, RangeTblEntry *rte)
1392 {
1393 bool include_noinherit;
1394 bool include_notnull;
1395 bool include_partition = false;
1396 List *safe_restrictions;
1397 List *constraint_pred;
1398 List *safe_constraints;
1399 ListCell *lc;
1400
1401 /* As of now, constraint exclusion works only with simple relations. */
1402 Assert(IS_SIMPLE_REL(rel));
1403
1404 /*
1405 * If there are no base restriction clauses, we have no hope of proving
1406 * anything below, so fall out quickly.
1407 */
1408 if (rel->baserestrictinfo == NIL)
1409 return false;
1410
1411 /*
1412 * Regardless of the setting of constraint_exclusion, detect
1413 * constant-FALSE-or-NULL restriction clauses. Because const-folding will
1414 * reduce "anything AND FALSE" to just "FALSE", any such case should
1415 * result in exactly one baserestrictinfo entry. This doesn't fire very
1416 * often, but it seems cheap enough to be worth doing anyway. (Without
1417 * this, we'd miss some optimizations that 9.5 and earlier found via much
1418 * more roundabout methods.)
1419 */
1420 if (list_length(rel->baserestrictinfo) == 1)
1421 {
1422 RestrictInfo *rinfo = (RestrictInfo *) linitial(rel->baserestrictinfo);
1423 Expr *clause = rinfo->clause;
1424
1425 if (clause && IsA(clause, Const) &&
1426 (((Const *) clause)->constisnull ||
1427 !DatumGetBool(((Const *) clause)->constvalue)))
1428 return true;
1429 }
1430
1431 /*
1432 * Skip further tests, depending on constraint_exclusion.
1433 */
1434 switch (constraint_exclusion)
1435 {
1436 case CONSTRAINT_EXCLUSION_OFF:
1437 /* In 'off' mode, never make any further tests */
1438 return false;
1439
1440 case CONSTRAINT_EXCLUSION_PARTITION:
1441
1442 /*
1443 * When constraint_exclusion is set to 'partition' we only handle
1444 * appendrel members. Normally, they are RELOPT_OTHER_MEMBER_REL
1445 * relations, but we also consider inherited target relations as
1446 * appendrel members for the purposes of constraint exclusion
1447 * (since, indeed, they were appendrel members earlier in
1448 * inheritance_planner).
1449 *
1450 * In both cases, partition pruning was already applied, so there
1451 * is no need to consider the rel's partition constraints here.
1452 */
1453 if (rel->reloptkind == RELOPT_OTHER_MEMBER_REL ||
1454 (rel->relid == root->parse->resultRelation &&
1455 root->inhTargetKind != INHKIND_NONE))
1456 break; /* appendrel member, so process it */
1457 return false;
1458
1459 case CONSTRAINT_EXCLUSION_ON:
1460
1461 /*
1462 * In 'on' mode, always apply constraint exclusion. If we are
1463 * considering a baserel that is a partition (i.e., it was
1464 * directly named rather than expanded from a parent table), then
1465 * its partition constraints haven't been considered yet, so
1466 * include them in the processing here.
1467 */
1468 if (rel->reloptkind == RELOPT_BASEREL &&
1469 !(rel->relid == root->parse->resultRelation &&
1470 root->inhTargetKind != INHKIND_NONE))
1471 include_partition = true;
1472 break; /* always try to exclude */
1473 }
1474
1475 /*
1476 * Check for self-contradictory restriction clauses. We dare not make
1477 * deductions with non-immutable functions, but any immutable clauses that
1478 * are self-contradictory allow us to conclude the scan is unnecessary.
1479 *
1480 * Note: strip off RestrictInfo because predicate_refuted_by() isn't
1481 * expecting to see any in its predicate argument.
1482 */
1483 safe_restrictions = NIL;
1484 foreach(lc, rel->baserestrictinfo)
1485 {
1486 RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc);
1487
1488 if (!contain_mutable_functions((Node *) rinfo->clause))
1489 safe_restrictions = lappend(safe_restrictions, rinfo->clause);
1490 }
1491
1492 /*
1493 * We can use weak refutation here, since we're comparing restriction
1494 * clauses with restriction clauses.
1495 */
1496 if (predicate_refuted_by(safe_restrictions, safe_restrictions, true))
1497 return true;
1498
1499 /*
1500 * Only plain relations have constraints, so stop here for other rtekinds.
1501 */
1502 if (rte->rtekind != RTE_RELATION)
1503 return false;
1504
1505 /*
1506 * If we are scanning just this table, we can use NO INHERIT constraints,
1507 * but not if we're scanning its children too. (Note that partitioned
1508 * tables should never have NO INHERIT constraints; but it's not necessary
1509 * for us to assume that here.)
1510 */
1511 include_noinherit = !rte->inh;
1512
1513 /*
1514 * Currently, attnotnull constraints must be treated as NO INHERIT unless
1515 * this is a partitioned table. In future we might track their
1516 * inheritance status more accurately, allowing this to be refined.
1517 */
1518 include_notnull = (!rte->inh || rte->relkind == RELKIND_PARTITIONED_TABLE);
1519
1520 /*
1521 * Fetch the appropriate set of constraint expressions.
1522 */
1523 constraint_pred = get_relation_constraints(root, rte->relid, rel,
1524 include_noinherit,
1525 include_notnull,
1526 include_partition);
1527
1528 /*
1529 * We do not currently enforce that CHECK constraints contain only
1530 * immutable functions, so it's necessary to check here. We daren't draw
1531 * conclusions from plan-time evaluation of non-immutable functions. Since
1532 * they're ANDed, we can just ignore any mutable constraints in the list,
1533 * and reason about the rest.
1534 */
1535 safe_constraints = NIL;
1536 foreach(lc, constraint_pred)
1537 {
1538 Node *pred = (Node *) lfirst(lc);
1539
1540 if (!contain_mutable_functions(pred))
1541 safe_constraints = lappend(safe_constraints, pred);
1542 }
1543
1544 /*
1545 * The constraints are effectively ANDed together, so we can just try to
1546 * refute the entire collection at once. This may allow us to make proofs
1547 * that would fail if we took them individually.
1548 *
1549 * Note: we use rel->baserestrictinfo, not safe_restrictions as might seem
1550 * an obvious optimization. Some of the clauses might be OR clauses that
1551 * have volatile and nonvolatile subclauses, and it's OK to make
1552 * deductions with the nonvolatile parts.
1553 *
1554 * We need strong refutation because we have to prove that the constraints
1555 * would yield false, not just NULL.
1556 */
1557 if (predicate_refuted_by(safe_constraints, rel->baserestrictinfo, false))
1558 return true;
1559
1560 return false;
1561 }
1562
1563
1564 /*
1565 * build_physical_tlist
1566 *
1567 * Build a targetlist consisting of exactly the relation's user attributes,
1568 * in order. The executor can special-case such tlists to avoid a projection
1569 * step at runtime, so we use such tlists preferentially for scan nodes.
1570 *
1571 * Exception: if there are any dropped or missing columns, we punt and return
1572 * NIL. Ideally we would like to handle these cases too. However this
1573 * creates problems for ExecTypeFromTL, which may be asked to build a tupdesc
1574 * for a tlist that includes vars of no-longer-existent types. In theory we
1575 * could dig out the required info from the pg_attribute entries of the
1576 * relation, but that data is not readily available to ExecTypeFromTL.
1577 * For now, we don't apply the physical-tlist optimization when there are
1578 * dropped cols.
1579 *
1580 * We also support building a "physical" tlist for subqueries, functions,
1581 * values lists, table expressions, and CTEs, since the same optimization can
1582 * occur in SubqueryScan, FunctionScan, ValuesScan, CteScan, TableFunc,
1583 * NamedTuplestoreScan, and WorkTableScan nodes.
1584 */
1585 List *
build_physical_tlist(PlannerInfo * root,RelOptInfo * rel)1586 build_physical_tlist(PlannerInfo *root, RelOptInfo *rel)
1587 {
1588 List *tlist = NIL;
1589 Index varno = rel->relid;
1590 RangeTblEntry *rte = planner_rt_fetch(varno, root);
1591 Relation relation;
1592 Query *subquery;
1593 Var *var;
1594 ListCell *l;
1595 int attrno,
1596 numattrs;
1597 List *colvars;
1598
1599 switch (rte->rtekind)
1600 {
1601 case RTE_RELATION:
1602 /* Assume we already have adequate lock */
1603 relation = table_open(rte->relid, NoLock);
1604
1605 numattrs = RelationGetNumberOfAttributes(relation);
1606 for (attrno = 1; attrno <= numattrs; attrno++)
1607 {
1608 Form_pg_attribute att_tup = TupleDescAttr(relation->rd_att,
1609 attrno - 1);
1610
1611 if (att_tup->attisdropped || att_tup->atthasmissing)
1612 {
1613 /* found a dropped or missing col, so punt */
1614 tlist = NIL;
1615 break;
1616 }
1617
1618 var = makeVar(varno,
1619 attrno,
1620 att_tup->atttypid,
1621 att_tup->atttypmod,
1622 att_tup->attcollation,
1623 0);
1624
1625 tlist = lappend(tlist,
1626 makeTargetEntry((Expr *) var,
1627 attrno,
1628 NULL,
1629 false));
1630 }
1631
1632 table_close(relation, NoLock);
1633 break;
1634
1635 case RTE_SUBQUERY:
1636 subquery = rte->subquery;
1637 foreach(l, subquery->targetList)
1638 {
1639 TargetEntry *tle = (TargetEntry *) lfirst(l);
1640
1641 /*
1642 * A resjunk column of the subquery can be reflected as
1643 * resjunk in the physical tlist; we need not punt.
1644 */
1645 var = makeVarFromTargetEntry(varno, tle);
1646
1647 tlist = lappend(tlist,
1648 makeTargetEntry((Expr *) var,
1649 tle->resno,
1650 NULL,
1651 tle->resjunk));
1652 }
1653 break;
1654
1655 case RTE_FUNCTION:
1656 case RTE_TABLEFUNC:
1657 case RTE_VALUES:
1658 case RTE_CTE:
1659 case RTE_NAMEDTUPLESTORE:
1660 case RTE_RESULT:
1661 /* Not all of these can have dropped cols, but share code anyway */
1662 expandRTE(rte, varno, 0, -1, true /* include dropped */ ,
1663 NULL, &colvars);
1664 foreach(l, colvars)
1665 {
1666 var = (Var *) lfirst(l);
1667
1668 /*
1669 * A non-Var in expandRTE's output means a dropped column;
1670 * must punt.
1671 */
1672 if (!IsA(var, Var))
1673 {
1674 tlist = NIL;
1675 break;
1676 }
1677
1678 tlist = lappend(tlist,
1679 makeTargetEntry((Expr *) var,
1680 var->varattno,
1681 NULL,
1682 false));
1683 }
1684 break;
1685
1686 default:
1687 /* caller error */
1688 elog(ERROR, "unsupported RTE kind %d in build_physical_tlist",
1689 (int) rte->rtekind);
1690 break;
1691 }
1692
1693 return tlist;
1694 }
1695
1696 /*
1697 * build_index_tlist
1698 *
1699 * Build a targetlist representing the columns of the specified index.
1700 * Each column is represented by a Var for the corresponding base-relation
1701 * column, or an expression in base-relation Vars, as appropriate.
1702 *
1703 * There are never any dropped columns in indexes, so unlike
1704 * build_physical_tlist, we need no failure case.
1705 */
1706 static List *
build_index_tlist(PlannerInfo * root,IndexOptInfo * index,Relation heapRelation)1707 build_index_tlist(PlannerInfo *root, IndexOptInfo *index,
1708 Relation heapRelation)
1709 {
1710 List *tlist = NIL;
1711 Index varno = index->rel->relid;
1712 ListCell *indexpr_item;
1713 int i;
1714
1715 indexpr_item = list_head(index->indexprs);
1716 for (i = 0; i < index->ncolumns; i++)
1717 {
1718 int indexkey = index->indexkeys[i];
1719 Expr *indexvar;
1720
1721 if (indexkey != 0)
1722 {
1723 /* simple column */
1724 const FormData_pg_attribute *att_tup;
1725
1726 if (indexkey < 0)
1727 att_tup = SystemAttributeDefinition(indexkey);
1728 else
1729 att_tup = TupleDescAttr(heapRelation->rd_att, indexkey - 1);
1730
1731 indexvar = (Expr *) makeVar(varno,
1732 indexkey,
1733 att_tup->atttypid,
1734 att_tup->atttypmod,
1735 att_tup->attcollation,
1736 0);
1737 }
1738 else
1739 {
1740 /* expression column */
1741 if (indexpr_item == NULL)
1742 elog(ERROR, "wrong number of index expressions");
1743 indexvar = (Expr *) lfirst(indexpr_item);
1744 indexpr_item = lnext(index->indexprs, indexpr_item);
1745 }
1746
1747 tlist = lappend(tlist,
1748 makeTargetEntry(indexvar,
1749 i + 1,
1750 NULL,
1751 false));
1752 }
1753 if (indexpr_item != NULL)
1754 elog(ERROR, "wrong number of index expressions");
1755
1756 return tlist;
1757 }
1758
1759 /*
1760 * restriction_selectivity
1761 *
1762 * Returns the selectivity of a specified restriction operator clause.
1763 * This code executes registered procedures stored in the
1764 * operator relation, by calling the function manager.
1765 *
1766 * See clause_selectivity() for the meaning of the additional parameters.
1767 */
1768 Selectivity
restriction_selectivity(PlannerInfo * root,Oid operatorid,List * args,Oid inputcollid,int varRelid)1769 restriction_selectivity(PlannerInfo *root,
1770 Oid operatorid,
1771 List *args,
1772 Oid inputcollid,
1773 int varRelid)
1774 {
1775 RegProcedure oprrest = get_oprrest(operatorid);
1776 float8 result;
1777
1778 /*
1779 * if the oprrest procedure is missing for whatever reason, use a
1780 * selectivity of 0.5
1781 */
1782 if (!oprrest)
1783 return (Selectivity) 0.5;
1784
1785 result = DatumGetFloat8(OidFunctionCall4Coll(oprrest,
1786 inputcollid,
1787 PointerGetDatum(root),
1788 ObjectIdGetDatum(operatorid),
1789 PointerGetDatum(args),
1790 Int32GetDatum(varRelid)));
1791
1792 if (result < 0.0 || result > 1.0)
1793 elog(ERROR, "invalid restriction selectivity: %f", result);
1794
1795 return (Selectivity) result;
1796 }
1797
1798 /*
1799 * join_selectivity
1800 *
1801 * Returns the selectivity of a specified join operator clause.
1802 * This code executes registered procedures stored in the
1803 * operator relation, by calling the function manager.
1804 *
1805 * See clause_selectivity() for the meaning of the additional parameters.
1806 */
1807 Selectivity
join_selectivity(PlannerInfo * root,Oid operatorid,List * args,Oid inputcollid,JoinType jointype,SpecialJoinInfo * sjinfo)1808 join_selectivity(PlannerInfo *root,
1809 Oid operatorid,
1810 List *args,
1811 Oid inputcollid,
1812 JoinType jointype,
1813 SpecialJoinInfo *sjinfo)
1814 {
1815 RegProcedure oprjoin = get_oprjoin(operatorid);
1816 float8 result;
1817
1818 /*
1819 * if the oprjoin procedure is missing for whatever reason, use a
1820 * selectivity of 0.5
1821 */
1822 if (!oprjoin)
1823 return (Selectivity) 0.5;
1824
1825 result = DatumGetFloat8(OidFunctionCall5Coll(oprjoin,
1826 inputcollid,
1827 PointerGetDatum(root),
1828 ObjectIdGetDatum(operatorid),
1829 PointerGetDatum(args),
1830 Int16GetDatum(jointype),
1831 PointerGetDatum(sjinfo)));
1832
1833 if (result < 0.0 || result > 1.0)
1834 elog(ERROR, "invalid join selectivity: %f", result);
1835
1836 return (Selectivity) result;
1837 }
1838
1839 /*
1840 * function_selectivity
1841 *
1842 * Returns the selectivity of a specified boolean function clause.
1843 * This code executes registered procedures stored in the
1844 * pg_proc relation, by calling the function manager.
1845 *
1846 * See clause_selectivity() for the meaning of the additional parameters.
1847 */
1848 Selectivity
function_selectivity(PlannerInfo * root,Oid funcid,List * args,Oid inputcollid,bool is_join,int varRelid,JoinType jointype,SpecialJoinInfo * sjinfo)1849 function_selectivity(PlannerInfo *root,
1850 Oid funcid,
1851 List *args,
1852 Oid inputcollid,
1853 bool is_join,
1854 int varRelid,
1855 JoinType jointype,
1856 SpecialJoinInfo *sjinfo)
1857 {
1858 RegProcedure prosupport = get_func_support(funcid);
1859 SupportRequestSelectivity req;
1860 SupportRequestSelectivity *sresult;
1861
1862 /*
1863 * If no support function is provided, use our historical default
1864 * estimate, 0.3333333. This seems a pretty unprincipled choice, but
1865 * Postgres has been using that estimate for function calls since 1992.
1866 * The hoariness of this behavior suggests that we should not be in too
1867 * much hurry to use another value.
1868 */
1869 if (!prosupport)
1870 return (Selectivity) 0.3333333;
1871
1872 req.type = T_SupportRequestSelectivity;
1873 req.root = root;
1874 req.funcid = funcid;
1875 req.args = args;
1876 req.inputcollid = inputcollid;
1877 req.is_join = is_join;
1878 req.varRelid = varRelid;
1879 req.jointype = jointype;
1880 req.sjinfo = sjinfo;
1881 req.selectivity = -1; /* to catch failure to set the value */
1882
1883 sresult = (SupportRequestSelectivity *)
1884 DatumGetPointer(OidFunctionCall1(prosupport,
1885 PointerGetDatum(&req)));
1886
1887 /* If support function fails, use default */
1888 if (sresult != &req)
1889 return (Selectivity) 0.3333333;
1890
1891 if (req.selectivity < 0.0 || req.selectivity > 1.0)
1892 elog(ERROR, "invalid function selectivity: %f", req.selectivity);
1893
1894 return (Selectivity) req.selectivity;
1895 }
1896
1897 /*
1898 * add_function_cost
1899 *
1900 * Get an estimate of the execution cost of a function, and *add* it to
1901 * the contents of *cost. The estimate may include both one-time and
1902 * per-tuple components, since QualCost does.
1903 *
1904 * The funcid must always be supplied. If it is being called as the
1905 * implementation of a specific parsetree node (FuncExpr, OpExpr,
1906 * WindowFunc, etc), pass that as "node", else pass NULL.
1907 *
1908 * In some usages root might be NULL, too.
1909 */
1910 void
add_function_cost(PlannerInfo * root,Oid funcid,Node * node,QualCost * cost)1911 add_function_cost(PlannerInfo *root, Oid funcid, Node *node,
1912 QualCost *cost)
1913 {
1914 HeapTuple proctup;
1915 Form_pg_proc procform;
1916
1917 proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1918 if (!HeapTupleIsValid(proctup))
1919 elog(ERROR, "cache lookup failed for function %u", funcid);
1920 procform = (Form_pg_proc) GETSTRUCT(proctup);
1921
1922 if (OidIsValid(procform->prosupport))
1923 {
1924 SupportRequestCost req;
1925 SupportRequestCost *sresult;
1926
1927 req.type = T_SupportRequestCost;
1928 req.root = root;
1929 req.funcid = funcid;
1930 req.node = node;
1931
1932 /* Initialize cost fields so that support function doesn't have to */
1933 req.startup = 0;
1934 req.per_tuple = 0;
1935
1936 sresult = (SupportRequestCost *)
1937 DatumGetPointer(OidFunctionCall1(procform->prosupport,
1938 PointerGetDatum(&req)));
1939
1940 if (sresult == &req)
1941 {
1942 /* Success, so accumulate support function's estimate into *cost */
1943 cost->startup += req.startup;
1944 cost->per_tuple += req.per_tuple;
1945 ReleaseSysCache(proctup);
1946 return;
1947 }
1948 }
1949
1950 /* No support function, or it failed, so rely on procost */
1951 cost->per_tuple += procform->procost * cpu_operator_cost;
1952
1953 ReleaseSysCache(proctup);
1954 }
1955
1956 /*
1957 * get_function_rows
1958 *
1959 * Get an estimate of the number of rows returned by a set-returning function.
1960 *
1961 * The funcid must always be supplied. In current usage, the calling node
1962 * will always be supplied, and will be either a FuncExpr or OpExpr.
1963 * But it's a good idea to not fail if it's NULL.
1964 *
1965 * In some usages root might be NULL, too.
1966 *
1967 * Note: this returns the unfiltered result of the support function, if any.
1968 * It's usually a good idea to apply clamp_row_est() to the result, but we
1969 * leave it to the caller to do so.
1970 */
1971 double
get_function_rows(PlannerInfo * root,Oid funcid,Node * node)1972 get_function_rows(PlannerInfo *root, Oid funcid, Node *node)
1973 {
1974 HeapTuple proctup;
1975 Form_pg_proc procform;
1976 double result;
1977
1978 proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1979 if (!HeapTupleIsValid(proctup))
1980 elog(ERROR, "cache lookup failed for function %u", funcid);
1981 procform = (Form_pg_proc) GETSTRUCT(proctup);
1982
1983 Assert(procform->proretset); /* else caller error */
1984
1985 if (OidIsValid(procform->prosupport))
1986 {
1987 SupportRequestRows req;
1988 SupportRequestRows *sresult;
1989
1990 req.type = T_SupportRequestRows;
1991 req.root = root;
1992 req.funcid = funcid;
1993 req.node = node;
1994
1995 req.rows = 0; /* just for sanity */
1996
1997 sresult = (SupportRequestRows *)
1998 DatumGetPointer(OidFunctionCall1(procform->prosupport,
1999 PointerGetDatum(&req)));
2000
2001 if (sresult == &req)
2002 {
2003 /* Success */
2004 ReleaseSysCache(proctup);
2005 return req.rows;
2006 }
2007 }
2008
2009 /* No support function, or it failed, so rely on prorows */
2010 result = procform->prorows;
2011
2012 ReleaseSysCache(proctup);
2013
2014 return result;
2015 }
2016
2017 /*
2018 * has_unique_index
2019 *
2020 * Detect whether there is a unique index on the specified attribute
2021 * of the specified relation, thus allowing us to conclude that all
2022 * the (non-null) values of the attribute are distinct.
2023 *
2024 * This function does not check the index's indimmediate property, which
2025 * means that uniqueness may transiently fail to hold intra-transaction.
2026 * That's appropriate when we are making statistical estimates, but beware
2027 * of using this for any correctness proofs.
2028 */
2029 bool
has_unique_index(RelOptInfo * rel,AttrNumber attno)2030 has_unique_index(RelOptInfo *rel, AttrNumber attno)
2031 {
2032 ListCell *ilist;
2033
2034 foreach(ilist, rel->indexlist)
2035 {
2036 IndexOptInfo *index = (IndexOptInfo *) lfirst(ilist);
2037
2038 /*
2039 * Note: ignore partial indexes, since they don't allow us to conclude
2040 * that all attr values are distinct, *unless* they are marked predOK
2041 * which means we know the index's predicate is satisfied by the
2042 * query. We don't take any interest in expressional indexes either.
2043 * Also, a multicolumn unique index doesn't allow us to conclude that
2044 * just the specified attr is unique.
2045 */
2046 if (index->unique &&
2047 index->nkeycolumns == 1 &&
2048 index->indexkeys[0] == attno &&
2049 (index->indpred == NIL || index->predOK))
2050 return true;
2051 }
2052 return false;
2053 }
2054
2055
2056 /*
2057 * has_row_triggers
2058 *
2059 * Detect whether the specified relation has any row-level triggers for event.
2060 */
2061 bool
has_row_triggers(PlannerInfo * root,Index rti,CmdType event)2062 has_row_triggers(PlannerInfo *root, Index rti, CmdType event)
2063 {
2064 RangeTblEntry *rte = planner_rt_fetch(rti, root);
2065 Relation relation;
2066 TriggerDesc *trigDesc;
2067 bool result = false;
2068
2069 /* Assume we already have adequate lock */
2070 relation = table_open(rte->relid, NoLock);
2071
2072 trigDesc = relation->trigdesc;
2073 switch (event)
2074 {
2075 case CMD_INSERT:
2076 if (trigDesc &&
2077 (trigDesc->trig_insert_after_row ||
2078 trigDesc->trig_insert_before_row))
2079 result = true;
2080 break;
2081 case CMD_UPDATE:
2082 if (trigDesc &&
2083 (trigDesc->trig_update_after_row ||
2084 trigDesc->trig_update_before_row))
2085 result = true;
2086 break;
2087 case CMD_DELETE:
2088 if (trigDesc &&
2089 (trigDesc->trig_delete_after_row ||
2090 trigDesc->trig_delete_before_row))
2091 result = true;
2092 break;
2093 default:
2094 elog(ERROR, "unrecognized CmdType: %d", (int) event);
2095 break;
2096 }
2097
2098 table_close(relation, NoLock);
2099 return result;
2100 }
2101
2102 bool
has_stored_generated_columns(PlannerInfo * root,Index rti)2103 has_stored_generated_columns(PlannerInfo *root, Index rti)
2104 {
2105 RangeTblEntry *rte = planner_rt_fetch(rti, root);
2106 Relation relation;
2107 TupleDesc tupdesc;
2108 bool result = false;
2109
2110 /* Assume we already have adequate lock */
2111 relation = table_open(rte->relid, NoLock);
2112
2113 tupdesc = RelationGetDescr(relation);
2114 result = tupdesc->constr && tupdesc->constr->has_generated_stored;
2115
2116 table_close(relation, NoLock);
2117
2118 return result;
2119 }
2120
2121 /*
2122 * set_relation_partition_info
2123 *
2124 * Set partitioning scheme and related information for a partitioned table.
2125 */
2126 static void
set_relation_partition_info(PlannerInfo * root,RelOptInfo * rel,Relation relation)2127 set_relation_partition_info(PlannerInfo *root, RelOptInfo *rel,
2128 Relation relation)
2129 {
2130 PartitionDesc partdesc;
2131
2132 /* Create the PartitionDirectory infrastructure if we didn't already */
2133 if (root->glob->partition_directory == NULL)
2134 root->glob->partition_directory =
2135 CreatePartitionDirectory(CurrentMemoryContext);
2136
2137 partdesc = PartitionDirectoryLookup(root->glob->partition_directory,
2138 relation);
2139 rel->part_scheme = find_partition_scheme(root, relation);
2140 Assert(partdesc != NULL && rel->part_scheme != NULL);
2141 rel->boundinfo = partdesc->boundinfo;
2142 rel->nparts = partdesc->nparts;
2143 set_baserel_partition_key_exprs(relation, rel);
2144 set_baserel_partition_constraint(relation, rel);
2145 }
2146
2147 /*
2148 * find_partition_scheme
2149 *
2150 * Find or create a PartitionScheme for this Relation.
2151 */
2152 static PartitionScheme
find_partition_scheme(PlannerInfo * root,Relation relation)2153 find_partition_scheme(PlannerInfo *root, Relation relation)
2154 {
2155 PartitionKey partkey = RelationGetPartitionKey(relation);
2156 ListCell *lc;
2157 int partnatts,
2158 i;
2159 PartitionScheme part_scheme;
2160
2161 /* A partitioned table should have a partition key. */
2162 Assert(partkey != NULL);
2163
2164 partnatts = partkey->partnatts;
2165
2166 /* Search for a matching partition scheme and return if found one. */
2167 foreach(lc, root->part_schemes)
2168 {
2169 part_scheme = lfirst(lc);
2170
2171 /* Match partitioning strategy and number of keys. */
2172 if (partkey->strategy != part_scheme->strategy ||
2173 partnatts != part_scheme->partnatts)
2174 continue;
2175
2176 /* Match partition key type properties. */
2177 if (memcmp(partkey->partopfamily, part_scheme->partopfamily,
2178 sizeof(Oid) * partnatts) != 0 ||
2179 memcmp(partkey->partopcintype, part_scheme->partopcintype,
2180 sizeof(Oid) * partnatts) != 0 ||
2181 memcmp(partkey->partcollation, part_scheme->partcollation,
2182 sizeof(Oid) * partnatts) != 0)
2183 continue;
2184
2185 /*
2186 * Length and byval information should match when partopcintype
2187 * matches.
2188 */
2189 Assert(memcmp(partkey->parttyplen, part_scheme->parttyplen,
2190 sizeof(int16) * partnatts) == 0);
2191 Assert(memcmp(partkey->parttypbyval, part_scheme->parttypbyval,
2192 sizeof(bool) * partnatts) == 0);
2193
2194 /*
2195 * If partopfamily and partopcintype matched, must have the same
2196 * partition comparison functions. Note that we cannot reliably
2197 * Assert the equality of function structs themselves for they might
2198 * be different across PartitionKey's, so just Assert for the function
2199 * OIDs.
2200 */
2201 #ifdef USE_ASSERT_CHECKING
2202 for (i = 0; i < partkey->partnatts; i++)
2203 Assert(partkey->partsupfunc[i].fn_oid ==
2204 part_scheme->partsupfunc[i].fn_oid);
2205 #endif
2206
2207 /* Found matching partition scheme. */
2208 return part_scheme;
2209 }
2210
2211 /*
2212 * Did not find matching partition scheme. Create one copying relevant
2213 * information from the relcache. We need to copy the contents of the
2214 * array since the relcache entry may not survive after we have closed the
2215 * relation.
2216 */
2217 part_scheme = (PartitionScheme) palloc0(sizeof(PartitionSchemeData));
2218 part_scheme->strategy = partkey->strategy;
2219 part_scheme->partnatts = partkey->partnatts;
2220
2221 part_scheme->partopfamily = (Oid *) palloc(sizeof(Oid) * partnatts);
2222 memcpy(part_scheme->partopfamily, partkey->partopfamily,
2223 sizeof(Oid) * partnatts);
2224
2225 part_scheme->partopcintype = (Oid *) palloc(sizeof(Oid) * partnatts);
2226 memcpy(part_scheme->partopcintype, partkey->partopcintype,
2227 sizeof(Oid) * partnatts);
2228
2229 part_scheme->partcollation = (Oid *) palloc(sizeof(Oid) * partnatts);
2230 memcpy(part_scheme->partcollation, partkey->partcollation,
2231 sizeof(Oid) * partnatts);
2232
2233 part_scheme->parttyplen = (int16 *) palloc(sizeof(int16) * partnatts);
2234 memcpy(part_scheme->parttyplen, partkey->parttyplen,
2235 sizeof(int16) * partnatts);
2236
2237 part_scheme->parttypbyval = (bool *) palloc(sizeof(bool) * partnatts);
2238 memcpy(part_scheme->parttypbyval, partkey->parttypbyval,
2239 sizeof(bool) * partnatts);
2240
2241 part_scheme->partsupfunc = (FmgrInfo *)
2242 palloc(sizeof(FmgrInfo) * partnatts);
2243 for (i = 0; i < partnatts; i++)
2244 fmgr_info_copy(&part_scheme->partsupfunc[i], &partkey->partsupfunc[i],
2245 CurrentMemoryContext);
2246
2247 /* Add the partitioning scheme to PlannerInfo. */
2248 root->part_schemes = lappend(root->part_schemes, part_scheme);
2249
2250 return part_scheme;
2251 }
2252
2253 /*
2254 * set_baserel_partition_key_exprs
2255 *
2256 * Builds partition key expressions for the given base relation and fills
2257 * rel->partexprs.
2258 */
2259 static void
set_baserel_partition_key_exprs(Relation relation,RelOptInfo * rel)2260 set_baserel_partition_key_exprs(Relation relation,
2261 RelOptInfo *rel)
2262 {
2263 PartitionKey partkey = RelationGetPartitionKey(relation);
2264 int partnatts;
2265 int cnt;
2266 List **partexprs;
2267 ListCell *lc;
2268 Index varno = rel->relid;
2269
2270 Assert(IS_SIMPLE_REL(rel) && rel->relid > 0);
2271
2272 /* A partitioned table should have a partition key. */
2273 Assert(partkey != NULL);
2274
2275 partnatts = partkey->partnatts;
2276 partexprs = (List **) palloc(sizeof(List *) * partnatts);
2277 lc = list_head(partkey->partexprs);
2278
2279 for (cnt = 0; cnt < partnatts; cnt++)
2280 {
2281 Expr *partexpr;
2282 AttrNumber attno = partkey->partattrs[cnt];
2283
2284 if (attno != InvalidAttrNumber)
2285 {
2286 /* Single column partition key is stored as a Var node. */
2287 Assert(attno > 0);
2288
2289 partexpr = (Expr *) makeVar(varno, attno,
2290 partkey->parttypid[cnt],
2291 partkey->parttypmod[cnt],
2292 partkey->parttypcoll[cnt], 0);
2293 }
2294 else
2295 {
2296 if (lc == NULL)
2297 elog(ERROR, "wrong number of partition key expressions");
2298
2299 /* Re-stamp the expression with given varno. */
2300 partexpr = (Expr *) copyObject(lfirst(lc));
2301 ChangeVarNodes((Node *) partexpr, 1, varno, 0);
2302 lc = lnext(partkey->partexprs, lc);
2303 }
2304
2305 /* Base relations have a single expression per key. */
2306 partexprs[cnt] = list_make1(partexpr);
2307 }
2308
2309 rel->partexprs = partexprs;
2310
2311 /*
2312 * A base relation does not have nullable partition key expressions, since
2313 * no outer join is involved. We still allocate an array of empty
2314 * expression lists to keep partition key expression handling code simple.
2315 * See build_joinrel_partition_info() and match_expr_to_partition_keys().
2316 */
2317 rel->nullable_partexprs = (List **) palloc0(sizeof(List *) * partnatts);
2318 }
2319
2320 /*
2321 * set_baserel_partition_constraint
2322 *
2323 * Builds the partition constraint for the given base relation and sets it
2324 * in the given RelOptInfo. All Var nodes are restamped with the relid of the
2325 * given relation.
2326 */
2327 static void
set_baserel_partition_constraint(Relation relation,RelOptInfo * rel)2328 set_baserel_partition_constraint(Relation relation, RelOptInfo *rel)
2329 {
2330 List *partconstr;
2331
2332 if (rel->partition_qual) /* already done */
2333 return;
2334
2335 /*
2336 * Run the partition quals through const-simplification similar to check
2337 * constraints. We skip canonicalize_qual, though, because partition
2338 * quals should be in canonical form already; also, since the qual is in
2339 * implicit-AND format, we'd have to explicitly convert it to explicit-AND
2340 * format and back again.
2341 */
2342 partconstr = RelationGetPartitionQual(relation);
2343 if (partconstr)
2344 {
2345 partconstr = (List *) expression_planner((Expr *) partconstr);
2346 if (rel->relid != 1)
2347 ChangeVarNodes((Node *) partconstr, 1, rel->relid, 0);
2348 rel->partition_qual = partconstr;
2349 }
2350 }
2351