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