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