Header And Logo

PostgreSQL
| The world's most advanced open source database.

plancat.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * plancat.c
00004  *     routines for accessing the system catalogs
00005  *
00006  *
00007  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00008  * Portions Copyright (c) 1994, Regents of the University of California
00009  *
00010  *
00011  * IDENTIFICATION
00012  *    src/backend/optimizer/util/plancat.c
00013  *
00014  *-------------------------------------------------------------------------
00015  */
00016 #include "postgres.h"
00017 
00018 #include <math.h>
00019 
00020 #include "access/genam.h"
00021 #include "access/heapam.h"
00022 #include "access/htup_details.h"
00023 #include "access/nbtree.h"
00024 #include "access/sysattr.h"
00025 #include "access/transam.h"
00026 #include "access/xlog.h"
00027 #include "catalog/catalog.h"
00028 #include "catalog/heap.h"
00029 #include "foreign/fdwapi.h"
00030 #include "miscadmin.h"
00031 #include "nodes/makefuncs.h"
00032 #include "optimizer/clauses.h"
00033 #include "optimizer/cost.h"
00034 #include "optimizer/plancat.h"
00035 #include "optimizer/predtest.h"
00036 #include "optimizer/prep.h"
00037 #include "parser/parse_relation.h"
00038 #include "parser/parsetree.h"
00039 #include "rewrite/rewriteManip.h"
00040 #include "storage/bufmgr.h"
00041 #include "utils/lsyscache.h"
00042 #include "utils/rel.h"
00043 #include "utils/snapmgr.h"
00044 
00045 
00046 /* GUC parameter */
00047 int         constraint_exclusion = CONSTRAINT_EXCLUSION_PARTITION;
00048 
00049 /* Hook for plugins to get control in get_relation_info() */
00050 get_relation_info_hook_type get_relation_info_hook = NULL;
00051 
00052 
00053 static int32 get_rel_data_width(Relation rel, int32 *attr_widths);
00054 static List *get_relation_constraints(PlannerInfo *root,
00055                          Oid relationObjectId, RelOptInfo *rel,
00056                          bool include_notnull);
00057 static List *build_index_tlist(PlannerInfo *root, IndexOptInfo *index,
00058                   Relation heapRelation);
00059 
00060 
00061 /*
00062  * get_relation_info -
00063  *    Retrieves catalog information for a given relation.
00064  *
00065  * Given the Oid of the relation, return the following info into fields
00066  * of the RelOptInfo struct:
00067  *
00068  *  min_attr    lowest valid AttrNumber
00069  *  max_attr    highest valid AttrNumber
00070  *  indexlist   list of IndexOptInfos for relation's indexes
00071  *  fdwroutine  if it's a foreign table, the FDW function pointers
00072  *  pages       number of pages
00073  *  tuples      number of tuples
00074  *
00075  * Also, initialize the attr_needed[] and attr_widths[] arrays.  In most
00076  * cases these are left as zeroes, but sometimes we need to compute attr
00077  * widths here, and we may as well cache the results for costsize.c.
00078  *
00079  * If inhparent is true, all we need to do is set up the attr arrays:
00080  * the RelOptInfo actually represents the appendrel formed by an inheritance
00081  * tree, and so the parent rel's physical size and index information isn't
00082  * important for it.
00083  */
00084 void
00085 get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
00086                   RelOptInfo *rel)
00087 {
00088     Index       varno = rel->relid;
00089     Relation    relation;
00090     bool        hasindex;
00091     List       *indexinfos = NIL;
00092 
00093     /*
00094      * We need not lock the relation since it was already locked, either by
00095      * the rewriter or when expand_inherited_rtentry() added it to the query's
00096      * rangetable.
00097      */
00098     relation = heap_open(relationObjectId, NoLock);
00099 
00100     /* Temporary and unlogged relations are inaccessible during recovery. */
00101     if (!RelationNeedsWAL(relation) && RecoveryInProgress())
00102         ereport(ERROR,
00103                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
00104                  errmsg("cannot access temporary or unlogged relations during recovery")));
00105 
00106     rel->min_attr = FirstLowInvalidHeapAttributeNumber + 1;
00107     rel->max_attr = RelationGetNumberOfAttributes(relation);
00108     rel->reltablespace = RelationGetForm(relation)->reltablespace;
00109 
00110     Assert(rel->max_attr >= rel->min_attr);
00111     rel->attr_needed = (Relids *)
00112         palloc0((rel->max_attr - rel->min_attr + 1) * sizeof(Relids));
00113     rel->attr_widths = (int32 *)
00114         palloc0((rel->max_attr - rel->min_attr + 1) * sizeof(int32));
00115 
00116     /*
00117      * Estimate relation size --- unless it's an inheritance parent, in which
00118      * case the size will be computed later in set_append_rel_pathlist, and we
00119      * must leave it zero for now to avoid bollixing the total_table_pages
00120      * calculation.
00121      */
00122     if (!inhparent)
00123         estimate_rel_size(relation, rel->attr_widths - rel->min_attr,
00124                           &rel->pages, &rel->tuples, &rel->allvisfrac);
00125 
00126     /*
00127      * Make list of indexes.  Ignore indexes on system catalogs if told to.
00128      * Don't bother with indexes for an inheritance parent, either.
00129      */
00130     if (inhparent ||
00131         (IgnoreSystemIndexes && IsSystemClass(relation->rd_rel)))
00132         hasindex = false;
00133     else
00134         hasindex = relation->rd_rel->relhasindex;
00135 
00136     if (hasindex)
00137     {
00138         List       *indexoidlist;
00139         ListCell   *l;
00140         LOCKMODE    lmode;
00141 
00142         indexoidlist = RelationGetIndexList(relation);
00143 
00144         /*
00145          * For each index, we get the same type of lock that the executor will
00146          * need, and do not release it.  This saves a couple of trips to the
00147          * shared lock manager while not creating any real loss of
00148          * concurrency, because no schema changes could be happening on the
00149          * index while we hold lock on the parent rel, and neither lock type
00150          * blocks any other kind of index operation.
00151          */
00152         if (rel->relid == root->parse->resultRelation)
00153             lmode = RowExclusiveLock;
00154         else
00155             lmode = AccessShareLock;
00156 
00157         foreach(l, indexoidlist)
00158         {
00159             Oid         indexoid = lfirst_oid(l);
00160             Relation    indexRelation;
00161             Form_pg_index index;
00162             IndexOptInfo *info;
00163             int         ncolumns;
00164             int         i;
00165 
00166             /*
00167              * Extract info from the relation descriptor for the index.
00168              */
00169             indexRelation = index_open(indexoid, lmode);
00170             index = indexRelation->rd_index;
00171 
00172             /*
00173              * Ignore invalid indexes, since they can't safely be used for
00174              * queries.  Note that this is OK because the data structure we
00175              * are constructing is only used by the planner --- the executor
00176              * still needs to insert into "invalid" indexes, if they're marked
00177              * IndexIsReady.
00178              */
00179             if (!IndexIsValid(index))
00180             {
00181                 index_close(indexRelation, NoLock);
00182                 continue;
00183             }
00184 
00185             /*
00186              * If the index is valid, but cannot yet be used, ignore it; but
00187              * mark the plan we are generating as transient. See
00188              * src/backend/access/heap/README.HOT for discussion.
00189              */
00190             if (index->indcheckxmin &&
00191                 !TransactionIdPrecedes(HeapTupleHeaderGetXmin(indexRelation->rd_indextuple->t_data),
00192                                        TransactionXmin))
00193             {
00194                 root->glob->transientPlan = true;
00195                 index_close(indexRelation, NoLock);
00196                 continue;
00197             }
00198 
00199             info = makeNode(IndexOptInfo);
00200 
00201             info->indexoid = index->indexrelid;
00202             info->reltablespace =
00203                 RelationGetForm(indexRelation)->reltablespace;
00204             info->rel = rel;
00205             info->ncolumns = ncolumns = index->indnatts;
00206             info->indexkeys = (int *) palloc(sizeof(int) * ncolumns);
00207             info->indexcollations = (Oid *) palloc(sizeof(Oid) * ncolumns);
00208             info->opfamily = (Oid *) palloc(sizeof(Oid) * ncolumns);
00209             info->opcintype = (Oid *) palloc(sizeof(Oid) * ncolumns);
00210 
00211             for (i = 0; i < ncolumns; i++)
00212             {
00213                 info->indexkeys[i] = index->indkey.values[i];
00214                 info->indexcollations[i] = indexRelation->rd_indcollation[i];
00215                 info->opfamily[i] = indexRelation->rd_opfamily[i];
00216                 info->opcintype[i] = indexRelation->rd_opcintype[i];
00217             }
00218 
00219             info->relam = indexRelation->rd_rel->relam;
00220             info->amcostestimate = indexRelation->rd_am->amcostestimate;
00221             info->canreturn = index_can_return(indexRelation);
00222             info->amcanorderbyop = indexRelation->rd_am->amcanorderbyop;
00223             info->amoptionalkey = indexRelation->rd_am->amoptionalkey;
00224             info->amsearcharray = indexRelation->rd_am->amsearcharray;
00225             info->amsearchnulls = indexRelation->rd_am->amsearchnulls;
00226             info->amhasgettuple = OidIsValid(indexRelation->rd_am->amgettuple);
00227             info->amhasgetbitmap = OidIsValid(indexRelation->rd_am->amgetbitmap);
00228 
00229             /*
00230              * Fetch the ordering information for the index, if any.
00231              */
00232             if (info->relam == BTREE_AM_OID)
00233             {
00234                 /*
00235                  * If it's a btree index, we can use its opfamily OIDs
00236                  * directly as the sort ordering opfamily OIDs.
00237                  */
00238                 Assert(indexRelation->rd_am->amcanorder);
00239 
00240                 info->sortopfamily = info->opfamily;
00241                 info->reverse_sort = (bool *) palloc(sizeof(bool) * ncolumns);
00242                 info->nulls_first = (bool *) palloc(sizeof(bool) * ncolumns);
00243 
00244                 for (i = 0; i < ncolumns; i++)
00245                 {
00246                     int16       opt = indexRelation->rd_indoption[i];
00247 
00248                     info->reverse_sort[i] = (opt & INDOPTION_DESC) != 0;
00249                     info->nulls_first[i] = (opt & INDOPTION_NULLS_FIRST) != 0;
00250                 }
00251             }
00252             else if (indexRelation->rd_am->amcanorder)
00253             {
00254                 /*
00255                  * Otherwise, identify the corresponding btree opfamilies by
00256                  * trying to map this index's "<" operators into btree.  Since
00257                  * "<" uniquely defines the behavior of a sort order, this is
00258                  * a sufficient test.
00259                  *
00260                  * XXX This method is rather slow and also requires the
00261                  * undesirable assumption that the other index AM numbers its
00262                  * strategies the same as btree.  It'd be better to have a way
00263                  * to explicitly declare the corresponding btree opfamily for
00264                  * each opfamily of the other index type.  But given the lack
00265                  * of current or foreseeable amcanorder index types, it's not
00266                  * worth expending more effort on now.
00267                  */
00268                 info->sortopfamily = (Oid *) palloc(sizeof(Oid) * ncolumns);
00269                 info->reverse_sort = (bool *) palloc(sizeof(bool) * ncolumns);
00270                 info->nulls_first = (bool *) palloc(sizeof(bool) * ncolumns);
00271 
00272                 for (i = 0; i < ncolumns; i++)
00273                 {
00274                     int16       opt = indexRelation->rd_indoption[i];
00275                     Oid         ltopr;
00276                     Oid         btopfamily;
00277                     Oid         btopcintype;
00278                     int16       btstrategy;
00279 
00280                     info->reverse_sort[i] = (opt & INDOPTION_DESC) != 0;
00281                     info->nulls_first[i] = (opt & INDOPTION_NULLS_FIRST) != 0;
00282 
00283                     ltopr = get_opfamily_member(info->opfamily[i],
00284                                                 info->opcintype[i],
00285                                                 info->opcintype[i],
00286                                                 BTLessStrategyNumber);
00287                     if (OidIsValid(ltopr) &&
00288                         get_ordering_op_properties(ltopr,
00289                                                    &btopfamily,
00290                                                    &btopcintype,
00291                                                    &btstrategy) &&
00292                         btopcintype == info->opcintype[i] &&
00293                         btstrategy == BTLessStrategyNumber)
00294                     {
00295                         /* Successful mapping */
00296                         info->sortopfamily[i] = btopfamily;
00297                     }
00298                     else
00299                     {
00300                         /* Fail ... quietly treat index as unordered */
00301                         info->sortopfamily = NULL;
00302                         info->reverse_sort = NULL;
00303                         info->nulls_first = NULL;
00304                         break;
00305                     }
00306                 }
00307             }
00308             else
00309             {
00310                 info->sortopfamily = NULL;
00311                 info->reverse_sort = NULL;
00312                 info->nulls_first = NULL;
00313             }
00314 
00315             /*
00316              * Fetch the index expressions and predicate, if any.  We must
00317              * modify the copies we obtain from the relcache to have the
00318              * correct varno for the parent relation, so that they match up
00319              * correctly against qual clauses.
00320              */
00321             info->indexprs = RelationGetIndexExpressions(indexRelation);
00322             info->indpred = RelationGetIndexPredicate(indexRelation);
00323             if (info->indexprs && varno != 1)
00324                 ChangeVarNodes((Node *) info->indexprs, 1, varno, 0);
00325             if (info->indpred && varno != 1)
00326                 ChangeVarNodes((Node *) info->indpred, 1, varno, 0);
00327 
00328             /* Build targetlist using the completed indexprs data */
00329             info->indextlist = build_index_tlist(root, info, relation);
00330 
00331             info->predOK = false;       /* set later in indxpath.c */
00332             info->unique = index->indisunique;
00333             info->immediate = index->indimmediate;
00334             info->hypothetical = false;
00335 
00336             /*
00337              * Estimate the index size.  If it's not a partial index, we lock
00338              * the number-of-tuples estimate to equal the parent table; if it
00339              * is partial then we have to use the same methods as we would for
00340              * a table, except we can be sure that the index is not larger
00341              * than the table.
00342              */
00343             if (info->indpred == NIL)
00344             {
00345                 info->pages = RelationGetNumberOfBlocks(indexRelation);
00346                 info->tuples = rel->tuples;
00347             }
00348             else
00349             {
00350                 double      allvisfrac; /* dummy */
00351 
00352                 estimate_rel_size(indexRelation, NULL,
00353                                   &info->pages, &info->tuples, &allvisfrac);
00354                 if (info->tuples > rel->tuples)
00355                     info->tuples = rel->tuples;
00356             }
00357 
00358             if (info->relam == BTREE_AM_OID)
00359             {
00360                 /* For btrees, get tree height while we have the index open */
00361                 info->tree_height = _bt_getrootheight(indexRelation);
00362             }
00363             else
00364             {
00365                 /* For other index types, just set it to "unknown" for now */
00366                 info->tree_height = -1;
00367             }
00368 
00369             index_close(indexRelation, NoLock);
00370 
00371             indexinfos = lcons(info, indexinfos);
00372         }
00373 
00374         list_free(indexoidlist);
00375     }
00376 
00377     rel->indexlist = indexinfos;
00378 
00379     /* Grab the fdwroutine info using the relcache, while we have it */
00380     if (relation->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
00381         rel->fdwroutine = GetFdwRoutineForRelation(relation, true);
00382     else
00383         rel->fdwroutine = NULL;
00384 
00385     heap_close(relation, NoLock);
00386 
00387     /*
00388      * Allow a plugin to editorialize on the info we obtained from the
00389      * catalogs.  Actions might include altering the assumed relation size,
00390      * removing an index, or adding a hypothetical index to the indexlist.
00391      */
00392     if (get_relation_info_hook)
00393         (*get_relation_info_hook) (root, relationObjectId, inhparent, rel);
00394 }
00395 
00396 /*
00397  * estimate_rel_size - estimate # pages and # tuples in a table or index
00398  *
00399  * We also estimate the fraction of the pages that are marked all-visible in
00400  * the visibility map, for use in estimation of index-only scans.
00401  *
00402  * If attr_widths isn't NULL, it points to the zero-index entry of the
00403  * relation's attr_widths[] cache; we fill this in if we have need to compute
00404  * the attribute widths for estimation purposes.
00405  */
00406 void
00407 estimate_rel_size(Relation rel, int32 *attr_widths,
00408                   BlockNumber *pages, double *tuples, double *allvisfrac)
00409 {
00410     BlockNumber curpages;
00411     BlockNumber relpages;
00412     double      reltuples;
00413     BlockNumber relallvisible;
00414     double      density;
00415 
00416     switch (rel->rd_rel->relkind)
00417     {
00418         case RELKIND_RELATION:
00419         case RELKIND_INDEX:
00420         case RELKIND_MATVIEW:
00421         case RELKIND_TOASTVALUE:
00422             /* it has storage, ok to call the smgr */
00423             curpages = RelationGetNumberOfBlocks(rel);
00424 
00425             /*
00426              * HACK: if the relation has never yet been vacuumed, use a
00427              * minimum size estimate of 10 pages.  The idea here is to avoid
00428              * assuming a newly-created table is really small, even if it
00429              * currently is, because that may not be true once some data gets
00430              * loaded into it.  Once a vacuum or analyze cycle has been done
00431              * on it, it's more reasonable to believe the size is somewhat
00432              * stable.
00433              *
00434              * (Note that this is only an issue if the plan gets cached and
00435              * used again after the table has been filled.  What we're trying
00436              * to avoid is using a nestloop-type plan on a table that has
00437              * grown substantially since the plan was made.  Normally,
00438              * autovacuum/autoanalyze will occur once enough inserts have
00439              * happened and cause cached-plan invalidation; but that doesn't
00440              * happen instantaneously, and it won't happen at all for cases
00441              * such as temporary tables.)
00442              *
00443              * We approximate "never vacuumed" by "has relpages = 0", which
00444              * means this will also fire on genuinely empty relations.  Not
00445              * great, but fortunately that's a seldom-seen case in the real
00446              * world, and it shouldn't degrade the quality of the plan too
00447              * much anyway to err in this direction.
00448              *
00449              * There are two exceptions wherein we don't apply this heuristic.
00450              * One is if the table has inheritance children.  Totally empty
00451              * parent tables are quite common, so we should be willing to
00452              * believe that they are empty.  Also, we don't apply the 10-page
00453              * minimum to indexes.
00454              */
00455             if (curpages < 10 &&
00456                 rel->rd_rel->relpages == 0 &&
00457                 !rel->rd_rel->relhassubclass &&
00458                 rel->rd_rel->relkind != RELKIND_INDEX)
00459                 curpages = 10;
00460 
00461             /* report estimated # pages */
00462             *pages = curpages;
00463             /* quick exit if rel is clearly empty */
00464             if (curpages == 0)
00465             {
00466                 *tuples = 0;
00467                 *allvisfrac = 0;
00468                 break;
00469             }
00470             /* coerce values in pg_class to more desirable types */
00471             relpages = (BlockNumber) rel->rd_rel->relpages;
00472             reltuples = (double) rel->rd_rel->reltuples;
00473             relallvisible = (BlockNumber) rel->rd_rel->relallvisible;
00474 
00475             /*
00476              * If it's an index, discount the metapage while estimating the
00477              * number of tuples.  This is a kluge because it assumes more than
00478              * it ought to about index structure.  Currently it's OK for
00479              * btree, hash, and GIN indexes but suspect for GiST indexes.
00480              */
00481             if (rel->rd_rel->relkind == RELKIND_INDEX &&
00482                 relpages > 0)
00483             {
00484                 curpages--;
00485                 relpages--;
00486             }
00487 
00488             /* estimate number of tuples from previous tuple density */
00489             if (relpages > 0)
00490                 density = reltuples / (double) relpages;
00491             else
00492             {
00493                 /*
00494                  * When we have no data because the relation was truncated,
00495                  * estimate tuple width from attribute datatypes.  We assume
00496                  * here that the pages are completely full, which is OK for
00497                  * tables (since they've presumably not been VACUUMed yet) but
00498                  * is probably an overestimate for indexes.  Fortunately
00499                  * get_relation_info() can clamp the overestimate to the
00500                  * parent table's size.
00501                  *
00502                  * Note: this code intentionally disregards alignment
00503                  * considerations, because (a) that would be gilding the lily
00504                  * considering how crude the estimate is, and (b) it creates
00505                  * platform dependencies in the default plans which are kind
00506                  * of a headache for regression testing.
00507                  */
00508                 int32       tuple_width;
00509 
00510                 tuple_width = get_rel_data_width(rel, attr_widths);
00511                 tuple_width += sizeof(HeapTupleHeaderData);
00512                 tuple_width += sizeof(ItemPointerData);
00513                 /* note: integer division is intentional here */
00514                 density = (BLCKSZ - SizeOfPageHeaderData) / tuple_width;
00515             }
00516             *tuples = rint(density * (double) curpages);
00517 
00518             /*
00519              * We use relallvisible as-is, rather than scaling it up like we
00520              * do for the pages and tuples counts, on the theory that any
00521              * pages added since the last VACUUM are most likely not marked
00522              * all-visible.  But costsize.c wants it converted to a fraction.
00523              */
00524             if (relallvisible == 0 || curpages <= 0)
00525                 *allvisfrac = 0;
00526             else if ((double) relallvisible >= curpages)
00527                 *allvisfrac = 1;
00528             else
00529                 *allvisfrac = (double) relallvisible / curpages;
00530             break;
00531         case RELKIND_SEQUENCE:
00532             /* Sequences always have a known size */
00533             *pages = 1;
00534             *tuples = 1;
00535             *allvisfrac = 0;
00536             break;
00537         case RELKIND_FOREIGN_TABLE:
00538             /* Just use whatever's in pg_class */
00539             *pages = rel->rd_rel->relpages;
00540             *tuples = rel->rd_rel->reltuples;
00541             *allvisfrac = 0;
00542             break;
00543         default:
00544             /* else it has no disk storage; probably shouldn't get here? */
00545             *pages = 0;
00546             *tuples = 0;
00547             *allvisfrac = 0;
00548             break;
00549     }
00550 }
00551 
00552 
00553 /*
00554  * get_rel_data_width
00555  *
00556  * Estimate the average width of (the data part of) the relation's tuples.
00557  *
00558  * If attr_widths isn't NULL, it points to the zero-index entry of the
00559  * relation's attr_widths[] cache; use and update that cache as appropriate.
00560  *
00561  * Currently we ignore dropped columns.  Ideally those should be included
00562  * in the result, but we haven't got any way to get info about them; and
00563  * since they might be mostly NULLs, treating them as zero-width is not
00564  * necessarily the wrong thing anyway.
00565  */
00566 static int32
00567 get_rel_data_width(Relation rel, int32 *attr_widths)
00568 {
00569     int32       tuple_width = 0;
00570     int         i;
00571 
00572     for (i = 1; i <= RelationGetNumberOfAttributes(rel); i++)
00573     {
00574         Form_pg_attribute att = rel->rd_att->attrs[i - 1];
00575         int32       item_width;
00576 
00577         if (att->attisdropped)
00578             continue;
00579 
00580         /* use previously cached data, if any */
00581         if (attr_widths != NULL && attr_widths[i] > 0)
00582         {
00583             tuple_width += attr_widths[i];
00584             continue;
00585         }
00586 
00587         /* This should match set_rel_width() in costsize.c */
00588         item_width = get_attavgwidth(RelationGetRelid(rel), i);
00589         if (item_width <= 0)
00590         {
00591             item_width = get_typavgwidth(att->atttypid, att->atttypmod);
00592             Assert(item_width > 0);
00593         }
00594         if (attr_widths != NULL)
00595             attr_widths[i] = item_width;
00596         tuple_width += item_width;
00597     }
00598 
00599     return tuple_width;
00600 }
00601 
00602 /*
00603  * get_relation_data_width
00604  *
00605  * External API for get_rel_data_width: same behavior except we have to
00606  * open the relcache entry.
00607  */
00608 int32
00609 get_relation_data_width(Oid relid, int32 *attr_widths)
00610 {
00611     int32       result;
00612     Relation    relation;
00613 
00614     /* As above, assume relation is already locked */
00615     relation = heap_open(relid, NoLock);
00616 
00617     result = get_rel_data_width(relation, attr_widths);
00618 
00619     heap_close(relation, NoLock);
00620 
00621     return result;
00622 }
00623 
00624 
00625 /*
00626  * get_relation_constraints
00627  *
00628  * Retrieve the validated CHECK constraint expressions of the given relation.
00629  *
00630  * Returns a List (possibly empty) of constraint expressions.  Each one
00631  * has been canonicalized, and its Vars are changed to have the varno
00632  * indicated by rel->relid.  This allows the expressions to be easily
00633  * compared to expressions taken from WHERE.
00634  *
00635  * If include_notnull is true, "col IS NOT NULL" expressions are generated
00636  * and added to the result for each column that's marked attnotnull.
00637  *
00638  * Note: at present this is invoked at most once per relation per planner
00639  * run, and in many cases it won't be invoked at all, so there seems no
00640  * point in caching the data in RelOptInfo.
00641  */
00642 static List *
00643 get_relation_constraints(PlannerInfo *root,
00644                          Oid relationObjectId, RelOptInfo *rel,
00645                          bool include_notnull)
00646 {
00647     List       *result = NIL;
00648     Index       varno = rel->relid;
00649     Relation    relation;
00650     TupleConstr *constr;
00651 
00652     /*
00653      * We assume the relation has already been safely locked.
00654      */
00655     relation = heap_open(relationObjectId, NoLock);
00656 
00657     constr = relation->rd_att->constr;
00658     if (constr != NULL)
00659     {
00660         int         num_check = constr->num_check;
00661         int         i;
00662 
00663         for (i = 0; i < num_check; i++)
00664         {
00665             Node       *cexpr;
00666 
00667             /*
00668              * If this constraint hasn't been fully validated yet, we must
00669              * ignore it here.
00670              */
00671             if (!constr->check[i].ccvalid)
00672                 continue;
00673 
00674             cexpr = stringToNode(constr->check[i].ccbin);
00675 
00676             /*
00677              * Run each expression through const-simplification and
00678              * canonicalization.  This is not just an optimization, but is
00679              * necessary, because we will be comparing it to
00680              * similarly-processed qual clauses, and may fail to detect valid
00681              * matches without this.  This must match the processing done to
00682              * qual clauses in preprocess_expression()!  (We can skip the
00683              * stuff involving subqueries, however, since we don't allow any
00684              * in check constraints.)
00685              */
00686             cexpr = eval_const_expressions(root, cexpr);
00687 
00688             cexpr = (Node *) canonicalize_qual((Expr *) cexpr);
00689 
00690             /* Fix Vars to have the desired varno */
00691             if (varno != 1)
00692                 ChangeVarNodes(cexpr, 1, varno, 0);
00693 
00694             /*
00695              * Finally, convert to implicit-AND format (that is, a List) and
00696              * append the resulting item(s) to our output list.
00697              */
00698             result = list_concat(result,
00699                                  make_ands_implicit((Expr *) cexpr));
00700         }
00701 
00702         /* Add NOT NULL constraints in expression form, if requested */
00703         if (include_notnull && constr->has_not_null)
00704         {
00705             int         natts = relation->rd_att->natts;
00706 
00707             for (i = 1; i <= natts; i++)
00708             {
00709                 Form_pg_attribute att = relation->rd_att->attrs[i - 1];
00710 
00711                 if (att->attnotnull && !att->attisdropped)
00712                 {
00713                     NullTest   *ntest = makeNode(NullTest);
00714 
00715                     ntest->arg = (Expr *) makeVar(varno,
00716                                                   i,
00717                                                   att->atttypid,
00718                                                   att->atttypmod,
00719                                                   att->attcollation,
00720                                                   0);
00721                     ntest->nulltesttype = IS_NOT_NULL;
00722                     ntest->argisrow = type_is_rowtype(att->atttypid);
00723                     result = lappend(result, ntest);
00724                 }
00725             }
00726         }
00727     }
00728 
00729     heap_close(relation, NoLock);
00730 
00731     return result;
00732 }
00733 
00734 
00735 /*
00736  * relation_excluded_by_constraints
00737  *
00738  * Detect whether the relation need not be scanned because it has either
00739  * self-inconsistent restrictions, or restrictions inconsistent with the
00740  * relation's validated CHECK constraints.
00741  *
00742  * Note: this examines only rel->relid, rel->reloptkind, and
00743  * rel->baserestrictinfo; therefore it can be called before filling in
00744  * other fields of the RelOptInfo.
00745  */
00746 bool
00747 relation_excluded_by_constraints(PlannerInfo *root,
00748                                  RelOptInfo *rel, RangeTblEntry *rte)
00749 {
00750     List       *safe_restrictions;
00751     List       *constraint_pred;
00752     List       *safe_constraints;
00753     ListCell   *lc;
00754 
00755     /* Skip the test if constraint exclusion is disabled for the rel */
00756     if (constraint_exclusion == CONSTRAINT_EXCLUSION_OFF ||
00757         (constraint_exclusion == CONSTRAINT_EXCLUSION_PARTITION &&
00758          !(rel->reloptkind == RELOPT_OTHER_MEMBER_REL ||
00759            (root->hasInheritedTarget &&
00760             rel->reloptkind == RELOPT_BASEREL &&
00761             rel->relid == root->parse->resultRelation))))
00762         return false;
00763 
00764     /*
00765      * Check for self-contradictory restriction clauses.  We dare not make
00766      * deductions with non-immutable functions, but any immutable clauses that
00767      * are self-contradictory allow us to conclude the scan is unnecessary.
00768      *
00769      * Note: strip off RestrictInfo because predicate_refuted_by() isn't
00770      * expecting to see any in its predicate argument.
00771      */
00772     safe_restrictions = NIL;
00773     foreach(lc, rel->baserestrictinfo)
00774     {
00775         RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc);
00776 
00777         if (!contain_mutable_functions((Node *) rinfo->clause))
00778             safe_restrictions = lappend(safe_restrictions, rinfo->clause);
00779     }
00780 
00781     if (predicate_refuted_by(safe_restrictions, safe_restrictions))
00782         return true;
00783 
00784     /* Only plain relations have constraints */
00785     if (rte->rtekind != RTE_RELATION || rte->inh)
00786         return false;
00787 
00788     /*
00789      * OK to fetch the constraint expressions.  Include "col IS NOT NULL"
00790      * expressions for attnotnull columns, in case we can refute those.
00791      */
00792     constraint_pred = get_relation_constraints(root, rte->relid, rel, true);
00793 
00794     /*
00795      * We do not currently enforce that CHECK constraints contain only
00796      * immutable functions, so it's necessary to check here. We daren't draw
00797      * conclusions from plan-time evaluation of non-immutable functions. Since
00798      * they're ANDed, we can just ignore any mutable constraints in the list,
00799      * and reason about the rest.
00800      */
00801     safe_constraints = NIL;
00802     foreach(lc, constraint_pred)
00803     {
00804         Node       *pred = (Node *) lfirst(lc);
00805 
00806         if (!contain_mutable_functions(pred))
00807             safe_constraints = lappend(safe_constraints, pred);
00808     }
00809 
00810     /*
00811      * The constraints are effectively ANDed together, so we can just try to
00812      * refute the entire collection at once.  This may allow us to make proofs
00813      * that would fail if we took them individually.
00814      *
00815      * Note: we use rel->baserestrictinfo, not safe_restrictions as might seem
00816      * an obvious optimization.  Some of the clauses might be OR clauses that
00817      * have volatile and nonvolatile subclauses, and it's OK to make
00818      * deductions with the nonvolatile parts.
00819      */
00820     if (predicate_refuted_by(safe_constraints, rel->baserestrictinfo))
00821         return true;
00822 
00823     return false;
00824 }
00825 
00826 
00827 /*
00828  * build_physical_tlist
00829  *
00830  * Build a targetlist consisting of exactly the relation's user attributes,
00831  * in order.  The executor can special-case such tlists to avoid a projection
00832  * step at runtime, so we use such tlists preferentially for scan nodes.
00833  *
00834  * Exception: if there are any dropped columns, we punt and return NIL.
00835  * Ideally we would like to handle the dropped-column case too.  However this
00836  * creates problems for ExecTypeFromTL, which may be asked to build a tupdesc
00837  * for a tlist that includes vars of no-longer-existent types.  In theory we
00838  * could dig out the required info from the pg_attribute entries of the
00839  * relation, but that data is not readily available to ExecTypeFromTL.
00840  * For now, we don't apply the physical-tlist optimization when there are
00841  * dropped cols.
00842  *
00843  * We also support building a "physical" tlist for subqueries, functions,
00844  * values lists, and CTEs, since the same optimization can occur in
00845  * SubqueryScan, FunctionScan, ValuesScan, CteScan, and WorkTableScan nodes.
00846  */
00847 List *
00848 build_physical_tlist(PlannerInfo *root, RelOptInfo *rel)
00849 {
00850     List       *tlist = NIL;
00851     Index       varno = rel->relid;
00852     RangeTblEntry *rte = planner_rt_fetch(varno, root);
00853     Relation    relation;
00854     Query      *subquery;
00855     Var        *var;
00856     ListCell   *l;
00857     int         attrno,
00858                 numattrs;
00859     List       *colvars;
00860 
00861     switch (rte->rtekind)
00862     {
00863         case RTE_RELATION:
00864             /* Assume we already have adequate lock */
00865             relation = heap_open(rte->relid, NoLock);
00866 
00867             numattrs = RelationGetNumberOfAttributes(relation);
00868             for (attrno = 1; attrno <= numattrs; attrno++)
00869             {
00870                 Form_pg_attribute att_tup = relation->rd_att->attrs[attrno - 1];
00871 
00872                 if (att_tup->attisdropped)
00873                 {
00874                     /* found a dropped col, so punt */
00875                     tlist = NIL;
00876                     break;
00877                 }
00878 
00879                 var = makeVar(varno,
00880                               attrno,
00881                               att_tup->atttypid,
00882                               att_tup->atttypmod,
00883                               att_tup->attcollation,
00884                               0);
00885 
00886                 tlist = lappend(tlist,
00887                                 makeTargetEntry((Expr *) var,
00888                                                 attrno,
00889                                                 NULL,
00890                                                 false));
00891             }
00892 
00893             heap_close(relation, NoLock);
00894             break;
00895 
00896         case RTE_SUBQUERY:
00897             subquery = rte->subquery;
00898             foreach(l, subquery->targetList)
00899             {
00900                 TargetEntry *tle = (TargetEntry *) lfirst(l);
00901 
00902                 /*
00903                  * A resjunk column of the subquery can be reflected as
00904                  * resjunk in the physical tlist; we need not punt.
00905                  */
00906                 var = makeVarFromTargetEntry(varno, tle);
00907 
00908                 tlist = lappend(tlist,
00909                                 makeTargetEntry((Expr *) var,
00910                                                 tle->resno,
00911                                                 NULL,
00912                                                 tle->resjunk));
00913             }
00914             break;
00915 
00916         case RTE_FUNCTION:
00917         case RTE_VALUES:
00918         case RTE_CTE:
00919             /* Not all of these can have dropped cols, but share code anyway */
00920             expandRTE(rte, varno, 0, -1, true /* include dropped */ ,
00921                       NULL, &colvars);
00922             foreach(l, colvars)
00923             {
00924                 var = (Var *) lfirst(l);
00925 
00926                 /*
00927                  * A non-Var in expandRTE's output means a dropped column;
00928                  * must punt.
00929                  */
00930                 if (!IsA(var, Var))
00931                 {
00932                     tlist = NIL;
00933                     break;
00934                 }
00935 
00936                 tlist = lappend(tlist,
00937                                 makeTargetEntry((Expr *) var,
00938                                                 var->varattno,
00939                                                 NULL,
00940                                                 false));
00941             }
00942             break;
00943 
00944         default:
00945             /* caller error */
00946             elog(ERROR, "unsupported RTE kind %d in build_physical_tlist",
00947                  (int) rte->rtekind);
00948             break;
00949     }
00950 
00951     return tlist;
00952 }
00953 
00954 /*
00955  * build_index_tlist
00956  *
00957  * Build a targetlist representing the columns of the specified index.
00958  * Each column is represented by a Var for the corresponding base-relation
00959  * column, or an expression in base-relation Vars, as appropriate.
00960  *
00961  * There are never any dropped columns in indexes, so unlike
00962  * build_physical_tlist, we need no failure case.
00963  */
00964 static List *
00965 build_index_tlist(PlannerInfo *root, IndexOptInfo *index,
00966                   Relation heapRelation)
00967 {
00968     List       *tlist = NIL;
00969     Index       varno = index->rel->relid;
00970     ListCell   *indexpr_item;
00971     int         i;
00972 
00973     indexpr_item = list_head(index->indexprs);
00974     for (i = 0; i < index->ncolumns; i++)
00975     {
00976         int         indexkey = index->indexkeys[i];
00977         Expr       *indexvar;
00978 
00979         if (indexkey != 0)
00980         {
00981             /* simple column */
00982             Form_pg_attribute att_tup;
00983 
00984             if (indexkey < 0)
00985                 att_tup = SystemAttributeDefinition(indexkey,
00986                                            heapRelation->rd_rel->relhasoids);
00987             else
00988                 att_tup = heapRelation->rd_att->attrs[indexkey - 1];
00989 
00990             indexvar = (Expr *) makeVar(varno,
00991                                         indexkey,
00992                                         att_tup->atttypid,
00993                                         att_tup->atttypmod,
00994                                         att_tup->attcollation,
00995                                         0);
00996         }
00997         else
00998         {
00999             /* expression column */
01000             if (indexpr_item == NULL)
01001                 elog(ERROR, "wrong number of index expressions");
01002             indexvar = (Expr *) lfirst(indexpr_item);
01003             indexpr_item = lnext(indexpr_item);
01004         }
01005 
01006         tlist = lappend(tlist,
01007                         makeTargetEntry(indexvar,
01008                                         i + 1,
01009                                         NULL,
01010                                         false));
01011     }
01012     if (indexpr_item != NULL)
01013         elog(ERROR, "wrong number of index expressions");
01014 
01015     return tlist;
01016 }
01017 
01018 /*
01019  * restriction_selectivity
01020  *
01021  * Returns the selectivity of a specified restriction operator clause.
01022  * This code executes registered procedures stored in the
01023  * operator relation, by calling the function manager.
01024  *
01025  * See clause_selectivity() for the meaning of the additional parameters.
01026  */
01027 Selectivity
01028 restriction_selectivity(PlannerInfo *root,
01029                         Oid operatorid,
01030                         List *args,
01031                         Oid inputcollid,
01032                         int varRelid)
01033 {
01034     RegProcedure oprrest = get_oprrest(operatorid);
01035     float8      result;
01036 
01037     /*
01038      * if the oprrest procedure is missing for whatever reason, use a
01039      * selectivity of 0.5
01040      */
01041     if (!oprrest)
01042         return (Selectivity) 0.5;
01043 
01044     result = DatumGetFloat8(OidFunctionCall4Coll(oprrest,
01045                                                  inputcollid,
01046                                                  PointerGetDatum(root),
01047                                                  ObjectIdGetDatum(operatorid),
01048                                                  PointerGetDatum(args),
01049                                                  Int32GetDatum(varRelid)));
01050 
01051     if (result < 0.0 || result > 1.0)
01052         elog(ERROR, "invalid restriction selectivity: %f", result);
01053 
01054     return (Selectivity) result;
01055 }
01056 
01057 /*
01058  * join_selectivity
01059  *
01060  * Returns the selectivity of a specified join operator clause.
01061  * This code executes registered procedures stored in the
01062  * operator relation, by calling the function manager.
01063  */
01064 Selectivity
01065 join_selectivity(PlannerInfo *root,
01066                  Oid operatorid,
01067                  List *args,
01068                  Oid inputcollid,
01069                  JoinType jointype,
01070                  SpecialJoinInfo *sjinfo)
01071 {
01072     RegProcedure oprjoin = get_oprjoin(operatorid);
01073     float8      result;
01074 
01075     /*
01076      * if the oprjoin procedure is missing for whatever reason, use a
01077      * selectivity of 0.5
01078      */
01079     if (!oprjoin)
01080         return (Selectivity) 0.5;
01081 
01082     result = DatumGetFloat8(OidFunctionCall5Coll(oprjoin,
01083                                                  inputcollid,
01084                                                  PointerGetDatum(root),
01085                                                  ObjectIdGetDatum(operatorid),
01086                                                  PointerGetDatum(args),
01087                                                  Int16GetDatum(jointype),
01088                                                  PointerGetDatum(sjinfo)));
01089 
01090     if (result < 0.0 || result > 1.0)
01091         elog(ERROR, "invalid join selectivity: %f", result);
01092 
01093     return (Selectivity) result;
01094 }
01095 
01096 /*
01097  * has_unique_index
01098  *
01099  * Detect whether there is a unique index on the specified attribute
01100  * of the specified relation, thus allowing us to conclude that all
01101  * the (non-null) values of the attribute are distinct.
01102  *
01103  * This function does not check the index's indimmediate property, which
01104  * means that uniqueness may transiently fail to hold intra-transaction.
01105  * That's appropriate when we are making statistical estimates, but beware
01106  * of using this for any correctness proofs.
01107  */
01108 bool
01109 has_unique_index(RelOptInfo *rel, AttrNumber attno)
01110 {
01111     ListCell   *ilist;
01112 
01113     foreach(ilist, rel->indexlist)
01114     {
01115         IndexOptInfo *index = (IndexOptInfo *) lfirst(ilist);
01116 
01117         /*
01118          * Note: ignore partial indexes, since they don't allow us to conclude
01119          * that all attr values are distinct, *unless* they are marked predOK
01120          * which means we know the index's predicate is satisfied by the
01121          * query. We don't take any interest in expressional indexes either.
01122          * Also, a multicolumn unique index doesn't allow us to conclude that
01123          * just the specified attr is unique.
01124          */
01125         if (index->unique &&
01126             index->ncolumns == 1 &&
01127             index->indexkeys[0] == attno &&
01128             (index->indpred == NIL || index->predOK))
01129             return true;
01130     }
01131     return false;
01132 }