1 /*-------------------------------------------------------------------------
2 *
3 * plancat.c
4 * routines for accessing the system catalogs
5 *
6 *
7 * Portions Copyright (c) 1996-2017, 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/heapam.h"
22 #include "access/htup_details.h"
23 #include "access/nbtree.h"
24 #include "access/sysattr.h"
25 #include "access/transam.h"
26 #include "access/xlog.h"
27 #include "catalog/catalog.h"
28 #include "catalog/dependency.h"
29 #include "catalog/heap.h"
30 #include "catalog/partition.h"
31 #include "catalog/pg_am.h"
32 #include "catalog/pg_statistic_ext.h"
33 #include "foreign/fdwapi.h"
34 #include "miscadmin.h"
35 #include "nodes/makefuncs.h"
36 #include "optimizer/clauses.h"
37 #include "optimizer/cost.h"
38 #include "optimizer/plancat.h"
39 #include "optimizer/predtest.h"
40 #include "optimizer/prep.h"
41 #include "parser/parse_relation.h"
42 #include "parser/parsetree.h"
43 #include "rewrite/rewriteManip.h"
44 #include "statistics/statistics.h"
45 #include "storage/bufmgr.h"
46 #include "utils/builtins.h"
47 #include "utils/lsyscache.h"
48 #include "utils/syscache.h"
49 #include "utils/rel.h"
50 #include "utils/snapmgr.h"
51
52
53 /* GUC parameter */
54 int constraint_exclusion = CONSTRAINT_EXCLUSION_PARTITION;
55
56 /* Hook for plugins to get control in get_relation_info() */
57 get_relation_info_hook_type get_relation_info_hook = NULL;
58
59
60 static void get_relation_foreign_keys(PlannerInfo *root, RelOptInfo *rel,
61 Relation relation, bool inhparent);
62 static bool infer_collation_opclass_match(InferenceElem *elem, Relation idxRel,
63 List *idxExprs);
64 static int32 get_rel_data_width(Relation rel, int32 *attr_widths);
65 static List *get_relation_constraints(PlannerInfo *root,
66 Oid relationObjectId, RelOptInfo *rel,
67 bool include_notnull);
68 static List *build_index_tlist(PlannerInfo *root, IndexOptInfo *index,
69 Relation heapRelation);
70 static List *get_relation_statistics(RelOptInfo *rel, Relation relation);
71
72 /*
73 * get_relation_info -
74 * Retrieves catalog information for a given relation.
75 *
76 * Given the Oid of the relation, return the following info into fields
77 * of the RelOptInfo struct:
78 *
79 * min_attr lowest valid AttrNumber
80 * max_attr highest valid AttrNumber
81 * indexlist list of IndexOptInfos for relation's indexes
82 * statlist list of StatisticExtInfo for relation's statistic objects
83 * serverid if it's a foreign table, the server OID
84 * fdwroutine if it's a foreign table, the FDW function pointers
85 * pages number of pages
86 * tuples number of tuples
87 * rel_parallel_workers user-defined number of parallel workers
88 *
89 * Also, add information about the relation's foreign keys to root->fkey_list.
90 *
91 * Also, initialize the attr_needed[] and attr_widths[] arrays. In most
92 * cases these are left as zeroes, but sometimes we need to compute attr
93 * widths here, and we may as well cache the results for costsize.c.
94 *
95 * If inhparent is true, all we need to do is set up the attr arrays:
96 * the RelOptInfo actually represents the appendrel formed by an inheritance
97 * tree, and so the parent rel's physical size and index information isn't
98 * important for it.
99 */
100 void
get_relation_info(PlannerInfo * root,Oid relationObjectId,bool inhparent,RelOptInfo * rel)101 get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
102 RelOptInfo *rel)
103 {
104 Index varno = rel->relid;
105 Relation relation;
106 bool hasindex;
107 List *indexinfos = NIL;
108
109 /*
110 * We need not lock the relation since it was already locked, either by
111 * the rewriter or when expand_inherited_rtentry() added it to the query's
112 * rangetable.
113 */
114 relation = heap_open(relationObjectId, NoLock);
115
116 /* Temporary and unlogged relations are inaccessible during recovery. */
117 if (!RelationNeedsWAL(relation) && RecoveryInProgress())
118 ereport(ERROR,
119 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
120 errmsg("cannot access temporary or unlogged relations during recovery")));
121
122 rel->min_attr = FirstLowInvalidHeapAttributeNumber + 1;
123 rel->max_attr = RelationGetNumberOfAttributes(relation);
124 rel->reltablespace = RelationGetForm(relation)->reltablespace;
125
126 Assert(rel->max_attr >= rel->min_attr);
127 rel->attr_needed = (Relids *)
128 palloc0((rel->max_attr - rel->min_attr + 1) * sizeof(Relids));
129 rel->attr_widths = (int32 *)
130 palloc0((rel->max_attr - rel->min_attr + 1) * sizeof(int32));
131
132 /*
133 * Estimate relation size --- unless it's an inheritance parent, in which
134 * case the size will be computed later in set_append_rel_pathlist, and we
135 * must leave it zero for now to avoid bollixing the total_table_pages
136 * calculation.
137 */
138 if (!inhparent)
139 estimate_rel_size(relation, rel->attr_widths - rel->min_attr,
140 &rel->pages, &rel->tuples, &rel->allvisfrac);
141
142 /* Retrieve the parallel_workers reloption, or -1 if not set. */
143 rel->rel_parallel_workers = RelationGetParallelWorkers(relation, -1);
144
145 /*
146 * Make list of indexes. Ignore indexes on system catalogs if told to.
147 * Don't bother with indexes for an inheritance parent, either.
148 */
149 if (inhparent ||
150 (IgnoreSystemIndexes && IsSystemRelation(relation)))
151 hasindex = false;
152 else
153 hasindex = relation->rd_rel->relhasindex;
154
155 if (hasindex)
156 {
157 List *indexoidlist;
158 ListCell *l;
159 LOCKMODE lmode;
160
161 indexoidlist = RelationGetIndexList(relation);
162
163 /*
164 * For each index, we get the same type of lock that the executor will
165 * need, and do not release it. This saves a couple of trips to the
166 * shared lock manager while not creating any real loss of
167 * concurrency, because no schema changes could be happening on the
168 * index while we hold lock on the parent rel, and neither lock type
169 * blocks any other kind of index operation.
170 */
171 if (rel->relid == root->parse->resultRelation)
172 lmode = RowExclusiveLock;
173 else
174 lmode = AccessShareLock;
175
176 foreach(l, indexoidlist)
177 {
178 Oid indexoid = lfirst_oid(l);
179 Relation indexRelation;
180 Form_pg_index index;
181 IndexAmRoutine *amroutine;
182 IndexOptInfo *info;
183 int ncolumns;
184 int i;
185
186 /*
187 * Extract info from the relation descriptor for the index.
188 */
189 indexRelation = index_open(indexoid, lmode);
190 index = indexRelation->rd_index;
191
192 /*
193 * Ignore invalid indexes, since they can't safely be used for
194 * queries. Note that this is OK because the data structure we
195 * are constructing is only used by the planner --- the executor
196 * still needs to insert into "invalid" indexes, if they're marked
197 * IndexIsReady.
198 */
199 if (!IndexIsValid(index))
200 {
201 index_close(indexRelation, NoLock);
202 continue;
203 }
204
205 /*
206 * If the index is valid, but cannot yet be used, ignore it; but
207 * mark the plan we are generating as transient. See
208 * src/backend/access/heap/README.HOT for discussion.
209 */
210 if (index->indcheckxmin &&
211 !TransactionIdPrecedes(HeapTupleHeaderGetXmin(indexRelation->rd_indextuple->t_data),
212 TransactionXmin))
213 {
214 root->glob->transientPlan = true;
215 index_close(indexRelation, NoLock);
216 continue;
217 }
218
219 info = makeNode(IndexOptInfo);
220
221 info->indexoid = index->indexrelid;
222 info->reltablespace =
223 RelationGetForm(indexRelation)->reltablespace;
224 info->rel = rel;
225 info->ncolumns = ncolumns = index->indnatts;
226 info->indexkeys = (int *) palloc(sizeof(int) * ncolumns);
227 info->indexcollations = (Oid *) palloc(sizeof(Oid) * ncolumns);
228 info->opfamily = (Oid *) palloc(sizeof(Oid) * ncolumns);
229 info->opcintype = (Oid *) palloc(sizeof(Oid) * ncolumns);
230 info->canreturn = (bool *) palloc(sizeof(bool) * ncolumns);
231
232 for (i = 0; i < ncolumns; i++)
233 {
234 info->indexkeys[i] = index->indkey.values[i];
235 info->indexcollations[i] = indexRelation->rd_indcollation[i];
236 info->opfamily[i] = indexRelation->rd_opfamily[i];
237 info->opcintype[i] = indexRelation->rd_opcintype[i];
238 info->canreturn[i] = index_can_return(indexRelation, i + 1);
239 }
240
241 info->relam = indexRelation->rd_rel->relam;
242
243 /* We copy just the fields we need, not all of rd_amroutine */
244 amroutine = indexRelation->rd_amroutine;
245 info->amcanorderbyop = amroutine->amcanorderbyop;
246 info->amoptionalkey = amroutine->amoptionalkey;
247 info->amsearcharray = amroutine->amsearcharray;
248 info->amsearchnulls = amroutine->amsearchnulls;
249 info->amcanparallel = amroutine->amcanparallel;
250 info->amhasgettuple = (amroutine->amgettuple != NULL);
251 info->amhasgetbitmap = (amroutine->amgetbitmap != NULL);
252 info->amcanmarkpos = (amroutine->ammarkpos != NULL &&
253 amroutine->amrestrpos != NULL);
254 info->amcostestimate = amroutine->amcostestimate;
255 Assert(info->amcostestimate != NULL);
256
257 /*
258 * Fetch the ordering information for the index, if any.
259 */
260 if (info->relam == BTREE_AM_OID)
261 {
262 /*
263 * If it's a btree index, we can use its opfamily OIDs
264 * directly as the sort ordering opfamily OIDs.
265 */
266 Assert(amroutine->amcanorder);
267
268 info->sortopfamily = info->opfamily;
269 info->reverse_sort = (bool *) palloc(sizeof(bool) * ncolumns);
270 info->nulls_first = (bool *) palloc(sizeof(bool) * ncolumns);
271
272 for (i = 0; i < ncolumns; i++)
273 {
274 int16 opt = indexRelation->rd_indoption[i];
275
276 info->reverse_sort[i] = (opt & INDOPTION_DESC) != 0;
277 info->nulls_first[i] = (opt & INDOPTION_NULLS_FIRST) != 0;
278 }
279 }
280 else if (amroutine->amcanorder)
281 {
282 /*
283 * Otherwise, identify the corresponding btree opfamilies by
284 * trying to map this index's "<" operators into btree. Since
285 * "<" uniquely defines the behavior of a sort order, this is
286 * a sufficient test.
287 *
288 * XXX This method is rather slow and also requires the
289 * undesirable assumption that the other index AM numbers its
290 * strategies the same as btree. It'd be better to have a way
291 * to explicitly declare the corresponding btree opfamily for
292 * each opfamily of the other index type. But given the lack
293 * of current or foreseeable amcanorder index types, it's not
294 * worth expending more effort on now.
295 */
296 info->sortopfamily = (Oid *) palloc(sizeof(Oid) * ncolumns);
297 info->reverse_sort = (bool *) palloc(sizeof(bool) * ncolumns);
298 info->nulls_first = (bool *) palloc(sizeof(bool) * ncolumns);
299
300 for (i = 0; i < ncolumns; i++)
301 {
302 int16 opt = indexRelation->rd_indoption[i];
303 Oid ltopr;
304 Oid btopfamily;
305 Oid btopcintype;
306 int16 btstrategy;
307
308 info->reverse_sort[i] = (opt & INDOPTION_DESC) != 0;
309 info->nulls_first[i] = (opt & INDOPTION_NULLS_FIRST) != 0;
310
311 ltopr = get_opfamily_member(info->opfamily[i],
312 info->opcintype[i],
313 info->opcintype[i],
314 BTLessStrategyNumber);
315 if (OidIsValid(ltopr) &&
316 get_ordering_op_properties(ltopr,
317 &btopfamily,
318 &btopcintype,
319 &btstrategy) &&
320 btopcintype == info->opcintype[i] &&
321 btstrategy == BTLessStrategyNumber)
322 {
323 /* Successful mapping */
324 info->sortopfamily[i] = btopfamily;
325 }
326 else
327 {
328 /* Fail ... quietly treat index as unordered */
329 info->sortopfamily = NULL;
330 info->reverse_sort = NULL;
331 info->nulls_first = NULL;
332 break;
333 }
334 }
335 }
336 else
337 {
338 info->sortopfamily = NULL;
339 info->reverse_sort = NULL;
340 info->nulls_first = NULL;
341 }
342
343 /*
344 * Fetch the index expressions and predicate, if any. We must
345 * modify the copies we obtain from the relcache to have the
346 * correct varno for the parent relation, so that they match up
347 * correctly against qual clauses.
348 */
349 info->indexprs = RelationGetIndexExpressions(indexRelation);
350 info->indpred = RelationGetIndexPredicate(indexRelation);
351 if (info->indexprs && varno != 1)
352 ChangeVarNodes((Node *) info->indexprs, 1, varno, 0);
353 if (info->indpred && varno != 1)
354 ChangeVarNodes((Node *) info->indpred, 1, varno, 0);
355
356 /* Build targetlist using the completed indexprs data */
357 info->indextlist = build_index_tlist(root, info, relation);
358
359 info->indrestrictinfo = NIL; /* set later, in indxpath.c */
360 info->predOK = false; /* set later, in indxpath.c */
361 info->unique = index->indisunique;
362 info->immediate = index->indimmediate;
363 info->hypothetical = false;
364
365 /*
366 * Estimate the index size. If it's not a partial index, we lock
367 * the number-of-tuples estimate to equal the parent table; if it
368 * is partial then we have to use the same methods as we would for
369 * a table, except we can be sure that the index is not larger
370 * than the table.
371 */
372 if (info->indpred == NIL)
373 {
374 info->pages = RelationGetNumberOfBlocks(indexRelation);
375 info->tuples = rel->tuples;
376 }
377 else
378 {
379 double allvisfrac; /* dummy */
380
381 estimate_rel_size(indexRelation, NULL,
382 &info->pages, &info->tuples, &allvisfrac);
383 if (info->tuples > rel->tuples)
384 info->tuples = rel->tuples;
385 }
386
387 if (info->relam == BTREE_AM_OID)
388 {
389 /* For btrees, get tree height while we have the index open */
390 info->tree_height = _bt_getrootheight(indexRelation);
391 }
392 else
393 {
394 /* For other index types, just set it to "unknown" for now */
395 info->tree_height = -1;
396 }
397
398 index_close(indexRelation, NoLock);
399
400 indexinfos = lcons(info, indexinfos);
401 }
402
403 list_free(indexoidlist);
404 }
405
406 rel->indexlist = indexinfos;
407
408 rel->statlist = get_relation_statistics(rel, relation);
409
410 /* Grab foreign-table info using the relcache, while we have it */
411 if (relation->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
412 {
413 rel->serverid = GetForeignServerIdByRelId(RelationGetRelid(relation));
414 rel->fdwroutine = GetFdwRoutineForRelation(relation, true);
415 }
416 else
417 {
418 rel->serverid = InvalidOid;
419 rel->fdwroutine = NULL;
420 }
421
422 /* Collect info about relation's foreign keys, if relevant */
423 get_relation_foreign_keys(root, rel, relation, inhparent);
424
425 heap_close(relation, NoLock);
426
427 /*
428 * Allow a plugin to editorialize on the info we obtained from the
429 * catalogs. Actions might include altering the assumed relation size,
430 * removing an index, or adding a hypothetical index to the indexlist.
431 */
432 if (get_relation_info_hook)
433 (*get_relation_info_hook) (root, relationObjectId, inhparent, rel);
434 }
435
436 /*
437 * get_relation_foreign_keys -
438 * Retrieves foreign key information for a given relation.
439 *
440 * ForeignKeyOptInfos for relevant foreign keys are created and added to
441 * root->fkey_list. We do this now while we have the relcache entry open.
442 * We could sometimes avoid making useless ForeignKeyOptInfos if we waited
443 * until all RelOptInfos have been built, but the cost of re-opening the
444 * relcache entries would probably exceed any savings.
445 */
446 static void
get_relation_foreign_keys(PlannerInfo * root,RelOptInfo * rel,Relation relation,bool inhparent)447 get_relation_foreign_keys(PlannerInfo *root, RelOptInfo *rel,
448 Relation relation, bool inhparent)
449 {
450 List *rtable = root->parse->rtable;
451 List *cachedfkeys;
452 ListCell *lc;
453
454 /*
455 * If it's not a baserel, we don't care about its FKs. Also, if the query
456 * references only a single relation, we can skip the lookup since no FKs
457 * could satisfy the requirements below.
458 */
459 if (rel->reloptkind != RELOPT_BASEREL ||
460 list_length(rtable) < 2)
461 return;
462
463 /*
464 * If it's the parent of an inheritance tree, ignore its FKs. We could
465 * make useful FK-based deductions if we found that all members of the
466 * inheritance tree have equivalent FK constraints, but detecting that
467 * would require code that hasn't been written.
468 */
469 if (inhparent)
470 return;
471
472 /*
473 * Extract data about relation's FKs from the relcache. Note that this
474 * list belongs to the relcache and might disappear in a cache flush, so
475 * we must not do any further catalog access within this function.
476 */
477 cachedfkeys = RelationGetFKeyList(relation);
478
479 /*
480 * Figure out which FKs are of interest for this query, and create
481 * ForeignKeyOptInfos for them. We want only FKs that reference some
482 * other RTE of the current query. In queries containing self-joins,
483 * there might be more than one other RTE for a referenced table, and we
484 * should make a ForeignKeyOptInfo for each occurrence.
485 *
486 * Ideally, we would ignore RTEs that correspond to non-baserels, but it's
487 * too hard to identify those here, so we might end up making some useless
488 * ForeignKeyOptInfos. If so, match_foreign_keys_to_quals() will remove
489 * them again.
490 */
491 foreach(lc, cachedfkeys)
492 {
493 ForeignKeyCacheInfo *cachedfk = (ForeignKeyCacheInfo *) lfirst(lc);
494 Index rti;
495 ListCell *lc2;
496
497 /* conrelid should always be that of the table we're considering */
498 Assert(cachedfk->conrelid == RelationGetRelid(relation));
499
500 /* Scan to find other RTEs matching confrelid */
501 rti = 0;
502 foreach(lc2, rtable)
503 {
504 RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc2);
505 ForeignKeyOptInfo *info;
506
507 rti++;
508 /* Ignore if not the correct table */
509 if (rte->rtekind != RTE_RELATION ||
510 rte->relid != cachedfk->confrelid)
511 continue;
512 /* Ignore if it's an inheritance parent; doesn't really match */
513 if (rte->inh)
514 continue;
515 /* Ignore self-referential FKs; we only care about joins */
516 if (rti == rel->relid)
517 continue;
518
519 /* OK, let's make an entry */
520 info = makeNode(ForeignKeyOptInfo);
521 info->con_relid = rel->relid;
522 info->ref_relid = rti;
523 info->nkeys = cachedfk->nkeys;
524 memcpy(info->conkey, cachedfk->conkey, sizeof(info->conkey));
525 memcpy(info->confkey, cachedfk->confkey, sizeof(info->confkey));
526 memcpy(info->conpfeqop, cachedfk->conpfeqop, sizeof(info->conpfeqop));
527 /* zero out fields to be filled by match_foreign_keys_to_quals */
528 info->nmatched_ec = 0;
529 info->nmatched_rcols = 0;
530 info->nmatched_ri = 0;
531 memset(info->eclass, 0, sizeof(info->eclass));
532 memset(info->rinfos, 0, sizeof(info->rinfos));
533
534 root->fkey_list = lappend(root->fkey_list, info);
535 }
536 }
537 }
538
539 /*
540 * infer_arbiter_indexes -
541 * Determine the unique indexes used to arbitrate speculative insertion.
542 *
543 * Uses user-supplied inference clause expressions and predicate to match a
544 * unique index from those defined and ready on the heap relation (target).
545 * An exact match is required on columns/expressions (although they can appear
546 * in any order). However, the predicate given by the user need only restrict
547 * insertion to a subset of some part of the table covered by some particular
548 * unique index (in particular, a partial unique index) in order to be
549 * inferred.
550 *
551 * The implementation does not consider which B-Tree operator class any
552 * particular available unique index attribute uses, unless one was specified
553 * in the inference specification. The same is true of collations. In
554 * particular, there is no system dependency on the default operator class for
555 * the purposes of inference. If no opclass (or collation) is specified, then
556 * all matching indexes (that may or may not match the default in terms of
557 * each attribute opclass/collation) are used for inference.
558 */
559 List *
infer_arbiter_indexes(PlannerInfo * root)560 infer_arbiter_indexes(PlannerInfo *root)
561 {
562 OnConflictExpr *onconflict = root->parse->onConflict;
563
564 /* Iteration state */
565 Relation relation;
566 Oid relationObjectId;
567 Oid indexOidFromConstraint = InvalidOid;
568 List *indexList;
569 ListCell *l;
570
571 /* Normalized inference attributes and inference expressions: */
572 Bitmapset *inferAttrs = NULL;
573 List *inferElems = NIL;
574
575 /* Results */
576 List *results = NIL;
577
578 /*
579 * Quickly return NIL for ON CONFLICT DO NOTHING without an inference
580 * specification or named constraint. ON CONFLICT DO UPDATE statements
581 * must always provide one or the other (but parser ought to have caught
582 * that already).
583 */
584 if (onconflict->arbiterElems == NIL &&
585 onconflict->constraint == InvalidOid)
586 return NIL;
587
588 /*
589 * We need not lock the relation since it was already locked, either by
590 * the rewriter or when expand_inherited_rtentry() added it to the query's
591 * rangetable.
592 */
593 relationObjectId = rt_fetch(root->parse->resultRelation,
594 root->parse->rtable)->relid;
595
596 relation = heap_open(relationObjectId, NoLock);
597
598 /*
599 * Build normalized/BMS representation of plain indexed attributes, as
600 * well as a separate list of expression items. This simplifies matching
601 * the cataloged definition of indexes.
602 */
603 foreach(l, onconflict->arbiterElems)
604 {
605 InferenceElem *elem = (InferenceElem *) lfirst(l);
606 Var *var;
607 int attno;
608
609 if (!IsA(elem->expr, Var))
610 {
611 /* If not a plain Var, just shove it in inferElems for now */
612 inferElems = lappend(inferElems, elem->expr);
613 continue;
614 }
615
616 var = (Var *) elem->expr;
617 attno = var->varattno;
618
619 if (attno == 0)
620 ereport(ERROR,
621 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
622 errmsg("whole row unique index inference specifications are not supported")));
623
624 inferAttrs = bms_add_member(inferAttrs,
625 attno - FirstLowInvalidHeapAttributeNumber);
626 }
627
628 /*
629 * Lookup named constraint's index. This is not immediately returned
630 * because some additional sanity checks are required.
631 */
632 if (onconflict->constraint != InvalidOid)
633 {
634 indexOidFromConstraint = get_constraint_index(onconflict->constraint);
635
636 if (indexOidFromConstraint == InvalidOid)
637 ereport(ERROR,
638 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
639 errmsg("constraint in ON CONFLICT clause has no associated index")));
640 }
641
642 /*
643 * Using that representation, iterate through the list of indexes on the
644 * target relation to try and find a match
645 */
646 indexList = RelationGetIndexList(relation);
647
648 foreach(l, indexList)
649 {
650 Oid indexoid = lfirst_oid(l);
651 Relation idxRel;
652 Form_pg_index idxForm;
653 Bitmapset *indexedAttrs;
654 List *idxExprs;
655 List *predExprs;
656 AttrNumber natt;
657 ListCell *el;
658
659 /*
660 * Extract info from the relation descriptor for the index. We know
661 * that this is a target, so get lock type it is known will ultimately
662 * be required by the executor.
663 *
664 * Let executor complain about !indimmediate case directly, because
665 * enforcement needs to occur there anyway when an inference clause is
666 * omitted.
667 */
668 idxRel = index_open(indexoid, RowExclusiveLock);
669 idxForm = idxRel->rd_index;
670
671 if (!IndexIsValid(idxForm))
672 goto next;
673
674 /*
675 * Note that we do not perform a check against indcheckxmin (like e.g.
676 * get_relation_info()) here to eliminate candidates, because
677 * uniqueness checking only cares about the most recently committed
678 * tuple versions.
679 */
680
681 /*
682 * Look for match on "ON constraint_name" variant, which may not be
683 * unique constraint. This can only be a constraint name.
684 */
685 if (indexOidFromConstraint == idxForm->indexrelid)
686 {
687 if (!idxForm->indisunique && onconflict->action == ONCONFLICT_UPDATE)
688 ereport(ERROR,
689 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
690 errmsg("ON CONFLICT DO UPDATE not supported with exclusion constraints")));
691
692 results = lappend_oid(results, idxForm->indexrelid);
693 list_free(indexList);
694 index_close(idxRel, NoLock);
695 heap_close(relation, NoLock);
696 return results;
697 }
698 else if (indexOidFromConstraint != InvalidOid)
699 {
700 /* No point in further work for index in named constraint case */
701 goto next;
702 }
703
704 /*
705 * Only considering conventional inference at this point (not named
706 * constraints), so index under consideration can be immediately
707 * skipped if it's not unique
708 */
709 if (!idxForm->indisunique)
710 goto next;
711
712 /* Build BMS representation of plain (non expression) index attrs */
713 indexedAttrs = NULL;
714 for (natt = 0; natt < idxForm->indnatts; natt++)
715 {
716 int attno = idxRel->rd_index->indkey.values[natt];
717
718 if (attno != 0)
719 indexedAttrs = bms_add_member(indexedAttrs,
720 attno - FirstLowInvalidHeapAttributeNumber);
721 }
722
723 /* Non-expression attributes (if any) must match */
724 if (!bms_equal(indexedAttrs, inferAttrs))
725 goto next;
726
727 /* Expression attributes (if any) must match */
728 idxExprs = RelationGetIndexExpressions(idxRel);
729 foreach(el, onconflict->arbiterElems)
730 {
731 InferenceElem *elem = (InferenceElem *) lfirst(el);
732
733 /*
734 * Ensure that collation/opclass aspects of inference expression
735 * element match. Even though this loop is primarily concerned
736 * with matching expressions, it is a convenient point to check
737 * this for both expressions and ordinary (non-expression)
738 * attributes appearing as inference elements.
739 */
740 if (!infer_collation_opclass_match(elem, idxRel, idxExprs))
741 goto next;
742
743 /*
744 * Plain Vars don't factor into count of expression elements, and
745 * the question of whether or not they satisfy the index
746 * definition has already been considered (they must).
747 */
748 if (IsA(elem->expr, Var))
749 continue;
750
751 /*
752 * Might as well avoid redundant check in the rare cases where
753 * infer_collation_opclass_match() is required to do real work.
754 * Otherwise, check that element expression appears in cataloged
755 * index definition.
756 */
757 if (elem->infercollid != InvalidOid ||
758 elem->inferopclass != InvalidOid ||
759 list_member(idxExprs, elem->expr))
760 continue;
761
762 goto next;
763 }
764
765 /*
766 * Now that all inference elements were matched, ensure that the
767 * expression elements from inference clause are not missing any
768 * cataloged expressions. This does the right thing when unique
769 * indexes redundantly repeat the same attribute, or if attributes
770 * redundantly appear multiple times within an inference clause.
771 */
772 if (list_difference(idxExprs, inferElems) != NIL)
773 goto next;
774
775 /*
776 * If it's a partial index, its predicate must be implied by the ON
777 * CONFLICT's WHERE clause.
778 */
779 predExprs = RelationGetIndexPredicate(idxRel);
780
781 if (!predicate_implied_by(predExprs, (List *) onconflict->arbiterWhere, false))
782 goto next;
783
784 results = lappend_oid(results, idxForm->indexrelid);
785 next:
786 index_close(idxRel, NoLock);
787 }
788
789 list_free(indexList);
790 heap_close(relation, NoLock);
791
792 if (results == NIL)
793 ereport(ERROR,
794 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
795 errmsg("there is no unique or exclusion constraint matching the ON CONFLICT specification")));
796
797 return results;
798 }
799
800 /*
801 * infer_collation_opclass_match - ensure infer element opclass/collation match
802 *
803 * Given unique index inference element from inference specification, if
804 * collation was specified, or if opclass was specified, verify that there is
805 * at least one matching indexed attribute (occasionally, there may be more).
806 * Skip this in the common case where inference specification does not include
807 * collation or opclass (instead matching everything, regardless of cataloged
808 * collation/opclass of indexed attribute).
809 *
810 * At least historically, Postgres has not offered collations or opclasses
811 * with alternative-to-default notions of equality, so these additional
812 * criteria should only be required infrequently.
813 *
814 * Don't give up immediately when an inference element matches some attribute
815 * cataloged as indexed but not matching additional opclass/collation
816 * criteria. This is done so that the implementation is as forgiving as
817 * possible of redundancy within cataloged index attributes (or, less
818 * usefully, within inference specification elements). If collations actually
819 * differ between apparently redundantly indexed attributes (redundant within
820 * or across indexes), then there really is no redundancy as such.
821 *
822 * Note that if an inference element specifies an opclass and a collation at
823 * once, both must match in at least one particular attribute within index
824 * catalog definition in order for that inference element to be considered
825 * inferred/satisfied.
826 */
827 static bool
infer_collation_opclass_match(InferenceElem * elem,Relation idxRel,List * idxExprs)828 infer_collation_opclass_match(InferenceElem *elem, Relation idxRel,
829 List *idxExprs)
830 {
831 AttrNumber natt;
832 Oid inferopfamily = InvalidOid; /* OID of opclass opfamily */
833 Oid inferopcinputtype = InvalidOid; /* OID of opclass input type */
834 int nplain = 0; /* # plain attrs observed */
835
836 /*
837 * If inference specification element lacks collation/opclass, then no
838 * need to check for exact match.
839 */
840 if (elem->infercollid == InvalidOid && elem->inferopclass == InvalidOid)
841 return true;
842
843 /*
844 * Lookup opfamily and input type, for matching indexes
845 */
846 if (elem->inferopclass)
847 {
848 inferopfamily = get_opclass_family(elem->inferopclass);
849 inferopcinputtype = get_opclass_input_type(elem->inferopclass);
850 }
851
852 for (natt = 1; natt <= idxRel->rd_att->natts; natt++)
853 {
854 Oid opfamily = idxRel->rd_opfamily[natt - 1];
855 Oid opcinputtype = idxRel->rd_opcintype[natt - 1];
856 Oid collation = idxRel->rd_indcollation[natt - 1];
857 int attno = idxRel->rd_index->indkey.values[natt - 1];
858
859 if (attno != 0)
860 nplain++;
861
862 if (elem->inferopclass != InvalidOid &&
863 (inferopfamily != opfamily || inferopcinputtype != opcinputtype))
864 {
865 /* Attribute needed to match opclass, but didn't */
866 continue;
867 }
868
869 if (elem->infercollid != InvalidOid &&
870 elem->infercollid != collation)
871 {
872 /* Attribute needed to match collation, but didn't */
873 continue;
874 }
875
876 /* If one matching index att found, good enough -- return true */
877 if (IsA(elem->expr, Var))
878 {
879 if (((Var *) elem->expr)->varattno == attno)
880 return true;
881 }
882 else if (attno == 0)
883 {
884 Node *nattExpr = list_nth(idxExprs, (natt - 1) - nplain);
885
886 /*
887 * Note that unlike routines like match_index_to_operand() we
888 * don't need to care about RelabelType. Neither the index
889 * definition nor the inference clause should contain them.
890 */
891 if (equal(elem->expr, nattExpr))
892 return true;
893 }
894 }
895
896 return false;
897 }
898
899 /*
900 * estimate_rel_size - estimate # pages and # tuples in a table or index
901 *
902 * We also estimate the fraction of the pages that are marked all-visible in
903 * the visibility map, for use in estimation of index-only scans.
904 *
905 * If attr_widths isn't NULL, it points to the zero-index entry of the
906 * relation's attr_widths[] cache; we fill this in if we have need to compute
907 * the attribute widths for estimation purposes.
908 */
909 void
estimate_rel_size(Relation rel,int32 * attr_widths,BlockNumber * pages,double * tuples,double * allvisfrac)910 estimate_rel_size(Relation rel, int32 *attr_widths,
911 BlockNumber *pages, double *tuples, double *allvisfrac)
912 {
913 BlockNumber curpages;
914 BlockNumber relpages;
915 double reltuples;
916 BlockNumber relallvisible;
917 double density;
918
919 switch (rel->rd_rel->relkind)
920 {
921 case RELKIND_RELATION:
922 case RELKIND_INDEX:
923 case RELKIND_MATVIEW:
924 case RELKIND_TOASTVALUE:
925 /* it has storage, ok to call the smgr */
926 curpages = RelationGetNumberOfBlocks(rel);
927
928 /*
929 * HACK: if the relation has never yet been vacuumed, use a
930 * minimum size estimate of 10 pages. The idea here is to avoid
931 * assuming a newly-created table is really small, even if it
932 * currently is, because that may not be true once some data gets
933 * loaded into it. Once a vacuum or analyze cycle has been done
934 * on it, it's more reasonable to believe the size is somewhat
935 * stable.
936 *
937 * (Note that this is only an issue if the plan gets cached and
938 * used again after the table has been filled. What we're trying
939 * to avoid is using a nestloop-type plan on a table that has
940 * grown substantially since the plan was made. Normally,
941 * autovacuum/autoanalyze will occur once enough inserts have
942 * happened and cause cached-plan invalidation; but that doesn't
943 * happen instantaneously, and it won't happen at all for cases
944 * such as temporary tables.)
945 *
946 * We approximate "never vacuumed" by "has relpages = 0", which
947 * means this will also fire on genuinely empty relations. Not
948 * great, but fortunately that's a seldom-seen case in the real
949 * world, and it shouldn't degrade the quality of the plan too
950 * much anyway to err in this direction.
951 *
952 * There are two exceptions wherein we don't apply this heuristic.
953 * One is if the table has inheritance children. Totally empty
954 * parent tables are quite common, so we should be willing to
955 * believe that they are empty. Also, we don't apply the 10-page
956 * minimum to indexes.
957 */
958 if (curpages < 10 &&
959 rel->rd_rel->relpages == 0 &&
960 !rel->rd_rel->relhassubclass &&
961 rel->rd_rel->relkind != RELKIND_INDEX)
962 curpages = 10;
963
964 /* report estimated # pages */
965 *pages = curpages;
966 /* quick exit if rel is clearly empty */
967 if (curpages == 0)
968 {
969 *tuples = 0;
970 *allvisfrac = 0;
971 break;
972 }
973 /* coerce values in pg_class to more desirable types */
974 relpages = (BlockNumber) rel->rd_rel->relpages;
975 reltuples = (double) rel->rd_rel->reltuples;
976 relallvisible = (BlockNumber) rel->rd_rel->relallvisible;
977
978 /*
979 * If it's an index, discount the metapage while estimating the
980 * number of tuples. This is a kluge because it assumes more than
981 * it ought to about index structure. Currently it's OK for
982 * btree, hash, and GIN indexes but suspect for GiST indexes.
983 */
984 if (rel->rd_rel->relkind == RELKIND_INDEX &&
985 relpages > 0)
986 {
987 curpages--;
988 relpages--;
989 }
990
991 /* estimate number of tuples from previous tuple density */
992 if (relpages > 0)
993 density = reltuples / (double) relpages;
994 else
995 {
996 /*
997 * When we have no data because the relation was truncated,
998 * estimate tuple width from attribute datatypes. We assume
999 * here that the pages are completely full, which is OK for
1000 * tables (since they've presumably not been VACUUMed yet) but
1001 * is probably an overestimate for indexes. Fortunately
1002 * get_relation_info() can clamp the overestimate to the
1003 * parent table's size.
1004 *
1005 * Note: this code intentionally disregards alignment
1006 * considerations, because (a) that would be gilding the lily
1007 * considering how crude the estimate is, and (b) it creates
1008 * platform dependencies in the default plans which are kind
1009 * of a headache for regression testing.
1010 */
1011 int32 tuple_width;
1012
1013 tuple_width = get_rel_data_width(rel, attr_widths);
1014 tuple_width += MAXALIGN(SizeofHeapTupleHeader);
1015 tuple_width += sizeof(ItemIdData);
1016 /* note: integer division is intentional here */
1017 density = (BLCKSZ - SizeOfPageHeaderData) / tuple_width;
1018 }
1019 *tuples = rint(density * (double) curpages);
1020
1021 /*
1022 * We use relallvisible as-is, rather than scaling it up like we
1023 * do for the pages and tuples counts, on the theory that any
1024 * pages added since the last VACUUM are most likely not marked
1025 * all-visible. But costsize.c wants it converted to a fraction.
1026 */
1027 if (relallvisible == 0 || curpages <= 0)
1028 *allvisfrac = 0;
1029 else if ((double) relallvisible >= curpages)
1030 *allvisfrac = 1;
1031 else
1032 *allvisfrac = (double) relallvisible / curpages;
1033 break;
1034 case RELKIND_SEQUENCE:
1035 /* Sequences always have a known size */
1036 *pages = 1;
1037 *tuples = 1;
1038 *allvisfrac = 0;
1039 break;
1040 case RELKIND_FOREIGN_TABLE:
1041 /* Just use whatever's in pg_class */
1042 *pages = rel->rd_rel->relpages;
1043 *tuples = rel->rd_rel->reltuples;
1044 *allvisfrac = 0;
1045 break;
1046 default:
1047 /* else it has no disk storage; probably shouldn't get here? */
1048 *pages = 0;
1049 *tuples = 0;
1050 *allvisfrac = 0;
1051 break;
1052 }
1053 }
1054
1055
1056 /*
1057 * get_rel_data_width
1058 *
1059 * Estimate the average width of (the data part of) the relation's tuples.
1060 *
1061 * If attr_widths isn't NULL, it points to the zero-index entry of the
1062 * relation's attr_widths[] cache; use and update that cache as appropriate.
1063 *
1064 * Currently we ignore dropped columns. Ideally those should be included
1065 * in the result, but we haven't got any way to get info about them; and
1066 * since they might be mostly NULLs, treating them as zero-width is not
1067 * necessarily the wrong thing anyway.
1068 */
1069 static int32
get_rel_data_width(Relation rel,int32 * attr_widths)1070 get_rel_data_width(Relation rel, int32 *attr_widths)
1071 {
1072 int32 tuple_width = 0;
1073 int i;
1074
1075 for (i = 1; i <= RelationGetNumberOfAttributes(rel); i++)
1076 {
1077 Form_pg_attribute att = rel->rd_att->attrs[i - 1];
1078 int32 item_width;
1079
1080 if (att->attisdropped)
1081 continue;
1082
1083 /* use previously cached data, if any */
1084 if (attr_widths != NULL && attr_widths[i] > 0)
1085 {
1086 tuple_width += attr_widths[i];
1087 continue;
1088 }
1089
1090 /* This should match set_rel_width() in costsize.c */
1091 item_width = get_attavgwidth(RelationGetRelid(rel), i);
1092 if (item_width <= 0)
1093 {
1094 item_width = get_typavgwidth(att->atttypid, att->atttypmod);
1095 Assert(item_width > 0);
1096 }
1097 if (attr_widths != NULL)
1098 attr_widths[i] = item_width;
1099 tuple_width += item_width;
1100 }
1101
1102 return tuple_width;
1103 }
1104
1105 /*
1106 * get_relation_data_width
1107 *
1108 * External API for get_rel_data_width: same behavior except we have to
1109 * open the relcache entry.
1110 */
1111 int32
get_relation_data_width(Oid relid,int32 * attr_widths)1112 get_relation_data_width(Oid relid, int32 *attr_widths)
1113 {
1114 int32 result;
1115 Relation relation;
1116
1117 /* As above, assume relation is already locked */
1118 relation = heap_open(relid, NoLock);
1119
1120 result = get_rel_data_width(relation, attr_widths);
1121
1122 heap_close(relation, NoLock);
1123
1124 return result;
1125 }
1126
1127
1128 /*
1129 * get_relation_constraints
1130 *
1131 * Retrieve the validated CHECK constraint expressions of the given relation.
1132 *
1133 * Returns a List (possibly empty) of constraint expressions. Each one
1134 * has been canonicalized, and its Vars are changed to have the varno
1135 * indicated by rel->relid. This allows the expressions to be easily
1136 * compared to expressions taken from WHERE.
1137 *
1138 * If include_notnull is true, "col IS NOT NULL" expressions are generated
1139 * and added to the result for each column that's marked attnotnull.
1140 *
1141 * Note: at present this is invoked at most once per relation per planner
1142 * run, and in many cases it won't be invoked at all, so there seems no
1143 * point in caching the data in RelOptInfo.
1144 */
1145 static List *
get_relation_constraints(PlannerInfo * root,Oid relationObjectId,RelOptInfo * rel,bool include_notnull)1146 get_relation_constraints(PlannerInfo *root,
1147 Oid relationObjectId, RelOptInfo *rel,
1148 bool include_notnull)
1149 {
1150 List *result = NIL;
1151 Index varno = rel->relid;
1152 Relation relation;
1153 TupleConstr *constr;
1154 List *pcqual;
1155
1156 /*
1157 * We assume the relation has already been safely locked.
1158 */
1159 relation = heap_open(relationObjectId, NoLock);
1160
1161 constr = relation->rd_att->constr;
1162 if (constr != NULL)
1163 {
1164 int num_check = constr->num_check;
1165 int i;
1166
1167 for (i = 0; i < num_check; i++)
1168 {
1169 Node *cexpr;
1170
1171 /*
1172 * If this constraint hasn't been fully validated yet, we must
1173 * ignore it here.
1174 */
1175 if (!constr->check[i].ccvalid)
1176 continue;
1177
1178 cexpr = stringToNode(constr->check[i].ccbin);
1179
1180 /*
1181 * Run each expression through const-simplification and
1182 * canonicalization. This is not just an optimization, but is
1183 * necessary, because we will be comparing it to
1184 * similarly-processed qual clauses, and may fail to detect valid
1185 * matches without this. This must match the processing done to
1186 * qual clauses in preprocess_expression()! (We can skip the
1187 * stuff involving subqueries, however, since we don't allow any
1188 * in check constraints.)
1189 */
1190 cexpr = eval_const_expressions(root, cexpr);
1191
1192 cexpr = (Node *) canonicalize_qual_ext((Expr *) cexpr, true);
1193
1194 /* Fix Vars to have the desired varno */
1195 if (varno != 1)
1196 ChangeVarNodes(cexpr, 1, varno, 0);
1197
1198 /*
1199 * Finally, convert to implicit-AND format (that is, a List) and
1200 * append the resulting item(s) to our output list.
1201 */
1202 result = list_concat(result,
1203 make_ands_implicit((Expr *) cexpr));
1204 }
1205
1206 /* Add NOT NULL constraints in expression form, if requested */
1207 if (include_notnull && constr->has_not_null)
1208 {
1209 int natts = relation->rd_att->natts;
1210
1211 for (i = 1; i <= natts; i++)
1212 {
1213 Form_pg_attribute att = relation->rd_att->attrs[i - 1];
1214
1215 if (att->attnotnull && !att->attisdropped)
1216 {
1217 NullTest *ntest = makeNode(NullTest);
1218
1219 ntest->arg = (Expr *) makeVar(varno,
1220 i,
1221 att->atttypid,
1222 att->atttypmod,
1223 att->attcollation,
1224 0);
1225 ntest->nulltesttype = IS_NOT_NULL;
1226
1227 /*
1228 * argisrow=false is correct even for a composite column,
1229 * because attnotnull does not represent a SQL-spec IS NOT
1230 * NULL test in such a case, just IS DISTINCT FROM NULL.
1231 */
1232 ntest->argisrow = false;
1233 ntest->location = -1;
1234 result = lappend(result, ntest);
1235 }
1236 }
1237 }
1238 }
1239
1240 /* Append partition predicates, if any */
1241 pcqual = RelationGetPartitionQual(relation);
1242 if (pcqual)
1243 {
1244 /*
1245 * Run the partition quals through const-simplification similar to
1246 * check constraints. We skip canonicalize_qual, though, because
1247 * partition quals should be in canonical form already; also, since
1248 * the qual is in implicit-AND format, we'd have to explicitly convert
1249 * it to explicit-AND format and back again.
1250 */
1251 pcqual = (List *) eval_const_expressions(root, (Node *) pcqual);
1252
1253 /* Fix Vars to have the desired varno */
1254 if (varno != 1)
1255 ChangeVarNodes((Node *) pcqual, 1, varno, 0);
1256
1257 result = list_concat(result, pcqual);
1258 }
1259
1260 heap_close(relation, NoLock);
1261
1262 return result;
1263 }
1264
1265 /*
1266 * get_relation_statistics
1267 * Retrieve extended statistics defined on the table.
1268 *
1269 * Returns a List (possibly empty) of StatisticExtInfo objects describing
1270 * the statistics. Note that this doesn't load the actual statistics data,
1271 * just the identifying metadata. Only stats actually built are considered.
1272 */
1273 static List *
get_relation_statistics(RelOptInfo * rel,Relation relation)1274 get_relation_statistics(RelOptInfo *rel, Relation relation)
1275 {
1276 List *statoidlist;
1277 List *stainfos = NIL;
1278 ListCell *l;
1279
1280 statoidlist = RelationGetStatExtList(relation);
1281
1282 foreach(l, statoidlist)
1283 {
1284 Oid statOid = lfirst_oid(l);
1285 Form_pg_statistic_ext staForm;
1286 HeapTuple htup;
1287 Bitmapset *keys = NULL;
1288 int i;
1289
1290 htup = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(statOid));
1291 if (!htup)
1292 elog(ERROR, "cache lookup failed for statistics object %u", statOid);
1293 staForm = (Form_pg_statistic_ext) GETSTRUCT(htup);
1294
1295 /*
1296 * First, build the array of columns covered. This is ultimately
1297 * wasted if no stats within the object have actually been built, but
1298 * it doesn't seem worth troubling over that case.
1299 */
1300 for (i = 0; i < staForm->stxkeys.dim1; i++)
1301 keys = bms_add_member(keys, staForm->stxkeys.values[i]);
1302
1303 /* add one StatisticExtInfo for each kind built */
1304 if (statext_is_kind_built(htup, STATS_EXT_NDISTINCT))
1305 {
1306 StatisticExtInfo *info = makeNode(StatisticExtInfo);
1307
1308 info->statOid = statOid;
1309 info->rel = rel;
1310 info->kind = STATS_EXT_NDISTINCT;
1311 info->keys = bms_copy(keys);
1312
1313 stainfos = lcons(info, stainfos);
1314 }
1315
1316 if (statext_is_kind_built(htup, STATS_EXT_DEPENDENCIES))
1317 {
1318 StatisticExtInfo *info = makeNode(StatisticExtInfo);
1319
1320 info->statOid = statOid;
1321 info->rel = rel;
1322 info->kind = STATS_EXT_DEPENDENCIES;
1323 info->keys = bms_copy(keys);
1324
1325 stainfos = lcons(info, stainfos);
1326 }
1327
1328 ReleaseSysCache(htup);
1329 bms_free(keys);
1330 }
1331
1332 list_free(statoidlist);
1333
1334 return stainfos;
1335 }
1336
1337 /*
1338 * relation_excluded_by_constraints
1339 *
1340 * Detect whether the relation need not be scanned because it has either
1341 * self-inconsistent restrictions, or restrictions inconsistent with the
1342 * relation's validated CHECK constraints.
1343 *
1344 * Note: this examines only rel->relid, rel->reloptkind, and
1345 * rel->baserestrictinfo; therefore it can be called before filling in
1346 * other fields of the RelOptInfo.
1347 */
1348 bool
relation_excluded_by_constraints(PlannerInfo * root,RelOptInfo * rel,RangeTblEntry * rte)1349 relation_excluded_by_constraints(PlannerInfo *root,
1350 RelOptInfo *rel, RangeTblEntry *rte)
1351 {
1352 List *safe_restrictions;
1353 List *constraint_pred;
1354 List *safe_constraints;
1355 ListCell *lc;
1356
1357 /* As of now, constraint exclusion works only with simple relations. */
1358 Assert(IS_SIMPLE_REL(rel));
1359
1360 /*
1361 * Regardless of the setting of constraint_exclusion, detect
1362 * constant-FALSE-or-NULL restriction clauses. Because const-folding will
1363 * reduce "anything AND FALSE" to just "FALSE", any such case should
1364 * result in exactly one baserestrictinfo entry. This doesn't fire very
1365 * often, but it seems cheap enough to be worth doing anyway. (Without
1366 * this, we'd miss some optimizations that 9.5 and earlier found via much
1367 * more roundabout methods.)
1368 */
1369 if (list_length(rel->baserestrictinfo) == 1)
1370 {
1371 RestrictInfo *rinfo = (RestrictInfo *) linitial(rel->baserestrictinfo);
1372 Expr *clause = rinfo->clause;
1373
1374 if (clause && IsA(clause, Const) &&
1375 (((Const *) clause)->constisnull ||
1376 !DatumGetBool(((Const *) clause)->constvalue)))
1377 return true;
1378 }
1379
1380 /* Skip further tests if constraint exclusion is disabled for the rel */
1381 if (constraint_exclusion == CONSTRAINT_EXCLUSION_OFF ||
1382 (constraint_exclusion == CONSTRAINT_EXCLUSION_PARTITION &&
1383 !(rel->reloptkind == RELOPT_OTHER_MEMBER_REL ||
1384 (root->hasInheritedTarget &&
1385 rel->reloptkind == RELOPT_BASEREL &&
1386 rel->relid == root->parse->resultRelation))))
1387 return false;
1388
1389 /*
1390 * Check for self-contradictory restriction clauses. We dare not make
1391 * deductions with non-immutable functions, but any immutable clauses that
1392 * are self-contradictory allow us to conclude the scan is unnecessary.
1393 *
1394 * Note: strip off RestrictInfo because predicate_refuted_by() isn't
1395 * expecting to see any in its predicate argument.
1396 */
1397 safe_restrictions = NIL;
1398 foreach(lc, rel->baserestrictinfo)
1399 {
1400 RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc);
1401
1402 if (!contain_mutable_functions((Node *) rinfo->clause))
1403 safe_restrictions = lappend(safe_restrictions, rinfo->clause);
1404 }
1405
1406 if (predicate_refuted_by(safe_restrictions, safe_restrictions, false))
1407 return true;
1408
1409 /* Only plain relations have constraints */
1410 if (rte->rtekind != RTE_RELATION || rte->inh)
1411 return false;
1412
1413 /*
1414 * OK to fetch the constraint expressions. Include "col IS NOT NULL"
1415 * expressions for attnotnull columns, in case we can refute those.
1416 */
1417 constraint_pred = get_relation_constraints(root, rte->relid, rel, true);
1418
1419 /*
1420 * We do not currently enforce that CHECK constraints contain only
1421 * immutable functions, so it's necessary to check here. We daren't draw
1422 * conclusions from plan-time evaluation of non-immutable functions. Since
1423 * they're ANDed, we can just ignore any mutable constraints in the list,
1424 * and reason about the rest.
1425 */
1426 safe_constraints = NIL;
1427 foreach(lc, constraint_pred)
1428 {
1429 Node *pred = (Node *) lfirst(lc);
1430
1431 if (!contain_mutable_functions(pred))
1432 safe_constraints = lappend(safe_constraints, pred);
1433 }
1434
1435 /*
1436 * The constraints are effectively ANDed together, so we can just try to
1437 * refute the entire collection at once. This may allow us to make proofs
1438 * that would fail if we took them individually.
1439 *
1440 * Note: we use rel->baserestrictinfo, not safe_restrictions as might seem
1441 * an obvious optimization. Some of the clauses might be OR clauses that
1442 * have volatile and nonvolatile subclauses, and it's OK to make
1443 * deductions with the nonvolatile parts.
1444 */
1445 if (predicate_refuted_by(safe_constraints, rel->baserestrictinfo, false))
1446 return true;
1447
1448 return false;
1449 }
1450
1451
1452 /*
1453 * build_physical_tlist
1454 *
1455 * Build a targetlist consisting of exactly the relation's user attributes,
1456 * in order. The executor can special-case such tlists to avoid a projection
1457 * step at runtime, so we use such tlists preferentially for scan nodes.
1458 *
1459 * Exception: if there are any dropped columns, we punt and return NIL.
1460 * Ideally we would like to handle the dropped-column case too. However this
1461 * creates problems for ExecTypeFromTL, which may be asked to build a tupdesc
1462 * for a tlist that includes vars of no-longer-existent types. In theory we
1463 * could dig out the required info from the pg_attribute entries of the
1464 * relation, but that data is not readily available to ExecTypeFromTL.
1465 * For now, we don't apply the physical-tlist optimization when there are
1466 * dropped cols.
1467 *
1468 * We also support building a "physical" tlist for subqueries, functions,
1469 * values lists, table expressions, and CTEs, since the same optimization can
1470 * occur in SubqueryScan, FunctionScan, ValuesScan, CteScan, TableFunc,
1471 * NamedTuplestoreScan, and WorkTableScan nodes.
1472 */
1473 List *
build_physical_tlist(PlannerInfo * root,RelOptInfo * rel)1474 build_physical_tlist(PlannerInfo *root, RelOptInfo *rel)
1475 {
1476 List *tlist = NIL;
1477 Index varno = rel->relid;
1478 RangeTblEntry *rte = planner_rt_fetch(varno, root);
1479 Relation relation;
1480 Query *subquery;
1481 Var *var;
1482 ListCell *l;
1483 int attrno,
1484 numattrs;
1485 List *colvars;
1486
1487 switch (rte->rtekind)
1488 {
1489 case RTE_RELATION:
1490 /* Assume we already have adequate lock */
1491 relation = heap_open(rte->relid, NoLock);
1492
1493 numattrs = RelationGetNumberOfAttributes(relation);
1494 for (attrno = 1; attrno <= numattrs; attrno++)
1495 {
1496 Form_pg_attribute att_tup = relation->rd_att->attrs[attrno - 1];
1497
1498 if (att_tup->attisdropped)
1499 {
1500 /* found a dropped col, so punt */
1501 tlist = NIL;
1502 break;
1503 }
1504
1505 var = makeVar(varno,
1506 attrno,
1507 att_tup->atttypid,
1508 att_tup->atttypmod,
1509 att_tup->attcollation,
1510 0);
1511
1512 tlist = lappend(tlist,
1513 makeTargetEntry((Expr *) var,
1514 attrno,
1515 NULL,
1516 false));
1517 }
1518
1519 heap_close(relation, NoLock);
1520 break;
1521
1522 case RTE_SUBQUERY:
1523 subquery = rte->subquery;
1524 foreach(l, subquery->targetList)
1525 {
1526 TargetEntry *tle = (TargetEntry *) lfirst(l);
1527
1528 /*
1529 * A resjunk column of the subquery can be reflected as
1530 * resjunk in the physical tlist; we need not punt.
1531 */
1532 var = makeVarFromTargetEntry(varno, tle);
1533
1534 tlist = lappend(tlist,
1535 makeTargetEntry((Expr *) var,
1536 tle->resno,
1537 NULL,
1538 tle->resjunk));
1539 }
1540 break;
1541
1542 case RTE_FUNCTION:
1543 case RTE_TABLEFUNC:
1544 case RTE_VALUES:
1545 case RTE_CTE:
1546 case RTE_NAMEDTUPLESTORE:
1547 /* Not all of these can have dropped cols, but share code anyway */
1548 expandRTE(rte, varno, 0, -1, true /* include dropped */ ,
1549 NULL, &colvars);
1550 foreach(l, colvars)
1551 {
1552 var = (Var *) lfirst(l);
1553
1554 /*
1555 * A non-Var in expandRTE's output means a dropped column;
1556 * must punt.
1557 */
1558 if (!IsA(var, Var))
1559 {
1560 tlist = NIL;
1561 break;
1562 }
1563
1564 tlist = lappend(tlist,
1565 makeTargetEntry((Expr *) var,
1566 var->varattno,
1567 NULL,
1568 false));
1569 }
1570 break;
1571
1572 default:
1573 /* caller error */
1574 elog(ERROR, "unsupported RTE kind %d in build_physical_tlist",
1575 (int) rte->rtekind);
1576 break;
1577 }
1578
1579 return tlist;
1580 }
1581
1582 /*
1583 * build_index_tlist
1584 *
1585 * Build a targetlist representing the columns of the specified index.
1586 * Each column is represented by a Var for the corresponding base-relation
1587 * column, or an expression in base-relation Vars, as appropriate.
1588 *
1589 * There are never any dropped columns in indexes, so unlike
1590 * build_physical_tlist, we need no failure case.
1591 */
1592 static List *
build_index_tlist(PlannerInfo * root,IndexOptInfo * index,Relation heapRelation)1593 build_index_tlist(PlannerInfo *root, IndexOptInfo *index,
1594 Relation heapRelation)
1595 {
1596 List *tlist = NIL;
1597 Index varno = index->rel->relid;
1598 ListCell *indexpr_item;
1599 int i;
1600
1601 indexpr_item = list_head(index->indexprs);
1602 for (i = 0; i < index->ncolumns; i++)
1603 {
1604 int indexkey = index->indexkeys[i];
1605 Expr *indexvar;
1606
1607 if (indexkey != 0)
1608 {
1609 /* simple column */
1610 Form_pg_attribute att_tup;
1611
1612 if (indexkey < 0)
1613 att_tup = SystemAttributeDefinition(indexkey,
1614 heapRelation->rd_rel->relhasoids);
1615 else
1616 att_tup = heapRelation->rd_att->attrs[indexkey - 1];
1617
1618 indexvar = (Expr *) makeVar(varno,
1619 indexkey,
1620 att_tup->atttypid,
1621 att_tup->atttypmod,
1622 att_tup->attcollation,
1623 0);
1624 }
1625 else
1626 {
1627 /* expression column */
1628 if (indexpr_item == NULL)
1629 elog(ERROR, "wrong number of index expressions");
1630 indexvar = (Expr *) lfirst(indexpr_item);
1631 indexpr_item = lnext(indexpr_item);
1632 }
1633
1634 tlist = lappend(tlist,
1635 makeTargetEntry(indexvar,
1636 i + 1,
1637 NULL,
1638 false));
1639 }
1640 if (indexpr_item != NULL)
1641 elog(ERROR, "wrong number of index expressions");
1642
1643 return tlist;
1644 }
1645
1646 /*
1647 * restriction_selectivity
1648 *
1649 * Returns the selectivity of a specified restriction operator clause.
1650 * This code executes registered procedures stored in the
1651 * operator relation, by calling the function manager.
1652 *
1653 * See clause_selectivity() for the meaning of the additional parameters.
1654 */
1655 Selectivity
restriction_selectivity(PlannerInfo * root,Oid operatorid,List * args,Oid inputcollid,int varRelid)1656 restriction_selectivity(PlannerInfo *root,
1657 Oid operatorid,
1658 List *args,
1659 Oid inputcollid,
1660 int varRelid)
1661 {
1662 RegProcedure oprrest = get_oprrest(operatorid);
1663 float8 result;
1664
1665 /*
1666 * if the oprrest procedure is missing for whatever reason, use a
1667 * selectivity of 0.5
1668 */
1669 if (!oprrest)
1670 return (Selectivity) 0.5;
1671
1672 result = DatumGetFloat8(OidFunctionCall4Coll(oprrest,
1673 inputcollid,
1674 PointerGetDatum(root),
1675 ObjectIdGetDatum(operatorid),
1676 PointerGetDatum(args),
1677 Int32GetDatum(varRelid)));
1678
1679 if (result < 0.0 || result > 1.0)
1680 elog(ERROR, "invalid restriction selectivity: %f", result);
1681
1682 return (Selectivity) result;
1683 }
1684
1685 /*
1686 * join_selectivity
1687 *
1688 * Returns the selectivity of a specified join operator clause.
1689 * This code executes registered procedures stored in the
1690 * operator relation, by calling the function manager.
1691 */
1692 Selectivity
join_selectivity(PlannerInfo * root,Oid operatorid,List * args,Oid inputcollid,JoinType jointype,SpecialJoinInfo * sjinfo)1693 join_selectivity(PlannerInfo *root,
1694 Oid operatorid,
1695 List *args,
1696 Oid inputcollid,
1697 JoinType jointype,
1698 SpecialJoinInfo *sjinfo)
1699 {
1700 RegProcedure oprjoin = get_oprjoin(operatorid);
1701 float8 result;
1702
1703 /*
1704 * if the oprjoin procedure is missing for whatever reason, use a
1705 * selectivity of 0.5
1706 */
1707 if (!oprjoin)
1708 return (Selectivity) 0.5;
1709
1710 result = DatumGetFloat8(OidFunctionCall5Coll(oprjoin,
1711 inputcollid,
1712 PointerGetDatum(root),
1713 ObjectIdGetDatum(operatorid),
1714 PointerGetDatum(args),
1715 Int16GetDatum(jointype),
1716 PointerGetDatum(sjinfo)));
1717
1718 if (result < 0.0 || result > 1.0)
1719 elog(ERROR, "invalid join selectivity: %f", result);
1720
1721 return (Selectivity) result;
1722 }
1723
1724 /*
1725 * has_unique_index
1726 *
1727 * Detect whether there is a unique index on the specified attribute
1728 * of the specified relation, thus allowing us to conclude that all
1729 * the (non-null) values of the attribute are distinct.
1730 *
1731 * This function does not check the index's indimmediate property, which
1732 * means that uniqueness may transiently fail to hold intra-transaction.
1733 * That's appropriate when we are making statistical estimates, but beware
1734 * of using this for any correctness proofs.
1735 */
1736 bool
has_unique_index(RelOptInfo * rel,AttrNumber attno)1737 has_unique_index(RelOptInfo *rel, AttrNumber attno)
1738 {
1739 ListCell *ilist;
1740
1741 foreach(ilist, rel->indexlist)
1742 {
1743 IndexOptInfo *index = (IndexOptInfo *) lfirst(ilist);
1744
1745 /*
1746 * Note: ignore partial indexes, since they don't allow us to conclude
1747 * that all attr values are distinct, *unless* they are marked predOK
1748 * which means we know the index's predicate is satisfied by the
1749 * query. We don't take any interest in expressional indexes either.
1750 * Also, a multicolumn unique index doesn't allow us to conclude that
1751 * just the specified attr is unique.
1752 */
1753 if (index->unique &&
1754 index->ncolumns == 1 &&
1755 index->indexkeys[0] == attno &&
1756 (index->indpred == NIL || index->predOK))
1757 return true;
1758 }
1759 return false;
1760 }
1761
1762
1763 /*
1764 * has_row_triggers
1765 *
1766 * Detect whether the specified relation has any row-level triggers for event.
1767 */
1768 bool
has_row_triggers(PlannerInfo * root,Index rti,CmdType event)1769 has_row_triggers(PlannerInfo *root, Index rti, CmdType event)
1770 {
1771 RangeTblEntry *rte = planner_rt_fetch(rti, root);
1772 Relation relation;
1773 TriggerDesc *trigDesc;
1774 bool result = false;
1775
1776 /* Assume we already have adequate lock */
1777 relation = heap_open(rte->relid, NoLock);
1778
1779 trigDesc = relation->trigdesc;
1780 switch (event)
1781 {
1782 case CMD_INSERT:
1783 if (trigDesc &&
1784 (trigDesc->trig_insert_after_row ||
1785 trigDesc->trig_insert_before_row))
1786 result = true;
1787 break;
1788 case CMD_UPDATE:
1789 if (trigDesc &&
1790 (trigDesc->trig_update_after_row ||
1791 trigDesc->trig_update_before_row))
1792 result = true;
1793 break;
1794 case CMD_DELETE:
1795 if (trigDesc &&
1796 (trigDesc->trig_delete_after_row ||
1797 trigDesc->trig_delete_before_row))
1798 result = true;
1799 break;
1800 default:
1801 elog(ERROR, "unrecognized CmdType: %d", (int) event);
1802 break;
1803 }
1804
1805 heap_close(relation, NoLock);
1806 return result;
1807 }
1808