Header And Logo

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

parse_relation.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * parse_relation.c
00004  *    parser support routines dealing with relations
00005  *
00006  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00007  * Portions Copyright (c) 1994, Regents of the University of California
00008  *
00009  *
00010  * IDENTIFICATION
00011  *    src/backend/parser/parse_relation.c
00012  *
00013  *-------------------------------------------------------------------------
00014  */
00015 #include "postgres.h"
00016 
00017 #include <ctype.h>
00018 
00019 #include "access/htup_details.h"
00020 #include "access/sysattr.h"
00021 #include "catalog/heap.h"
00022 #include "catalog/namespace.h"
00023 #include "catalog/pg_type.h"
00024 #include "funcapi.h"
00025 #include "nodes/makefuncs.h"
00026 #include "nodes/nodeFuncs.h"
00027 #include "parser/parsetree.h"
00028 #include "parser/parse_relation.h"
00029 #include "parser/parse_type.h"
00030 #include "utils/builtins.h"
00031 #include "utils/lsyscache.h"
00032 #include "utils/rel.h"
00033 #include "utils/syscache.h"
00034 
00035 
00036 static RangeTblEntry *scanNameSpaceForRefname(ParseState *pstate,
00037                         const char *refname, int location);
00038 static RangeTblEntry *scanNameSpaceForRelid(ParseState *pstate, Oid relid,
00039                       int location);
00040 static void markRTEForSelectPriv(ParseState *pstate, RangeTblEntry *rte,
00041                      int rtindex, AttrNumber col);
00042 static void expandRelation(Oid relid, Alias *eref,
00043                int rtindex, int sublevels_up,
00044                int location, bool include_dropped,
00045                List **colnames, List **colvars);
00046 static void expandTupleDesc(TupleDesc tupdesc, Alias *eref,
00047                 int rtindex, int sublevels_up,
00048                 int location, bool include_dropped,
00049                 List **colnames, List **colvars);
00050 static int  specialAttNum(const char *attname);
00051 static bool isQueryUsingTempRelation_walker(Node *node, void *context);
00052 
00053 
00054 /*
00055  * refnameRangeTblEntry
00056  *    Given a possibly-qualified refname, look to see if it matches any RTE.
00057  *    If so, return a pointer to the RangeTblEntry; else return NULL.
00058  *
00059  *    Optionally get RTE's nesting depth (0 = current) into *sublevels_up.
00060  *    If sublevels_up is NULL, only consider items at the current nesting
00061  *    level.
00062  *
00063  * An unqualified refname (schemaname == NULL) can match any RTE with matching
00064  * alias, or matching unqualified relname in the case of alias-less relation
00065  * RTEs.  It is possible that such a refname matches multiple RTEs in the
00066  * nearest nesting level that has a match; if so, we report an error via
00067  * ereport().
00068  *
00069  * A qualified refname (schemaname != NULL) can only match a relation RTE
00070  * that (a) has no alias and (b) is for the same relation identified by
00071  * schemaname.refname.  In this case we convert schemaname.refname to a
00072  * relation OID and search by relid, rather than by alias name.  This is
00073  * peculiar, but it's what SQL says to do.
00074  */
00075 RangeTblEntry *
00076 refnameRangeTblEntry(ParseState *pstate,
00077                      const char *schemaname,
00078                      const char *refname,
00079                      int location,
00080                      int *sublevels_up)
00081 {
00082     Oid         relId = InvalidOid;
00083 
00084     if (sublevels_up)
00085         *sublevels_up = 0;
00086 
00087     if (schemaname != NULL)
00088     {
00089         Oid         namespaceId;
00090 
00091         /*
00092          * We can use LookupNamespaceNoError() here because we are only
00093          * interested in finding existing RTEs.  Checking USAGE permission on
00094          * the schema is unnecessary since it would have already been checked
00095          * when the RTE was made.  Furthermore, we want to report "RTE not
00096          * found", not "no permissions for schema", if the name happens to
00097          * match a schema name the user hasn't got access to.
00098          */
00099         namespaceId = LookupNamespaceNoError(schemaname);
00100         if (!OidIsValid(namespaceId))
00101             return NULL;
00102         relId = get_relname_relid(refname, namespaceId);
00103         if (!OidIsValid(relId))
00104             return NULL;
00105     }
00106 
00107     while (pstate != NULL)
00108     {
00109         RangeTblEntry *result;
00110 
00111         if (OidIsValid(relId))
00112             result = scanNameSpaceForRelid(pstate, relId, location);
00113         else
00114             result = scanNameSpaceForRefname(pstate, refname, location);
00115 
00116         if (result)
00117             return result;
00118 
00119         if (sublevels_up)
00120             (*sublevels_up)++;
00121         else
00122             break;
00123 
00124         pstate = pstate->parentParseState;
00125     }
00126     return NULL;
00127 }
00128 
00129 /*
00130  * Search the query's table namespace for an RTE matching the
00131  * given unqualified refname.  Return the RTE if a unique match, or NULL
00132  * if no match.  Raise error if multiple matches.
00133  */
00134 static RangeTblEntry *
00135 scanNameSpaceForRefname(ParseState *pstate, const char *refname, int location)
00136 {
00137     RangeTblEntry *result = NULL;
00138     ListCell   *l;
00139 
00140     foreach(l, pstate->p_namespace)
00141     {
00142         ParseNamespaceItem *nsitem = (ParseNamespaceItem *) lfirst(l);
00143         RangeTblEntry *rte = nsitem->p_rte;
00144 
00145         /* Ignore columns-only items */
00146         if (!nsitem->p_rel_visible)
00147             continue;
00148         /* If not inside LATERAL, ignore lateral-only items */
00149         if (nsitem->p_lateral_only && !pstate->p_lateral_active)
00150             continue;
00151 
00152         if (strcmp(rte->eref->aliasname, refname) == 0)
00153         {
00154             if (result)
00155                 ereport(ERROR,
00156                         (errcode(ERRCODE_AMBIGUOUS_ALIAS),
00157                          errmsg("table reference \"%s\" is ambiguous",
00158                                 refname),
00159                          parser_errposition(pstate, location)));
00160             /* SQL:2008 demands this be an error, not an invisible item */
00161             if (nsitem->p_lateral_only && !nsitem->p_lateral_ok)
00162                 ereport(ERROR,
00163                         (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
00164                          errmsg("invalid reference to FROM-clause entry for table \"%s\"",
00165                                 refname),
00166                          errdetail("The combining JOIN type must be INNER or LEFT for a LATERAL reference."),
00167                          parser_errposition(pstate, location)));
00168             result = rte;
00169         }
00170     }
00171     return result;
00172 }
00173 
00174 /*
00175  * Search the query's table namespace for a relation RTE matching the
00176  * given relation OID.  Return the RTE if a unique match, or NULL
00177  * if no match.  Raise error if multiple matches (which shouldn't
00178  * happen if the namespace was checked correctly when it was created).
00179  *
00180  * See the comments for refnameRangeTblEntry to understand why this
00181  * acts the way it does.
00182  */
00183 static RangeTblEntry *
00184 scanNameSpaceForRelid(ParseState *pstate, Oid relid, int location)
00185 {
00186     RangeTblEntry *result = NULL;
00187     ListCell   *l;
00188 
00189     foreach(l, pstate->p_namespace)
00190     {
00191         ParseNamespaceItem *nsitem = (ParseNamespaceItem *) lfirst(l);
00192         RangeTblEntry *rte = nsitem->p_rte;
00193 
00194         /* Ignore columns-only items */
00195         if (!nsitem->p_rel_visible)
00196             continue;
00197         /* If not inside LATERAL, ignore lateral-only items */
00198         if (nsitem->p_lateral_only && !pstate->p_lateral_active)
00199             continue;
00200 
00201         /* yes, the test for alias == NULL should be there... */
00202         if (rte->rtekind == RTE_RELATION &&
00203             rte->relid == relid &&
00204             rte->alias == NULL)
00205         {
00206             if (result)
00207                 ereport(ERROR,
00208                         (errcode(ERRCODE_AMBIGUOUS_ALIAS),
00209                          errmsg("table reference %u is ambiguous",
00210                                 relid),
00211                          parser_errposition(pstate, location)));
00212             /* SQL:2008 demands this be an error, not an invisible item */
00213             if (nsitem->p_lateral_only && !nsitem->p_lateral_ok)
00214                 ereport(ERROR,
00215                         (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
00216                          errmsg("invalid reference to FROM-clause entry for table \"%s\"",
00217                                 rte->eref->aliasname),
00218                          errdetail("The combining JOIN type must be INNER or LEFT for a LATERAL reference."),
00219                          parser_errposition(pstate, location)));
00220             result = rte;
00221         }
00222     }
00223     return result;
00224 }
00225 
00226 /*
00227  * Search the query's CTE namespace for a CTE matching the given unqualified
00228  * refname.  Return the CTE (and its levelsup count) if a match, or NULL
00229  * if no match.  We need not worry about multiple matches, since parse_cte.c
00230  * rejects WITH lists containing duplicate CTE names.
00231  */
00232 CommonTableExpr *
00233 scanNameSpaceForCTE(ParseState *pstate, const char *refname,
00234                     Index *ctelevelsup)
00235 {
00236     Index       levelsup;
00237 
00238     for (levelsup = 0;
00239          pstate != NULL;
00240          pstate = pstate->parentParseState, levelsup++)
00241     {
00242         ListCell   *lc;
00243 
00244         foreach(lc, pstate->p_ctenamespace)
00245         {
00246             CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc);
00247 
00248             if (strcmp(cte->ctename, refname) == 0)
00249             {
00250                 *ctelevelsup = levelsup;
00251                 return cte;
00252             }
00253         }
00254     }
00255     return NULL;
00256 }
00257 
00258 /*
00259  * Search for a possible "future CTE", that is one that is not yet in scope
00260  * according to the WITH scoping rules.  This has nothing to do with valid
00261  * SQL semantics, but it's important for error reporting purposes.
00262  */
00263 static bool
00264 isFutureCTE(ParseState *pstate, const char *refname)
00265 {
00266     for (; pstate != NULL; pstate = pstate->parentParseState)
00267     {
00268         ListCell   *lc;
00269 
00270         foreach(lc, pstate->p_future_ctes)
00271         {
00272             CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc);
00273 
00274             if (strcmp(cte->ctename, refname) == 0)
00275                 return true;
00276         }
00277     }
00278     return false;
00279 }
00280 
00281 /*
00282  * searchRangeTableForRel
00283  *    See if any RangeTblEntry could possibly match the RangeVar.
00284  *    If so, return a pointer to the RangeTblEntry; else return NULL.
00285  *
00286  * This is different from refnameRangeTblEntry in that it considers every
00287  * entry in the ParseState's rangetable(s), not only those that are currently
00288  * visible in the p_namespace list(s).  This behavior is invalid per the SQL
00289  * spec, and it may give ambiguous results (there might be multiple equally
00290  * valid matches, but only one will be returned).  This must be used ONLY
00291  * as a heuristic in giving suitable error messages.  See errorMissingRTE.
00292  *
00293  * Notice that we consider both matches on actual relation (or CTE) name
00294  * and matches on alias.
00295  */
00296 static RangeTblEntry *
00297 searchRangeTableForRel(ParseState *pstate, RangeVar *relation)
00298 {
00299     const char *refname = relation->relname;
00300     Oid         relId = InvalidOid;
00301     CommonTableExpr *cte = NULL;
00302     Index       ctelevelsup = 0;
00303     Index       levelsup;
00304 
00305     /*
00306      * If it's an unqualified name, check for possible CTE matches. A CTE
00307      * hides any real relation matches.  If no CTE, look for a matching
00308      * relation.
00309      *
00310      * NB: It's not critical that RangeVarGetRelid return the correct answer
00311      * here in the face of concurrent DDL.  If it doesn't, the worst case
00312      * scenario is a less-clear error message.  Also, the tables involved in
00313      * the query are already locked, which reduces the number of cases in
00314      * which surprising behavior can occur.  So we do the name lookup
00315      * unlocked.
00316      */
00317     if (!relation->schemaname)
00318         cte = scanNameSpaceForCTE(pstate, refname, &ctelevelsup);
00319     if (!cte)
00320         relId = RangeVarGetRelid(relation, NoLock, true);
00321 
00322     /* Now look for RTEs matching either the relation/CTE or the alias */
00323     for (levelsup = 0;
00324          pstate != NULL;
00325          pstate = pstate->parentParseState, levelsup++)
00326     {
00327         ListCell   *l;
00328 
00329         foreach(l, pstate->p_rtable)
00330         {
00331             RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
00332 
00333             if (rte->rtekind == RTE_RELATION &&
00334                 OidIsValid(relId) &&
00335                 rte->relid == relId)
00336                 return rte;
00337             if (rte->rtekind == RTE_CTE &&
00338                 cte != NULL &&
00339                 rte->ctelevelsup + levelsup == ctelevelsup &&
00340                 strcmp(rte->ctename, refname) == 0)
00341                 return rte;
00342             if (strcmp(rte->eref->aliasname, refname) == 0)
00343                 return rte;
00344         }
00345     }
00346     return NULL;
00347 }
00348 
00349 /*
00350  * Check for relation-name conflicts between two namespace lists.
00351  * Raise an error if any is found.
00352  *
00353  * Note: we assume that each given argument does not contain conflicts
00354  * itself; we just want to know if the two can be merged together.
00355  *
00356  * Per SQL, two alias-less plain relation RTEs do not conflict even if
00357  * they have the same eref->aliasname (ie, same relation name), if they
00358  * are for different relation OIDs (implying they are in different schemas).
00359  *
00360  * We ignore the lateral-only flags in the namespace items: the lists must
00361  * not conflict, even when all items are considered visible.  However,
00362  * columns-only items should be ignored.
00363  */
00364 void
00365 checkNameSpaceConflicts(ParseState *pstate, List *namespace1,
00366                         List *namespace2)
00367 {
00368     ListCell   *l1;
00369 
00370     foreach(l1, namespace1)
00371     {
00372         ParseNamespaceItem *nsitem1 = (ParseNamespaceItem *) lfirst(l1);
00373         RangeTblEntry *rte1 = nsitem1->p_rte;
00374         const char *aliasname1 = rte1->eref->aliasname;
00375         ListCell   *l2;
00376 
00377         if (!nsitem1->p_rel_visible)
00378             continue;
00379 
00380         foreach(l2, namespace2)
00381         {
00382             ParseNamespaceItem *nsitem2 = (ParseNamespaceItem *) lfirst(l2);
00383             RangeTblEntry *rte2 = nsitem2->p_rte;
00384 
00385             if (!nsitem2->p_rel_visible)
00386                 continue;
00387             if (strcmp(rte2->eref->aliasname, aliasname1) != 0)
00388                 continue;       /* definitely no conflict */
00389             if (rte1->rtekind == RTE_RELATION && rte1->alias == NULL &&
00390                 rte2->rtekind == RTE_RELATION && rte2->alias == NULL &&
00391                 rte1->relid != rte2->relid)
00392                 continue;       /* no conflict per SQL rule */
00393             ereport(ERROR,
00394                     (errcode(ERRCODE_DUPLICATE_ALIAS),
00395                      errmsg("table name \"%s\" specified more than once",
00396                             aliasname1)));
00397         }
00398     }
00399 }
00400 
00401 /*
00402  * given an RTE, return RT index (starting with 1) of the entry,
00403  * and optionally get its nesting depth (0 = current).  If sublevels_up
00404  * is NULL, only consider rels at the current nesting level.
00405  * Raises error if RTE not found.
00406  */
00407 int
00408 RTERangeTablePosn(ParseState *pstate, RangeTblEntry *rte, int *sublevels_up)
00409 {
00410     int         index;
00411     ListCell   *l;
00412 
00413     if (sublevels_up)
00414         *sublevels_up = 0;
00415 
00416     while (pstate != NULL)
00417     {
00418         index = 1;
00419         foreach(l, pstate->p_rtable)
00420         {
00421             if (rte == (RangeTblEntry *) lfirst(l))
00422                 return index;
00423             index++;
00424         }
00425         pstate = pstate->parentParseState;
00426         if (sublevels_up)
00427             (*sublevels_up)++;
00428         else
00429             break;
00430     }
00431 
00432     elog(ERROR, "RTE not found (internal error)");
00433     return 0;                   /* keep compiler quiet */
00434 }
00435 
00436 /*
00437  * Given an RT index and nesting depth, find the corresponding RTE.
00438  * This is the inverse of RTERangeTablePosn.
00439  */
00440 RangeTblEntry *
00441 GetRTEByRangeTablePosn(ParseState *pstate,
00442                        int varno,
00443                        int sublevels_up)
00444 {
00445     while (sublevels_up-- > 0)
00446     {
00447         pstate = pstate->parentParseState;
00448         Assert(pstate != NULL);
00449     }
00450     Assert(varno > 0 && varno <= list_length(pstate->p_rtable));
00451     return rt_fetch(varno, pstate->p_rtable);
00452 }
00453 
00454 /*
00455  * Fetch the CTE for a CTE-reference RTE.
00456  *
00457  * rtelevelsup is the number of query levels above the given pstate that the
00458  * RTE came from.  Callers that don't have this information readily available
00459  * may pass -1 instead.
00460  */
00461 CommonTableExpr *
00462 GetCTEForRTE(ParseState *pstate, RangeTblEntry *rte, int rtelevelsup)
00463 {
00464     Index       levelsup;
00465     ListCell   *lc;
00466 
00467     /* Determine RTE's levelsup if caller didn't know it */
00468     if (rtelevelsup < 0)
00469         (void) RTERangeTablePosn(pstate, rte, &rtelevelsup);
00470 
00471     Assert(rte->rtekind == RTE_CTE);
00472     levelsup = rte->ctelevelsup + rtelevelsup;
00473     while (levelsup-- > 0)
00474     {
00475         pstate = pstate->parentParseState;
00476         if (!pstate)            /* shouldn't happen */
00477             elog(ERROR, "bad levelsup for CTE \"%s\"", rte->ctename);
00478     }
00479     foreach(lc, pstate->p_ctenamespace)
00480     {
00481         CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc);
00482 
00483         if (strcmp(cte->ctename, rte->ctename) == 0)
00484             return cte;
00485     }
00486     /* shouldn't happen */
00487     elog(ERROR, "could not find CTE \"%s\"", rte->ctename);
00488     return NULL;                /* keep compiler quiet */
00489 }
00490 
00491 /*
00492  * scanRTEForColumn
00493  *    Search the column names of a single RTE for the given name.
00494  *    If found, return an appropriate Var node, else return NULL.
00495  *    If the name proves ambiguous within this RTE, raise error.
00496  *
00497  * Side effect: if we find a match, mark the RTE as requiring read access
00498  * for the column.
00499  */
00500 Node *
00501 scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte, char *colname,
00502                  int location)
00503 {
00504     Node       *result = NULL;
00505     int         attnum = 0;
00506     Var        *var;
00507     ListCell   *c;
00508 
00509     /*
00510      * Scan the user column names (or aliases) for a match. Complain if
00511      * multiple matches.
00512      *
00513      * Note: eref->colnames may include entries for dropped columns, but those
00514      * will be empty strings that cannot match any legal SQL identifier, so we
00515      * don't bother to test for that case here.
00516      *
00517      * Should this somehow go wrong and we try to access a dropped column,
00518      * we'll still catch it by virtue of the checks in
00519      * get_rte_attribute_type(), which is called by make_var().  That routine
00520      * has to do a cache lookup anyway, so the check there is cheap.
00521      */
00522     foreach(c, rte->eref->colnames)
00523     {
00524         attnum++;
00525         if (strcmp(strVal(lfirst(c)), colname) == 0)
00526         {
00527             if (result)
00528                 ereport(ERROR,
00529                         (errcode(ERRCODE_AMBIGUOUS_COLUMN),
00530                          errmsg("column reference \"%s\" is ambiguous",
00531                                 colname),
00532                          parser_errposition(pstate, location)));
00533             var = make_var(pstate, rte, attnum, location);
00534             /* Require read access to the column */
00535             markVarForSelectPriv(pstate, var, rte);
00536             result = (Node *) var;
00537         }
00538     }
00539 
00540     /*
00541      * If we have a unique match, return it.  Note that this allows a user
00542      * alias to override a system column name (such as OID) without error.
00543      */
00544     if (result)
00545         return result;
00546 
00547     /*
00548      * If the RTE represents a real table, consider system column names.
00549      */
00550     if (rte->rtekind == RTE_RELATION)
00551     {
00552         /* quick check to see if name could be a system column */
00553         attnum = specialAttNum(colname);
00554         if (attnum != InvalidAttrNumber)
00555         {
00556             /* now check to see if column actually is defined */
00557             if (SearchSysCacheExists2(ATTNUM,
00558                                       ObjectIdGetDatum(rte->relid),
00559                                       Int16GetDatum(attnum)))
00560             {
00561                 var = make_var(pstate, rte, attnum, location);
00562                 /* Require read access to the column */
00563                 markVarForSelectPriv(pstate, var, rte);
00564                 result = (Node *) var;
00565             }
00566         }
00567     }
00568 
00569     return result;
00570 }
00571 
00572 /*
00573  * colNameToVar
00574  *    Search for an unqualified column name.
00575  *    If found, return the appropriate Var node (or expression).
00576  *    If not found, return NULL.  If the name proves ambiguous, raise error.
00577  *    If localonly is true, only names in the innermost query are considered.
00578  */
00579 Node *
00580 colNameToVar(ParseState *pstate, char *colname, bool localonly,
00581              int location)
00582 {
00583     Node       *result = NULL;
00584     ParseState *orig_pstate = pstate;
00585 
00586     while (pstate != NULL)
00587     {
00588         ListCell   *l;
00589 
00590         foreach(l, pstate->p_namespace)
00591         {
00592             ParseNamespaceItem *nsitem = (ParseNamespaceItem *) lfirst(l);
00593             RangeTblEntry *rte = nsitem->p_rte;
00594             Node       *newresult;
00595 
00596             /* Ignore table-only items */
00597             if (!nsitem->p_cols_visible)
00598                 continue;
00599             /* If not inside LATERAL, ignore lateral-only items */
00600             if (nsitem->p_lateral_only && !pstate->p_lateral_active)
00601                 continue;
00602 
00603             /* use orig_pstate here to get the right sublevels_up */
00604             newresult = scanRTEForColumn(orig_pstate, rte, colname, location);
00605 
00606             if (newresult)
00607             {
00608                 if (result)
00609                     ereport(ERROR,
00610                             (errcode(ERRCODE_AMBIGUOUS_COLUMN),
00611                              errmsg("column reference \"%s\" is ambiguous",
00612                                     colname),
00613                              parser_errposition(orig_pstate, location)));
00614                 /* SQL:2008 demands this be an error, not an invisible item */
00615                 if (nsitem->p_lateral_only && !nsitem->p_lateral_ok)
00616                     ereport(ERROR,
00617                             (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
00618                              errmsg("invalid reference to FROM-clause entry for table \"%s\"",
00619                                     rte->eref->aliasname),
00620                              errdetail("The combining JOIN type must be INNER or LEFT for a LATERAL reference."),
00621                              parser_errposition(orig_pstate, location)));
00622                 result = newresult;
00623             }
00624         }
00625 
00626         if (result != NULL || localonly)
00627             break;              /* found, or don't want to look at parent */
00628 
00629         pstate = pstate->parentParseState;
00630     }
00631 
00632     return result;
00633 }
00634 
00635 /*
00636  * searchRangeTableForCol
00637  *    See if any RangeTblEntry could possibly provide the given column name.
00638  *    If so, return a pointer to the RangeTblEntry; else return NULL.
00639  *
00640  * This is different from colNameToVar in that it considers every entry in
00641  * the ParseState's rangetable(s), not only those that are currently visible
00642  * in the p_namespace list(s).  This behavior is invalid per the SQL spec,
00643  * and it may give ambiguous results (there might be multiple equally valid
00644  * matches, but only one will be returned).  This must be used ONLY as a
00645  * heuristic in giving suitable error messages.  See errorMissingColumn.
00646  */
00647 static RangeTblEntry *
00648 searchRangeTableForCol(ParseState *pstate, char *colname, int location)
00649 {
00650     ParseState *orig_pstate = pstate;
00651 
00652     while (pstate != NULL)
00653     {
00654         ListCell   *l;
00655 
00656         foreach(l, pstate->p_rtable)
00657         {
00658             RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
00659 
00660             if (scanRTEForColumn(orig_pstate, rte, colname, location))
00661                 return rte;
00662         }
00663 
00664         pstate = pstate->parentParseState;
00665     }
00666     return NULL;
00667 }
00668 
00669 /*
00670  * markRTEForSelectPriv
00671  *     Mark the specified column of an RTE as requiring SELECT privilege
00672  *
00673  * col == InvalidAttrNumber means a "whole row" reference
00674  *
00675  * The caller should pass the actual RTE if it has it handy; otherwise pass
00676  * NULL, and we'll look it up here.  (This uglification of the API is
00677  * worthwhile because nearly all external callers have the RTE at hand.)
00678  */
00679 static void
00680 markRTEForSelectPriv(ParseState *pstate, RangeTblEntry *rte,
00681                      int rtindex, AttrNumber col)
00682 {
00683     if (rte == NULL)
00684         rte = rt_fetch(rtindex, pstate->p_rtable);
00685 
00686     if (rte->rtekind == RTE_RELATION)
00687     {
00688         /* Make sure the rel as a whole is marked for SELECT access */
00689         rte->requiredPerms |= ACL_SELECT;
00690         /* Must offset the attnum to fit in a bitmapset */
00691         rte->selectedCols = bms_add_member(rte->selectedCols,
00692                                    col - FirstLowInvalidHeapAttributeNumber);
00693     }
00694     else if (rte->rtekind == RTE_JOIN)
00695     {
00696         if (col == InvalidAttrNumber)
00697         {
00698             /*
00699              * A whole-row reference to a join has to be treated as whole-row
00700              * references to the two inputs.
00701              */
00702             JoinExpr   *j;
00703 
00704             if (rtindex > 0 && rtindex <= list_length(pstate->p_joinexprs))
00705                 j = (JoinExpr *) list_nth(pstate->p_joinexprs, rtindex - 1);
00706             else
00707                 j = NULL;
00708             if (j == NULL)
00709                 elog(ERROR, "could not find JoinExpr for whole-row reference");
00710             Assert(IsA(j, JoinExpr));
00711 
00712             /* Note: we can't see FromExpr here */
00713             if (IsA(j->larg, RangeTblRef))
00714             {
00715                 int         varno = ((RangeTblRef *) j->larg)->rtindex;
00716 
00717                 markRTEForSelectPriv(pstate, NULL, varno, InvalidAttrNumber);
00718             }
00719             else if (IsA(j->larg, JoinExpr))
00720             {
00721                 int         varno = ((JoinExpr *) j->larg)->rtindex;
00722 
00723                 markRTEForSelectPriv(pstate, NULL, varno, InvalidAttrNumber);
00724             }
00725             else
00726                 elog(ERROR, "unrecognized node type: %d",
00727                      (int) nodeTag(j->larg));
00728             if (IsA(j->rarg, RangeTblRef))
00729             {
00730                 int         varno = ((RangeTblRef *) j->rarg)->rtindex;
00731 
00732                 markRTEForSelectPriv(pstate, NULL, varno, InvalidAttrNumber);
00733             }
00734             else if (IsA(j->rarg, JoinExpr))
00735             {
00736                 int         varno = ((JoinExpr *) j->rarg)->rtindex;
00737 
00738                 markRTEForSelectPriv(pstate, NULL, varno, InvalidAttrNumber);
00739             }
00740             else
00741                 elog(ERROR, "unrecognized node type: %d",
00742                      (int) nodeTag(j->rarg));
00743         }
00744         else
00745         {
00746             /*
00747              * Regular join attribute, look at the alias-variable list.
00748              *
00749              * The aliasvar could be either a Var or a COALESCE expression,
00750              * but in the latter case we should already have marked the two
00751              * referent variables as being selected, due to their use in the
00752              * JOIN clause.  So we need only be concerned with the simple Var
00753              * case.
00754              */
00755             Var        *aliasvar;
00756 
00757             Assert(col > 0 && col <= list_length(rte->joinaliasvars));
00758             aliasvar = (Var *) list_nth(rte->joinaliasvars, col - 1);
00759             if (IsA(aliasvar, Var))
00760                 markVarForSelectPriv(pstate, aliasvar, NULL);
00761         }
00762     }
00763     /* other RTE types don't require privilege marking */
00764 }
00765 
00766 /*
00767  * markVarForSelectPriv
00768  *     Mark the RTE referenced by a Var as requiring SELECT privilege
00769  *
00770  * The caller should pass the Var's referenced RTE if it has it handy
00771  * (nearly all do); otherwise pass NULL.
00772  */
00773 void
00774 markVarForSelectPriv(ParseState *pstate, Var *var, RangeTblEntry *rte)
00775 {
00776     Index       lv;
00777 
00778     Assert(IsA(var, Var));
00779     /* Find the appropriate pstate if it's an uplevel Var */
00780     for (lv = 0; lv < var->varlevelsup; lv++)
00781         pstate = pstate->parentParseState;
00782     markRTEForSelectPriv(pstate, rte, var->varno, var->varattno);
00783 }
00784 
00785 /*
00786  * buildRelationAliases
00787  *      Construct the eref column name list for a relation RTE.
00788  *      This code is also used for the case of a function RTE returning
00789  *      a named composite type.
00790  *
00791  * tupdesc: the physical column information
00792  * alias: the user-supplied alias, or NULL if none
00793  * eref: the eref Alias to store column names in
00794  *
00795  * eref->colnames is filled in.  Also, alias->colnames is rebuilt to insert
00796  * empty strings for any dropped columns, so that it will be one-to-one with
00797  * physical column numbers.
00798  */
00799 static void
00800 buildRelationAliases(TupleDesc tupdesc, Alias *alias, Alias *eref)
00801 {
00802     int         maxattrs = tupdesc->natts;
00803     ListCell   *aliaslc;
00804     int         numaliases;
00805     int         varattno;
00806     int         numdropped = 0;
00807 
00808     Assert(eref->colnames == NIL);
00809 
00810     if (alias)
00811     {
00812         aliaslc = list_head(alias->colnames);
00813         numaliases = list_length(alias->colnames);
00814         /* We'll rebuild the alias colname list */
00815         alias->colnames = NIL;
00816     }
00817     else
00818     {
00819         aliaslc = NULL;
00820         numaliases = 0;
00821     }
00822 
00823     for (varattno = 0; varattno < maxattrs; varattno++)
00824     {
00825         Form_pg_attribute attr = tupdesc->attrs[varattno];
00826         Value      *attrname;
00827 
00828         if (attr->attisdropped)
00829         {
00830             /* Always insert an empty string for a dropped column */
00831             attrname = makeString(pstrdup(""));
00832             if (aliaslc)
00833                 alias->colnames = lappend(alias->colnames, attrname);
00834             numdropped++;
00835         }
00836         else if (aliaslc)
00837         {
00838             /* Use the next user-supplied alias */
00839             attrname = (Value *) lfirst(aliaslc);
00840             aliaslc = lnext(aliaslc);
00841             alias->colnames = lappend(alias->colnames, attrname);
00842         }
00843         else
00844         {
00845             attrname = makeString(pstrdup(NameStr(attr->attname)));
00846             /* we're done with the alias if any */
00847         }
00848 
00849         eref->colnames = lappend(eref->colnames, attrname);
00850     }
00851 
00852     /* Too many user-supplied aliases? */
00853     if (aliaslc)
00854         ereport(ERROR,
00855                 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
00856                  errmsg("table \"%s\" has %d columns available but %d columns specified",
00857                         eref->aliasname, maxattrs - numdropped, numaliases)));
00858 }
00859 
00860 /*
00861  * buildScalarFunctionAlias
00862  *      Construct the eref column name list for a function RTE,
00863  *      when the function returns a scalar type (not composite or RECORD).
00864  *
00865  * funcexpr: transformed expression tree for the function call
00866  * funcname: function name (used only for error message)
00867  * alias: the user-supplied alias, or NULL if none
00868  * eref: the eref Alias to store column names in
00869  *
00870  * eref->colnames is filled in.
00871  */
00872 static void
00873 buildScalarFunctionAlias(Node *funcexpr, char *funcname,
00874                          Alias *alias, Alias *eref)
00875 {
00876     char       *pname;
00877 
00878     Assert(eref->colnames == NIL);
00879 
00880     /* Use user-specified column alias if there is one. */
00881     if (alias && alias->colnames != NIL)
00882     {
00883         if (list_length(alias->colnames) != 1)
00884             ereport(ERROR,
00885                     (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
00886                   errmsg("too many column aliases specified for function %s",
00887                          funcname)));
00888         eref->colnames = copyObject(alias->colnames);
00889         return;
00890     }
00891 
00892     /*
00893      * If the expression is a simple function call, and the function has a
00894      * single OUT parameter that is named, use the parameter's name.
00895      */
00896     if (funcexpr && IsA(funcexpr, FuncExpr))
00897     {
00898         pname = get_func_result_name(((FuncExpr *) funcexpr)->funcid);
00899         if (pname)
00900         {
00901             eref->colnames = list_make1(makeString(pname));
00902             return;
00903         }
00904     }
00905 
00906     /*
00907      * Otherwise use the previously-determined alias (not necessarily the
00908      * function name!)
00909      */
00910     eref->colnames = list_make1(makeString(eref->aliasname));
00911 }
00912 
00913 /*
00914  * Open a table during parse analysis
00915  *
00916  * This is essentially just the same as heap_openrv(), except that it caters
00917  * to some parser-specific error reporting needs, notably that it arranges
00918  * to include the RangeVar's parse location in any resulting error.
00919  *
00920  * Note: properly, lockmode should be declared LOCKMODE not int, but that
00921  * would require importing storage/lock.h into parse_relation.h.  Since
00922  * LOCKMODE is typedef'd as int anyway, that seems like overkill.
00923  */
00924 Relation
00925 parserOpenTable(ParseState *pstate, const RangeVar *relation, int lockmode)
00926 {
00927     Relation    rel;
00928     ParseCallbackState pcbstate;
00929 
00930     setup_parser_errposition_callback(&pcbstate, pstate, relation->location);
00931     rel = heap_openrv_extended(relation, lockmode, true);
00932     if (rel == NULL)
00933     {
00934         if (relation->schemaname)
00935             ereport(ERROR,
00936                     (errcode(ERRCODE_UNDEFINED_TABLE),
00937                      errmsg("relation \"%s.%s\" does not exist",
00938                             relation->schemaname, relation->relname)));
00939         else
00940         {
00941             /*
00942              * An unqualified name might have been meant as a reference to
00943              * some not-yet-in-scope CTE.  The bare "does not exist" message
00944              * has proven remarkably unhelpful for figuring out such problems,
00945              * so we take pains to offer a specific hint.
00946              */
00947             if (isFutureCTE(pstate, relation->relname))
00948                 ereport(ERROR,
00949                         (errcode(ERRCODE_UNDEFINED_TABLE),
00950                          errmsg("relation \"%s\" does not exist",
00951                                 relation->relname),
00952                          errdetail("There is a WITH item named \"%s\", but it cannot be referenced from this part of the query.",
00953                                    relation->relname),
00954                          errhint("Use WITH RECURSIVE, or re-order the WITH items to remove forward references.")));
00955             else
00956                 ereport(ERROR,
00957                         (errcode(ERRCODE_UNDEFINED_TABLE),
00958                          errmsg("relation \"%s\" does not exist",
00959                                 relation->relname)));
00960         }
00961     }
00962     cancel_parser_errposition_callback(&pcbstate);
00963     return rel;
00964 }
00965 
00966 /*
00967  * Add an entry for a relation to the pstate's range table (p_rtable).
00968  *
00969  * If pstate is NULL, we just build an RTE and return it without adding it
00970  * to an rtable list.
00971  *
00972  * Note: formerly this checked for refname conflicts, but that's wrong.
00973  * Caller is responsible for checking for conflicts in the appropriate scope.
00974  */
00975 RangeTblEntry *
00976 addRangeTableEntry(ParseState *pstate,
00977                    RangeVar *relation,
00978                    Alias *alias,
00979                    bool inh,
00980                    bool inFromCl)
00981 {
00982     RangeTblEntry *rte = makeNode(RangeTblEntry);
00983     char       *refname = alias ? alias->aliasname : relation->relname;
00984     LOCKMODE    lockmode;
00985     Relation    rel;
00986 
00987     rte->rtekind = RTE_RELATION;
00988     rte->alias = alias;
00989 
00990     /*
00991      * Get the rel's OID.  This access also ensures that we have an up-to-date
00992      * relcache entry for the rel.  Since this is typically the first access
00993      * to a rel in a statement, be careful to get the right access level
00994      * depending on whether we're doing SELECT FOR UPDATE/SHARE.
00995      */
00996     lockmode = isLockedRefname(pstate, refname) ? RowShareLock : AccessShareLock;
00997     rel = parserOpenTable(pstate, relation, lockmode);
00998     rte->relid = RelationGetRelid(rel);
00999     rte->relkind = rel->rd_rel->relkind;
01000 
01001     /*
01002      * Build the list of effective column names using user-supplied aliases
01003      * and/or actual column names.
01004      */
01005     rte->eref = makeAlias(refname, NIL);
01006     buildRelationAliases(rel->rd_att, alias, rte->eref);
01007 
01008     /*
01009      * Drop the rel refcount, but keep the access lock till end of transaction
01010      * so that the table can't be deleted or have its schema modified
01011      * underneath us.
01012      */
01013     heap_close(rel, NoLock);
01014 
01015     /*
01016      * Set flags and access permissions.
01017      *
01018      * The initial default on access checks is always check-for-READ-access,
01019      * which is the right thing for all except target tables.
01020      */
01021     rte->lateral = false;
01022     rte->inh = inh;
01023     rte->inFromCl = inFromCl;
01024 
01025     rte->requiredPerms = ACL_SELECT;
01026     rte->checkAsUser = InvalidOid;      /* not set-uid by default, either */
01027     rte->selectedCols = NULL;
01028     rte->modifiedCols = NULL;
01029 
01030     /*
01031      * Add completed RTE to pstate's range table list, but not to join list
01032      * nor namespace --- caller must do that if appropriate.
01033      */
01034     if (pstate != NULL)
01035         pstate->p_rtable = lappend(pstate->p_rtable, rte);
01036 
01037     return rte;
01038 }
01039 
01040 /*
01041  * Add an entry for a relation to the pstate's range table (p_rtable).
01042  *
01043  * This is just like addRangeTableEntry() except that it makes an RTE
01044  * given an already-open relation instead of a RangeVar reference.
01045  */
01046 RangeTblEntry *
01047 addRangeTableEntryForRelation(ParseState *pstate,
01048                               Relation rel,
01049                               Alias *alias,
01050                               bool inh,
01051                               bool inFromCl)
01052 {
01053     RangeTblEntry *rte = makeNode(RangeTblEntry);
01054     char       *refname = alias ? alias->aliasname : RelationGetRelationName(rel);
01055 
01056     rte->rtekind = RTE_RELATION;
01057     rte->alias = alias;
01058     rte->relid = RelationGetRelid(rel);
01059     rte->relkind = rel->rd_rel->relkind;
01060 
01061     /*
01062      * Build the list of effective column names using user-supplied aliases
01063      * and/or actual column names.
01064      */
01065     rte->eref = makeAlias(refname, NIL);
01066     buildRelationAliases(rel->rd_att, alias, rte->eref);
01067 
01068     /*
01069      * Set flags and access permissions.
01070      *
01071      * The initial default on access checks is always check-for-READ-access,
01072      * which is the right thing for all except target tables.
01073      */
01074     rte->lateral = false;
01075     rte->inh = inh;
01076     rte->inFromCl = inFromCl;
01077 
01078     rte->requiredPerms = ACL_SELECT;
01079     rte->checkAsUser = InvalidOid;      /* not set-uid by default, either */
01080     rte->selectedCols = NULL;
01081     rte->modifiedCols = NULL;
01082 
01083     /*
01084      * Add completed RTE to pstate's range table list, but not to join list
01085      * nor namespace --- caller must do that if appropriate.
01086      */
01087     if (pstate != NULL)
01088         pstate->p_rtable = lappend(pstate->p_rtable, rte);
01089 
01090     return rte;
01091 }
01092 
01093 /*
01094  * Add an entry for a subquery to the pstate's range table (p_rtable).
01095  *
01096  * This is just like addRangeTableEntry() except that it makes a subquery RTE.
01097  * Note that an alias clause *must* be supplied.
01098  */
01099 RangeTblEntry *
01100 addRangeTableEntryForSubquery(ParseState *pstate,
01101                               Query *subquery,
01102                               Alias *alias,
01103                               bool lateral,
01104                               bool inFromCl)
01105 {
01106     RangeTblEntry *rte = makeNode(RangeTblEntry);
01107     char       *refname = alias->aliasname;
01108     Alias      *eref;
01109     int         numaliases;
01110     int         varattno;
01111     ListCell   *tlistitem;
01112 
01113     rte->rtekind = RTE_SUBQUERY;
01114     rte->relid = InvalidOid;
01115     rte->subquery = subquery;
01116     rte->alias = alias;
01117 
01118     eref = copyObject(alias);
01119     numaliases = list_length(eref->colnames);
01120 
01121     /* fill in any unspecified alias columns */
01122     varattno = 0;
01123     foreach(tlistitem, subquery->targetList)
01124     {
01125         TargetEntry *te = (TargetEntry *) lfirst(tlistitem);
01126 
01127         if (te->resjunk)
01128             continue;
01129         varattno++;
01130         Assert(varattno == te->resno);
01131         if (varattno > numaliases)
01132         {
01133             char       *attrname;
01134 
01135             attrname = pstrdup(te->resname);
01136             eref->colnames = lappend(eref->colnames, makeString(attrname));
01137         }
01138     }
01139     if (varattno < numaliases)
01140         ereport(ERROR,
01141                 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
01142                  errmsg("table \"%s\" has %d columns available but %d columns specified",
01143                         refname, varattno, numaliases)));
01144 
01145     rte->eref = eref;
01146 
01147     /*
01148      * Set flags and access permissions.
01149      *
01150      * Subqueries are never checked for access rights.
01151      */
01152     rte->lateral = lateral;
01153     rte->inh = false;           /* never true for subqueries */
01154     rte->inFromCl = inFromCl;
01155 
01156     rte->requiredPerms = 0;
01157     rte->checkAsUser = InvalidOid;
01158     rte->selectedCols = NULL;
01159     rte->modifiedCols = NULL;
01160 
01161     /*
01162      * Add completed RTE to pstate's range table list, but not to join list
01163      * nor namespace --- caller must do that if appropriate.
01164      */
01165     if (pstate != NULL)
01166         pstate->p_rtable = lappend(pstate->p_rtable, rte);
01167 
01168     return rte;
01169 }
01170 
01171 /*
01172  * Add an entry for a function to the pstate's range table (p_rtable).
01173  *
01174  * This is just like addRangeTableEntry() except that it makes a function RTE.
01175  */
01176 RangeTblEntry *
01177 addRangeTableEntryForFunction(ParseState *pstate,
01178                               char *funcname,
01179                               Node *funcexpr,
01180                               RangeFunction *rangefunc,
01181                               bool lateral,
01182                               bool inFromCl)
01183 {
01184     RangeTblEntry *rte = makeNode(RangeTblEntry);
01185     TypeFuncClass functypclass;
01186     Oid         funcrettype;
01187     TupleDesc   tupdesc;
01188     Alias      *alias = rangefunc->alias;
01189     List       *coldeflist = rangefunc->coldeflist;
01190     Alias      *eref;
01191 
01192     rte->rtekind = RTE_FUNCTION;
01193     rte->relid = InvalidOid;
01194     rte->subquery = NULL;
01195     rte->funcexpr = funcexpr;
01196     rte->funccoltypes = NIL;
01197     rte->funccoltypmods = NIL;
01198     rte->funccolcollations = NIL;
01199     rte->alias = alias;
01200 
01201     eref = makeAlias(alias ? alias->aliasname : funcname, NIL);
01202     rte->eref = eref;
01203 
01204     /*
01205      * Now determine if the function returns a simple or composite type.
01206      */
01207     functypclass = get_expr_result_type(funcexpr,
01208                                         &funcrettype,
01209                                         &tupdesc);
01210 
01211     /*
01212      * A coldeflist is required if the function returns RECORD and hasn't got
01213      * a predetermined record type, and is prohibited otherwise.
01214      */
01215     if (coldeflist != NIL)
01216     {
01217         if (functypclass != TYPEFUNC_RECORD)
01218             ereport(ERROR,
01219                     (errcode(ERRCODE_SYNTAX_ERROR),
01220                      errmsg("a column definition list is only allowed for functions returning \"record\""),
01221                      parser_errposition(pstate, exprLocation(funcexpr))));
01222     }
01223     else
01224     {
01225         if (functypclass == TYPEFUNC_RECORD)
01226             ereport(ERROR,
01227                     (errcode(ERRCODE_SYNTAX_ERROR),
01228                      errmsg("a column definition list is required for functions returning \"record\""),
01229                      parser_errposition(pstate, exprLocation(funcexpr))));
01230     }
01231 
01232     if (functypclass == TYPEFUNC_COMPOSITE)
01233     {
01234         /* Composite data type, e.g. a table's row type */
01235         Assert(tupdesc);
01236         /* Build the column alias list */
01237         buildRelationAliases(tupdesc, alias, eref);
01238     }
01239     else if (functypclass == TYPEFUNC_SCALAR)
01240     {
01241         /* Base data type, i.e. scalar */
01242         buildScalarFunctionAlias(funcexpr, funcname, alias, eref);
01243     }
01244     else if (functypclass == TYPEFUNC_RECORD)
01245     {
01246         ListCell   *col;
01247 
01248         /*
01249          * Use the column definition list to form the alias list and
01250          * funccoltypes/funccoltypmods/funccolcollations lists.
01251          */
01252         foreach(col, coldeflist)
01253         {
01254             ColumnDef  *n = (ColumnDef *) lfirst(col);
01255             char       *attrname;
01256             Oid         attrtype;
01257             int32       attrtypmod;
01258             Oid         attrcollation;
01259 
01260             attrname = pstrdup(n->colname);
01261             if (n->typeName->setof)
01262                 ereport(ERROR,
01263                         (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
01264                          errmsg("column \"%s\" cannot be declared SETOF",
01265                                 attrname),
01266                          parser_errposition(pstate, n->typeName->location)));
01267             typenameTypeIdAndMod(pstate, n->typeName, &attrtype, &attrtypmod);
01268             attrcollation = GetColumnDefCollation(pstate, n, attrtype);
01269             eref->colnames = lappend(eref->colnames, makeString(attrname));
01270             rte->funccoltypes = lappend_oid(rte->funccoltypes, attrtype);
01271             rte->funccoltypmods = lappend_int(rte->funccoltypmods, attrtypmod);
01272             rte->funccolcollations = lappend_oid(rte->funccolcollations,
01273                                                  attrcollation);
01274         }
01275     }
01276     else
01277         ereport(ERROR,
01278                 (errcode(ERRCODE_DATATYPE_MISMATCH),
01279              errmsg("function \"%s\" in FROM has unsupported return type %s",
01280                     funcname, format_type_be(funcrettype)),
01281                  parser_errposition(pstate, exprLocation(funcexpr))));
01282 
01283     /*
01284      * Set flags and access permissions.
01285      *
01286      * Functions are never checked for access rights (at least, not by the RTE
01287      * permissions mechanism).
01288      */
01289     rte->lateral = lateral;
01290     rte->inh = false;           /* never true for functions */
01291     rte->inFromCl = inFromCl;
01292 
01293     rte->requiredPerms = 0;
01294     rte->checkAsUser = InvalidOid;
01295     rte->selectedCols = NULL;
01296     rte->modifiedCols = NULL;
01297 
01298     /*
01299      * Add completed RTE to pstate's range table list, but not to join list
01300      * nor namespace --- caller must do that if appropriate.
01301      */
01302     if (pstate != NULL)
01303         pstate->p_rtable = lappend(pstate->p_rtable, rte);
01304 
01305     return rte;
01306 }
01307 
01308 /*
01309  * Add an entry for a VALUES list to the pstate's range table (p_rtable).
01310  *
01311  * This is much like addRangeTableEntry() except that it makes a values RTE.
01312  */
01313 RangeTblEntry *
01314 addRangeTableEntryForValues(ParseState *pstate,
01315                             List *exprs,
01316                             List *collations,
01317                             Alias *alias,
01318                             bool lateral,
01319                             bool inFromCl)
01320 {
01321     RangeTblEntry *rte = makeNode(RangeTblEntry);
01322     char       *refname = alias ? alias->aliasname : pstrdup("*VALUES*");
01323     Alias      *eref;
01324     int         numaliases;
01325     int         numcolumns;
01326 
01327     rte->rtekind = RTE_VALUES;
01328     rte->relid = InvalidOid;
01329     rte->subquery = NULL;
01330     rte->values_lists = exprs;
01331     rte->values_collations = collations;
01332     rte->alias = alias;
01333 
01334     eref = alias ? copyObject(alias) : makeAlias(refname, NIL);
01335 
01336     /* fill in any unspecified alias columns */
01337     numcolumns = list_length((List *) linitial(exprs));
01338     numaliases = list_length(eref->colnames);
01339     while (numaliases < numcolumns)
01340     {
01341         char        attrname[64];
01342 
01343         numaliases++;
01344         snprintf(attrname, sizeof(attrname), "column%d", numaliases);
01345         eref->colnames = lappend(eref->colnames,
01346                                  makeString(pstrdup(attrname)));
01347     }
01348     if (numcolumns < numaliases)
01349         ereport(ERROR,
01350                 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
01351                  errmsg("VALUES lists \"%s\" have %d columns available but %d columns specified",
01352                         refname, numcolumns, numaliases)));
01353 
01354     rte->eref = eref;
01355 
01356     /*
01357      * Set flags and access permissions.
01358      *
01359      * Subqueries are never checked for access rights.
01360      */
01361     rte->lateral = lateral;
01362     rte->inh = false;           /* never true for values RTEs */
01363     rte->inFromCl = inFromCl;
01364 
01365     rte->requiredPerms = 0;
01366     rte->checkAsUser = InvalidOid;
01367     rte->selectedCols = NULL;
01368     rte->modifiedCols = NULL;
01369 
01370     /*
01371      * Add completed RTE to pstate's range table list, but not to join list
01372      * nor namespace --- caller must do that if appropriate.
01373      */
01374     if (pstate != NULL)
01375         pstate->p_rtable = lappend(pstate->p_rtable, rte);
01376 
01377     return rte;
01378 }
01379 
01380 /*
01381  * Add an entry for a join to the pstate's range table (p_rtable).
01382  *
01383  * This is much like addRangeTableEntry() except that it makes a join RTE.
01384  */
01385 RangeTblEntry *
01386 addRangeTableEntryForJoin(ParseState *pstate,
01387                           List *colnames,
01388                           JoinType jointype,
01389                           List *aliasvars,
01390                           Alias *alias,
01391                           bool inFromCl)
01392 {
01393     RangeTblEntry *rte = makeNode(RangeTblEntry);
01394     Alias      *eref;
01395     int         numaliases;
01396 
01397     /*
01398      * Fail if join has too many columns --- we must be able to reference any
01399      * of the columns with an AttrNumber.
01400      */
01401     if (list_length(aliasvars) > MaxAttrNumber)
01402         ereport(ERROR,
01403                 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
01404                  errmsg("joins can have at most %d columns",
01405                         MaxAttrNumber)));
01406 
01407     rte->rtekind = RTE_JOIN;
01408     rte->relid = InvalidOid;
01409     rte->subquery = NULL;
01410     rte->jointype = jointype;
01411     rte->joinaliasvars = aliasvars;
01412     rte->alias = alias;
01413 
01414     eref = alias ? (Alias *) copyObject(alias) : makeAlias("unnamed_join", NIL);
01415     numaliases = list_length(eref->colnames);
01416 
01417     /* fill in any unspecified alias columns */
01418     if (numaliases < list_length(colnames))
01419         eref->colnames = list_concat(eref->colnames,
01420                                      list_copy_tail(colnames, numaliases));
01421 
01422     rte->eref = eref;
01423 
01424     /*
01425      * Set flags and access permissions.
01426      *
01427      * Joins are never checked for access rights.
01428      */
01429     rte->lateral = false;
01430     rte->inh = false;           /* never true for joins */
01431     rte->inFromCl = inFromCl;
01432 
01433     rte->requiredPerms = 0;
01434     rte->checkAsUser = InvalidOid;
01435     rte->selectedCols = NULL;
01436     rte->modifiedCols = NULL;
01437 
01438     /*
01439      * Add completed RTE to pstate's range table list, but not to join list
01440      * nor namespace --- caller must do that if appropriate.
01441      */
01442     if (pstate != NULL)
01443         pstate->p_rtable = lappend(pstate->p_rtable, rte);
01444 
01445     return rte;
01446 }
01447 
01448 /*
01449  * Add an entry for a CTE reference to the pstate's range table (p_rtable).
01450  *
01451  * This is much like addRangeTableEntry() except that it makes a CTE RTE.
01452  */
01453 RangeTblEntry *
01454 addRangeTableEntryForCTE(ParseState *pstate,
01455                          CommonTableExpr *cte,
01456                          Index levelsup,
01457                          RangeVar *rv,
01458                          bool inFromCl)
01459 {
01460     RangeTblEntry *rte = makeNode(RangeTblEntry);
01461     Alias      *alias = rv->alias;
01462     char       *refname = alias ? alias->aliasname : cte->ctename;
01463     Alias      *eref;
01464     int         numaliases;
01465     int         varattno;
01466     ListCell   *lc;
01467 
01468     rte->rtekind = RTE_CTE;
01469     rte->ctename = cte->ctename;
01470     rte->ctelevelsup = levelsup;
01471 
01472     /* Self-reference if and only if CTE's parse analysis isn't completed */
01473     rte->self_reference = !IsA(cte->ctequery, Query);
01474     Assert(cte->cterecursive || !rte->self_reference);
01475     /* Bump the CTE's refcount if this isn't a self-reference */
01476     if (!rte->self_reference)
01477         cte->cterefcount++;
01478 
01479     /*
01480      * We throw error if the CTE is INSERT/UPDATE/DELETE without RETURNING.
01481      * This won't get checked in case of a self-reference, but that's OK
01482      * because data-modifying CTEs aren't allowed to be recursive anyhow.
01483      */
01484     if (IsA(cte->ctequery, Query))
01485     {
01486         Query      *ctequery = (Query *) cte->ctequery;
01487 
01488         if (ctequery->commandType != CMD_SELECT &&
01489             ctequery->returningList == NIL)
01490             ereport(ERROR,
01491                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
01492                  errmsg("WITH query \"%s\" does not have a RETURNING clause",
01493                         cte->ctename),
01494                      parser_errposition(pstate, rv->location)));
01495     }
01496 
01497     rte->ctecoltypes = cte->ctecoltypes;
01498     rte->ctecoltypmods = cte->ctecoltypmods;
01499     rte->ctecolcollations = cte->ctecolcollations;
01500 
01501     rte->alias = alias;
01502     if (alias)
01503         eref = copyObject(alias);
01504     else
01505         eref = makeAlias(refname, NIL);
01506     numaliases = list_length(eref->colnames);
01507 
01508     /* fill in any unspecified alias columns */
01509     varattno = 0;
01510     foreach(lc, cte->ctecolnames)
01511     {
01512         varattno++;
01513         if (varattno > numaliases)
01514             eref->colnames = lappend(eref->colnames, lfirst(lc));
01515     }
01516     if (varattno < numaliases)
01517         ereport(ERROR,
01518                 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
01519                  errmsg("table \"%s\" has %d columns available but %d columns specified",
01520                         refname, varattno, numaliases)));
01521 
01522     rte->eref = eref;
01523 
01524     /*
01525      * Set flags and access permissions.
01526      *
01527      * Subqueries are never checked for access rights.
01528      */
01529     rte->lateral = false;
01530     rte->inh = false;           /* never true for subqueries */
01531     rte->inFromCl = inFromCl;
01532 
01533     rte->requiredPerms = 0;
01534     rte->checkAsUser = InvalidOid;
01535     rte->selectedCols = NULL;
01536     rte->modifiedCols = NULL;
01537 
01538     /*
01539      * Add completed RTE to pstate's range table list, but not to join list
01540      * nor namespace --- caller must do that if appropriate.
01541      */
01542     if (pstate != NULL)
01543         pstate->p_rtable = lappend(pstate->p_rtable, rte);
01544 
01545     return rte;
01546 }
01547 
01548 
01549 /*
01550  * Has the specified refname been selected FOR UPDATE/FOR SHARE?
01551  *
01552  * This is used when we have not yet done transformLockingClause, but need
01553  * to know the correct lock to take during initial opening of relations.
01554  *
01555  * Note: we pay no attention to whether it's FOR UPDATE vs FOR SHARE,
01556  * since the table-level lock is the same either way.
01557  */
01558 bool
01559 isLockedRefname(ParseState *pstate, const char *refname)
01560 {
01561     ListCell   *l;
01562 
01563     /*
01564      * If we are in a subquery specified as locked FOR UPDATE/SHARE from
01565      * parent level, then act as though there's a generic FOR UPDATE here.
01566      */
01567     if (pstate->p_locked_from_parent)
01568         return true;
01569 
01570     foreach(l, pstate->p_locking_clause)
01571     {
01572         LockingClause *lc = (LockingClause *) lfirst(l);
01573 
01574         if (lc->lockedRels == NIL)
01575         {
01576             /* all tables used in query */
01577             return true;
01578         }
01579         else
01580         {
01581             /* just the named tables */
01582             ListCell   *l2;
01583 
01584             foreach(l2, lc->lockedRels)
01585             {
01586                 RangeVar   *thisrel = (RangeVar *) lfirst(l2);
01587 
01588                 if (strcmp(refname, thisrel->relname) == 0)
01589                     return true;
01590             }
01591         }
01592     }
01593     return false;
01594 }
01595 
01596 /*
01597  * Add the given RTE as a top-level entry in the pstate's join list
01598  * and/or namespace list.  (We assume caller has checked for any
01599  * namespace conflicts.)  The RTE is always marked as unconditionally
01600  * visible, that is, not LATERAL-only.
01601  */
01602 void
01603 addRTEtoQuery(ParseState *pstate, RangeTblEntry *rte,
01604               bool addToJoinList,
01605               bool addToRelNameSpace, bool addToVarNameSpace)
01606 {
01607     if (addToJoinList)
01608     {
01609         int         rtindex = RTERangeTablePosn(pstate, rte, NULL);
01610         RangeTblRef *rtr = makeNode(RangeTblRef);
01611 
01612         rtr->rtindex = rtindex;
01613         pstate->p_joinlist = lappend(pstate->p_joinlist, rtr);
01614     }
01615     if (addToRelNameSpace || addToVarNameSpace)
01616     {
01617         ParseNamespaceItem *nsitem;
01618 
01619         nsitem = (ParseNamespaceItem *) palloc(sizeof(ParseNamespaceItem));
01620         nsitem->p_rte = rte;
01621         nsitem->p_rel_visible = addToRelNameSpace;
01622         nsitem->p_cols_visible = addToVarNameSpace;
01623         nsitem->p_lateral_only = false;
01624         nsitem->p_lateral_ok = true;
01625         pstate->p_namespace = lappend(pstate->p_namespace, nsitem);
01626     }
01627 }
01628 
01629 /*
01630  * expandRTE -- expand the columns of a rangetable entry
01631  *
01632  * This creates lists of an RTE's column names (aliases if provided, else
01633  * real names) and Vars for each column.  Only user columns are considered.
01634  * If include_dropped is FALSE then dropped columns are omitted from the
01635  * results.  If include_dropped is TRUE then empty strings and NULL constants
01636  * (not Vars!) are returned for dropped columns.
01637  *
01638  * rtindex, sublevels_up, and location are the varno, varlevelsup, and location
01639  * values to use in the created Vars.  Ordinarily rtindex should match the
01640  * actual position of the RTE in its rangetable.
01641  *
01642  * The output lists go into *colnames and *colvars.
01643  * If only one of the two kinds of output list is needed, pass NULL for the
01644  * output pointer for the unwanted one.
01645  */
01646 void
01647 expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up,
01648           int location, bool include_dropped,
01649           List **colnames, List **colvars)
01650 {
01651     int         varattno;
01652 
01653     if (colnames)
01654         *colnames = NIL;
01655     if (colvars)
01656         *colvars = NIL;
01657 
01658     switch (rte->rtekind)
01659     {
01660         case RTE_RELATION:
01661             /* Ordinary relation RTE */
01662             expandRelation(rte->relid, rte->eref,
01663                            rtindex, sublevels_up, location,
01664                            include_dropped, colnames, colvars);
01665             break;
01666         case RTE_SUBQUERY:
01667             {
01668                 /* Subquery RTE */
01669                 ListCell   *aliasp_item = list_head(rte->eref->colnames);
01670                 ListCell   *tlistitem;
01671 
01672                 varattno = 0;
01673                 foreach(tlistitem, rte->subquery->targetList)
01674                 {
01675                     TargetEntry *te = (TargetEntry *) lfirst(tlistitem);
01676 
01677                     if (te->resjunk)
01678                         continue;
01679                     varattno++;
01680                     Assert(varattno == te->resno);
01681 
01682                     if (colnames)
01683                     {
01684                         /* Assume there is one alias per target item */
01685                         char       *label = strVal(lfirst(aliasp_item));
01686 
01687                         *colnames = lappend(*colnames, makeString(pstrdup(label)));
01688                         aliasp_item = lnext(aliasp_item);
01689                     }
01690 
01691                     if (colvars)
01692                     {
01693                         Var        *varnode;
01694 
01695                         varnode = makeVar(rtindex, varattno,
01696                                           exprType((Node *) te->expr),
01697                                           exprTypmod((Node *) te->expr),
01698                                           exprCollation((Node *) te->expr),
01699                                           sublevels_up);
01700                         varnode->location = location;
01701 
01702                         *colvars = lappend(*colvars, varnode);
01703                     }
01704                 }
01705             }
01706             break;
01707         case RTE_FUNCTION:
01708             {
01709                 /* Function RTE */
01710                 TypeFuncClass functypclass;
01711                 Oid         funcrettype;
01712                 TupleDesc   tupdesc;
01713 
01714                 functypclass = get_expr_result_type(rte->funcexpr,
01715                                                     &funcrettype,
01716                                                     &tupdesc);
01717                 if (functypclass == TYPEFUNC_COMPOSITE)
01718                 {
01719                     /* Composite data type, e.g. a table's row type */
01720                     Assert(tupdesc);
01721                     expandTupleDesc(tupdesc, rte->eref,
01722                                     rtindex, sublevels_up, location,
01723                                     include_dropped, colnames, colvars);
01724                 }
01725                 else if (functypclass == TYPEFUNC_SCALAR)
01726                 {
01727                     /* Base data type, i.e. scalar */
01728                     if (colnames)
01729                         *colnames = lappend(*colnames,
01730                                             linitial(rte->eref->colnames));
01731 
01732                     if (colvars)
01733                     {
01734                         Var        *varnode;
01735 
01736                         varnode = makeVar(rtindex, 1,
01737                                           funcrettype, -1,
01738                                           exprCollation(rte->funcexpr),
01739                                           sublevels_up);
01740                         varnode->location = location;
01741 
01742                         *colvars = lappend(*colvars, varnode);
01743                     }
01744                 }
01745                 else if (functypclass == TYPEFUNC_RECORD)
01746                 {
01747                     if (colnames)
01748                         *colnames = copyObject(rte->eref->colnames);
01749                     if (colvars)
01750                     {
01751                         ListCell   *l1;
01752                         ListCell   *l2;
01753                         ListCell   *l3;
01754                         int         attnum = 0;
01755 
01756                         forthree(l1, rte->funccoltypes,
01757                                  l2, rte->funccoltypmods,
01758                                  l3, rte->funccolcollations)
01759                         {
01760                             Oid         attrtype = lfirst_oid(l1);
01761                             int32       attrtypmod = lfirst_int(l2);
01762                             Oid         attrcollation = lfirst_oid(l3);
01763                             Var        *varnode;
01764 
01765                             attnum++;
01766                             varnode = makeVar(rtindex,
01767                                               attnum,
01768                                               attrtype,
01769                                               attrtypmod,
01770                                               attrcollation,
01771                                               sublevels_up);
01772                             varnode->location = location;
01773                             *colvars = lappend(*colvars, varnode);
01774                         }
01775                     }
01776                 }
01777                 else
01778                 {
01779                     /* addRangeTableEntryForFunction should've caught this */
01780                     elog(ERROR, "function in FROM has unsupported return type");
01781                 }
01782             }
01783             break;
01784         case RTE_VALUES:
01785             {
01786                 /* Values RTE */
01787                 ListCell   *aliasp_item = list_head(rte->eref->colnames);
01788                 ListCell   *lcv;
01789                 ListCell   *lcc;
01790 
01791                 varattno = 0;
01792                 forboth(lcv, (List *) linitial(rte->values_lists),
01793                         lcc, rte->values_collations)
01794                 {
01795                     Node       *col = (Node *) lfirst(lcv);
01796                     Oid         colcollation = lfirst_oid(lcc);
01797 
01798                     varattno++;
01799                     if (colnames)
01800                     {
01801                         /* Assume there is one alias per column */
01802                         char       *label = strVal(lfirst(aliasp_item));
01803 
01804                         *colnames = lappend(*colnames,
01805                                             makeString(pstrdup(label)));
01806                         aliasp_item = lnext(aliasp_item);
01807                     }
01808 
01809                     if (colvars)
01810                     {
01811                         Var        *varnode;
01812 
01813                         varnode = makeVar(rtindex, varattno,
01814                                           exprType(col),
01815                                           exprTypmod(col),
01816                                           colcollation,
01817                                           sublevels_up);
01818                         varnode->location = location;
01819                         *colvars = lappend(*colvars, varnode);
01820                     }
01821                 }
01822             }
01823             break;
01824         case RTE_JOIN:
01825             {
01826                 /* Join RTE */
01827                 ListCell   *colname;
01828                 ListCell   *aliasvar;
01829 
01830                 Assert(list_length(rte->eref->colnames) == list_length(rte->joinaliasvars));
01831 
01832                 varattno = 0;
01833                 forboth(colname, rte->eref->colnames, aliasvar, rte->joinaliasvars)
01834                 {
01835                     Node       *avar = (Node *) lfirst(aliasvar);
01836 
01837                     varattno++;
01838 
01839                     /*
01840                      * During ordinary parsing, there will never be any
01841                      * deleted columns in the join; but we have to check since
01842                      * this routine is also used by the rewriter, and joins
01843                      * found in stored rules might have join columns for
01844                      * since-deleted columns.  This will be signaled by a NULL
01845                      * Const in the alias-vars list.
01846                      */
01847                     if (IsA(avar, Const))
01848                     {
01849                         if (include_dropped)
01850                         {
01851                             if (colnames)
01852                                 *colnames = lappend(*colnames,
01853                                                     makeString(pstrdup("")));
01854                             if (colvars)
01855                                 *colvars = lappend(*colvars,
01856                                                    copyObject(avar));
01857                         }
01858                         continue;
01859                     }
01860 
01861                     if (colnames)
01862                     {
01863                         char       *label = strVal(lfirst(colname));
01864 
01865                         *colnames = lappend(*colnames,
01866                                             makeString(pstrdup(label)));
01867                     }
01868 
01869                     if (colvars)
01870                     {
01871                         Var        *varnode;
01872 
01873                         varnode = makeVar(rtindex, varattno,
01874                                           exprType(avar),
01875                                           exprTypmod(avar),
01876                                           exprCollation(avar),
01877                                           sublevels_up);
01878                         varnode->location = location;
01879 
01880                         *colvars = lappend(*colvars, varnode);
01881                     }
01882                 }
01883             }
01884             break;
01885         case RTE_CTE:
01886             {
01887                 ListCell   *aliasp_item = list_head(rte->eref->colnames);
01888                 ListCell   *lct;
01889                 ListCell   *lcm;
01890                 ListCell   *lcc;
01891 
01892                 varattno = 0;
01893                 forthree(lct, rte->ctecoltypes,
01894                          lcm, rte->ctecoltypmods,
01895                          lcc, rte->ctecolcollations)
01896                 {
01897                     Oid         coltype = lfirst_oid(lct);
01898                     int32       coltypmod = lfirst_int(lcm);
01899                     Oid         colcoll = lfirst_oid(lcc);
01900 
01901                     varattno++;
01902 
01903                     if (colnames)
01904                     {
01905                         /* Assume there is one alias per output column */
01906                         char       *label = strVal(lfirst(aliasp_item));
01907 
01908                         *colnames = lappend(*colnames, makeString(pstrdup(label)));
01909                         aliasp_item = lnext(aliasp_item);
01910                     }
01911 
01912                     if (colvars)
01913                     {
01914                         Var        *varnode;
01915 
01916                         varnode = makeVar(rtindex, varattno,
01917                                           coltype, coltypmod, colcoll,
01918                                           sublevels_up);
01919                         *colvars = lappend(*colvars, varnode);
01920                     }
01921                 }
01922             }
01923             break;
01924         default:
01925             elog(ERROR, "unrecognized RTE kind: %d", (int) rte->rtekind);
01926     }
01927 }
01928 
01929 /*
01930  * expandRelation -- expandRTE subroutine
01931  */
01932 static void
01933 expandRelation(Oid relid, Alias *eref, int rtindex, int sublevels_up,
01934                int location, bool include_dropped,
01935                List **colnames, List **colvars)
01936 {
01937     Relation    rel;
01938 
01939     /* Get the tupledesc and turn it over to expandTupleDesc */
01940     rel = relation_open(relid, AccessShareLock);
01941     expandTupleDesc(rel->rd_att, eref, rtindex, sublevels_up,
01942                     location, include_dropped,
01943                     colnames, colvars);
01944     relation_close(rel, AccessShareLock);
01945 }
01946 
01947 /*
01948  * expandTupleDesc -- expandRTE subroutine
01949  */
01950 static void
01951 expandTupleDesc(TupleDesc tupdesc, Alias *eref,
01952                 int rtindex, int sublevels_up,
01953                 int location, bool include_dropped,
01954                 List **colnames, List **colvars)
01955 {
01956     int         maxattrs = tupdesc->natts;
01957     int         numaliases = list_length(eref->colnames);
01958     int         varattno;
01959 
01960     for (varattno = 0; varattno < maxattrs; varattno++)
01961     {
01962         Form_pg_attribute attr = tupdesc->attrs[varattno];
01963 
01964         if (attr->attisdropped)
01965         {
01966             if (include_dropped)
01967             {
01968                 if (colnames)
01969                     *colnames = lappend(*colnames, makeString(pstrdup("")));
01970                 if (colvars)
01971                 {
01972                     /*
01973                      * can't use atttypid here, but it doesn't really matter
01974                      * what type the Const claims to be.
01975                      */
01976                     *colvars = lappend(*colvars,
01977                                      makeNullConst(INT4OID, -1, InvalidOid));
01978                 }
01979             }
01980             continue;
01981         }
01982 
01983         if (colnames)
01984         {
01985             char       *label;
01986 
01987             if (varattno < numaliases)
01988                 label = strVal(list_nth(eref->colnames, varattno));
01989             else
01990                 label = NameStr(attr->attname);
01991             *colnames = lappend(*colnames, makeString(pstrdup(label)));
01992         }
01993 
01994         if (colvars)
01995         {
01996             Var        *varnode;
01997 
01998             varnode = makeVar(rtindex, attr->attnum,
01999                               attr->atttypid, attr->atttypmod,
02000                               attr->attcollation,
02001                               sublevels_up);
02002             varnode->location = location;
02003 
02004             *colvars = lappend(*colvars, varnode);
02005         }
02006     }
02007 }
02008 
02009 /*
02010  * expandRelAttrs -
02011  *    Workhorse for "*" expansion: produce a list of targetentries
02012  *    for the attributes of the RTE
02013  *
02014  * As with expandRTE, rtindex/sublevels_up determine the varno/varlevelsup
02015  * fields of the Vars produced, and location sets their location.
02016  * pstate->p_next_resno determines the resnos assigned to the TLEs.
02017  * The referenced columns are marked as requiring SELECT access.
02018  */
02019 List *
02020 expandRelAttrs(ParseState *pstate, RangeTblEntry *rte,
02021                int rtindex, int sublevels_up, int location)
02022 {
02023     List       *names,
02024                *vars;
02025     ListCell   *name,
02026                *var;
02027     List       *te_list = NIL;
02028 
02029     expandRTE(rte, rtindex, sublevels_up, location, false,
02030               &names, &vars);
02031 
02032     /*
02033      * Require read access to the table.  This is normally redundant with the
02034      * markVarForSelectPriv calls below, but not if the table has zero
02035      * columns.
02036      */
02037     rte->requiredPerms |= ACL_SELECT;
02038 
02039     forboth(name, names, var, vars)
02040     {
02041         char       *label = strVal(lfirst(name));
02042         Var        *varnode = (Var *) lfirst(var);
02043         TargetEntry *te;
02044 
02045         te = makeTargetEntry((Expr *) varnode,
02046                              (AttrNumber) pstate->p_next_resno++,
02047                              label,
02048                              false);
02049         te_list = lappend(te_list, te);
02050 
02051         /* Require read access to each column */
02052         markVarForSelectPriv(pstate, varnode, rte);
02053     }
02054 
02055     Assert(name == NULL && var == NULL);        /* lists not the same length? */
02056 
02057     return te_list;
02058 }
02059 
02060 /*
02061  * get_rte_attribute_name
02062  *      Get an attribute name from a RangeTblEntry
02063  *
02064  * This is unlike get_attname() because we use aliases if available.
02065  * In particular, it will work on an RTE for a subselect or join, whereas
02066  * get_attname() only works on real relations.
02067  *
02068  * "*" is returned if the given attnum is InvalidAttrNumber --- this case
02069  * occurs when a Var represents a whole tuple of a relation.
02070  */
02071 char *
02072 get_rte_attribute_name(RangeTblEntry *rte, AttrNumber attnum)
02073 {
02074     if (attnum == InvalidAttrNumber)
02075         return "*";
02076 
02077     /*
02078      * If there is a user-written column alias, use it.
02079      */
02080     if (rte->alias &&
02081         attnum > 0 && attnum <= list_length(rte->alias->colnames))
02082         return strVal(list_nth(rte->alias->colnames, attnum - 1));
02083 
02084     /*
02085      * If the RTE is a relation, go to the system catalogs not the
02086      * eref->colnames list.  This is a little slower but it will give the
02087      * right answer if the column has been renamed since the eref list was
02088      * built (which can easily happen for rules).
02089      */
02090     if (rte->rtekind == RTE_RELATION)
02091         return get_relid_attribute_name(rte->relid, attnum);
02092 
02093     /*
02094      * Otherwise use the column name from eref.  There should always be one.
02095      */
02096     if (attnum > 0 && attnum <= list_length(rte->eref->colnames))
02097         return strVal(list_nth(rte->eref->colnames, attnum - 1));
02098 
02099     /* else caller gave us a bogus attnum */
02100     elog(ERROR, "invalid attnum %d for rangetable entry %s",
02101          attnum, rte->eref->aliasname);
02102     return NULL;                /* keep compiler quiet */
02103 }
02104 
02105 /*
02106  * get_rte_attribute_type
02107  *      Get attribute type/typmod/collation information from a RangeTblEntry
02108  */
02109 void
02110 get_rte_attribute_type(RangeTblEntry *rte, AttrNumber attnum,
02111                        Oid *vartype, int32 *vartypmod, Oid *varcollid)
02112 {
02113     switch (rte->rtekind)
02114     {
02115         case RTE_RELATION:
02116             {
02117                 /* Plain relation RTE --- get the attribute's type info */
02118                 HeapTuple   tp;
02119                 Form_pg_attribute att_tup;
02120 
02121                 tp = SearchSysCache2(ATTNUM,
02122                                      ObjectIdGetDatum(rte->relid),
02123                                      Int16GetDatum(attnum));
02124                 if (!HeapTupleIsValid(tp))      /* shouldn't happen */
02125                     elog(ERROR, "cache lookup failed for attribute %d of relation %u",
02126                          attnum, rte->relid);
02127                 att_tup = (Form_pg_attribute) GETSTRUCT(tp);
02128 
02129                 /*
02130                  * If dropped column, pretend it ain't there.  See notes in
02131                  * scanRTEForColumn.
02132                  */
02133                 if (att_tup->attisdropped)
02134                     ereport(ERROR,
02135                             (errcode(ERRCODE_UNDEFINED_COLUMN),
02136                     errmsg("column \"%s\" of relation \"%s\" does not exist",
02137                            NameStr(att_tup->attname),
02138                            get_rel_name(rte->relid))));
02139                 *vartype = att_tup->atttypid;
02140                 *vartypmod = att_tup->atttypmod;
02141                 *varcollid = att_tup->attcollation;
02142                 ReleaseSysCache(tp);
02143             }
02144             break;
02145         case RTE_SUBQUERY:
02146             {
02147                 /* Subselect RTE --- get type info from subselect's tlist */
02148                 TargetEntry *te = get_tle_by_resno(rte->subquery->targetList,
02149                                                    attnum);
02150 
02151                 if (te == NULL || te->resjunk)
02152                     elog(ERROR, "subquery %s does not have attribute %d",
02153                          rte->eref->aliasname, attnum);
02154                 *vartype = exprType((Node *) te->expr);
02155                 *vartypmod = exprTypmod((Node *) te->expr);
02156                 *varcollid = exprCollation((Node *) te->expr);
02157             }
02158             break;
02159         case RTE_FUNCTION:
02160             {
02161                 /* Function RTE */
02162                 TypeFuncClass functypclass;
02163                 Oid         funcrettype;
02164                 TupleDesc   tupdesc;
02165 
02166                 functypclass = get_expr_result_type(rte->funcexpr,
02167                                                     &funcrettype,
02168                                                     &tupdesc);
02169 
02170                 if (functypclass == TYPEFUNC_COMPOSITE)
02171                 {
02172                     /* Composite data type, e.g. a table's row type */
02173                     Form_pg_attribute att_tup;
02174 
02175                     Assert(tupdesc);
02176                     /* this is probably a can't-happen case */
02177                     if (attnum < 1 || attnum > tupdesc->natts)
02178                         ereport(ERROR,
02179                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
02180                         errmsg("column %d of relation \"%s\" does not exist",
02181                                attnum,
02182                                rte->eref->aliasname)));
02183 
02184                     att_tup = tupdesc->attrs[attnum - 1];
02185 
02186                     /*
02187                      * If dropped column, pretend it ain't there.  See notes
02188                      * in scanRTEForColumn.
02189                      */
02190                     if (att_tup->attisdropped)
02191                         ereport(ERROR,
02192                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
02193                                  errmsg("column \"%s\" of relation \"%s\" does not exist",
02194                                         NameStr(att_tup->attname),
02195                                         rte->eref->aliasname)));
02196                     *vartype = att_tup->atttypid;
02197                     *vartypmod = att_tup->atttypmod;
02198                     *varcollid = att_tup->attcollation;
02199                 }
02200                 else if (functypclass == TYPEFUNC_SCALAR)
02201                 {
02202                     /* Base data type, i.e. scalar */
02203                     *vartype = funcrettype;
02204                     *vartypmod = -1;
02205                     *varcollid = exprCollation(rte->funcexpr);
02206                 }
02207                 else if (functypclass == TYPEFUNC_RECORD)
02208                 {
02209                     *vartype = list_nth_oid(rte->funccoltypes, attnum - 1);
02210                     *vartypmod = list_nth_int(rte->funccoltypmods, attnum - 1);
02211                     *varcollid = list_nth_oid(rte->funccolcollations, attnum - 1);
02212                 }
02213                 else
02214                 {
02215                     /* addRangeTableEntryForFunction should've caught this */
02216                     elog(ERROR, "function in FROM has unsupported return type");
02217                 }
02218             }
02219             break;
02220         case RTE_VALUES:
02221             {
02222                 /* Values RTE --- get type info from first sublist */
02223                 /* collation is stored separately, though */
02224                 List       *collist = (List *) linitial(rte->values_lists);
02225                 Node       *col;
02226 
02227                 if (attnum < 1 || attnum > list_length(collist))
02228                     elog(ERROR, "values list %s does not have attribute %d",
02229                          rte->eref->aliasname, attnum);
02230                 col = (Node *) list_nth(collist, attnum - 1);
02231                 *vartype = exprType(col);
02232                 *vartypmod = exprTypmod(col);
02233                 *varcollid = list_nth_oid(rte->values_collations, attnum - 1);
02234             }
02235             break;
02236         case RTE_JOIN:
02237             {
02238                 /*
02239                  * Join RTE --- get type info from join RTE's alias variable
02240                  */
02241                 Node       *aliasvar;
02242 
02243                 Assert(attnum > 0 && attnum <= list_length(rte->joinaliasvars));
02244                 aliasvar = (Node *) list_nth(rte->joinaliasvars, attnum - 1);
02245                 *vartype = exprType(aliasvar);
02246                 *vartypmod = exprTypmod(aliasvar);
02247                 *varcollid = exprCollation(aliasvar);
02248             }
02249             break;
02250         case RTE_CTE:
02251             {
02252                 /* CTE RTE --- get type info from lists in the RTE */
02253                 Assert(attnum > 0 && attnum <= list_length(rte->ctecoltypes));
02254                 *vartype = list_nth_oid(rte->ctecoltypes, attnum - 1);
02255                 *vartypmod = list_nth_int(rte->ctecoltypmods, attnum - 1);
02256                 *varcollid = list_nth_oid(rte->ctecolcollations, attnum - 1);
02257             }
02258             break;
02259         default:
02260             elog(ERROR, "unrecognized RTE kind: %d", (int) rte->rtekind);
02261     }
02262 }
02263 
02264 /*
02265  * get_rte_attribute_is_dropped
02266  *      Check whether attempted attribute ref is to a dropped column
02267  */
02268 bool
02269 get_rte_attribute_is_dropped(RangeTblEntry *rte, AttrNumber attnum)
02270 {
02271     bool        result;
02272 
02273     switch (rte->rtekind)
02274     {
02275         case RTE_RELATION:
02276             {
02277                 /*
02278                  * Plain relation RTE --- get the attribute's catalog entry
02279                  */
02280                 HeapTuple   tp;
02281                 Form_pg_attribute att_tup;
02282 
02283                 tp = SearchSysCache2(ATTNUM,
02284                                      ObjectIdGetDatum(rte->relid),
02285                                      Int16GetDatum(attnum));
02286                 if (!HeapTupleIsValid(tp))      /* shouldn't happen */
02287                     elog(ERROR, "cache lookup failed for attribute %d of relation %u",
02288                          attnum, rte->relid);
02289                 att_tup = (Form_pg_attribute) GETSTRUCT(tp);
02290                 result = att_tup->attisdropped;
02291                 ReleaseSysCache(tp);
02292             }
02293             break;
02294         case RTE_SUBQUERY:
02295         case RTE_VALUES:
02296         case RTE_CTE:
02297             /* Subselect, Values, CTE RTEs never have dropped columns */
02298             result = false;
02299             break;
02300         case RTE_JOIN:
02301             {
02302                 /*
02303                  * A join RTE would not have dropped columns when constructed,
02304                  * but one in a stored rule might contain columns that were
02305                  * dropped from the underlying tables, if said columns are
02306                  * nowhere explicitly referenced in the rule.  This will be
02307                  * signaled to us by a NULL Const in the joinaliasvars list.
02308                  */
02309                 Var        *aliasvar;
02310 
02311                 if (attnum <= 0 ||
02312                     attnum > list_length(rte->joinaliasvars))
02313                     elog(ERROR, "invalid varattno %d", attnum);
02314                 aliasvar = (Var *) list_nth(rte->joinaliasvars, attnum - 1);
02315 
02316                 result = IsA(aliasvar, Const);
02317             }
02318             break;
02319         case RTE_FUNCTION:
02320             {
02321                 /* Function RTE */
02322                 Oid         funcrettype = exprType(rte->funcexpr);
02323                 Oid         funcrelid = typeidTypeRelid(funcrettype);
02324 
02325                 if (OidIsValid(funcrelid))
02326                 {
02327                     /*
02328                      * Composite data type, i.e. a table's row type
02329                      *
02330                      * Same as ordinary relation RTE
02331                      */
02332                     HeapTuple   tp;
02333                     Form_pg_attribute att_tup;
02334 
02335                     tp = SearchSysCache2(ATTNUM,
02336                                          ObjectIdGetDatum(funcrelid),
02337                                          Int16GetDatum(attnum));
02338                     if (!HeapTupleIsValid(tp))  /* shouldn't happen */
02339                         elog(ERROR, "cache lookup failed for attribute %d of relation %u",
02340                              attnum, funcrelid);
02341                     att_tup = (Form_pg_attribute) GETSTRUCT(tp);
02342                     result = att_tup->attisdropped;
02343                     ReleaseSysCache(tp);
02344                 }
02345                 else
02346                 {
02347                     /*
02348                      * Must be a base data type, i.e. scalar
02349                      */
02350                     result = false;
02351                 }
02352             }
02353             break;
02354         default:
02355             elog(ERROR, "unrecognized RTE kind: %d", (int) rte->rtekind);
02356             result = false;     /* keep compiler quiet */
02357     }
02358 
02359     return result;
02360 }
02361 
02362 /*
02363  * Given a targetlist and a resno, return the matching TargetEntry
02364  *
02365  * Returns NULL if resno is not present in list.
02366  *
02367  * Note: we need to search, rather than just indexing with list_nth(),
02368  * because not all tlists are sorted by resno.
02369  */
02370 TargetEntry *
02371 get_tle_by_resno(List *tlist, AttrNumber resno)
02372 {
02373     ListCell   *l;
02374 
02375     foreach(l, tlist)
02376     {
02377         TargetEntry *tle = (TargetEntry *) lfirst(l);
02378 
02379         if (tle->resno == resno)
02380             return tle;
02381     }
02382     return NULL;
02383 }
02384 
02385 /*
02386  * Given a Query and rangetable index, return relation's RowMarkClause if any
02387  *
02388  * Returns NULL if relation is not selected FOR UPDATE/SHARE
02389  */
02390 RowMarkClause *
02391 get_parse_rowmark(Query *qry, Index rtindex)
02392 {
02393     ListCell   *l;
02394 
02395     foreach(l, qry->rowMarks)
02396     {
02397         RowMarkClause *rc = (RowMarkClause *) lfirst(l);
02398 
02399         if (rc->rti == rtindex)
02400             return rc;
02401     }
02402     return NULL;
02403 }
02404 
02405 /*
02406  *  given relation and att name, return attnum of variable
02407  *
02408  *  Returns InvalidAttrNumber if the attr doesn't exist (or is dropped).
02409  *
02410  *  This should only be used if the relation is already
02411  *  heap_open()'ed.  Use the cache version get_attnum()
02412  *  for access to non-opened relations.
02413  */
02414 int
02415 attnameAttNum(Relation rd, const char *attname, bool sysColOK)
02416 {
02417     int         i;
02418 
02419     for (i = 0; i < rd->rd_rel->relnatts; i++)
02420     {
02421         Form_pg_attribute att = rd->rd_att->attrs[i];
02422 
02423         if (namestrcmp(&(att->attname), attname) == 0 && !att->attisdropped)
02424             return i + 1;
02425     }
02426 
02427     if (sysColOK)
02428     {
02429         if ((i = specialAttNum(attname)) != InvalidAttrNumber)
02430         {
02431             if (i != ObjectIdAttributeNumber || rd->rd_rel->relhasoids)
02432                 return i;
02433         }
02434     }
02435 
02436     /* on failure */
02437     return InvalidAttrNumber;
02438 }
02439 
02440 /* specialAttNum()
02441  *
02442  * Check attribute name to see if it is "special", e.g. "oid".
02443  * - thomas 2000-02-07
02444  *
02445  * Note: this only discovers whether the name could be a system attribute.
02446  * Caller needs to verify that it really is an attribute of the rel,
02447  * at least in the case of "oid", which is now optional.
02448  */
02449 static int
02450 specialAttNum(const char *attname)
02451 {
02452     Form_pg_attribute sysatt;
02453 
02454     sysatt = SystemAttributeByName(attname,
02455                                    true /* "oid" will be accepted */ );
02456     if (sysatt != NULL)
02457         return sysatt->attnum;
02458     return InvalidAttrNumber;
02459 }
02460 
02461 
02462 /*
02463  * given attribute id, return name of that attribute
02464  *
02465  *  This should only be used if the relation is already
02466  *  heap_open()'ed.  Use the cache version get_atttype()
02467  *  for access to non-opened relations.
02468  */
02469 Name
02470 attnumAttName(Relation rd, int attid)
02471 {
02472     if (attid <= 0)
02473     {
02474         Form_pg_attribute sysatt;
02475 
02476         sysatt = SystemAttributeDefinition(attid, rd->rd_rel->relhasoids);
02477         return &sysatt->attname;
02478     }
02479     if (attid > rd->rd_att->natts)
02480         elog(ERROR, "invalid attribute number %d", attid);
02481     return &rd->rd_att->attrs[attid - 1]->attname;
02482 }
02483 
02484 /*
02485  * given attribute id, return type of that attribute
02486  *
02487  *  This should only be used if the relation is already
02488  *  heap_open()'ed.  Use the cache version get_atttype()
02489  *  for access to non-opened relations.
02490  */
02491 Oid
02492 attnumTypeId(Relation rd, int attid)
02493 {
02494     if (attid <= 0)
02495     {
02496         Form_pg_attribute sysatt;
02497 
02498         sysatt = SystemAttributeDefinition(attid, rd->rd_rel->relhasoids);
02499         return sysatt->atttypid;
02500     }
02501     if (attid > rd->rd_att->natts)
02502         elog(ERROR, "invalid attribute number %d", attid);
02503     return rd->rd_att->attrs[attid - 1]->atttypid;
02504 }
02505 
02506 /*
02507  * given attribute id, return collation of that attribute
02508  *
02509  *  This should only be used if the relation is already heap_open()'ed.
02510  */
02511 Oid
02512 attnumCollationId(Relation rd, int attid)
02513 {
02514     if (attid <= 0)
02515     {
02516         /* All system attributes are of noncollatable types. */
02517         return InvalidOid;
02518     }
02519     if (attid > rd->rd_att->natts)
02520         elog(ERROR, "invalid attribute number %d", attid);
02521     return rd->rd_att->attrs[attid - 1]->attcollation;
02522 }
02523 
02524 /*
02525  * Generate a suitable error about a missing RTE.
02526  *
02527  * Since this is a very common type of error, we work rather hard to
02528  * produce a helpful message.
02529  */
02530 void
02531 errorMissingRTE(ParseState *pstate, RangeVar *relation)
02532 {
02533     RangeTblEntry *rte;
02534     int         sublevels_up;
02535     const char *badAlias = NULL;
02536 
02537     /*
02538      * Check to see if there are any potential matches in the query's
02539      * rangetable.  (Note: cases involving a bad schema name in the RangeVar
02540      * will throw error immediately here.  That seems OK.)
02541      */
02542     rte = searchRangeTableForRel(pstate, relation);
02543 
02544     /*
02545      * If we found a match that has an alias and the alias is visible in the
02546      * namespace, then the problem is probably use of the relation's real name
02547      * instead of its alias, ie "SELECT foo.* FROM foo f". This mistake is
02548      * common enough to justify a specific hint.
02549      *
02550      * If we found a match that doesn't meet those criteria, assume the
02551      * problem is illegal use of a relation outside its scope, as in the
02552      * MySQL-ism "SELECT ... FROM a, b LEFT JOIN c ON (a.x = c.y)".
02553      */
02554     if (rte && rte->alias &&
02555         strcmp(rte->eref->aliasname, relation->relname) != 0 &&
02556         refnameRangeTblEntry(pstate, NULL, rte->eref->aliasname,
02557                              relation->location,
02558                              &sublevels_up) == rte)
02559         badAlias = rte->eref->aliasname;
02560 
02561     if (rte)
02562         ereport(ERROR,
02563                 (errcode(ERRCODE_UNDEFINED_TABLE),
02564             errmsg("invalid reference to FROM-clause entry for table \"%s\"",
02565                    relation->relname),
02566                  (badAlias ?
02567             errhint("Perhaps you meant to reference the table alias \"%s\".",
02568                     badAlias) :
02569                   errhint("There is an entry for table \"%s\", but it cannot be referenced from this part of the query.",
02570                           rte->eref->aliasname)),
02571                  parser_errposition(pstate, relation->location)));
02572     else
02573         ereport(ERROR,
02574                 (errcode(ERRCODE_UNDEFINED_TABLE),
02575                  errmsg("missing FROM-clause entry for table \"%s\"",
02576                         relation->relname),
02577                  parser_errposition(pstate, relation->location)));
02578 }
02579 
02580 /*
02581  * Generate a suitable error about a missing column.
02582  *
02583  * Since this is a very common type of error, we work rather hard to
02584  * produce a helpful message.
02585  */
02586 void
02587 errorMissingColumn(ParseState *pstate,
02588                    char *relname, char *colname, int location)
02589 {
02590     RangeTblEntry *rte;
02591 
02592     /*
02593      * If relname was given, just play dumb and report it.  (In practice, a
02594      * bad qualification name should end up at errorMissingRTE, not here, so
02595      * no need to work hard on this case.)
02596      */
02597     if (relname)
02598         ereport(ERROR,
02599                 (errcode(ERRCODE_UNDEFINED_COLUMN),
02600                  errmsg("column %s.%s does not exist", relname, colname),
02601                  parser_errposition(pstate, location)));
02602 
02603     /*
02604      * Otherwise, search the entire rtable looking for possible matches.  If
02605      * we find one, emit a hint about it.
02606      *
02607      * TODO: improve this code (and also errorMissingRTE) to mention using
02608      * LATERAL if appropriate.
02609      */
02610     rte = searchRangeTableForCol(pstate, colname, location);
02611 
02612     ereport(ERROR,
02613             (errcode(ERRCODE_UNDEFINED_COLUMN),
02614              errmsg("column \"%s\" does not exist", colname),
02615              rte ? errhint("There is a column named \"%s\" in table \"%s\", but it cannot be referenced from this part of the query.",
02616                            colname, rte->eref->aliasname) : 0,
02617              parser_errposition(pstate, location)));
02618 }
02619 
02620 
02621 /*
02622  * Examine a fully-parsed query, and return TRUE iff any relation underlying
02623  * the query is a temporary relation (table, view, or materialized view).
02624  */
02625 bool
02626 isQueryUsingTempRelation(Query *query)
02627 {
02628     return isQueryUsingTempRelation_walker((Node *) query, NULL);
02629 }
02630 
02631 static bool
02632 isQueryUsingTempRelation_walker(Node *node, void *context)
02633 {
02634     if (node == NULL)
02635         return false;
02636 
02637     if (IsA(node, Query))
02638     {
02639         Query      *query = (Query *) node;
02640         ListCell   *rtable;
02641 
02642         foreach(rtable, query->rtable)
02643         {
02644             RangeTblEntry *rte = lfirst(rtable);
02645 
02646             if (rte->rtekind == RTE_RELATION)
02647             {
02648                 Relation    rel = heap_open(rte->relid, AccessShareLock);
02649                 char        relpersistence = rel->rd_rel->relpersistence;
02650 
02651                 heap_close(rel, AccessShareLock);
02652                 if (relpersistence == RELPERSISTENCE_TEMP)
02653                     return true;
02654             }
02655         }
02656 
02657         return query_tree_walker(query,
02658                                  isQueryUsingTempRelation_walker,
02659                                  context,
02660                                  QTW_IGNORE_JOINALIASES);
02661     }
02662 
02663     return expression_tree_walker(node,
02664                                   isQueryUsingTempRelation_walker,
02665                                   context);
02666 }