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