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