LCOV - code coverage report
Current view: top level - src/backend/parser - parse_relation.c (source / functions) Hit Total Coverage
Test: PostgreSQL 13devel Lines: 977 1079 90.5 %
Date: 2019-11-15 23:07:02 Functions: 50 50 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * parse_relation.c
       4             :  *    parser support routines dealing with relations
       5             :  *
       6             :  * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
       7             :  * Portions Copyright (c) 1994, Regents of the University of California
       8             :  *
       9             :  *
      10             :  * IDENTIFICATION
      11             :  *    src/backend/parser/parse_relation.c
      12             :  *
      13             :  *-------------------------------------------------------------------------
      14             :  */
      15             : #include "postgres.h"
      16             : 
      17             : #include <ctype.h>
      18             : 
      19             : #include "access/htup_details.h"
      20             : #include "access/relation.h"
      21             : #include "access/sysattr.h"
      22             : #include "access/table.h"
      23             : #include "catalog/heap.h"
      24             : #include "catalog/namespace.h"
      25             : #include "catalog/pg_type.h"
      26             : #include "funcapi.h"
      27             : #include "nodes/makefuncs.h"
      28             : #include "nodes/nodeFuncs.h"
      29             : #include "parser/parse_enr.h"
      30             : #include "parser/parse_relation.h"
      31             : #include "parser/parse_type.h"
      32             : #include "parser/parsetree.h"
      33             : #include "storage/lmgr.h"
      34             : #include "utils/builtins.h"
      35             : #include "utils/lsyscache.h"
      36             : #include "utils/rel.h"
      37             : #include "utils/syscache.h"
      38             : #include "utils/varlena.h"
      39             : 
      40             : #define MAX_FUZZY_DISTANCE              3
      41             : 
      42             : static RangeTblEntry *scanNameSpaceForRefname(ParseState *pstate,
      43             :                                               const char *refname, int location);
      44             : static RangeTblEntry *scanNameSpaceForRelid(ParseState *pstate, Oid relid,
      45             :                                             int location);
      46             : static void check_lateral_ref_ok(ParseState *pstate, ParseNamespaceItem *nsitem,
      47             :                                  int location);
      48             : static void markRTEForSelectPriv(ParseState *pstate, RangeTblEntry *rte,
      49             :                                  int rtindex, AttrNumber col);
      50             : static void expandRelation(Oid relid, Alias *eref,
      51             :                            int rtindex, int sublevels_up,
      52             :                            int location, bool include_dropped,
      53             :                            List **colnames, List **colvars);
      54             : static void expandTupleDesc(TupleDesc tupdesc, Alias *eref,
      55             :                             int count, int offset,
      56             :                             int rtindex, int sublevels_up,
      57             :                             int location, bool include_dropped,
      58             :                             List **colnames, List **colvars);
      59             : static int  specialAttNum(const char *attname);
      60             : static bool isQueryUsingTempRelation_walker(Node *node, void *context);
      61             : 
      62             : 
      63             : /*
      64             :  * refnameRangeTblEntry
      65             :  *    Given a possibly-qualified refname, look to see if it matches any RTE.
      66             :  *    If so, return a pointer to the RangeTblEntry; else return NULL.
      67             :  *
      68             :  *    Optionally get RTE's nesting depth (0 = current) into *sublevels_up.
      69             :  *    If sublevels_up is NULL, only consider items at the current nesting
      70             :  *    level.
      71             :  *
      72             :  * An unqualified refname (schemaname == NULL) can match any RTE with matching
      73             :  * alias, or matching unqualified relname in the case of alias-less relation
      74             :  * RTEs.  It is possible that such a refname matches multiple RTEs in the
      75             :  * nearest nesting level that has a match; if so, we report an error via
      76             :  * ereport().
      77             :  *
      78             :  * A qualified refname (schemaname != NULL) can only match a relation RTE
      79             :  * that (a) has no alias and (b) is for the same relation identified by
      80             :  * schemaname.refname.  In this case we convert schemaname.refname to a
      81             :  * relation OID and search by relid, rather than by alias name.  This is
      82             :  * peculiar, but it's what SQL says to do.
      83             :  */
      84             : RangeTblEntry *
      85     1162336 : refnameRangeTblEntry(ParseState *pstate,
      86             :                      const char *schemaname,
      87             :                      const char *refname,
      88             :                      int location,
      89             :                      int *sublevels_up)
      90             : {
      91     1162336 :     Oid         relId = InvalidOid;
      92             : 
      93     1162336 :     if (sublevels_up)
      94     1162336 :         *sublevels_up = 0;
      95             : 
      96     1162336 :     if (schemaname != NULL)
      97             :     {
      98             :         Oid         namespaceId;
      99             : 
     100             :         /*
     101             :          * We can use LookupNamespaceNoError() here because we are only
     102             :          * interested in finding existing RTEs.  Checking USAGE permission on
     103             :          * the schema is unnecessary since it would have already been checked
     104             :          * when the RTE was made.  Furthermore, we want to report "RTE not
     105             :          * found", not "no permissions for schema", if the name happens to
     106             :          * match a schema name the user hasn't got access to.
     107             :          */
     108          32 :         namespaceId = LookupNamespaceNoError(schemaname);
     109          32 :         if (!OidIsValid(namespaceId))
     110          28 :             return NULL;
     111           4 :         relId = get_relname_relid(refname, namespaceId);
     112           4 :         if (!OidIsValid(relId))
     113           0 :             return NULL;
     114             :     }
     115             : 
     116     2426720 :     while (pstate != NULL)
     117             :     {
     118             :         RangeTblEntry *result;
     119             : 
     120     1248586 :         if (OidIsValid(relId))
     121           8 :             result = scanNameSpaceForRelid(pstate, relId, location);
     122             :         else
     123     1248578 :             result = scanNameSpaceForRefname(pstate, refname, location);
     124             : 
     125     1248570 :         if (result)
     126     1146466 :             return result;
     127             : 
     128      102104 :         if (sublevels_up)
     129      102104 :             (*sublevels_up)++;
     130             :         else
     131           0 :             break;
     132             : 
     133      102104 :         pstate = pstate->parentParseState;
     134             :     }
     135       15826 :     return NULL;
     136             : }
     137             : 
     138             : /*
     139             :  * Search the query's table namespace for an RTE matching the
     140             :  * given unqualified refname.  Return the RTE if a unique match, or NULL
     141             :  * if no match.  Raise error if multiple matches.
     142             :  *
     143             :  * Note: it might seem that we shouldn't have to worry about the possibility
     144             :  * of multiple matches; after all, the SQL standard disallows duplicate table
     145             :  * aliases within a given SELECT level.  Historically, however, Postgres has
     146             :  * been laxer than that.  For example, we allow
     147             :  *      SELECT ... FROM tab1 x CROSS JOIN (tab2 x CROSS JOIN tab3 y) z
     148             :  * on the grounds that the aliased join (z) hides the aliases within it,
     149             :  * therefore there is no conflict between the two RTEs named "x".  However,
     150             :  * if tab3 is a LATERAL subquery, then from within the subquery both "x"es
     151             :  * are visible.  Rather than rejecting queries that used to work, we allow
     152             :  * this situation, and complain only if there's actually an ambiguous
     153             :  * reference to "x".
     154             :  */
     155             : static RangeTblEntry *
     156     1248578 : scanNameSpaceForRefname(ParseState *pstate, const char *refname, int location)
     157             : {
     158     1248578 :     RangeTblEntry *result = NULL;
     159             :     ListCell   *l;
     160             : 
     161     6459364 :     foreach(l, pstate->p_namespace)
     162             :     {
     163     5210802 :         ParseNamespaceItem *nsitem = (ParseNamespaceItem *) lfirst(l);
     164     5210802 :         RangeTblEntry *rte = nsitem->p_rte;
     165             : 
     166             :         /* Ignore columns-only items */
     167     5210802 :         if (!nsitem->p_rel_visible)
     168     1501234 :             continue;
     169             :         /* If not inside LATERAL, ignore lateral-only items */
     170     3709568 :         if (nsitem->p_lateral_only && !pstate->p_lateral_active)
     171          32 :             continue;
     172             : 
     173     3709536 :         if (strcmp(rte->eref->aliasname, refname) == 0)
     174             :         {
     175     1146486 :             if (result)
     176           8 :                 ereport(ERROR,
     177             :                         (errcode(ERRCODE_AMBIGUOUS_ALIAS),
     178             :                          errmsg("table reference \"%s\" is ambiguous",
     179             :                                 refname),
     180             :                          parser_errposition(pstate, location)));
     181     1146478 :             check_lateral_ref_ok(pstate, nsitem, location);
     182     1146470 :             result = rte;
     183             :         }
     184             :     }
     185     1248562 :     return result;
     186             : }
     187             : 
     188             : /*
     189             :  * Search the query's table namespace for a relation RTE matching the
     190             :  * given relation OID.  Return the RTE if a unique match, or NULL
     191             :  * if no match.  Raise error if multiple matches.
     192             :  *
     193             :  * See the comments for refnameRangeTblEntry to understand why this
     194             :  * acts the way it does.
     195             :  */
     196             : static RangeTblEntry *
     197           8 : scanNameSpaceForRelid(ParseState *pstate, Oid relid, int location)
     198             : {
     199           8 :     RangeTblEntry *result = NULL;
     200             :     ListCell   *l;
     201             : 
     202          16 :     foreach(l, pstate->p_namespace)
     203             :     {
     204           8 :         ParseNamespaceItem *nsitem = (ParseNamespaceItem *) lfirst(l);
     205           8 :         RangeTblEntry *rte = nsitem->p_rte;
     206             : 
     207             :         /* Ignore columns-only items */
     208           8 :         if (!nsitem->p_rel_visible)
     209           0 :             continue;
     210             :         /* If not inside LATERAL, ignore lateral-only items */
     211           8 :         if (nsitem->p_lateral_only && !pstate->p_lateral_active)
     212           0 :             continue;
     213             : 
     214             :         /* yes, the test for alias == NULL should be there... */
     215          16 :         if (rte->rtekind == RTE_RELATION &&
     216          12 :             rte->relid == relid &&
     217           4 :             rte->alias == NULL)
     218             :         {
     219           4 :             if (result)
     220           0 :                 ereport(ERROR,
     221             :                         (errcode(ERRCODE_AMBIGUOUS_ALIAS),
     222             :                          errmsg("table reference %u is ambiguous",
     223             :                                 relid),
     224             :                          parser_errposition(pstate, location)));
     225           4 :             check_lateral_ref_ok(pstate, nsitem, location);
     226           4 :             result = rte;
     227             :         }
     228             :     }
     229           8 :     return result;
     230             : }
     231             : 
     232             : /*
     233             :  * Search the query's CTE namespace for a CTE matching the given unqualified
     234             :  * refname.  Return the CTE (and its levelsup count) if a match, or NULL
     235             :  * if no match.  We need not worry about multiple matches, since parse_cte.c
     236             :  * rejects WITH lists containing duplicate CTE names.
     237             :  */
     238             : CommonTableExpr *
     239      221580 : scanNameSpaceForCTE(ParseState *pstate, const char *refname,
     240             :                     Index *ctelevelsup)
     241             : {
     242             :     Index       levelsup;
     243             : 
     244      758404 :     for (levelsup = 0;
     245             :          pstate != NULL;
     246      315244 :          pstate = pstate->parentParseState, levelsup++)
     247             :     {
     248             :         ListCell   *lc;
     249             : 
     250      319336 :         foreach(lc, pstate->p_ctenamespace)
     251             :         {
     252        4092 :             CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc);
     253             : 
     254        4092 :             if (strcmp(cte->ctename, refname) == 0)
     255             :             {
     256        1874 :                 *ctelevelsup = levelsup;
     257        1874 :                 return cte;
     258             :             }
     259             :         }
     260             :     }
     261      219706 :     return NULL;
     262             : }
     263             : 
     264             : /*
     265             :  * Search for a possible "future CTE", that is one that is not yet in scope
     266             :  * according to the WITH scoping rules.  This has nothing to do with valid
     267             :  * SQL semantics, but it's important for error reporting purposes.
     268             :  */
     269             : static bool
     270         104 : isFutureCTE(ParseState *pstate, const char *refname)
     271             : {
     272         216 :     for (; pstate != NULL; pstate = pstate->parentParseState)
     273             :     {
     274             :         ListCell   *lc;
     275             : 
     276         116 :         foreach(lc, pstate->p_future_ctes)
     277             :         {
     278           4 :             CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc);
     279             : 
     280           4 :             if (strcmp(cte->ctename, refname) == 0)
     281           4 :                 return true;
     282             :         }
     283             :     }
     284         100 :     return false;
     285             : }
     286             : 
     287             : /*
     288             :  * Search the query's ephemeral named relation namespace for a relation
     289             :  * matching the given unqualified refname.
     290             :  */
     291             : bool
     292      286410 : scanNameSpaceForENR(ParseState *pstate, const char *refname)
     293             : {
     294      286410 :     return name_matches_visible_ENR(pstate, refname);
     295             : }
     296             : 
     297             : /*
     298             :  * searchRangeTableForRel
     299             :  *    See if any RangeTblEntry could possibly match the RangeVar.
     300             :  *    If so, return a pointer to the RangeTblEntry; else return NULL.
     301             :  *
     302             :  * This is different from refnameRangeTblEntry in that it considers every
     303             :  * entry in the ParseState's rangetable(s), not only those that are currently
     304             :  * visible in the p_namespace list(s).  This behavior is invalid per the SQL
     305             :  * spec, and it may give ambiguous results (there might be multiple equally
     306             :  * valid matches, but only one will be returned).  This must be used ONLY
     307             :  * as a heuristic in giving suitable error messages.  See errorMissingRTE.
     308             :  *
     309             :  * Notice that we consider both matches on actual relation (or CTE) name
     310             :  * and matches on alias.
     311             :  */
     312             : static RangeTblEntry *
     313          48 : searchRangeTableForRel(ParseState *pstate, RangeVar *relation)
     314             : {
     315          48 :     const char *refname = relation->relname;
     316          48 :     Oid         relId = InvalidOid;
     317          48 :     CommonTableExpr *cte = NULL;
     318          48 :     bool        isenr = false;
     319          48 :     Index       ctelevelsup = 0;
     320             :     Index       levelsup;
     321             : 
     322             :     /*
     323             :      * If it's an unqualified name, check for possible CTE matches. A CTE
     324             :      * hides any real relation matches.  If no CTE, look for a matching
     325             :      * relation.
     326             :      *
     327             :      * NB: It's not critical that RangeVarGetRelid return the correct answer
     328             :      * here in the face of concurrent DDL.  If it doesn't, the worst case
     329             :      * scenario is a less-clear error message.  Also, the tables involved in
     330             :      * the query are already locked, which reduces the number of cases in
     331             :      * which surprising behavior can occur.  So we do the name lookup
     332             :      * unlocked.
     333             :      */
     334          48 :     if (!relation->schemaname)
     335             :     {
     336          48 :         cte = scanNameSpaceForCTE(pstate, refname, &ctelevelsup);
     337          48 :         if (!cte)
     338          48 :             isenr = scanNameSpaceForENR(pstate, refname);
     339             :     }
     340             : 
     341          48 :     if (!cte && !isenr)
     342          48 :         relId = RangeVarGetRelid(relation, NoLock, true);
     343             : 
     344             :     /* Now look for RTEs matching either the relation/CTE/ENR or the alias */
     345         120 :     for (levelsup = 0;
     346             :          pstate != NULL;
     347          24 :          pstate = pstate->parentParseState, levelsup++)
     348             :     {
     349             :         ListCell   *l;
     350             : 
     351          92 :         foreach(l, pstate->p_rtable)
     352             :         {
     353          68 :             RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
     354             : 
     355          68 :             if (rte->rtekind == RTE_RELATION &&
     356          52 :                 OidIsValid(relId) &&
     357          52 :                 rte->relid == relId)
     358          64 :                 return rte;
     359          44 :             if (rte->rtekind == RTE_CTE &&
     360           0 :                 cte != NULL &&
     361           0 :                 rte->ctelevelsup + levelsup == ctelevelsup &&
     362           0 :                 strcmp(rte->ctename, refname) == 0)
     363           0 :                 return rte;
     364          44 :             if (rte->rtekind == RTE_NAMEDTUPLESTORE &&
     365           0 :                 isenr &&
     366           0 :                 strcmp(rte->enrname, refname) == 0)
     367           0 :                 return rte;
     368          44 :             if (strcmp(rte->eref->aliasname, refname) == 0)
     369          16 :                 return rte;
     370             :         }
     371             :     }
     372           8 :     return NULL;
     373             : }
     374             : 
     375             : /*
     376             :  * Check for relation-name conflicts between two namespace lists.
     377             :  * Raise an error if any is found.
     378             :  *
     379             :  * Note: we assume that each given argument does not contain conflicts
     380             :  * itself; we just want to know if the two can be merged together.
     381             :  *
     382             :  * Per SQL, two alias-less plain relation RTEs do not conflict even if
     383             :  * they have the same eref->aliasname (ie, same relation name), if they
     384             :  * are for different relation OIDs (implying they are in different schemas).
     385             :  *
     386             :  * We ignore the lateral-only flags in the namespace items: the lists must
     387             :  * not conflict, even when all items are considered visible.  However,
     388             :  * columns-only items should be ignored.
     389             :  */
     390             : void
     391      386044 : checkNameSpaceConflicts(ParseState *pstate, List *namespace1,
     392             :                         List *namespace2)
     393             : {
     394             :     ListCell   *l1;
     395             : 
     396      685476 :     foreach(l1, namespace1)
     397             :     {
     398      299436 :         ParseNamespaceItem *nsitem1 = (ParseNamespaceItem *) lfirst(l1);
     399      299436 :         RangeTblEntry *rte1 = nsitem1->p_rte;
     400      299436 :         const char *aliasname1 = rte1->eref->aliasname;
     401             :         ListCell   *l2;
     402             : 
     403      299436 :         if (!nsitem1->p_rel_visible)
     404       58130 :             continue;
     405             : 
     406      533372 :         foreach(l2, namespace2)
     407             :         {
     408      292070 :             ParseNamespaceItem *nsitem2 = (ParseNamespaceItem *) lfirst(l2);
     409      292070 :             RangeTblEntry *rte2 = nsitem2->p_rte;
     410             : 
     411      292070 :             if (!nsitem2->p_rel_visible)
     412       25382 :                 continue;
     413      266688 :             if (strcmp(rte2->eref->aliasname, aliasname1) != 0)
     414      266684 :                 continue;       /* definitely no conflict */
     415           8 :             if (rte1->rtekind == RTE_RELATION && rte1->alias == NULL &&
     416          12 :                 rte2->rtekind == RTE_RELATION && rte2->alias == NULL &&
     417           4 :                 rte1->relid != rte2->relid)
     418           0 :                 continue;       /* no conflict per SQL rule */
     419           4 :             ereport(ERROR,
     420             :                     (errcode(ERRCODE_DUPLICATE_ALIAS),
     421             :                      errmsg("table name \"%s\" specified more than once",
     422             :                             aliasname1)));
     423             :         }
     424             :     }
     425      386040 : }
     426             : 
     427             : /*
     428             :  * Complain if a namespace item is currently disallowed as a LATERAL reference.
     429             :  * This enforces both SQL:2008's rather odd idea of what to do with a LATERAL
     430             :  * reference to the wrong side of an outer join, and our own prohibition on
     431             :  * referencing the target table of an UPDATE or DELETE as a lateral reference
     432             :  * in a FROM/USING clause.
     433             :  *
     434             :  * Convenience subroutine to avoid multiple copies of a rather ugly ereport.
     435             :  */
     436             : static void
     437     1699628 : check_lateral_ref_ok(ParseState *pstate, ParseNamespaceItem *nsitem,
     438             :                      int location)
     439             : {
     440     1699628 :     if (nsitem->p_lateral_only && !nsitem->p_lateral_ok)
     441             :     {
     442             :         /* SQL:2008 demands this be an error, not an invisible item */
     443          16 :         RangeTblEntry *rte = nsitem->p_rte;
     444          16 :         char       *refname = rte->eref->aliasname;
     445             : 
     446          16 :         ereport(ERROR,
     447             :                 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
     448             :                  errmsg("invalid reference to FROM-clause entry for table \"%s\"",
     449             :                         refname),
     450             :                  (rte == pstate->p_target_rangetblentry) ?
     451             :                  errhint("There is an entry for table \"%s\", but it cannot be referenced from this part of the query.",
     452             :                          refname) :
     453             :                  errdetail("The combining JOIN type must be INNER or LEFT for a LATERAL reference."),
     454             :                  parser_errposition(pstate, location)));
     455             :     }
     456     1699612 : }
     457             : 
     458             : /*
     459             :  * given an RTE, return RT index (starting with 1) of the entry,
     460             :  * and optionally get its nesting depth (0 = current).  If sublevels_up
     461             :  * is NULL, only consider rels at the current nesting level.
     462             :  * Raises error if RTE not found.
     463             :  */
     464             : int
     465     1750360 : RTERangeTablePosn(ParseState *pstate, RangeTblEntry *rte, int *sublevels_up)
     466             : {
     467             :     int         index;
     468             :     ListCell   *l;
     469             : 
     470     1750360 :     if (sublevels_up)
     471     1700152 :         *sublevels_up = 0;
     472             : 
     473     3613894 :     while (pstate != NULL)
     474             :     {
     475     1863534 :         index = 1;
     476     3551754 :         foreach(l, pstate->p_rtable)
     477             :         {
     478     3438580 :             if (rte == (RangeTblEntry *) lfirst(l))
     479     1750360 :                 return index;
     480     1688220 :             index++;
     481             :         }
     482      113174 :         pstate = pstate->parentParseState;
     483      113174 :         if (sublevels_up)
     484      113174 :             (*sublevels_up)++;
     485             :         else
     486           0 :             break;
     487             :     }
     488             : 
     489           0 :     elog(ERROR, "RTE not found (internal error)");
     490             :     return 0;                   /* keep compiler quiet */
     491             : }
     492             : 
     493             : /*
     494             :  * Given an RT index and nesting depth, find the corresponding RTE.
     495             :  * This is the inverse of RTERangeTablePosn.
     496             :  */
     497             : RangeTblEntry *
     498      717912 : GetRTEByRangeTablePosn(ParseState *pstate,
     499             :                        int varno,
     500             :                        int sublevels_up)
     501             : {
     502     1436200 :     while (sublevels_up-- > 0)
     503             :     {
     504         376 :         pstate = pstate->parentParseState;
     505             :         Assert(pstate != NULL);
     506             :     }
     507             :     Assert(varno > 0 && varno <= list_length(pstate->p_rtable));
     508      717912 :     return rt_fetch(varno, pstate->p_rtable);
     509             : }
     510             : 
     511             : /*
     512             :  * Fetch the CTE for a CTE-reference RTE.
     513             :  *
     514             :  * rtelevelsup is the number of query levels above the given pstate that the
     515             :  * RTE came from.  Callers that don't have this information readily available
     516             :  * may pass -1 instead.
     517             :  */
     518             : CommonTableExpr *
     519        2064 : GetCTEForRTE(ParseState *pstate, RangeTblEntry *rte, int rtelevelsup)
     520             : {
     521             :     Index       levelsup;
     522             :     ListCell   *lc;
     523             : 
     524             :     /* Determine RTE's levelsup if caller didn't know it */
     525        2064 :     if (rtelevelsup < 0)
     526           0 :         (void) RTERangeTablePosn(pstate, rte, &rtelevelsup);
     527             : 
     528             :     Assert(rte->rtekind == RTE_CTE);
     529        2064 :     levelsup = rte->ctelevelsup + rtelevelsup;
     530        5622 :     while (levelsup-- > 0)
     531             :     {
     532        1494 :         pstate = pstate->parentParseState;
     533        1494 :         if (!pstate)            /* shouldn't happen */
     534           0 :             elog(ERROR, "bad levelsup for CTE \"%s\"", rte->ctename);
     535             :     }
     536        2612 :     foreach(lc, pstate->p_ctenamespace)
     537             :     {
     538        2612 :         CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc);
     539             : 
     540        2612 :         if (strcmp(cte->ctename, rte->ctename) == 0)
     541        2064 :             return cte;
     542             :     }
     543             :     /* shouldn't happen */
     544           0 :     elog(ERROR, "could not find CTE \"%s\"", rte->ctename);
     545             :     return NULL;                /* keep compiler quiet */
     546             : }
     547             : 
     548             : /*
     549             :  * updateFuzzyAttrMatchState
     550             :  *    Using Levenshtein distance, consider if column is best fuzzy match.
     551             :  */
     552             : static void
     553        1256 : updateFuzzyAttrMatchState(int fuzzy_rte_penalty,
     554             :                           FuzzyAttrMatchState *fuzzystate, RangeTblEntry *rte,
     555             :                           const char *actual, const char *match, int attnum)
     556             : {
     557             :     int         columndistance;
     558             :     int         matchlen;
     559             : 
     560             :     /* Bail before computing the Levenshtein distance if there's no hope. */
     561        1256 :     if (fuzzy_rte_penalty > fuzzystate->distance)
     562          16 :         return;
     563             : 
     564             :     /*
     565             :      * Outright reject dropped columns, which can appear here with apparent
     566             :      * empty actual names, per remarks within scanRTEForColumn().
     567             :      */
     568        1240 :     if (actual[0] == '\0')
     569          84 :         return;
     570             : 
     571             :     /* Use Levenshtein to compute match distance. */
     572        1156 :     matchlen = strlen(match);
     573        1156 :     columndistance =
     574        1156 :         varstr_levenshtein_less_equal(actual, strlen(actual), match, matchlen,
     575             :                                       1, 1, 1,
     576        1156 :                                       fuzzystate->distance + 1
     577        1156 :                                       - fuzzy_rte_penalty,
     578             :                                       true);
     579             : 
     580             :     /*
     581             :      * If more than half the characters are different, don't treat it as a
     582             :      * match, to avoid making ridiculous suggestions.
     583             :      */
     584        1156 :     if (columndistance > matchlen / 2)
     585         596 :         return;
     586             : 
     587             :     /*
     588             :      * From this point on, we can ignore the distinction between the RTE-name
     589             :      * distance and the column-name distance.
     590             :      */
     591         560 :     columndistance += fuzzy_rte_penalty;
     592             : 
     593             :     /*
     594             :      * If the new distance is less than or equal to that of the best match
     595             :      * found so far, update fuzzystate.
     596             :      */
     597         560 :     if (columndistance < fuzzystate->distance)
     598             :     {
     599             :         /* Store new lowest observed distance for RTE */
     600          76 :         fuzzystate->distance = columndistance;
     601          76 :         fuzzystate->rfirst = rte;
     602          76 :         fuzzystate->first = attnum;
     603          76 :         fuzzystate->rsecond = NULL;
     604          76 :         fuzzystate->second = InvalidAttrNumber;
     605             :     }
     606         484 :     else if (columndistance == fuzzystate->distance)
     607             :     {
     608             :         /*
     609             :          * This match distance may equal a prior match within this same range
     610             :          * table.  When that happens, the prior match may also be given, but
     611             :          * only if there is no more than two equally distant matches from the
     612             :          * RTE (in turn, our caller will only accept two equally distant
     613             :          * matches overall).
     614             :          */
     615           4 :         if (AttributeNumberIsValid(fuzzystate->second))
     616             :         {
     617             :             /* Too many RTE-level matches */
     618           0 :             fuzzystate->rfirst = NULL;
     619           0 :             fuzzystate->first = InvalidAttrNumber;
     620           0 :             fuzzystate->rsecond = NULL;
     621           0 :             fuzzystate->second = InvalidAttrNumber;
     622             :             /* Clearly, distance is too low a bar (for *any* RTE) */
     623           0 :             fuzzystate->distance = columndistance - 1;
     624             :         }
     625           4 :         else if (AttributeNumberIsValid(fuzzystate->first))
     626             :         {
     627             :             /* Record as provisional second match for RTE */
     628           4 :             fuzzystate->rsecond = rte;
     629           4 :             fuzzystate->second = attnum;
     630             :         }
     631           0 :         else if (fuzzystate->distance <= MAX_FUZZY_DISTANCE)
     632             :         {
     633             :             /*
     634             :              * Record as provisional first match (this can occasionally occur
     635             :              * because previous lowest distance was "too low a bar", rather
     636             :              * than being associated with a real match)
     637             :              */
     638           0 :             fuzzystate->rfirst = rte;
     639           0 :             fuzzystate->first = attnum;
     640             :         }
     641             :     }
     642             : }
     643             : 
     644             : /*
     645             :  * scanRTEForColumn
     646             :  *    Search the column names of a single RTE for the given name.
     647             :  *    If found, return an appropriate Var node, else return NULL.
     648             :  *    If the name proves ambiguous within this RTE, raise error.
     649             :  *
     650             :  * Side effect: if we find a match, mark the RTE as requiring read access
     651             :  * for the column.
     652             :  *
     653             :  * Additional side effect: if fuzzystate is non-NULL, check non-system columns
     654             :  * for an approximate match and update fuzzystate accordingly.
     655             :  */
     656             : Node *
     657     1773502 : scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte, const char *colname,
     658             :                  int location, int fuzzy_rte_penalty,
     659             :                  FuzzyAttrMatchState *fuzzystate)
     660             : {
     661     1773502 :     Node       *result = NULL;
     662     1773502 :     int         attnum = 0;
     663             :     Var        *var;
     664             :     ListCell   *c;
     665             : 
     666             :     /*
     667             :      * Scan the user column names (or aliases) for a match. Complain if
     668             :      * multiple matches.
     669             :      *
     670             :      * Note: eref->colnames may include entries for dropped columns, but those
     671             :      * will be empty strings that cannot match any legal SQL identifier, so we
     672             :      * don't bother to test for that case here.
     673             :      *
     674             :      * Should this somehow go wrong and we try to access a dropped column,
     675             :      * we'll still catch it by virtue of the checks in
     676             :      * get_rte_attribute_type(), which is called by make_var().  That routine
     677             :      * has to do a cache lookup anyway, so the check there is cheap.  Callers
     678             :      * interested in finding match with shortest distance need to defend
     679             :      * against this directly, though.
     680             :      */
     681    35783392 :     foreach(c, rte->eref->colnames)
     682             :     {
     683    34009898 :         const char *attcolname = strVal(lfirst(c));
     684             : 
     685    34009898 :         attnum++;
     686    34009898 :         if (strcmp(attcolname, colname) == 0)
     687             :         {
     688     1641960 :             if (result)
     689           8 :                 ereport(ERROR,
     690             :                         (errcode(ERRCODE_AMBIGUOUS_COLUMN),
     691             :                          errmsg("column reference \"%s\" is ambiguous",
     692             :                                 colname),
     693             :                          parser_errposition(pstate, location)));
     694     1641952 :             var = make_var(pstate, rte, attnum, location);
     695             :             /* Require read access to the column */
     696     1641952 :             markVarForSelectPriv(pstate, var, rte);
     697     1641952 :             result = (Node *) var;
     698             :         }
     699             : 
     700             :         /* Updating fuzzy match state, if provided. */
     701    34009890 :         if (fuzzystate != NULL)
     702        1256 :             updateFuzzyAttrMatchState(fuzzy_rte_penalty, fuzzystate,
     703             :                                       rte, attcolname, colname, attnum);
     704             :     }
     705             : 
     706             :     /*
     707             :      * If we have a unique match, return it.  Note that this allows a user
     708             :      * alias to override a system column name (such as OID) without error.
     709             :      */
     710     1773494 :     if (result)
     711     1641944 :         return result;
     712             : 
     713             :     /*
     714             :      * If the RTE represents a real relation, consider system column names.
     715             :      * Composites are only used for pseudo-relations like ON CONFLICT's
     716             :      * excluded.
     717             :      */
     718      226382 :     if (rte->rtekind == RTE_RELATION &&
     719       94832 :         rte->relkind != RELKIND_COMPOSITE_TYPE)
     720             :     {
     721             :         /* quick check to see if name could be a system column */
     722       94800 :         attnum = specialAttNum(colname);
     723             : 
     724             :         /* In constraint check, no system column is allowed except tableOid */
     725       94800 :         if (pstate->p_expr_kind == EXPR_KIND_CHECK_CONSTRAINT &&
     726           8 :             attnum < InvalidAttrNumber && attnum != TableOidAttributeNumber)
     727           4 :             ereport(ERROR,
     728             :                     (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
     729             :                      errmsg("system column \"%s\" reference in check constraint is invalid",
     730             :                             colname),
     731             :                      parser_errposition(pstate, location)));
     732             : 
     733             :         /*
     734             :          * In generated column, no system column is allowed except tableOid.
     735             :          */
     736       94796 :         if (pstate->p_expr_kind == EXPR_KIND_GENERATED_COLUMN &&
     737          10 :             attnum < InvalidAttrNumber && attnum != TableOidAttributeNumber)
     738           4 :             ereport(ERROR,
     739             :                     (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
     740             :                      errmsg("cannot use system column \"%s\" in column generation expression",
     741             :                             colname),
     742             :                      parser_errposition(pstate, location)));
     743             : 
     744       94792 :         if (attnum != InvalidAttrNumber)
     745             :         {
     746             :             /* now check to see if column actually is defined */
     747       36602 :             if (SearchSysCacheExists2(ATTNUM,
     748             :                                       ObjectIdGetDatum(rte->relid),
     749             :                                       Int16GetDatum(attnum)))
     750             :             {
     751       36594 :                 var = make_var(pstate, rte, attnum, location);
     752             :                 /* Require read access to the column */
     753       36594 :                 markVarForSelectPriv(pstate, var, rte);
     754       36594 :                 result = (Node *) var;
     755             :             }
     756             :         }
     757             :     }
     758             : 
     759      131542 :     return result;
     760             : }
     761             : 
     762             : /*
     763             :  * colNameToVar
     764             :  *    Search for an unqualified column name.
     765             :  *    If found, return the appropriate Var node (or expression).
     766             :  *    If not found, return NULL.  If the name proves ambiguous, raise error.
     767             :  *    If localonly is true, only names in the innermost query are considered.
     768             :  */
     769             : Node *
     770      585762 : colNameToVar(ParseState *pstate, const char *colname, bool localonly,
     771             :              int location)
     772             : {
     773      585762 :     Node       *result = NULL;
     774      585762 :     ParseState *orig_pstate = pstate;
     775             : 
     776     1231492 :     while (pstate != NULL)
     777             :     {
     778             :         ListCell   *l;
     779             : 
     780     1821888 :         foreach(l, pstate->p_namespace)
     781             :         {
     782     1208746 :             ParseNamespaceItem *nsitem = (ParseNamespaceItem *) lfirst(l);
     783     1208746 :             RangeTblEntry *rte = nsitem->p_rte;
     784             :             Node       *newresult;
     785             : 
     786             :             /* Ignore table-only items */
     787     1208746 :             if (!nsitem->p_cols_visible)
     788      561004 :                 continue;
     789             :             /* If not inside LATERAL, ignore lateral-only items */
     790      647742 :             if (nsitem->p_lateral_only && !pstate->p_lateral_active)
     791          28 :                 continue;
     792             : 
     793             :             /* use orig_pstate here to get the right sublevels_up */
     794      647714 :             newresult = scanRTEForColumn(orig_pstate, rte, colname, location,
     795             :                                          0, NULL);
     796             : 
     797      647698 :             if (newresult)
     798             :             {
     799      553158 :                 if (result)
     800          12 :                     ereport(ERROR,
     801             :                             (errcode(ERRCODE_AMBIGUOUS_COLUMN),
     802             :                              errmsg("column reference \"%s\" is ambiguous",
     803             :                                     colname),
     804             :                              parser_errposition(pstate, location)));
     805      553146 :                 check_lateral_ref_ok(pstate, nsitem, location);
     806      553138 :                 result = newresult;
     807             :             }
     808             :         }
     809             : 
     810      613142 :         if (result != NULL || localonly)
     811             :             break;              /* found, or don't want to look at parent */
     812             : 
     813       59968 :         pstate = pstate->parentParseState;
     814             :     }
     815             : 
     816      585726 :     return result;
     817             : }
     818             : 
     819             : /*
     820             :  * searchRangeTableForCol
     821             :  *    See if any RangeTblEntry could possibly provide the given column name (or
     822             :  *    find the best match available).  Returns state with relevant details.
     823             :  *
     824             :  * This is different from colNameToVar in that it considers every entry in
     825             :  * the ParseState's rangetable(s), not only those that are currently visible
     826             :  * in the p_namespace list(s).  This behavior is invalid per the SQL spec,
     827             :  * and it may give ambiguous results (there might be multiple equally valid
     828             :  * matches, but only one will be returned).  This must be used ONLY as a
     829             :  * heuristic in giving suitable error messages.  See errorMissingColumn.
     830             :  *
     831             :  * This function is also different in that it will consider approximate
     832             :  * matches -- if the user entered an alias/column pair that is only slightly
     833             :  * different from a valid pair, we may be able to infer what they meant to
     834             :  * type and provide a reasonable hint.
     835             :  *
     836             :  * The FuzzyAttrMatchState will have 'rfirst' pointing to the best RTE
     837             :  * containing the most promising match for the alias and column name.  If
     838             :  * the alias and column names match exactly, 'first' will be InvalidAttrNumber;
     839             :  * otherwise, it will be the attribute number for the match.  In the latter
     840             :  * case, 'rsecond' may point to a second, equally close approximate match,
     841             :  * and 'second' will contain the attribute number for the second match.
     842             :  */
     843             : static FuzzyAttrMatchState *
     844         202 : searchRangeTableForCol(ParseState *pstate, const char *alias, const char *colname,
     845             :                        int location)
     846             : {
     847         202 :     ParseState *orig_pstate = pstate;
     848         202 :     FuzzyAttrMatchState *fuzzystate = palloc(sizeof(FuzzyAttrMatchState));
     849             : 
     850         202 :     fuzzystate->distance = MAX_FUZZY_DISTANCE + 1;
     851         202 :     fuzzystate->rfirst = NULL;
     852         202 :     fuzzystate->rsecond = NULL;
     853         202 :     fuzzystate->first = InvalidAttrNumber;
     854         202 :     fuzzystate->second = InvalidAttrNumber;
     855             : 
     856         602 :     while (pstate != NULL)
     857             :     {
     858             :         ListCell   *l;
     859             : 
     860         450 :         foreach(l, pstate->p_rtable)
     861             :         {
     862         252 :             RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
     863         252 :             int         fuzzy_rte_penalty = 0;
     864             : 
     865             :             /*
     866             :              * Typically, it is not useful to look for matches within join
     867             :              * RTEs; they effectively duplicate other RTEs for our purposes,
     868             :              * and if a match is chosen from a join RTE, an unhelpful alias is
     869             :              * displayed in the final diagnostic message.
     870             :              */
     871         252 :             if (rte->rtekind == RTE_JOIN)
     872          24 :                 continue;
     873             : 
     874             :             /*
     875             :              * If the user didn't specify an alias, then matches against one
     876             :              * RTE are as good as another.  But if the user did specify an
     877             :              * alias, then we want at least a fuzzy - and preferably an exact
     878             :              * - match for the range table entry.
     879             :              */
     880         228 :             if (alias != NULL)
     881          64 :                 fuzzy_rte_penalty =
     882         128 :                     varstr_levenshtein_less_equal(alias, strlen(alias),
     883          64 :                                                   rte->eref->aliasname,
     884          64 :                                                   strlen(rte->eref->aliasname),
     885             :                                                   1, 1, 1,
     886             :                                                   MAX_FUZZY_DISTANCE + 1,
     887             :                                                   true);
     888             : 
     889             :             /*
     890             :              * Scan for a matching column; if we find an exact match, we're
     891             :              * done.  Otherwise, update fuzzystate.
     892             :              */
     893         228 :             if (scanRTEForColumn(orig_pstate, rte, colname, location,
     894             :                                  fuzzy_rte_penalty, fuzzystate)
     895          32 :                 && fuzzy_rte_penalty == 0)
     896             :             {
     897          24 :                 fuzzystate->rfirst = rte;
     898          24 :                 fuzzystate->first = InvalidAttrNumber;
     899          24 :                 fuzzystate->rsecond = NULL;
     900          24 :                 fuzzystate->second = InvalidAttrNumber;
     901          24 :                 return fuzzystate;
     902             :             }
     903             :         }
     904             : 
     905         198 :         pstate = pstate->parentParseState;
     906             :     }
     907             : 
     908         178 :     return fuzzystate;
     909             : }
     910             : 
     911             : /*
     912             :  * markRTEForSelectPriv
     913             :  *     Mark the specified column of an RTE as requiring SELECT privilege
     914             :  *
     915             :  * col == InvalidAttrNumber means a "whole row" reference
     916             :  *
     917             :  * The caller should pass the actual RTE if it has it handy; otherwise pass
     918             :  * NULL, and we'll look it up here.  (This uglification of the API is
     919             :  * worthwhile because nearly all external callers have the RTE at hand.)
     920             :  */
     921             : static void
     922     1957684 : markRTEForSelectPriv(ParseState *pstate, RangeTblEntry *rte,
     923             :                      int rtindex, AttrNumber col)
     924             : {
     925     1957684 :     if (rte == NULL)
     926      119450 :         rte = rt_fetch(rtindex, pstate->p_rtable);
     927             : 
     928     1957684 :     if (rte->rtekind == RTE_RELATION)
     929             :     {
     930             :         /* Make sure the rel as a whole is marked for SELECT access */
     931     1594078 :         rte->requiredPerms |= ACL_SELECT;
     932             :         /* Must offset the attnum to fit in a bitmapset */
     933     1594078 :         rte->selectedCols = bms_add_member(rte->selectedCols,
     934             :                                            col - FirstLowInvalidHeapAttributeNumber);
     935             :     }
     936      363606 :     else if (rte->rtekind == RTE_JOIN)
     937             :     {
     938      119582 :         if (col == InvalidAttrNumber)
     939             :         {
     940             :             /*
     941             :              * A whole-row reference to a join has to be treated as whole-row
     942             :              * references to the two inputs.
     943             :              */
     944             :             JoinExpr   *j;
     945             : 
     946           4 :             if (rtindex > 0 && rtindex <= list_length(pstate->p_joinexprs))
     947           4 :                 j = list_nth_node(JoinExpr, pstate->p_joinexprs, rtindex - 1);
     948             :             else
     949           0 :                 j = NULL;
     950           4 :             if (j == NULL)
     951           0 :                 elog(ERROR, "could not find JoinExpr for whole-row reference");
     952             : 
     953             :             /* Note: we can't see FromExpr here */
     954           4 :             if (IsA(j->larg, RangeTblRef))
     955             :             {
     956           4 :                 int         varno = ((RangeTblRef *) j->larg)->rtindex;
     957             : 
     958           4 :                 markRTEForSelectPriv(pstate, NULL, varno, InvalidAttrNumber);
     959             :             }
     960           0 :             else if (IsA(j->larg, JoinExpr))
     961             :             {
     962           0 :                 int         varno = ((JoinExpr *) j->larg)->rtindex;
     963             : 
     964           0 :                 markRTEForSelectPriv(pstate, NULL, varno, InvalidAttrNumber);
     965             :             }
     966             :             else
     967           0 :                 elog(ERROR, "unrecognized node type: %d",
     968             :                      (int) nodeTag(j->larg));
     969           4 :             if (IsA(j->rarg, RangeTblRef))
     970             :             {
     971           4 :                 int         varno = ((RangeTblRef *) j->rarg)->rtindex;
     972             : 
     973           4 :                 markRTEForSelectPriv(pstate, NULL, varno, InvalidAttrNumber);
     974             :             }
     975           0 :             else if (IsA(j->rarg, JoinExpr))
     976             :             {
     977           0 :                 int         varno = ((JoinExpr *) j->rarg)->rtindex;
     978             : 
     979           0 :                 markRTEForSelectPriv(pstate, NULL, varno, InvalidAttrNumber);
     980             :             }
     981             :             else
     982           0 :                 elog(ERROR, "unrecognized node type: %d",
     983             :                      (int) nodeTag(j->rarg));
     984             :         }
     985             :         else
     986             :         {
     987             :             /*
     988             :              * Regular join attribute, look at the alias-variable list.
     989             :              *
     990             :              * The aliasvar could be either a Var or a COALESCE expression,
     991             :              * but in the latter case we should already have marked the two
     992             :              * referent variables as being selected, due to their use in the
     993             :              * JOIN clause.  So we need only be concerned with the Var case.
     994             :              * But we do need to drill down through implicit coercions.
     995             :              */
     996             :             Var        *aliasvar;
     997             : 
     998             :             Assert(col > 0 && col <= list_length(rte->joinaliasvars));
     999      119578 :             aliasvar = (Var *) list_nth(rte->joinaliasvars, col - 1);
    1000      119578 :             aliasvar = (Var *) strip_implicit_coercions((Node *) aliasvar);
    1001      119578 :             if (aliasvar && IsA(aliasvar, Var))
    1002      119442 :                 markVarForSelectPriv(pstate, aliasvar, NULL);
    1003             :         }
    1004             :     }
    1005             :     /* other RTE types don't require privilege marking */
    1006     1957684 : }
    1007             : 
    1008             : /*
    1009             :  * markVarForSelectPriv
    1010             :  *     Mark the RTE referenced by a Var as requiring SELECT privilege
    1011             :  *
    1012             :  * The caller should pass the Var's referenced RTE if it has it handy
    1013             :  * (nearly all do); otherwise pass NULL.
    1014             :  */
    1015             : void
    1016     1957676 : markVarForSelectPriv(ParseState *pstate, Var *var, RangeTblEntry *rte)
    1017             : {
    1018             :     Index       lv;
    1019             : 
    1020             :     Assert(IsA(var, Var));
    1021             :     /* Find the appropriate pstate if it's an uplevel Var */
    1022     2070882 :     for (lv = 0; lv < var->varlevelsup; lv++)
    1023      113206 :         pstate = pstate->parentParseState;
    1024     1957676 :     markRTEForSelectPriv(pstate, rte, var->varno, var->varattno);
    1025     1957676 : }
    1026             : 
    1027             : /*
    1028             :  * buildRelationAliases
    1029             :  *      Construct the eref column name list for a relation RTE.
    1030             :  *      This code is also used for function RTEs.
    1031             :  *
    1032             :  * tupdesc: the physical column information
    1033             :  * alias: the user-supplied alias, or NULL if none
    1034             :  * eref: the eref Alias to store column names in
    1035             :  *
    1036             :  * eref->colnames is filled in.  Also, alias->colnames is rebuilt to insert
    1037             :  * empty strings for any dropped columns, so that it will be one-to-one with
    1038             :  * physical column numbers.
    1039             :  *
    1040             :  * It is an error for there to be more aliases present than required.
    1041             :  */
    1042             : static void
    1043      554714 : buildRelationAliases(TupleDesc tupdesc, Alias *alias, Alias *eref)
    1044             : {
    1045      554714 :     int         maxattrs = tupdesc->natts;
    1046             :     List       *aliaslist;
    1047             :     ListCell   *aliaslc;
    1048             :     int         numaliases;
    1049             :     int         varattno;
    1050      554714 :     int         numdropped = 0;
    1051             : 
    1052             :     Assert(eref->colnames == NIL);
    1053             : 
    1054      554714 :     if (alias)
    1055             :     {
    1056      324306 :         aliaslist = alias->colnames;
    1057      324306 :         aliaslc = list_head(aliaslist);
    1058      324306 :         numaliases = list_length(aliaslist);
    1059             :         /* We'll rebuild the alias colname list */
    1060      324306 :         alias->colnames = NIL;
    1061             :     }
    1062             :     else
    1063             :     {
    1064      230408 :         aliaslist = NIL;
    1065      230408 :         aliaslc = NULL;
    1066      230408 :         numaliases = 0;
    1067             :     }
    1068             : 
    1069     6646722 :     for (varattno = 0; varattno < maxattrs; varattno++)
    1070             :     {
    1071     6092008 :         Form_pg_attribute attr = TupleDescAttr(tupdesc, varattno);
    1072             :         Value      *attrname;
    1073             : 
    1074     6092008 :         if (attr->attisdropped)
    1075             :         {
    1076             :             /* Always insert an empty string for a dropped column */
    1077        4112 :             attrname = makeString(pstrdup(""));
    1078        4112 :             if (aliaslc)
    1079           0 :                 alias->colnames = lappend(alias->colnames, attrname);
    1080        4112 :             numdropped++;
    1081             :         }
    1082     6087896 :         else if (aliaslc)
    1083             :         {
    1084             :             /* Use the next user-supplied alias */
    1085       20644 :             attrname = (Value *) lfirst(aliaslc);
    1086       20644 :             aliaslc = lnext(aliaslist, aliaslc);
    1087       20644 :             alias->colnames = lappend(alias->colnames, attrname);
    1088             :         }
    1089             :         else
    1090             :         {
    1091     6067252 :             attrname = makeString(pstrdup(NameStr(attr->attname)));
    1092             :             /* we're done with the alias if any */
    1093             :         }
    1094             : 
    1095     6092008 :         eref->colnames = lappend(eref->colnames, attrname);
    1096             :     }
    1097             : 
    1098             :     /* Too many user-supplied aliases? */
    1099      554714 :     if (aliaslc)
    1100           0 :         ereport(ERROR,
    1101             :                 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
    1102             :                  errmsg("table \"%s\" has %d columns available but %d columns specified",
    1103             :                         eref->aliasname, maxattrs - numdropped, numaliases)));
    1104      554714 : }
    1105             : 
    1106             : /*
    1107             :  * chooseScalarFunctionAlias
    1108             :  *      Select the column alias for a function in a function RTE,
    1109             :  *      when the function returns a scalar type (not composite or RECORD).
    1110             :  *
    1111             :  * funcexpr: transformed expression tree for the function call
    1112             :  * funcname: function name (as determined by FigureColname)
    1113             :  * alias: the user-supplied alias for the RTE, or NULL if none
    1114             :  * nfuncs: the number of functions appearing in the function RTE
    1115             :  *
    1116             :  * Note that the name we choose might be overridden later, if the user-given
    1117             :  * alias includes column alias names.  That's of no concern here.
    1118             :  */
    1119             : static char *
    1120       19442 : chooseScalarFunctionAlias(Node *funcexpr, char *funcname,
    1121             :                           Alias *alias, int nfuncs)
    1122             : {
    1123             :     char       *pname;
    1124             : 
    1125             :     /*
    1126             :      * If the expression is a simple function call, and the function has a
    1127             :      * single OUT parameter that is named, use the parameter's name.
    1128             :      */
    1129       19442 :     if (funcexpr && IsA(funcexpr, FuncExpr))
    1130             :     {
    1131       19426 :         pname = get_func_result_name(((FuncExpr *) funcexpr)->funcid);
    1132       19426 :         if (pname)
    1133         608 :             return pname;
    1134             :     }
    1135             : 
    1136             :     /*
    1137             :      * If there's just one function in the RTE, and the user gave an RTE alias
    1138             :      * name, use that name.  (This makes FROM func() AS foo use "foo" as the
    1139             :      * column name as well as the table alias.)
    1140             :      */
    1141       18834 :     if (nfuncs == 1 && alias)
    1142       17636 :         return alias->aliasname;
    1143             : 
    1144             :     /*
    1145             :      * Otherwise use the function name.
    1146             :      */
    1147        1198 :     return funcname;
    1148             : }
    1149             : 
    1150             : /*
    1151             :  * Open a table during parse analysis
    1152             :  *
    1153             :  * This is essentially just the same as table_openrv(), except that it caters
    1154             :  * to some parser-specific error reporting needs, notably that it arranges
    1155             :  * to include the RangeVar's parse location in any resulting error.
    1156             :  *
    1157             :  * Note: properly, lockmode should be declared LOCKMODE not int, but that
    1158             :  * would require importing storage/lock.h into parse_relation.h.  Since
    1159             :  * LOCKMODE is typedef'd as int anyway, that seems like overkill.
    1160             :  */
    1161             : Relation
    1162      395774 : parserOpenTable(ParseState *pstate, const RangeVar *relation, int lockmode)
    1163             : {
    1164             :     Relation    rel;
    1165             :     ParseCallbackState pcbstate;
    1166             : 
    1167      395774 :     setup_parser_errposition_callback(&pcbstate, pstate, relation->location);
    1168      395774 :     rel = table_openrv_extended(relation, lockmode, true);
    1169      395774 :     if (rel == NULL)
    1170             :     {
    1171         104 :         if (relation->schemaname)
    1172           0 :             ereport(ERROR,
    1173             :                     (errcode(ERRCODE_UNDEFINED_TABLE),
    1174             :                      errmsg("relation \"%s.%s\" does not exist",
    1175             :                             relation->schemaname, relation->relname)));
    1176             :         else
    1177             :         {
    1178             :             /*
    1179             :              * An unqualified name might have been meant as a reference to
    1180             :              * some not-yet-in-scope CTE.  The bare "does not exist" message
    1181             :              * has proven remarkably unhelpful for figuring out such problems,
    1182             :              * so we take pains to offer a specific hint.
    1183             :              */
    1184         104 :             if (isFutureCTE(pstate, relation->relname))
    1185           4 :                 ereport(ERROR,
    1186             :                         (errcode(ERRCODE_UNDEFINED_TABLE),
    1187             :                          errmsg("relation \"%s\" does not exist",
    1188             :                                 relation->relname),
    1189             :                          errdetail("There is a WITH item named \"%s\", but it cannot be referenced from this part of the query.",
    1190             :                                    relation->relname),
    1191             :                          errhint("Use WITH RECURSIVE, or re-order the WITH items to remove forward references.")));
    1192             :             else
    1193         100 :                 ereport(ERROR,
    1194             :                         (errcode(ERRCODE_UNDEFINED_TABLE),
    1195             :                          errmsg("relation \"%s\" does not exist",
    1196             :                                 relation->relname)));
    1197             :         }
    1198             :     }
    1199      395670 :     cancel_parser_errposition_callback(&pcbstate);
    1200      395670 :     return rel;
    1201             : }
    1202             : 
    1203             : /*
    1204             :  * Add an entry for a relation to the pstate's range table (p_rtable).
    1205             :  *
    1206             :  * Note: formerly this checked for refname conflicts, but that's wrong.
    1207             :  * Caller is responsible for checking for conflicts in the appropriate scope.
    1208             :  */
    1209             : RangeTblEntry *
    1210      325540 : addRangeTableEntry(ParseState *pstate,
    1211             :                    RangeVar *relation,
    1212             :                    Alias *alias,
    1213             :                    bool inh,
    1214             :                    bool inFromCl)
    1215             : {
    1216      325540 :     RangeTblEntry *rte = makeNode(RangeTblEntry);
    1217      325540 :     char       *refname = alias ? alias->aliasname : relation->relname;
    1218             :     LOCKMODE    lockmode;
    1219             :     Relation    rel;
    1220             : 
    1221             :     Assert(pstate != NULL);
    1222             : 
    1223      325540 :     rte->rtekind = RTE_RELATION;
    1224      325540 :     rte->alias = alias;
    1225             : 
    1226             :     /*
    1227             :      * Identify the type of lock we'll need on this relation.  It's not the
    1228             :      * query's target table (that case is handled elsewhere), so we need
    1229             :      * either RowShareLock if it's locked by FOR UPDATE/SHARE, or plain
    1230             :      * AccessShareLock otherwise.
    1231             :      */
    1232      325540 :     lockmode = isLockedRefname(pstate, refname) ? RowShareLock : AccessShareLock;
    1233             : 
    1234             :     /*
    1235             :      * Get the rel's OID.  This access also ensures that we have an up-to-date
    1236             :      * relcache entry for the rel.  Since this is typically the first access
    1237             :      * to a rel in a statement, we must open the rel with the proper lockmode.
    1238             :      */
    1239      325540 :     rel = parserOpenTable(pstate, relation, lockmode);
    1240      325450 :     rte->relid = RelationGetRelid(rel);
    1241      325450 :     rte->relkind = rel->rd_rel->relkind;
    1242      325450 :     rte->rellockmode = lockmode;
    1243             : 
    1244             :     /*
    1245             :      * Build the list of effective column names using user-supplied aliases
    1246             :      * and/or actual column names.
    1247             :      */
    1248      325450 :     rte->eref = makeAlias(refname, NIL);
    1249      325450 :     buildRelationAliases(rel->rd_att, alias, rte->eref);
    1250             : 
    1251             :     /*
    1252             :      * Drop the rel refcount, but keep the access lock till end of transaction
    1253             :      * so that the table can't be deleted or have its schema modified
    1254             :      * underneath us.
    1255             :      */
    1256      325450 :     table_close(rel, NoLock);
    1257             : 
    1258             :     /*
    1259             :      * Set flags and access permissions.
    1260             :      *
    1261             :      * The initial default on access checks is always check-for-READ-access,
    1262             :      * which is the right thing for all except target tables.
    1263             :      */
    1264      325450 :     rte->lateral = false;
    1265      325450 :     rte->inh = inh;
    1266      325450 :     rte->inFromCl = inFromCl;
    1267             : 
    1268      325450 :     rte->requiredPerms = ACL_SELECT;
    1269      325450 :     rte->checkAsUser = InvalidOid;   /* not set-uid by default, either */
    1270      325450 :     rte->selectedCols = NULL;
    1271      325450 :     rte->insertedCols = NULL;
    1272      325450 :     rte->updatedCols = NULL;
    1273      325450 :     rte->extraUpdatedCols = NULL;
    1274             : 
    1275             :     /*
    1276             :      * Add completed RTE to pstate's range table list, but not to join list
    1277             :      * nor namespace --- caller must do that if appropriate.
    1278             :      */
    1279      325450 :     pstate->p_rtable = lappend(pstate->p_rtable, rte);
    1280             : 
    1281      325450 :     return rte;
    1282             : }
    1283             : 
    1284             : /*
    1285             :  * Add an entry for a relation to the pstate's range table (p_rtable).
    1286             :  *
    1287             :  * This is just like addRangeTableEntry() except that it makes an RTE
    1288             :  * given an already-open relation instead of a RangeVar reference.
    1289             :  *
    1290             :  * lockmode is the lock type required for query execution; it must be one
    1291             :  * of AccessShareLock, RowShareLock, or RowExclusiveLock depending on the
    1292             :  * RTE's role within the query.  The caller must hold that lock mode
    1293             :  * or a stronger one.
    1294             :  *
    1295             :  * Note: properly, lockmode should be declared LOCKMODE not int, but that
    1296             :  * would require importing storage/lock.h into parse_relation.h.  Since
    1297             :  * LOCKMODE is typedef'd as int anyway, that seems like overkill.
    1298             :  */
    1299             : RangeTblEntry *
    1300      190662 : addRangeTableEntryForRelation(ParseState *pstate,
    1301             :                               Relation rel,
    1302             :                               int lockmode,
    1303             :                               Alias *alias,
    1304             :                               bool inh,
    1305             :                               bool inFromCl)
    1306             : {
    1307      190662 :     RangeTblEntry *rte = makeNode(RangeTblEntry);
    1308      190662 :     char       *refname = alias ? alias->aliasname : RelationGetRelationName(rel);
    1309             : 
    1310             :     Assert(pstate != NULL);
    1311             : 
    1312             :     Assert(lockmode == AccessShareLock ||
    1313             :            lockmode == RowShareLock ||
    1314             :            lockmode == RowExclusiveLock);
    1315             :     Assert(CheckRelationLockedByMe(rel, lockmode, true));
    1316             : 
    1317      190662 :     rte->rtekind = RTE_RELATION;
    1318      190662 :     rte->alias = alias;
    1319      190662 :     rte->relid = RelationGetRelid(rel);
    1320      190662 :     rte->relkind = rel->rd_rel->relkind;
    1321      190662 :     rte->rellockmode = lockmode;
    1322             : 
    1323             :     /*
    1324             :      * Build the list of effective column names using user-supplied aliases
    1325             :      * and/or actual column names.
    1326             :      */
    1327      190662 :     rte->eref = makeAlias(refname, NIL);
    1328      190662 :     buildRelationAliases(rel->rd_att, alias, rte->eref);
    1329             : 
    1330             :     /*
    1331             :      * Set flags and access permissions.
    1332             :      *
    1333             :      * The initial default on access checks is always check-for-READ-access,
    1334             :      * which is the right thing for all except target tables.
    1335             :      */
    1336      190662 :     rte->lateral = false;
    1337      190662 :     rte->inh = inh;
    1338      190662 :     rte->inFromCl = inFromCl;
    1339             : 
    1340      190662 :     rte->requiredPerms = ACL_SELECT;
    1341      190662 :     rte->checkAsUser = InvalidOid;   /* not set-uid by default, either */
    1342      190662 :     rte->selectedCols = NULL;
    1343      190662 :     rte->insertedCols = NULL;
    1344      190662 :     rte->updatedCols = NULL;
    1345      190662 :     rte->extraUpdatedCols = NULL;
    1346             : 
    1347             :     /*
    1348             :      * Add completed RTE to pstate's range table list, but not to join list
    1349             :      * nor namespace --- caller must do that if appropriate.
    1350             :      */
    1351      190662 :     pstate->p_rtable = lappend(pstate->p_rtable, rte);
    1352             : 
    1353      190662 :     return rte;
    1354             : }
    1355             : 
    1356             : /*
    1357             :  * Add an entry for a subquery to the pstate's range table (p_rtable).
    1358             :  *
    1359             :  * This is just like addRangeTableEntry() except that it makes a subquery RTE.
    1360             :  * Note that an alias clause *must* be supplied.
    1361             :  */
    1362             : RangeTblEntry *
    1363       59576 : addRangeTableEntryForSubquery(ParseState *pstate,
    1364             :                               Query *subquery,
    1365             :                               Alias *alias,
    1366             :                               bool lateral,
    1367             :                               bool inFromCl)
    1368             : {
    1369       59576 :     RangeTblEntry *rte = makeNode(RangeTblEntry);
    1370       59576 :     char       *refname = alias->aliasname;
    1371             :     Alias      *eref;
    1372             :     int         numaliases;
    1373             :     int         varattno;
    1374             :     ListCell   *tlistitem;
    1375             : 
    1376             :     Assert(pstate != NULL);
    1377             : 
    1378       59576 :     rte->rtekind = RTE_SUBQUERY;
    1379       59576 :     rte->subquery = subquery;
    1380       59576 :     rte->alias = alias;
    1381             : 
    1382       59576 :     eref = copyObject(alias);
    1383       59576 :     numaliases = list_length(eref->colnames);
    1384             : 
    1385             :     /* fill in any unspecified alias columns */
    1386       59576 :     varattno = 0;
    1387      310992 :     foreach(tlistitem, subquery->targetList)
    1388             :     {
    1389      251416 :         TargetEntry *te = (TargetEntry *) lfirst(tlistitem);
    1390             : 
    1391      251416 :         if (te->resjunk)
    1392         104 :             continue;
    1393      251312 :         varattno++;
    1394             :         Assert(varattno == te->resno);
    1395      251312 :         if (varattno > numaliases)
    1396             :         {
    1397             :             char       *attrname;
    1398             : 
    1399      215194 :             attrname = pstrdup(te->resname);
    1400      215194 :             eref->colnames = lappend(eref->colnames, makeString(attrname));
    1401             :         }
    1402             :     }
    1403       59576 :     if (varattno < numaliases)
    1404           0 :         ereport(ERROR,
    1405             :                 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
    1406             :                  errmsg("table \"%s\" has %d columns available but %d columns specified",
    1407             :                         refname, varattno, numaliases)));
    1408             : 
    1409       59576 :     rte->eref = eref;
    1410             : 
    1411             :     /*
    1412             :      * Set flags and access permissions.
    1413             :      *
    1414             :      * Subqueries are never checked for access rights.
    1415             :      */
    1416       59576 :     rte->lateral = lateral;
    1417       59576 :     rte->inh = false;            /* never true for subqueries */
    1418       59576 :     rte->inFromCl = inFromCl;
    1419             : 
    1420       59576 :     rte->requiredPerms = 0;
    1421       59576 :     rte->checkAsUser = InvalidOid;
    1422       59576 :     rte->selectedCols = NULL;
    1423       59576 :     rte->insertedCols = NULL;
    1424       59576 :     rte->updatedCols = NULL;
    1425       59576 :     rte->extraUpdatedCols = NULL;
    1426             : 
    1427             :     /*
    1428             :      * Add completed RTE to pstate's range table list, but not to join list
    1429             :      * nor namespace --- caller must do that if appropriate.
    1430             :      */
    1431       59576 :     pstate->p_rtable = lappend(pstate->p_rtable, rte);
    1432             : 
    1433       59576 :     return rte;
    1434             : }
    1435             : 
    1436             : /*
    1437             :  * Add an entry for a function (or functions) to the pstate's range table
    1438             :  * (p_rtable).
    1439             :  *
    1440             :  * This is just like addRangeTableEntry() except that it makes a function RTE.
    1441             :  */
    1442             : RangeTblEntry *
    1443       38366 : addRangeTableEntryForFunction(ParseState *pstate,
    1444             :                               List *funcnames,
    1445             :                               List *funcexprs,
    1446             :                               List *coldeflists,
    1447             :                               RangeFunction *rangefunc,
    1448             :                               bool lateral,
    1449             :                               bool inFromCl)
    1450             : {
    1451       38366 :     RangeTblEntry *rte = makeNode(RangeTblEntry);
    1452       38366 :     Alias      *alias = rangefunc->alias;
    1453             :     Alias      *eref;
    1454             :     char       *aliasname;
    1455       38366 :     int         nfuncs = list_length(funcexprs);
    1456             :     TupleDesc  *functupdescs;
    1457             :     TupleDesc   tupdesc;
    1458             :     ListCell   *lc1,
    1459             :                *lc2,
    1460             :                *lc3;
    1461             :     int         i;
    1462             :     int         j;
    1463             :     int         funcno;
    1464             :     int         natts,
    1465             :                 totalatts;
    1466             : 
    1467             :     Assert(pstate != NULL);
    1468             : 
    1469       38366 :     rte->rtekind = RTE_FUNCTION;
    1470       38366 :     rte->relid = InvalidOid;
    1471       38366 :     rte->subquery = NULL;
    1472       38366 :     rte->functions = NIL;        /* we'll fill this list below */
    1473       38366 :     rte->funcordinality = rangefunc->ordinality;
    1474       38366 :     rte->alias = alias;
    1475             : 
    1476             :     /*
    1477             :      * Choose the RTE alias name.  We default to using the first function's
    1478             :      * name even when there's more than one; which is maybe arguable but beats
    1479             :      * using something constant like "table".
    1480             :      */
    1481       38366 :     if (alias)
    1482       27274 :         aliasname = alias->aliasname;
    1483             :     else
    1484       11092 :         aliasname = linitial(funcnames);
    1485             : 
    1486       38366 :     eref = makeAlias(aliasname, NIL);
    1487       38366 :     rte->eref = eref;
    1488             : 
    1489             :     /* Process each function ... */
    1490       38366 :     functupdescs = (TupleDesc *) palloc(nfuncs * sizeof(TupleDesc));
    1491             : 
    1492       38366 :     totalatts = 0;
    1493       38366 :     funcno = 0;
    1494       76888 :     forthree(lc1, funcexprs, lc2, funcnames, lc3, coldeflists)
    1495             :     {
    1496       38546 :         Node       *funcexpr = (Node *) lfirst(lc1);
    1497       38546 :         char       *funcname = (char *) lfirst(lc2);
    1498       38546 :         List       *coldeflist = (List *) lfirst(lc3);
    1499       38546 :         RangeTblFunction *rtfunc = makeNode(RangeTblFunction);
    1500             :         TypeFuncClass functypclass;
    1501             :         Oid         funcrettype;
    1502             : 
    1503             :         /* Initialize RangeTblFunction node */
    1504       38546 :         rtfunc->funcexpr = funcexpr;
    1505       38546 :         rtfunc->funccolnames = NIL;
    1506       38546 :         rtfunc->funccoltypes = NIL;
    1507       38546 :         rtfunc->funccoltypmods = NIL;
    1508       38546 :         rtfunc->funccolcollations = NIL;
    1509       38546 :         rtfunc->funcparams = NULL;   /* not set until planning */
    1510             : 
    1511             :         /*
    1512             :          * Now determine if the function returns a simple or composite type.
    1513             :          */
    1514       38546 :         functypclass = get_expr_result_type(funcexpr,
    1515             :                                             &funcrettype,
    1516             :                                             &tupdesc);
    1517             : 
    1518             :         /*
    1519             :          * A coldeflist is required if the function returns RECORD and hasn't
    1520             :          * got a predetermined record type, and is prohibited otherwise.
    1521             :          */
    1522       38546 :         if (coldeflist != NIL)
    1523             :         {
    1524         518 :             if (functypclass != TYPEFUNC_RECORD)
    1525           0 :                 ereport(ERROR,
    1526             :                         (errcode(ERRCODE_SYNTAX_ERROR),
    1527             :                          errmsg("a column definition list is only allowed for functions returning \"record\""),
    1528             :                          parser_errposition(pstate,
    1529             :                                             exprLocation((Node *) coldeflist))));
    1530             :         }
    1531             :         else
    1532             :         {
    1533       38028 :             if (functypclass == TYPEFUNC_RECORD)
    1534          24 :                 ereport(ERROR,
    1535             :                         (errcode(ERRCODE_SYNTAX_ERROR),
    1536             :                          errmsg("a column definition list is required for functions returning \"record\""),
    1537             :                          parser_errposition(pstate, exprLocation(funcexpr))));
    1538             :         }
    1539             : 
    1540       38522 :         if (functypclass == TYPEFUNC_COMPOSITE ||
    1541             :             functypclass == TYPEFUNC_COMPOSITE_DOMAIN)
    1542             :         {
    1543             :             /* Composite data type, e.g. a table's row type */
    1544             :             Assert(tupdesc);
    1545             :         }
    1546       19960 :         else if (functypclass == TYPEFUNC_SCALAR)
    1547             :         {
    1548             :             /* Base data type, i.e. scalar */
    1549       19442 :             tupdesc = CreateTemplateTupleDesc(1);
    1550       38884 :             TupleDescInitEntry(tupdesc,
    1551             :                                (AttrNumber) 1,
    1552       19442 :                                chooseScalarFunctionAlias(funcexpr, funcname,
    1553             :                                                          alias, nfuncs),
    1554             :                                funcrettype,
    1555             :                                -1,
    1556             :                                0);
    1557             :         }
    1558         518 :         else if (functypclass == TYPEFUNC_RECORD)
    1559             :         {
    1560             :             ListCell   *col;
    1561             : 
    1562             :             /*
    1563             :              * Use the column definition list to construct a tupdesc and fill
    1564             :              * in the RangeTblFunction's lists.
    1565             :              */
    1566         518 :             tupdesc = CreateTemplateTupleDesc(list_length(coldeflist));
    1567         518 :             i = 1;
    1568        1786 :             foreach(col, coldeflist)
    1569             :             {
    1570        1268 :                 ColumnDef  *n = (ColumnDef *) lfirst(col);
    1571             :                 char       *attrname;
    1572             :                 Oid         attrtype;
    1573             :                 int32       attrtypmod;
    1574             :                 Oid         attrcollation;
    1575             : 
    1576        1268 :                 attrname = n->colname;
    1577        1268 :                 if (n->typeName->setof)
    1578           0 :                     ereport(ERROR,
    1579             :                             (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
    1580             :                              errmsg("column \"%s\" cannot be declared SETOF",
    1581             :                                     attrname),
    1582             :                              parser_errposition(pstate, n->location)));
    1583        1268 :                 typenameTypeIdAndMod(pstate, n->typeName,
    1584             :                                      &attrtype, &attrtypmod);
    1585        1268 :                 attrcollation = GetColumnDefCollation(pstate, n, attrtype);
    1586        2536 :                 TupleDescInitEntry(tupdesc,
    1587        1268 :                                    (AttrNumber) i,
    1588             :                                    attrname,
    1589             :                                    attrtype,
    1590             :                                    attrtypmod,
    1591             :                                    0);
    1592        1268 :                 TupleDescInitEntryCollation(tupdesc,
    1593        1268 :                                             (AttrNumber) i,
    1594             :                                             attrcollation);
    1595        1268 :                 rtfunc->funccolnames = lappend(rtfunc->funccolnames,
    1596        1268 :                                                makeString(pstrdup(attrname)));
    1597        1268 :                 rtfunc->funccoltypes = lappend_oid(rtfunc->funccoltypes,
    1598             :                                                    attrtype);
    1599        1268 :                 rtfunc->funccoltypmods = lappend_int(rtfunc->funccoltypmods,
    1600             :                                                      attrtypmod);
    1601        1268 :                 rtfunc->funccolcollations = lappend_oid(rtfunc->funccolcollations,
    1602             :                                                         attrcollation);
    1603             : 
    1604        1268 :                 i++;
    1605             :             }
    1606             : 
    1607             :             /*
    1608             :              * Ensure that the coldeflist defines a legal set of names (no
    1609             :              * duplicates, but we needn't worry about system column names) and
    1610             :              * datatypes.  Although we mostly can't allow pseudo-types, it
    1611             :              * seems safe to allow RECORD and RECORD[], since values within
    1612             :              * those type classes are self-identifying at runtime, and the
    1613             :              * coldeflist doesn't represent anything that will be visible to
    1614             :              * other sessions.
    1615             :              */
    1616         518 :             CheckAttributeNamesTypes(tupdesc, RELKIND_COMPOSITE_TYPE,
    1617             :                                      CHKATYPE_ANYRECORD);
    1618             :         }
    1619             :         else
    1620           0 :             ereport(ERROR,
    1621             :                     (errcode(ERRCODE_DATATYPE_MISMATCH),
    1622             :                      errmsg("function \"%s\" in FROM has unsupported return type %s",
    1623             :                             funcname, format_type_be(funcrettype)),
    1624             :                      parser_errposition(pstate, exprLocation(funcexpr))));
    1625             : 
    1626             :         /* Finish off the RangeTblFunction and add it to the RTE's list */
    1627       38522 :         rtfunc->funccolcount = tupdesc->natts;
    1628       38522 :         rte->functions = lappend(rte->functions, rtfunc);
    1629             : 
    1630             :         /* Save the tupdesc for use below */
    1631       38522 :         functupdescs[funcno] = tupdesc;
    1632       38522 :         totalatts += tupdesc->natts;
    1633       38522 :         funcno++;
    1634             :     }
    1635             : 
    1636             :     /*
    1637             :      * If there's more than one function, or we want an ordinality column, we
    1638             :      * have to produce a merged tupdesc.
    1639             :      */
    1640       38342 :     if (nfuncs > 1 || rangefunc->ordinality)
    1641             :     {
    1642        6206 :         if (rangefunc->ordinality)
    1643        6166 :             totalatts++;
    1644             : 
    1645             :         /* Merge the tuple descs of each function into a composite one */
    1646        6206 :         tupdesc = CreateTemplateTupleDesc(totalatts);
    1647        6206 :         natts = 0;
    1648       12592 :         for (i = 0; i < nfuncs; i++)
    1649             :         {
    1650       13140 :             for (j = 1; j <= functupdescs[i]->natts; j++)
    1651        6754 :                 TupleDescCopyEntry(tupdesc, ++natts, functupdescs[i], j);
    1652             :         }
    1653             : 
    1654             :         /* Add the ordinality column if needed */
    1655        6206 :         if (rangefunc->ordinality)
    1656       12332 :             TupleDescInitEntry(tupdesc,
    1657        6166 :                                (AttrNumber) ++natts,
    1658             :                                "ordinality",
    1659             :                                INT8OID,
    1660             :                                -1,
    1661             :                                0);
    1662             : 
    1663        6206 :         Assert(natts == totalatts);
    1664             :     }
    1665             :     else
    1666             :     {
    1667             :         /* We can just use the single function's tupdesc as-is */
    1668       32136 :         tupdesc = functupdescs[0];
    1669             :     }
    1670             : 
    1671             :     /* Use the tupdesc while assigning column aliases for the RTE */
    1672       38342 :     buildRelationAliases(tupdesc, alias, eref);
    1673             : 
    1674             :     /*
    1675             :      * Set flags and access permissions.
    1676             :      *
    1677             :      * Functions are never checked for access rights (at least, not by the RTE
    1678             :      * permissions mechanism).
    1679             :      */
    1680       38342 :     rte->lateral = lateral;
    1681       38342 :     rte->inh = false;            /* never true for functions */
    1682       38342 :     rte->inFromCl = inFromCl;
    1683             : 
    1684       38342 :     rte->requiredPerms = 0;
    1685       38342 :     rte->checkAsUser = InvalidOid;
    1686       38342 :     rte->selectedCols = NULL;
    1687       38342 :     rte->insertedCols = NULL;
    1688       38342 :     rte->updatedCols = NULL;
    1689       38342 :     rte->extraUpdatedCols = NULL;
    1690             : 
    1691             :     /*
    1692             :      * Add completed RTE to pstate's range table list, but not to join list
    1693             :      * nor namespace --- caller must do that if appropriate.
    1694             :      */
    1695       38342 :     pstate->p_rtable = lappend(pstate->p_rtable, rte);
    1696             : 
    1697       38342 :     return rte;
    1698             : }
    1699             : 
    1700             : /*
    1701             :  * Add an entry for a table function to the pstate's range table (p_rtable).
    1702             :  *
    1703             :  * This is much like addRangeTableEntry() except that it makes a tablefunc RTE.
    1704             :  */
    1705             : RangeTblEntry *
    1706         140 : addRangeTableEntryForTableFunc(ParseState *pstate,
    1707             :                                TableFunc *tf,
    1708             :                                Alias *alias,
    1709             :                                bool lateral,
    1710             :                                bool inFromCl)
    1711             : {
    1712         140 :     RangeTblEntry *rte = makeNode(RangeTblEntry);
    1713         140 :     char       *refname = alias ? alias->aliasname : pstrdup("xmltable");
    1714             :     Alias      *eref;
    1715             :     int         numaliases;
    1716             : 
    1717             :     Assert(pstate != NULL);
    1718             : 
    1719         140 :     rte->rtekind = RTE_TABLEFUNC;
    1720         140 :     rte->relid = InvalidOid;
    1721         140 :     rte->subquery = NULL;
    1722         140 :     rte->tablefunc = tf;
    1723         140 :     rte->coltypes = tf->coltypes;
    1724         140 :     rte->coltypmods = tf->coltypmods;
    1725         140 :     rte->colcollations = tf->colcollations;
    1726         140 :     rte->alias = alias;
    1727             : 
    1728         140 :     eref = alias ? copyObject(alias) : makeAlias(refname, NIL);
    1729         140 :     numaliases = list_length(eref->colnames);
    1730             : 
    1731             :     /* fill in any unspecified alias columns */
    1732         140 :     if (numaliases < list_length(tf->colnames))
    1733         140 :         eref->colnames = list_concat(eref->colnames,
    1734         140 :                                      list_copy_tail(tf->colnames, numaliases));
    1735             : 
    1736         140 :     rte->eref = eref;
    1737             : 
    1738             :     /*
    1739             :      * Set flags and access permissions.
    1740             :      *
    1741             :      * Tablefuncs are never checked for access rights (at least, not by the
    1742             :      * RTE permissions mechanism).
    1743             :      */
    1744         140 :     rte->lateral = lateral;
    1745         140 :     rte->inh = false;            /* never true for tablefunc RTEs */
    1746         140 :     rte->inFromCl = inFromCl;
    1747             : 
    1748         140 :     rte->requiredPerms = 0;
    1749         140 :     rte->checkAsUser = InvalidOid;
    1750         140 :     rte->selectedCols = NULL;
    1751         140 :     rte->insertedCols = NULL;
    1752         140 :     rte->updatedCols = NULL;
    1753         140 :     rte->extraUpdatedCols = NULL;
    1754             : 
    1755             :     /*
    1756             :      * Add completed RTE to pstate's range table list, but not to join list
    1757             :      * nor namespace --- caller must do that if appropriate.
    1758             :      */
    1759         140 :     pstate->p_rtable = lappend(pstate->p_rtable, rte);
    1760             : 
    1761         140 :     return rte;
    1762             : }
    1763             : 
    1764             : /*
    1765             :  * Add an entry for a VALUES list to the pstate's range table (p_rtable).
    1766             :  *
    1767             :  * This is much like addRangeTableEntry() except that it makes a values RTE.
    1768             :  */
    1769             : RangeTblEntry *
    1770        4692 : addRangeTableEntryForValues(ParseState *pstate,
    1771             :                             List *exprs,
    1772             :                             List *coltypes,
    1773             :                             List *coltypmods,
    1774             :                             List *colcollations,
    1775             :                             Alias *alias,
    1776             :                             bool lateral,
    1777             :                             bool inFromCl)
    1778             : {
    1779        4692 :     RangeTblEntry *rte = makeNode(RangeTblEntry);
    1780        4692 :     char       *refname = alias ? alias->aliasname : pstrdup("*VALUES*");
    1781             :     Alias      *eref;
    1782             :     int         numaliases;
    1783             :     int         numcolumns;
    1784             : 
    1785             :     Assert(pstate != NULL);
    1786             : 
    1787        4692 :     rte->rtekind = RTE_VALUES;
    1788        4692 :     rte->relid = InvalidOid;
    1789        4692 :     rte->subquery = NULL;
    1790        4692 :     rte->values_lists = exprs;
    1791        4692 :     rte->coltypes = coltypes;
    1792        4692 :     rte->coltypmods = coltypmods;
    1793        4692 :     rte->colcollations = colcollations;
    1794        4692 :     rte->alias = alias;
    1795             : 
    1796        4692 :     eref = alias ? copyObject(alias) : makeAlias(refname, NIL);
    1797             : 
    1798             :     /* fill in any unspecified alias columns */
    1799        4692 :     numcolumns = list_length((List *) linitial(exprs));
    1800        4692 :     numaliases = list_length(eref->colnames);
    1801       17020 :     while (numaliases < numcolumns)
    1802             :     {
    1803             :         char        attrname[64];
    1804             : 
    1805        7636 :         numaliases++;
    1806        7636 :         snprintf(attrname, sizeof(attrname), "column%d", numaliases);
    1807        7636 :         eref->colnames = lappend(eref->colnames,
    1808        7636 :                                  makeString(pstrdup(attrname)));
    1809             :     }
    1810        4692 :     if (numcolumns < numaliases)
    1811           0 :         ereport(ERROR,
    1812             :                 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
    1813             :                  errmsg("VALUES lists \"%s\" have %d columns available but %d columns specified",
    1814             :                         refname, numcolumns, numaliases)));
    1815             : 
    1816        4692 :     rte->eref = eref;
    1817             : 
    1818             :     /*
    1819             :      * Set flags and access permissions.
    1820             :      *
    1821             :      * Subqueries are never checked for access rights.
    1822             :      */
    1823        4692 :     rte->lateral = lateral;
    1824        4692 :     rte->inh = false;            /* never true for values RTEs */
    1825        4692 :     rte->inFromCl = inFromCl;
    1826             : 
    1827        4692 :     rte->requiredPerms = 0;
    1828        4692 :     rte->checkAsUser = InvalidOid;
    1829        4692 :     rte->selectedCols = NULL;
    1830        4692 :     rte->insertedCols = NULL;
    1831        4692 :     rte->updatedCols = NULL;
    1832        4692 :     rte->extraUpdatedCols = NULL;
    1833             : 
    1834             :     /*
    1835             :      * Add completed RTE to pstate's range table list, but not to join list
    1836             :      * nor namespace --- caller must do that if appropriate.
    1837             :      */
    1838        4692 :     pstate->p_rtable = lappend(pstate->p_rtable, rte);
    1839             : 
    1840        4692 :     return rte;
    1841             : }
    1842             : 
    1843             : /*
    1844             :  * Add an entry for a join to the pstate's range table (p_rtable).
    1845             :  *
    1846             :  * This is much like addRangeTableEntry() except that it makes a join RTE.
    1847             :  */
    1848             : RangeTblEntry *
    1849       88102 : addRangeTableEntryForJoin(ParseState *pstate,
    1850             :                           List *colnames,
    1851             :                           JoinType jointype,
    1852             :                           List *aliasvars,
    1853             :                           Alias *alias,
    1854             :                           bool inFromCl)
    1855             : {
    1856       88102 :     RangeTblEntry *rte = makeNode(RangeTblEntry);
    1857             :     Alias      *eref;
    1858             :     int         numaliases;
    1859             : 
    1860             :     Assert(pstate != NULL);
    1861             : 
    1862             :     /*
    1863             :      * Fail if join has too many columns --- we must be able to reference any
    1864             :      * of the columns with an AttrNumber.
    1865             :      */
    1866       88102 :     if (list_length(aliasvars) > MaxAttrNumber)
    1867           0 :         ereport(ERROR,
    1868             :                 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
    1869             :                  errmsg("joins can have at most %d columns",
    1870             :                         MaxAttrNumber)));
    1871             : 
    1872       88102 :     rte->rtekind = RTE_JOIN;
    1873       88102 :     rte->relid = InvalidOid;
    1874       88102 :     rte->subquery = NULL;
    1875       88102 :     rte->jointype = jointype;
    1876       88102 :     rte->joinaliasvars = aliasvars;
    1877       88102 :     rte->alias = alias;
    1878             : 
    1879       88102 :     eref = alias ? copyObject(alias) : makeAlias("unnamed_join", NIL);
    1880       88102 :     numaliases = list_length(eref->colnames);
    1881             : 
    1882             :     /* fill in any unspecified alias columns */
    1883       88102 :     if (numaliases < list_length(colnames))
    1884       88014 :         eref->colnames = list_concat(eref->colnames,
    1885       88014 :                                      list_copy_tail(colnames, numaliases));
    1886             : 
    1887       88102 :     rte->eref = eref;
    1888             : 
    1889             :     /*
    1890             :      * Set flags and access permissions.
    1891             :      *
    1892             :      * Joins are never checked for access rights.
    1893             :      */
    1894       88102 :     rte->lateral = false;
    1895       88102 :     rte->inh = false;            /* never true for joins */
    1896       88102 :     rte->inFromCl = inFromCl;
    1897             : 
    1898       88102 :     rte->requiredPerms = 0;
    1899       88102 :     rte->checkAsUser = InvalidOid;
    1900       88102 :     rte->selectedCols = NULL;
    1901       88102 :     rte->insertedCols = NULL;
    1902       88102 :     rte->updatedCols = NULL;
    1903       88102 :     rte->extraUpdatedCols = NULL;
    1904             : 
    1905             :     /*
    1906             :      * Add completed RTE to pstate's range table list, but not to join list
    1907             :      * nor namespace --- caller must do that if appropriate.
    1908             :      */
    1909       88102 :     pstate->p_rtable = lappend(pstate->p_rtable, rte);
    1910             : 
    1911       88102 :     return rte;
    1912             : }
    1913             : 
    1914             : /*
    1915             :  * Add an entry for a CTE reference to the pstate's range table (p_rtable).
    1916             :  *
    1917             :  * This is much like addRangeTableEntry() except that it makes a CTE RTE.
    1918             :  */
    1919             : RangeTblEntry *
    1920        1874 : addRangeTableEntryForCTE(ParseState *pstate,
    1921             :                          CommonTableExpr *cte,
    1922             :                          Index levelsup,
    1923             :                          RangeVar *rv,
    1924             :                          bool inFromCl)
    1925             : {
    1926        1874 :     RangeTblEntry *rte = makeNode(RangeTblEntry);
    1927        1874 :     Alias      *alias = rv->alias;
    1928        1874 :     char       *refname = alias ? alias->aliasname : cte->ctename;
    1929             :     Alias      *eref;
    1930             :     int         numaliases;
    1931             :     int         varattno;
    1932             :     ListCell   *lc;
    1933             : 
    1934             :     Assert(pstate != NULL);
    1935             : 
    1936        1874 :     rte->rtekind = RTE_CTE;
    1937        1874 :     rte->ctename = cte->ctename;
    1938        1874 :     rte->ctelevelsup = levelsup;
    1939             : 
    1940             :     /* Self-reference if and only if CTE's parse analysis isn't completed */
    1941        1874 :     rte->self_reference = !IsA(cte->ctequery, Query);
    1942             :     Assert(cte->cterecursive || !rte->self_reference);
    1943             :     /* Bump the CTE's refcount if this isn't a self-reference */
    1944        1874 :     if (!rte->self_reference)
    1945        1520 :         cte->cterefcount++;
    1946             : 
    1947             :     /*
    1948             :      * We throw error if the CTE is INSERT/UPDATE/DELETE without RETURNING.
    1949             :      * This won't get checked in case of a self-reference, but that's OK
    1950             :      * because data-modifying CTEs aren't allowed to be recursive anyhow.
    1951             :      */
    1952        1874 :     if (IsA(cte->ctequery, Query))
    1953             :     {
    1954        1520 :         Query      *ctequery = (Query *) cte->ctequery;
    1955             : 
    1956        1678 :         if (ctequery->commandType != CMD_SELECT &&
    1957         158 :             ctequery->returningList == NIL)
    1958           4 :             ereport(ERROR,
    1959             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    1960             :                      errmsg("WITH query \"%s\" does not have a RETURNING clause",
    1961             :                             cte->ctename),
    1962             :                      parser_errposition(pstate, rv->location)));
    1963             :     }
    1964             : 
    1965        1870 :     rte->coltypes = cte->ctecoltypes;
    1966        1870 :     rte->coltypmods = cte->ctecoltypmods;
    1967        1870 :     rte->colcollations = cte->ctecolcollations;
    1968             : 
    1969        1870 :     rte->alias = alias;
    1970        1870 :     if (alias)
    1971         100 :         eref = copyObject(alias);
    1972             :     else
    1973        1770 :         eref = makeAlias(refname, NIL);
    1974        1870 :     numaliases = list_length(eref->colnames);
    1975             : 
    1976             :     /* fill in any unspecified alias columns */
    1977        1870 :     varattno = 0;
    1978        6160 :     foreach(lc, cte->ctecolnames)
    1979             :     {
    1980        4290 :         varattno++;
    1981        4290 :         if (varattno > numaliases)
    1982        4290 :             eref->colnames = lappend(eref->colnames, lfirst(lc));
    1983             :     }
    1984        1870 :     if (varattno < numaliases)
    1985           0 :         ereport(ERROR,
    1986             :                 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
    1987             :                  errmsg("table \"%s\" has %d columns available but %d columns specified",
    1988             :                         refname, varattno, numaliases)));
    1989             : 
    1990        1870 :     rte->eref = eref;
    1991             : 
    1992             :     /*
    1993             :      * Set flags and access permissions.
    1994             :      *
    1995             :      * Subqueries are never checked for access rights.
    1996             :      */
    1997        1870 :     rte->lateral = false;
    1998        1870 :     rte->inh = false;            /* never true for subqueries */
    1999        1870 :     rte->inFromCl = inFromCl;
    2000             : 
    2001        1870 :     rte->requiredPerms = 0;
    2002        1870 :     rte->checkAsUser = InvalidOid;
    2003        1870 :     rte->selectedCols = NULL;
    2004        1870 :     rte->insertedCols = NULL;
    2005        1870 :     rte->updatedCols = NULL;
    2006        1870 :     rte->extraUpdatedCols = NULL;
    2007             : 
    2008             :     /*
    2009             :      * Add completed RTE to pstate's range table list, but not to join list
    2010             :      * nor namespace --- caller must do that if appropriate.
    2011             :      */
    2012        1870 :     pstate->p_rtable = lappend(pstate->p_rtable, rte);
    2013             : 
    2014        1870 :     return rte;
    2015             : }
    2016             : 
    2017             : /*
    2018             :  * Add an entry for an ephemeral named relation reference to the pstate's
    2019             :  * range table (p_rtable).
    2020             :  *
    2021             :  * It is expected that the RangeVar, which up until now is only known to be an
    2022             :  * ephemeral named relation, will (in conjunction with the QueryEnvironment in
    2023             :  * the ParseState), create a RangeTblEntry for a specific *kind* of ephemeral
    2024             :  * named relation, based on enrtype.
    2025             :  *
    2026             :  * This is much like addRangeTableEntry() except that it makes an RTE for an
    2027             :  * ephemeral named relation.
    2028             :  */
    2029             : RangeTblEntry *
    2030         260 : addRangeTableEntryForENR(ParseState *pstate,
    2031             :                          RangeVar *rv,
    2032             :                          bool inFromCl)
    2033             : {
    2034         260 :     RangeTblEntry *rte = makeNode(RangeTblEntry);
    2035         260 :     Alias      *alias = rv->alias;
    2036         260 :     char       *refname = alias ? alias->aliasname : rv->relname;
    2037             :     EphemeralNamedRelationMetadata enrmd;
    2038             :     TupleDesc   tupdesc;
    2039             :     int         attno;
    2040             : 
    2041             :     Assert(pstate != NULL);
    2042         260 :     enrmd = get_visible_ENR(pstate, rv->relname);
    2043             :     Assert(enrmd != NULL);
    2044             : 
    2045         260 :     switch (enrmd->enrtype)
    2046             :     {
    2047             :         case ENR_NAMED_TUPLESTORE:
    2048         260 :             rte->rtekind = RTE_NAMEDTUPLESTORE;
    2049         260 :             break;
    2050             : 
    2051             :         default:
    2052           0 :             elog(ERROR, "unexpected enrtype: %d", enrmd->enrtype);
    2053             :             return NULL;        /* for fussy compilers */
    2054             :     }
    2055             : 
    2056             :     /*
    2057             :      * Record dependency on a relation.  This allows plans to be invalidated
    2058             :      * if they access transition tables linked to a table that is altered.
    2059             :      */
    2060         260 :     rte->relid = enrmd->reliddesc;
    2061             : 
    2062             :     /*
    2063             :      * Build the list of effective column names using user-supplied aliases
    2064             :      * and/or actual column names.
    2065             :      */
    2066         260 :     tupdesc = ENRMetadataGetTupDesc(enrmd);
    2067         260 :     rte->eref = makeAlias(refname, NIL);
    2068         260 :     buildRelationAliases(tupdesc, alias, rte->eref);
    2069             : 
    2070             :     /* Record additional data for ENR, including column type info */
    2071         260 :     rte->enrname = enrmd->name;
    2072         260 :     rte->enrtuples = enrmd->enrtuples;
    2073         260 :     rte->coltypes = NIL;
    2074         260 :     rte->coltypmods = NIL;
    2075         260 :     rte->colcollations = NIL;
    2076         864 :     for (attno = 1; attno <= tupdesc->natts; ++attno)
    2077             :     {
    2078         604 :         Form_pg_attribute att = TupleDescAttr(tupdesc, attno - 1);
    2079             : 
    2080         604 :         if (att->attisdropped)
    2081             :         {
    2082             :             /* Record zeroes for a dropped column */
    2083          12 :             rte->coltypes = lappend_oid(rte->coltypes, InvalidOid);
    2084          12 :             rte->coltypmods = lappend_int(rte->coltypmods, 0);
    2085          12 :             rte->colcollations = lappend_oid(rte->colcollations, InvalidOid);
    2086             :         }
    2087             :         else
    2088             :         {
    2089             :             /* Let's just make sure we can tell this isn't dropped */
    2090         592 :             if (att->atttypid == InvalidOid)
    2091           0 :                 elog(ERROR, "atttypid is invalid for non-dropped column in \"%s\"",
    2092             :                      rv->relname);
    2093         592 :             rte->coltypes = lappend_oid(rte->coltypes, att->atttypid);
    2094         592 :             rte->coltypmods = lappend_int(rte->coltypmods, att->atttypmod);
    2095         592 :             rte->colcollations = lappend_oid(rte->colcollations,
    2096             :                                              att->attcollation);
    2097             :         }
    2098             :     }
    2099             : 
    2100             :     /*
    2101             :      * Set flags and access permissions.
    2102             :      *
    2103             :      * ENRs are never checked for access rights.
    2104             :      */
    2105         260 :     rte->lateral = false;
    2106         260 :     rte->inh = false;            /* never true for ENRs */
    2107         260 :     rte->inFromCl = inFromCl;
    2108             : 
    2109         260 :     rte->requiredPerms = 0;
    2110         260 :     rte->checkAsUser = InvalidOid;
    2111         260 :     rte->selectedCols = NULL;
    2112             : 
    2113             :     /*
    2114             :      * Add completed RTE to pstate's range table list, but not to join list
    2115             :      * nor namespace --- caller must do that if appropriate.
    2116             :      */
    2117         260 :     pstate->p_rtable = lappend(pstate->p_rtable, rte);
    2118             : 
    2119         260 :     return rte;
    2120             : }
    2121             : 
    2122             : 
    2123             : /*
    2124             :  * Has the specified refname been selected FOR UPDATE/FOR SHARE?
    2125             :  *
    2126             :  * This is used when we have not yet done transformLockingClause, but need
    2127             :  * to know the correct lock to take during initial opening of relations.
    2128             :  *
    2129             :  * Note: we pay no attention to whether it's FOR UPDATE vs FOR SHARE,
    2130             :  * since the table-level lock is the same either way.
    2131             :  */
    2132             : bool
    2133      345642 : isLockedRefname(ParseState *pstate, const char *refname)
    2134             : {
    2135             :     ListCell   *l;
    2136             : 
    2137             :     /*
    2138             :      * If we are in a subquery specified as locked FOR UPDATE/SHARE from
    2139             :      * parent level, then act as though there's a generic FOR UPDATE here.
    2140             :      */
    2141      345642 :     if (pstate->p_locked_from_parent)
    2142           4 :         return true;
    2143             : 
    2144      345916 :     foreach(l, pstate->p_locking_clause)
    2145             :     {
    2146        4112 :         LockingClause *lc = (LockingClause *) lfirst(l);
    2147             : 
    2148        4112 :         if (lc->lockedRels == NIL)
    2149             :         {
    2150             :             /* all tables used in query */
    2151        5382 :             return true;
    2152             :         }
    2153             :         else
    2154             :         {
    2155             :             /* just the named tables */
    2156             :             ListCell   *l2;
    2157             : 
    2158        2866 :             foreach(l2, lc->lockedRels)
    2159             :             {
    2160        2588 :                 RangeVar   *thisrel = (RangeVar *) lfirst(l2);
    2161             : 
    2162        2588 :                 if (strcmp(refname, thisrel->relname) == 0)
    2163        2286 :                     return true;
    2164             :             }
    2165             :         }
    2166             :     }
    2167      341804 :     return false;
    2168             : }
    2169             : 
    2170             : /*
    2171             :  * Add the given RTE as a top-level entry in the pstate's join list
    2172             :  * and/or namespace list.  (We assume caller has checked for any
    2173             :  * namespace conflicts.)  The RTE is always marked as unconditionally
    2174             :  * visible, that is, not LATERAL-only.
    2175             :  *
    2176             :  * Note: some callers know that they can find the new ParseNamespaceItem
    2177             :  * at the end of the pstate->p_namespace list.  This is a bit ugly but not
    2178             :  * worth complicating this function's signature for.
    2179             :  */
    2180             : void
    2181       59054 : addRTEtoQuery(ParseState *pstate, RangeTblEntry *rte,
    2182             :               bool addToJoinList,
    2183             :               bool addToRelNameSpace, bool addToVarNameSpace)
    2184             : {
    2185       59054 :     if (addToJoinList)
    2186             :     {
    2187       20188 :         int         rtindex = RTERangeTablePosn(pstate, rte, NULL);
    2188       20188 :         RangeTblRef *rtr = makeNode(RangeTblRef);
    2189             : 
    2190       20188 :         rtr->rtindex = rtindex;
    2191       20188 :         pstate->p_joinlist = lappend(pstate->p_joinlist, rtr);
    2192             :     }
    2193       59054 :     if (addToRelNameSpace || addToVarNameSpace)
    2194             :     {
    2195             :         ParseNamespaceItem *nsitem;
    2196             : 
    2197       58558 :         nsitem = (ParseNamespaceItem *) palloc(sizeof(ParseNamespaceItem));
    2198       58558 :         nsitem->p_rte = rte;
    2199       58558 :         nsitem->p_rel_visible = addToRelNameSpace;
    2200       58558 :         nsitem->p_cols_visible = addToVarNameSpace;
    2201       58558 :         nsitem->p_lateral_only = false;
    2202       58558 :         nsitem->p_lateral_ok = true;
    2203       58558 :         pstate->p_namespace = lappend(pstate->p_namespace, nsitem);
    2204             :     }
    2205       59054 : }
    2206             : 
    2207             : /*
    2208             :  * expandRTE -- expand the columns of a rangetable entry
    2209             :  *
    2210             :  * This creates lists of an RTE's column names (aliases if provided, else
    2211             :  * real names) and Vars for each column.  Only user columns are considered.
    2212             :  * If include_dropped is false then dropped columns are omitted from the
    2213             :  * results.  If include_dropped is true then empty strings and NULL constants
    2214             :  * (not Vars!) are returned for dropped columns.
    2215             :  *
    2216             :  * rtindex, sublevels_up, and location are the varno, varlevelsup, and location
    2217             :  * values to use in the created Vars.  Ordinarily rtindex should match the
    2218             :  * actual position of the RTE in its rangetable.
    2219             :  *
    2220             :  * The output lists go into *colnames and *colvars.
    2221             :  * If only one of the two kinds of output list is needed, pass NULL for the
    2222             :  * output pointer for the unwanted one.
    2223             :  */
    2224             : void
    2225      203062 : expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up,
    2226             :           int location, bool include_dropped,
    2227             :           List **colnames, List **colvars)
    2228             : {
    2229             :     int         varattno;
    2230             : 
    2231      203062 :     if (colnames)
    2232      192280 :         *colnames = NIL;
    2233      203062 :     if (colvars)
    2234      203062 :         *colvars = NIL;
    2235             : 
    2236      203062 :     switch (rte->rtekind)
    2237             :     {
    2238             :         case RTE_RELATION:
    2239             :             /* Ordinary relation RTE */
    2240      138054 :             expandRelation(rte->relid, rte->eref,
    2241             :                            rtindex, sublevels_up, location,
    2242             :                            include_dropped, colnames, colvars);
    2243      138054 :             break;
    2244             :         case RTE_SUBQUERY:
    2245             :             {
    2246             :                 /* Subquery RTE */
    2247        3100 :                 ListCell   *aliasp_item = list_head(rte->eref->colnames);
    2248             :                 ListCell   *tlistitem;
    2249             : 
    2250        3100 :                 varattno = 0;
    2251       11838 :                 foreach(tlistitem, rte->subquery->targetList)
    2252             :                 {
    2253        8746 :                     TargetEntry *te = (TargetEntry *) lfirst(tlistitem);
    2254             : 
    2255        8746 :                     if (te->resjunk)
    2256          52 :                         continue;
    2257        8694 :                     varattno++;
    2258             :                     Assert(varattno == te->resno);
    2259             : 
    2260             :                     /*
    2261             :                      * In scenarios where columns have been added to a view
    2262             :                      * since the outer query was originally parsed, there can
    2263             :                      * be more items in the subquery tlist than the outer
    2264             :                      * query expects.  We should ignore such extra column(s)
    2265             :                      * --- compare the behavior for composite-returning
    2266             :                      * functions, in the RTE_FUNCTION case below.
    2267             :                      */
    2268        8694 :                     if (!aliasp_item)
    2269           8 :                         break;
    2270             : 
    2271        8686 :                     if (colnames)
    2272             :                     {
    2273        8642 :                         char       *label = strVal(lfirst(aliasp_item));
    2274             : 
    2275        8642 :                         *colnames = lappend(*colnames, makeString(pstrdup(label)));
    2276             :                     }
    2277             : 
    2278        8686 :                     if (colvars)
    2279             :                     {
    2280             :                         Var        *varnode;
    2281             : 
    2282       34744 :                         varnode = makeVar(rtindex, varattno,
    2283        8686 :                                           exprType((Node *) te->expr),
    2284        8686 :                                           exprTypmod((Node *) te->expr),
    2285        8686 :                                           exprCollation((Node *) te->expr),
    2286             :                                           sublevels_up);
    2287        8686 :                         varnode->location = location;
    2288             : 
    2289        8686 :                         *colvars = lappend(*colvars, varnode);
    2290             :                     }
    2291             : 
    2292        8686 :                     aliasp_item = lnext(rte->eref->colnames, aliasp_item);
    2293             :                 }
    2294             :             }
    2295        3100 :             break;
    2296             :         case RTE_FUNCTION:
    2297             :             {
    2298             :                 /* Function RTE */
    2299       19660 :                 int         atts_done = 0;
    2300             :                 ListCell   *lc;
    2301             : 
    2302       39512 :                 foreach(lc, rte->functions)
    2303             :                 {
    2304       19852 :                     RangeTblFunction *rtfunc = (RangeTblFunction *) lfirst(lc);
    2305             :                     TypeFuncClass functypclass;
    2306             :                     Oid         funcrettype;
    2307             :                     TupleDesc   tupdesc;
    2308             : 
    2309       19852 :                     functypclass = get_expr_result_type(rtfunc->funcexpr,
    2310             :                                                         &funcrettype,
    2311             :                                                         &tupdesc);
    2312       19852 :                     if (functypclass == TYPEFUNC_COMPOSITE ||
    2313             :                         functypclass == TYPEFUNC_COMPOSITE_DOMAIN)
    2314             :                     {
    2315             :                         /* Composite data type, e.g. a table's row type */
    2316             :                         Assert(tupdesc);
    2317        9674 :                         expandTupleDesc(tupdesc, rte->eref,
    2318             :                                         rtfunc->funccolcount, atts_done,
    2319             :                                         rtindex, sublevels_up, location,
    2320             :                                         include_dropped, colnames, colvars);
    2321             :                     }
    2322       10178 :                     else if (functypclass == TYPEFUNC_SCALAR)
    2323             :                     {
    2324             :                         /* Base data type, i.e. scalar */
    2325        9670 :                         if (colnames)
    2326        2874 :                             *colnames = lappend(*colnames,
    2327        2874 :                                                 list_nth(rte->eref->colnames,
    2328             :                                                          atts_done));
    2329             : 
    2330        9670 :                         if (colvars)
    2331             :                         {
    2332             :                             Var        *varnode;
    2333             : 
    2334       19340 :                             varnode = makeVar(rtindex, atts_done + 1,
    2335             :                                               funcrettype, -1,
    2336        9670 :                                               exprCollation(rtfunc->funcexpr),
    2337             :                                               sublevels_up);
    2338        9670 :                             varnode->location = location;
    2339             : 
    2340        9670 :                             *colvars = lappend(*colvars, varnode);
    2341             :                         }
    2342             :                     }
    2343         508 :                     else if (functypclass == TYPEFUNC_RECORD)
    2344             :                     {
    2345         508 :                         if (colnames)
    2346             :                         {
    2347             :                             List       *namelist;
    2348             : 
    2349             :                             /* extract appropriate subset of column list */
    2350         508 :                             namelist = list_copy_tail(rte->eref->colnames,
    2351             :                                                       atts_done);
    2352         508 :                             namelist = list_truncate(namelist,
    2353             :                                                      rtfunc->funccolcount);
    2354         508 :                             *colnames = list_concat(*colnames, namelist);
    2355             :                         }
    2356             : 
    2357         508 :                         if (colvars)
    2358             :                         {
    2359             :                             ListCell   *l1;
    2360             :                             ListCell   *l2;
    2361             :                             ListCell   *l3;
    2362         508 :                             int         attnum = atts_done;
    2363             : 
    2364        1754 :                             forthree(l1, rtfunc->funccoltypes,
    2365             :                                      l2, rtfunc->funccoltypmods,
    2366             :                                      l3, rtfunc->funccolcollations)
    2367             :                             {
    2368        1246 :                                 Oid         attrtype = lfirst_oid(l1);
    2369        1246 :                                 int32       attrtypmod = lfirst_int(l2);
    2370        1246 :                                 Oid         attrcollation = lfirst_oid(l3);
    2371             :                                 Var        *varnode;
    2372             : 
    2373        1246 :                                 attnum++;
    2374        1246 :                                 varnode = makeVar(rtindex,
    2375             :                                                   attnum,
    2376             :                                                   attrtype,
    2377             :                                                   attrtypmod,
    2378             :                                                   attrcollation,
    2379             :                                                   sublevels_up);
    2380        1246 :                                 varnode->location = location;
    2381        1246 :                                 *colvars = lappend(*colvars, varnode);
    2382             :                             }
    2383             :                         }
    2384             :                     }
    2385             :                     else
    2386             :                     {
    2387             :                         /* addRangeTableEntryForFunction should've caught this */
    2388           0 :                         elog(ERROR, "function in FROM has unsupported return type");
    2389             :                     }
    2390       19852 :                     atts_done += rtfunc->funccolcount;
    2391             :                 }
    2392             : 
    2393             :                 /* Append the ordinality column if any */
    2394       19660 :                 if (rte->funcordinality)
    2395             :                 {
    2396        6188 :                     if (colnames)
    2397         200 :                         *colnames = lappend(*colnames,
    2398         200 :                                             llast(rte->eref->colnames));
    2399             : 
    2400        6188 :                     if (colvars)
    2401             :                     {
    2402       12376 :                         Var        *varnode = makeVar(rtindex,
    2403        6188 :                                                       atts_done + 1,
    2404             :                                                       INT8OID,
    2405             :                                                       -1,
    2406             :                                                       InvalidOid,
    2407             :                                                       sublevels_up);
    2408             : 
    2409        6188 :                         *colvars = lappend(*colvars, varnode);
    2410             :                     }
    2411             :                 }
    2412             :             }
    2413       19660 :             break;
    2414             :         case RTE_JOIN:
    2415             :             {
    2416             :                 /* Join RTE */
    2417             :                 ListCell   *colname;
    2418             :                 ListCell   *aliasvar;
    2419             : 
    2420             :                 Assert(list_length(rte->eref->colnames) == list_length(rte->joinaliasvars));
    2421             : 
    2422       35590 :                 varattno = 0;
    2423     1921168 :                 forboth(colname, rte->eref->colnames, aliasvar, rte->joinaliasvars)
    2424             :                 {
    2425     1885578 :                     Node       *avar = (Node *) lfirst(aliasvar);
    2426             : 
    2427     1885578 :                     varattno++;
    2428             : 
    2429             :                     /*
    2430             :                      * During ordinary parsing, there will never be any
    2431             :                      * deleted columns in the join; but we have to check since
    2432             :                      * this routine is also used by the rewriter, and joins
    2433             :                      * found in stored rules might have join columns for
    2434             :                      * since-deleted columns.  This will be signaled by a null
    2435             :                      * pointer in the alias-vars list.
    2436             :                      */
    2437     1885578 :                     if (avar == NULL)
    2438             :                     {
    2439           0 :                         if (include_dropped)
    2440             :                         {
    2441           0 :                             if (colnames)
    2442           0 :                                 *colnames = lappend(*colnames,
    2443           0 :                                                     makeString(pstrdup("")));
    2444           0 :                             if (colvars)
    2445             :                             {
    2446             :                                 /*
    2447             :                                  * Can't use join's column type here (it might
    2448             :                                  * be dropped!); but it doesn't really matter
    2449             :                                  * what type the Const claims to be.
    2450             :                                  */
    2451           0 :                                 *colvars = lappend(*colvars,
    2452           0 :                                                    makeNullConst(INT4OID, -1,
    2453             :                                                                  InvalidOid));
    2454             :                             }
    2455             :                         }
    2456           0 :                         continue;
    2457             :                     }
    2458             : 
    2459     1885578 :                     if (colnames)
    2460             :                     {
    2461     1885578 :                         char       *label = strVal(lfirst(colname));
    2462             : 
    2463     1885578 :                         *colnames = lappend(*colnames,
    2464     1885578 :                                             makeString(pstrdup(label)));
    2465             :                     }
    2466             : 
    2467     1885578 :                     if (colvars)
    2468             :                     {
    2469             :                         Var        *varnode;
    2470             : 
    2471     1885578 :                         varnode = makeVar(rtindex, varattno,
    2472             :                                           exprType(avar),
    2473             :                                           exprTypmod(avar),
    2474             :                                           exprCollation(avar),
    2475             :                                           sublevels_up);
    2476     1885578 :                         varnode->location = location;
    2477             : 
    2478     1885578 :                         *colvars = lappend(*colvars, varnode);
    2479             :                     }
    2480             :                 }
    2481             :             }
    2482       35590 :             break;
    2483             :         case RTE_TABLEFUNC:
    2484             :         case RTE_VALUES:
    2485             :         case RTE_CTE:
    2486             :         case RTE_NAMEDTUPLESTORE:
    2487             :             {
    2488             :                 /* Tablefunc, Values, CTE, or ENR RTE */
    2489        6658 :                 ListCell   *aliasp_item = list_head(rte->eref->colnames);
    2490             :                 ListCell   *lct;
    2491             :                 ListCell   *lcm;
    2492             :                 ListCell   *lcc;
    2493             : 
    2494        6658 :                 varattno = 0;
    2495       18570 :                 forthree(lct, rte->coltypes,
    2496             :                          lcm, rte->coltypmods,
    2497             :                          lcc, rte->colcollations)
    2498             :                 {
    2499       11912 :                     Oid         coltype = lfirst_oid(lct);
    2500       11912 :                     int32       coltypmod = lfirst_int(lcm);
    2501       11912 :                     Oid         colcoll = lfirst_oid(lcc);
    2502             : 
    2503       11912 :                     varattno++;
    2504             : 
    2505       11912 :                     if (colnames)
    2506             :                     {
    2507             :                         /* Assume there is one alias per output column */
    2508        6230 :                         if (OidIsValid(coltype))
    2509             :                         {
    2510        6230 :                             char       *label = strVal(lfirst(aliasp_item));
    2511             : 
    2512        6230 :                             *colnames = lappend(*colnames,
    2513        6230 :                                                 makeString(pstrdup(label)));
    2514             :                         }
    2515           0 :                         else if (include_dropped)
    2516           0 :                             *colnames = lappend(*colnames,
    2517           0 :                                                 makeString(pstrdup("")));
    2518             : 
    2519        6230 :                         aliasp_item = lnext(rte->eref->colnames, aliasp_item);
    2520             :                     }
    2521             : 
    2522       11912 :                     if (colvars)
    2523             :                     {
    2524       11912 :                         if (OidIsValid(coltype))
    2525             :                         {
    2526             :                             Var        *varnode;
    2527             : 
    2528       11912 :                             varnode = makeVar(rtindex, varattno,
    2529             :                                               coltype, coltypmod, colcoll,
    2530             :                                               sublevels_up);
    2531       11912 :                             varnode->location = location;
    2532             : 
    2533       11912 :                             *colvars = lappend(*colvars, varnode);
    2534             :                         }
    2535           0 :                         else if (include_dropped)
    2536             :                         {
    2537             :                             /*
    2538             :                              * It doesn't really matter what type the Const
    2539             :                              * claims to be.
    2540             :                              */
    2541           0 :                             *colvars = lappend(*colvars,
    2542           0 :                                                makeNullConst(INT4OID, -1,
    2543             :                                                              InvalidOid));
    2544             :                         }
    2545             :                     }
    2546             :                 }
    2547             :             }
    2548        6658 :             break;
    2549             :         case RTE_RESULT:
    2550             :             /* These expose no columns, so nothing to do */
    2551           0 :             break;
    2552             :         default:
    2553           0 :             elog(ERROR, "unrecognized RTE kind: %d", (int) rte->rtekind);
    2554             :     }
    2555      203062 : }
    2556             : 
    2557             : /*
    2558             :  * expandRelation -- expandRTE subroutine
    2559             :  */
    2560             : static void
    2561      138054 : expandRelation(Oid relid, Alias *eref, int rtindex, int sublevels_up,
    2562             :                int location, bool include_dropped,
    2563             :                List **colnames, List **colvars)
    2564             : {
    2565             :     Relation    rel;
    2566             : 
    2567             :     /* Get the tupledesc and turn it over to expandTupleDesc */
    2568      138054 :     rel = relation_open(relid, AccessShareLock);
    2569      138054 :     expandTupleDesc(rel->rd_att, eref, rel->rd_att->natts, 0,
    2570             :                     rtindex, sublevels_up,
    2571             :                     location, include_dropped,
    2572             :                     colnames, colvars);
    2573      138054 :     relation_close(rel, AccessShareLock);
    2574      138054 : }
    2575             : 
    2576             : /*
    2577             :  * expandTupleDesc -- expandRTE subroutine
    2578             :  *
    2579             :  * Generate names and/or Vars for the first "count" attributes of the tupdesc,
    2580             :  * and append them to colnames/colvars.  "offset" is added to the varattno
    2581             :  * that each Var would otherwise have, and we also skip the first "offset"
    2582             :  * entries in eref->colnames.  (These provisions allow use of this code for
    2583             :  * an individual composite-returning function in an RTE_FUNCTION RTE.)
    2584             :  */
    2585             : static void
    2586      147728 : expandTupleDesc(TupleDesc tupdesc, Alias *eref, int count, int offset,
    2587             :                 int rtindex, int sublevels_up,
    2588             :                 int location, bool include_dropped,
    2589             :                 List **colnames, List **colvars)
    2590             : {
    2591             :     ListCell   *aliascell;
    2592             :     int         varattno;
    2593             : 
    2594      295456 :     aliascell = (offset < list_length(eref->colnames)) ?
    2595      147728 :         list_nth_cell(eref->colnames, offset) : NULL;
    2596             : 
    2597             :     Assert(count <= tupdesc->natts);
    2598     2300494 :     for (varattno = 0; varattno < count; varattno++)
    2599             :     {
    2600     2152766 :         Form_pg_attribute attr = TupleDescAttr(tupdesc, varattno);
    2601             : 
    2602     2152766 :         if (attr->attisdropped)
    2603             :         {
    2604        1066 :             if (include_dropped)
    2605             :             {
    2606           0 :                 if (colnames)
    2607           0 :                     *colnames = lappend(*colnames, makeString(pstrdup("")));
    2608           0 :                 if (colvars)
    2609             :                 {
    2610             :                     /*
    2611             :                      * can't use atttypid here, but it doesn't really matter
    2612             :                      * what type the Const claims to be.
    2613             :                      */
    2614           0 :                     *colvars = lappend(*colvars,
    2615           0 :                                        makeNullConst(INT4OID, -1, InvalidOid));
    2616             :                 }
    2617             :             }
    2618        1066 :             if (aliascell)
    2619        1066 :                 aliascell = lnext(eref->colnames, aliascell);
    2620        1066 :             continue;
    2621             :         }
    2622             : 
    2623     2151700 :         if (colnames)
    2624             :         {
    2625             :             char       *label;
    2626             : 
    2627     2144698 :             if (aliascell)
    2628             :             {
    2629     2144698 :                 label = strVal(lfirst(aliascell));
    2630     2144698 :                 aliascell = lnext(eref->colnames, aliascell);
    2631             :             }
    2632             :             else
    2633             :             {
    2634             :                 /* If we run out of aliases, use the underlying name */
    2635           0 :                 label = NameStr(attr->attname);
    2636             :             }
    2637     2144698 :             *colnames = lappend(*colnames, makeString(pstrdup(label)));
    2638             :         }
    2639             : 
    2640     2151700 :         if (colvars)
    2641             :         {
    2642             :             Var        *varnode;
    2643             : 
    2644     2151700 :             varnode = makeVar(rtindex, varattno + offset + 1,
    2645             :                               attr->atttypid, attr->atttypmod,
    2646             :                               attr->attcollation,
    2647             :                               sublevels_up);
    2648     2151700 :             varnode->location = location;
    2649             : 
    2650     2151700 :             *colvars = lappend(*colvars, varnode);
    2651             :         }
    2652             :     }
    2653      147728 : }
    2654             : 
    2655             : /*
    2656             :  * expandRelAttrs -
    2657             :  *    Workhorse for "*" expansion: produce a list of targetentries
    2658             :  *    for the attributes of the RTE
    2659             :  *
    2660             :  * As with expandRTE, rtindex/sublevels_up determine the varno/varlevelsup
    2661             :  * fields of the Vars produced, and location sets their location.
    2662             :  * pstate->p_next_resno determines the resnos assigned to the TLEs.
    2663             :  * The referenced columns are marked as requiring SELECT access.
    2664             :  */
    2665             : List *
    2666       33656 : expandRelAttrs(ParseState *pstate, RangeTblEntry *rte,
    2667             :                int rtindex, int sublevels_up, int location)
    2668             : {
    2669             :     List       *names,
    2670             :                *vars;
    2671             :     ListCell   *name,
    2672             :                *var;
    2673       33656 :     List       *te_list = NIL;
    2674             : 
    2675       33656 :     expandRTE(rte, rtindex, sublevels_up, location, false,
    2676             :               &names, &vars);
    2677             : 
    2678             :     /*
    2679             :      * Require read access to the table.  This is normally redundant with the
    2680             :      * markVarForSelectPriv calls below, but not if the table has zero
    2681             :      * columns.
    2682             :      */
    2683       33656 :     rte->requiredPerms |= ACL_SELECT;
    2684             : 
    2685      171852 :     forboth(name, names, var, vars)
    2686             :     {
    2687      138196 :         char       *label = strVal(lfirst(name));
    2688      138196 :         Var        *varnode = (Var *) lfirst(var);
    2689             :         TargetEntry *te;
    2690             : 
    2691      138196 :         te = makeTargetEntry((Expr *) varnode,
    2692      138196 :                              (AttrNumber) pstate->p_next_resno++,
    2693             :                              label,
    2694             :                              false);
    2695      138196 :         te_list = lappend(te_list, te);
    2696             : 
    2697             :         /* Require read access to each column */
    2698      138196 :         markVarForSelectPriv(pstate, varnode, rte);
    2699             :     }
    2700             : 
    2701             :     Assert(name == NULL && var == NULL);    /* lists not the same length? */
    2702             : 
    2703       33656 :     return te_list;
    2704             : }
    2705             : 
    2706             : /*
    2707             :  * get_rte_attribute_name
    2708             :  *      Get an attribute name from a RangeTblEntry
    2709             :  *
    2710             :  * This is unlike get_attname() because we use aliases if available.
    2711             :  * In particular, it will work on an RTE for a subselect or join, whereas
    2712             :  * get_attname() only works on real relations.
    2713             :  *
    2714             :  * "*" is returned if the given attnum is InvalidAttrNumber --- this case
    2715             :  * occurs when a Var represents a whole tuple of a relation.
    2716             :  */
    2717             : char *
    2718         604 : get_rte_attribute_name(RangeTblEntry *rte, AttrNumber attnum)
    2719             : {
    2720         604 :     if (attnum == InvalidAttrNumber)
    2721           0 :         return "*";
    2722             : 
    2723             :     /*
    2724             :      * If there is a user-written column alias, use it.
    2725             :      */
    2726         604 :     if (rte->alias &&
    2727          20 :         attnum > 0 && attnum <= list_length(rte->alias->colnames))
    2728           0 :         return strVal(list_nth(rte->alias->colnames, attnum - 1));
    2729             : 
    2730             :     /*
    2731             :      * If the RTE is a relation, go to the system catalogs not the
    2732             :      * eref->colnames list.  This is a little slower but it will give the
    2733             :      * right answer if the column has been renamed since the eref list was
    2734             :      * built (which can easily happen for rules).
    2735             :      */
    2736         604 :     if (rte->rtekind == RTE_RELATION)
    2737         600 :         return get_attname(rte->relid, attnum, false);
    2738             : 
    2739             :     /*
    2740             :      * Otherwise use the column name from eref.  There should always be one.
    2741             :      */
    2742           4 :     if (attnum > 0 && attnum <= list_length(rte->eref->colnames))
    2743           4 :         return strVal(list_nth(rte->eref->colnames, attnum - 1));
    2744             : 
    2745             :     /* else caller gave us a bogus attnum */
    2746           0 :     elog(ERROR, "invalid attnum %d for rangetable entry %s",
    2747             :          attnum, rte->eref->aliasname);
    2748             :     return NULL;                /* keep compiler quiet */
    2749             : }
    2750             : 
    2751             : /*
    2752             :  * get_rte_attribute_type
    2753             :  *      Get attribute type/typmod/collation information from a RangeTblEntry
    2754             :  */
    2755             : void
    2756     1678888 : get_rte_attribute_type(RangeTblEntry *rte, AttrNumber attnum,
    2757             :                        Oid *vartype, int32 *vartypmod, Oid *varcollid)
    2758             : {
    2759     1678888 :     switch (rte->rtekind)
    2760             :     {
    2761             :         case RTE_RELATION:
    2762             :             {
    2763             :                 /* Plain relation RTE --- get the attribute's type info */
    2764             :                 HeapTuple   tp;
    2765             :                 Form_pg_attribute att_tup;
    2766             : 
    2767     2846136 :                 tp = SearchSysCache2(ATTNUM,
    2768     1423068 :                                      ObjectIdGetDatum(rte->relid),
    2769             :                                      Int16GetDatum(attnum));
    2770     1423068 :                 if (!HeapTupleIsValid(tp))  /* shouldn't happen */
    2771           0 :                     elog(ERROR, "cache lookup failed for attribute %d of relation %u",
    2772             :                          attnum, rte->relid);
    2773     1423068 :                 att_tup = (Form_pg_attribute) GETSTRUCT(tp);
    2774             : 
    2775             :                 /*
    2776             :                  * If dropped column, pretend it ain't there.  See notes in
    2777             :                  * scanRTEForColumn.
    2778             :                  */
    2779     1423068 :                 if (att_tup->attisdropped)
    2780           0 :                     ereport(ERROR,
    2781             :                             (errcode(ERRCODE_UNDEFINED_COLUMN),
    2782             :                              errmsg("column \"%s\" of relation \"%s\" does not exist",
    2783             :                                     NameStr(att_tup->attname),
    2784             :                                     get_rel_name(rte->relid))));
    2785     1423068 :                 *vartype = att_tup->atttypid;
    2786     1423068 :                 *vartypmod = att_tup->atttypmod;
    2787     1423068 :                 *varcollid = att_tup->attcollation;
    2788     1423068 :                 ReleaseSysCache(tp);
    2789             :             }
    2790     1423068 :             break;
    2791             :         case RTE_SUBQUERY:
    2792             :             {
    2793             :                 /* Subselect RTE --- get type info from subselect's tlist */
    2794       89234 :                 TargetEntry *te = get_tle_by_resno(rte->subquery->targetList,
    2795             :                                                    attnum);
    2796             : 
    2797       89234 :                 if (te == NULL || te->resjunk)
    2798           0 :                     elog(ERROR, "subquery %s does not have attribute %d",
    2799             :                          rte->eref->aliasname, attnum);
    2800       89234 :                 *vartype = exprType((Node *) te->expr);
    2801       89234 :                 *vartypmod = exprTypmod((Node *) te->expr);
    2802       89234 :                 *varcollid = exprCollation((Node *) te->expr);
    2803             :             }
    2804       89234 :             break;
    2805             :         case RTE_FUNCTION:
    2806             :             {
    2807             :                 /* Function RTE */
    2808             :                 ListCell   *lc;
    2809      107770 :                 int         atts_done = 0;
    2810             : 
    2811             :                 /* Identify which function covers the requested column */
    2812      113776 :                 foreach(lc, rte->functions)
    2813             :                 {
    2814      107802 :                     RangeTblFunction *rtfunc = (RangeTblFunction *) lfirst(lc);
    2815             : 
    2816      215604 :                     if (attnum > atts_done &&
    2817      107802 :                         attnum <= atts_done + rtfunc->funccolcount)
    2818             :                     {
    2819             :                         TypeFuncClass functypclass;
    2820             :                         Oid         funcrettype;
    2821             :                         TupleDesc   tupdesc;
    2822             : 
    2823      101796 :                         attnum -= atts_done;    /* now relative to this func */
    2824      101796 :                         functypclass = get_expr_result_type(rtfunc->funcexpr,
    2825             :                                                             &funcrettype,
    2826             :                                                             &tupdesc);
    2827             : 
    2828      101796 :                         if (functypclass == TYPEFUNC_COMPOSITE ||
    2829             :                             functypclass == TYPEFUNC_COMPOSITE_DOMAIN)
    2830       75500 :                         {
    2831             :                             /* Composite data type, e.g. a table's row type */
    2832             :                             Form_pg_attribute att_tup;
    2833             : 
    2834             :                             Assert(tupdesc);
    2835             :                             Assert(attnum <= tupdesc->natts);
    2836       75500 :                             att_tup = TupleDescAttr(tupdesc, attnum - 1);
    2837             : 
    2838             :                             /*
    2839             :                              * If dropped column, pretend it ain't there.  See
    2840             :                              * notes in scanRTEForColumn.
    2841             :                              */
    2842       75500 :                             if (att_tup->attisdropped)
    2843           0 :                                 ereport(ERROR,
    2844             :                                         (errcode(ERRCODE_UNDEFINED_COLUMN),
    2845             :                                          errmsg("column \"%s\" of relation \"%s\" does not exist",
    2846             :                                                 NameStr(att_tup->attname),
    2847             :                                                 rte->eref->aliasname)));
    2848       75500 :                             *vartype = att_tup->atttypid;
    2849       75500 :                             *vartypmod = att_tup->atttypmod;
    2850       75500 :                             *varcollid = att_tup->attcollation;
    2851             :                         }
    2852       26296 :                         else if (functypclass == TYPEFUNC_SCALAR)
    2853             :                         {
    2854             :                             /* Base data type, i.e. scalar */
    2855       26230 :                             *vartype = funcrettype;
    2856       26230 :                             *vartypmod = -1;
    2857       26230 :                             *varcollid = exprCollation(rtfunc->funcexpr);
    2858             :                         }
    2859          66 :                         else if (functypclass == TYPEFUNC_RECORD)
    2860             :                         {
    2861          66 :                             *vartype = list_nth_oid(rtfunc->funccoltypes,
    2862             :                                                     attnum - 1);
    2863          66 :                             *vartypmod = list_nth_int(rtfunc->funccoltypmods,
    2864             :                                                       attnum - 1);
    2865          66 :                             *varcollid = list_nth_oid(rtfunc->funccolcollations,
    2866             :                                                       attnum - 1);
    2867             :                         }
    2868             :                         else
    2869             :                         {
    2870             :                             /*
    2871             :                              * addRangeTableEntryForFunction should've caught
    2872             :                              * this
    2873             :                              */
    2874           0 :                             elog(ERROR, "function in FROM has unsupported return type");
    2875             :                         }
    2876      101796 :                         return;
    2877             :                     }
    2878        6006 :                     atts_done += rtfunc->funccolcount;
    2879             :                 }
    2880             : 
    2881             :                 /* If we get here, must be looking for the ordinality column */
    2882        5974 :                 if (rte->funcordinality && attnum == atts_done + 1)
    2883             :                 {
    2884        5974 :                     *vartype = INT8OID;
    2885        5974 :                     *vartypmod = -1;
    2886        5974 :                     *varcollid = InvalidOid;
    2887        5974 :                     return;
    2888             :                 }
    2889             : 
    2890             :                 /* this probably can't happen ... */
    2891           0 :                 ereport(ERROR,
    2892             :                         (errcode(ERRCODE_UNDEFINED_COLUMN),
    2893             :                          errmsg("column %d of relation \"%s\" does not exist",
    2894             :                                 attnum,
    2895             :                                 rte->eref->aliasname)));
    2896             :             }
    2897             :             break;
    2898             :         case RTE_JOIN:
    2899             :             {
    2900             :                 /*
    2901             :                  * Join RTE --- get type info from join RTE's alias variable
    2902             :                  */
    2903             :                 Node       *aliasvar;
    2904             : 
    2905             :                 Assert(attnum > 0 && attnum <= list_length(rte->joinaliasvars));
    2906       55006 :                 aliasvar = (Node *) list_nth(rte->joinaliasvars, attnum - 1);
    2907             :                 Assert(aliasvar != NULL);
    2908       55006 :                 *vartype = exprType(aliasvar);
    2909       55006 :                 *vartypmod = exprTypmod(aliasvar);
    2910       55006 :                 *varcollid = exprCollation(aliasvar);
    2911             :             }
    2912       55006 :             break;
    2913             :         case RTE_TABLEFUNC:
    2914             :         case RTE_VALUES:
    2915             :         case RTE_CTE:
    2916             :         case RTE_NAMEDTUPLESTORE:
    2917             :             {
    2918             :                 /*
    2919             :                  * tablefunc, VALUES, CTE, or ENR RTE --- get type info from
    2920             :                  * lists in the RTE
    2921             :                  */
    2922             :                 Assert(attnum > 0 && attnum <= list_length(rte->coltypes));
    2923        3810 :                 *vartype = list_nth_oid(rte->coltypes, attnum - 1);
    2924        3810 :                 *vartypmod = list_nth_int(rte->coltypmods, attnum - 1);
    2925        3810 :                 *varcollid = list_nth_oid(rte->colcollations, attnum - 1);
    2926             : 
    2927             :                 /* For ENR, better check for dropped column */
    2928        3810 :                 if (!OidIsValid(*vartype))
    2929           0 :                     ereport(ERROR,
    2930             :                             (errcode(ERRCODE_UNDEFINED_COLUMN),
    2931             :                              errmsg("column %d of relation \"%s\" does not exist",
    2932             :                                     attnum,
    2933             :                                     rte->eref->aliasname)));
    2934             :             }
    2935        3810 :             break;
    2936             :         case RTE_RESULT:
    2937             :             /* this probably can't happen ... */
    2938           0 :             ereport(ERROR,
    2939             :                     (errcode(ERRCODE_UNDEFINED_COLUMN),
    2940             :                      errmsg("column %d of relation \"%s\" does not exist",
    2941             :                             attnum,
    2942             :                             rte->eref->aliasname)));
    2943             :             break;
    2944             :         default:
    2945           0 :             elog(ERROR, "unrecognized RTE kind: %d", (int) rte->rtekind);
    2946             :     }
    2947             : }
    2948             : 
    2949             : /*
    2950             :  * get_rte_attribute_is_dropped
    2951             :  *      Check whether attempted attribute ref is to a dropped column
    2952             :  */
    2953             : bool
    2954      330758 : get_rte_attribute_is_dropped(RangeTblEntry *rte, AttrNumber attnum)
    2955             : {
    2956             :     bool        result;
    2957             : 
    2958      330758 :     switch (rte->rtekind)
    2959             :     {
    2960             :         case RTE_RELATION:
    2961             :             {
    2962             :                 /*
    2963             :                  * Plain relation RTE --- get the attribute's catalog entry
    2964             :                  */
    2965             :                 HeapTuple   tp;
    2966             :                 Form_pg_attribute att_tup;
    2967             : 
    2968      430508 :                 tp = SearchSysCache2(ATTNUM,
    2969      215254 :                                      ObjectIdGetDatum(rte->relid),
    2970             :                                      Int16GetDatum(attnum));
    2971      215254 :                 if (!HeapTupleIsValid(tp))  /* shouldn't happen */
    2972           0 :                     elog(ERROR, "cache lookup failed for attribute %d of relation %u",
    2973             :                          attnum, rte->relid);
    2974      215254 :                 att_tup = (Form_pg_attribute) GETSTRUCT(tp);
    2975      215254 :                 result = att_tup->attisdropped;
    2976      215254 :                 ReleaseSysCache(tp);
    2977             :             }
    2978      215254 :             break;
    2979             :         case RTE_SUBQUERY:
    2980             :         case RTE_TABLEFUNC:
    2981             :         case RTE_VALUES:
    2982             :         case RTE_CTE:
    2983             : 
    2984             :             /*
    2985             :              * Subselect, Table Functions, Values, CTE RTEs never have dropped
    2986             :              * columns
    2987             :              */
    2988          32 :             result = false;
    2989          32 :             break;
    2990             :         case RTE_NAMEDTUPLESTORE:
    2991             :             {
    2992             :                 /* Check dropped-ness by testing for valid coltype */
    2993           0 :                 if (attnum <= 0 ||
    2994           0 :                     attnum > list_length(rte->coltypes))
    2995           0 :                     elog(ERROR, "invalid varattno %d", attnum);
    2996           0 :                 result = !OidIsValid((list_nth_oid(rte->coltypes, attnum - 1)));
    2997             :             }
    2998           0 :             break;
    2999             :         case RTE_JOIN:
    3000             :             {
    3001             :                 /*
    3002             :                  * A join RTE would not have dropped columns when constructed,
    3003             :                  * but one in a stored rule might contain columns that were
    3004             :                  * dropped from the underlying tables, if said columns are
    3005             :                  * nowhere explicitly referenced in the rule.  This will be
    3006             :                  * signaled to us by a null pointer in the joinaliasvars list.
    3007             :                  */
    3008             :                 Var        *aliasvar;
    3009             : 
    3010      207016 :                 if (attnum <= 0 ||
    3011      103508 :                     attnum > list_length(rte->joinaliasvars))
    3012           0 :                     elog(ERROR, "invalid varattno %d", attnum);
    3013      103508 :                 aliasvar = (Var *) list_nth(rte->joinaliasvars, attnum - 1);
    3014             : 
    3015      103508 :                 result = (aliasvar == NULL);
    3016             :             }
    3017      103508 :             break;
    3018             :         case RTE_FUNCTION:
    3019             :             {
    3020             :                 /* Function RTE */
    3021             :                 ListCell   *lc;
    3022       11964 :                 int         atts_done = 0;
    3023             : 
    3024             :                 /*
    3025             :                  * Dropped attributes are only possible with functions that
    3026             :                  * return named composite types.  In such a case we have to
    3027             :                  * look up the result type to see if it currently has this
    3028             :                  * column dropped.  So first, loop over the funcs until we
    3029             :                  * find the one that covers the requested column.
    3030             :                  */
    3031       12004 :                 foreach(lc, rte->functions)
    3032             :                 {
    3033       11988 :                     RangeTblFunction *rtfunc = (RangeTblFunction *) lfirst(lc);
    3034             : 
    3035       23976 :                     if (attnum > atts_done &&
    3036       11988 :                         attnum <= atts_done + rtfunc->funccolcount)
    3037             :                     {
    3038             :                         TupleDesc   tupdesc;
    3039             : 
    3040       11948 :                         tupdesc = get_expr_result_tupdesc(rtfunc->funcexpr,
    3041             :                                                           true);
    3042       11948 :                         if (tupdesc)
    3043             :                         {
    3044             :                             /* Composite data type, e.g. a table's row type */
    3045             :                             Form_pg_attribute att_tup;
    3046             : 
    3047             :                             Assert(tupdesc);
    3048             :                             Assert(attnum - atts_done <= tupdesc->natts);
    3049       11932 :                             att_tup = TupleDescAttr(tupdesc,
    3050             :                                                     attnum - atts_done - 1);
    3051       23880 :                             return att_tup->attisdropped;
    3052             :                         }
    3053             :                         /* Otherwise, it can't have any dropped columns */
    3054          16 :                         return false;
    3055             :                     }
    3056          40 :                     atts_done += rtfunc->funccolcount;
    3057             :                 }
    3058             : 
    3059             :                 /* If we get here, must be looking for the ordinality column */
    3060          32 :                 if (rte->funcordinality && attnum == atts_done + 1)
    3061          16 :                     return false;
    3062             : 
    3063             :                 /* this probably can't happen ... */
    3064           0 :                 ereport(ERROR,
    3065             :                         (errcode(ERRCODE_UNDEFINED_COLUMN),
    3066             :                          errmsg("column %d of relation \"%s\" does not exist",
    3067             :                                 attnum,
    3068             :                                 rte->eref->aliasname)));
    3069             :                 result = false; /* keep compiler quiet */
    3070             :             }
    3071             :             break;
    3072             :         case RTE_RESULT:
    3073             :             /* this probably can't happen ... */
    3074           0 :             ereport(ERROR,
    3075             :                     (errcode(ERRCODE_UNDEFINED_COLUMN),
    3076             :                      errmsg("column %d of relation \"%s\" does not exist",
    3077             :                             attnum,
    3078             :                             rte->eref->aliasname)));
    3079             :             result = false;     /* keep compiler quiet */
    3080             :             break;
    3081             :         default:
    3082           0 :             elog(ERROR, "unrecognized RTE kind: %d", (int) rte->rtekind);
    3083             :             result = false;     /* keep compiler quiet */
    3084             :     }
    3085             : 
    3086      318794 :     return result;
    3087             : }
    3088             : 
    3089             : /*
    3090             :  * Given a targetlist and a resno, return the matching TargetEntry
    3091             :  *
    3092             :  * Returns NULL if resno is not present in list.
    3093             :  *
    3094             :  * Note: we need to search, rather than just indexing with list_nth(),
    3095             :  * because not all tlists are sorted by resno.
    3096             :  */
    3097             : TargetEntry *
    3098      275242 : get_tle_by_resno(List *tlist, AttrNumber resno)
    3099             : {
    3100             :     ListCell   *l;
    3101             : 
    3102      904354 :     foreach(l, tlist)
    3103             :     {
    3104      904082 :         TargetEntry *tle = (TargetEntry *) lfirst(l);
    3105             : 
    3106      904082 :         if (tle->resno == resno)
    3107      274970 :             return tle;
    3108             :     }
    3109         272 :     return NULL;
    3110             : }
    3111             : 
    3112             : /*
    3113             :  * Given a Query and rangetable index, return relation's RowMarkClause if any
    3114             :  *
    3115             :  * Returns NULL if relation is not selected FOR UPDATE/SHARE
    3116             :  */
    3117             : RowMarkClause *
    3118       18678 : get_parse_rowmark(Query *qry, Index rtindex)
    3119             : {
    3120             :     ListCell   *l;
    3121             : 
    3122       18906 :     foreach(l, qry->rowMarks)
    3123             :     {
    3124         292 :         RowMarkClause *rc = (RowMarkClause *) lfirst(l);
    3125             : 
    3126         292 :         if (rc->rti == rtindex)
    3127          64 :             return rc;
    3128             :     }
    3129       18614 :     return NULL;
    3130             : }
    3131             : 
    3132             : /*
    3133             :  *  given relation and att name, return attnum of variable
    3134             :  *
    3135             :  *  Returns InvalidAttrNumber if the attr doesn't exist (or is dropped).
    3136             :  *
    3137             :  *  This should only be used if the relation is already
    3138             :  *  table_open()'ed.  Use the cache version get_attnum()
    3139             :  *  for access to non-opened relations.
    3140             :  */
    3141             : int
    3142       45662 : attnameAttNum(Relation rd, const char *attname, bool sysColOK)
    3143             : {
    3144             :     int         i;
    3145             : 
    3146      233328 :     for (i = 0; i < RelationGetNumberOfAttributes(rd); i++)
    3147             :     {
    3148      233262 :         Form_pg_attribute att = TupleDescAttr(rd->rd_att, i);
    3149             : 
    3150      233262 :         if (namestrcmp(&(att->attname), attname) == 0 && !att->attisdropped)
    3151       45596 :             return i + 1;
    3152             :     }
    3153             : 
    3154          66 :     if (sysColOK)
    3155             :     {
    3156           8 :         if ((i = specialAttNum(attname)) != InvalidAttrNumber)
    3157           0 :             return i;
    3158             :     }
    3159             : 
    3160             :     /* on failure */
    3161          66 :     return InvalidAttrNumber;
    3162             : }
    3163             : 
    3164             : /* specialAttNum()
    3165             :  *
    3166             :  * Check attribute name to see if it is "special", e.g. "xmin".
    3167             :  * - thomas 2000-02-07
    3168             :  *
    3169             :  * Note: this only discovers whether the name could be a system attribute.
    3170             :  * Caller needs to ensure that it really is an attribute of the rel.
    3171             :  */
    3172             : static int
    3173       94808 : specialAttNum(const char *attname)
    3174             : {
    3175             :     const FormData_pg_attribute *sysatt;
    3176             : 
    3177       94808 :     sysatt = SystemAttributeByName(attname);
    3178       94808 :     if (sysatt != NULL)
    3179       36610 :         return sysatt->attnum;
    3180       58198 :     return InvalidAttrNumber;
    3181             : }
    3182             : 
    3183             : 
    3184             : /*
    3185             :  * given attribute id, return name of that attribute
    3186             :  *
    3187             :  *  This should only be used if the relation is already
    3188             :  *  table_open()'ed.  Use the cache version get_atttype()
    3189             :  *  for access to non-opened relations.
    3190             :  */
    3191             : const NameData *
    3192        6990 : attnumAttName(Relation rd, int attid)
    3193             : {
    3194        6990 :     if (attid <= 0)
    3195             :     {
    3196             :         const FormData_pg_attribute *sysatt;
    3197             : 
    3198           0 :         sysatt = SystemAttributeDefinition(attid);
    3199           0 :         return &sysatt->attname;
    3200             :     }
    3201        6990 :     if (attid > rd->rd_att->natts)
    3202           0 :         elog(ERROR, "invalid attribute number %d", attid);
    3203        6990 :     return &TupleDescAttr(rd->rd_att, attid - 1)->attname;
    3204             : }
    3205             : 
    3206             : /*
    3207             :  * given attribute id, return type of that attribute
    3208             :  *
    3209             :  *  This should only be used if the relation is already
    3210             :  *  table_open()'ed.  Use the cache version get_atttype()
    3211             :  *  for access to non-opened relations.
    3212             :  */
    3213             : Oid
    3214      232080 : attnumTypeId(Relation rd, int attid)
    3215             : {
    3216      232080 :     if (attid <= 0)
    3217             :     {
    3218             :         const FormData_pg_attribute *sysatt;
    3219             : 
    3220           0 :         sysatt = SystemAttributeDefinition(attid);
    3221           0 :         return sysatt->atttypid;
    3222             :     }
    3223      232080 :     if (attid > rd->rd_att->natts)
    3224           0 :         elog(ERROR, "invalid attribute number %d", attid);
    3225      232080 :     return TupleDescAttr(rd->rd_att, attid - 1)->atttypid;
    3226             : }
    3227             : 
    3228             : /*
    3229             :  * given attribute id, return collation of that attribute
    3230             :  *
    3231             :  *  This should only be used if the relation is already table_open()'ed.
    3232             :  */
    3233             : Oid
    3234        2644 : attnumCollationId(Relation rd, int attid)
    3235             : {
    3236        2644 :     if (attid <= 0)
    3237             :     {
    3238             :         /* All system attributes are of noncollatable types. */
    3239           0 :         return InvalidOid;
    3240             :     }
    3241        2644 :     if (attid > rd->rd_att->natts)
    3242           0 :         elog(ERROR, "invalid attribute number %d", attid);
    3243        2644 :     return TupleDescAttr(rd->rd_att, attid - 1)->attcollation;
    3244             : }
    3245             : 
    3246             : /*
    3247             :  * Generate a suitable error about a missing RTE.
    3248             :  *
    3249             :  * Since this is a very common type of error, we work rather hard to
    3250             :  * produce a helpful message.
    3251             :  */
    3252             : void
    3253          48 : errorMissingRTE(ParseState *pstate, RangeVar *relation)
    3254             : {
    3255             :     RangeTblEntry *rte;
    3256             :     int         sublevels_up;
    3257          48 :     const char *badAlias = NULL;
    3258             : 
    3259             :     /*
    3260             :      * Check to see if there are any potential matches in the query's
    3261             :      * rangetable.  (Note: cases involving a bad schema name in the RangeVar
    3262             :      * will throw error immediately here.  That seems OK.)
    3263             :      */
    3264          48 :     rte = searchRangeTableForRel(pstate, relation);
    3265             : 
    3266             :     /*
    3267             :      * If we found a match that has an alias and the alias is visible in the
    3268             :      * namespace, then the problem is probably use of the relation's real name
    3269             :      * instead of its alias, ie "SELECT foo.* FROM foo f". This mistake is
    3270             :      * common enough to justify a specific hint.
    3271             :      *
    3272             :      * If we found a match that doesn't meet those criteria, assume the
    3273             :      * problem is illegal use of a relation outside its scope, as in the
    3274             :      * MySQL-ism "SELECT ... FROM a, b LEFT JOIN c ON (a.x = c.y)".
    3275             :      */
    3276          80 :     if (rte && rte->alias &&
    3277          48 :         strcmp(rte->eref->aliasname, relation->relname) != 0 &&
    3278          16 :         refnameRangeTblEntry(pstate, NULL, rte->eref->aliasname,
    3279             :                              relation->location,
    3280             :                              &sublevels_up) == rte)
    3281          16 :         badAlias = rte->eref->aliasname;
    3282             : 
    3283          48 :     if (rte)
    3284          40 :         ereport(ERROR,
    3285             :                 (errcode(ERRCODE_UNDEFINED_TABLE),
    3286             :                  errmsg("invalid reference to FROM-clause entry for table \"%s\"",
    3287             :                         relation->relname),
    3288             :                  (badAlias ?
    3289             :                   errhint("Perhaps you meant to reference the table alias \"%s\".",
    3290             :                           badAlias) :
    3291             :                   errhint("There is an entry for table \"%s\", but it cannot be referenced from this part of the query.",
    3292             :                           rte->eref->aliasname)),
    3293             :                  parser_errposition(pstate, relation->location)));
    3294             :     else
    3295           8 :         ereport(ERROR,
    3296             :                 (errcode(ERRCODE_UNDEFINED_TABLE),
    3297             :                  errmsg("missing FROM-clause entry for table \"%s\"",
    3298             :                         relation->relname),
    3299             :                  parser_errposition(pstate, relation->location)));
    3300             : }
    3301             : 
    3302             : /*
    3303             :  * Generate a suitable error about a missing column.
    3304             :  *
    3305             :  * Since this is a very common type of error, we work rather hard to
    3306             :  * produce a helpful message.
    3307             :  */
    3308             : void
    3309         202 : errorMissingColumn(ParseState *pstate,
    3310             :                    const char *relname, const char *colname, int location)
    3311             : {
    3312             :     FuzzyAttrMatchState *state;
    3313         202 :     char       *closestfirst = NULL;
    3314             : 
    3315             :     /*
    3316             :      * Search the entire rtable looking for possible matches.  If we find one,
    3317             :      * emit a hint about it.
    3318             :      *
    3319             :      * TODO: improve this code (and also errorMissingRTE) to mention using
    3320             :      * LATERAL if appropriate.
    3321             :      */
    3322         202 :     state = searchRangeTableForCol(pstate, relname, colname, location);
    3323             : 
    3324             :     /*
    3325             :      * Extract closest col string for best match, if any.
    3326             :      *
    3327             :      * Infer an exact match referenced despite not being visible from the fact
    3328             :      * that an attribute number was not present in state passed back -- this
    3329             :      * is what is reported when !closestfirst.  There might also be an exact
    3330             :      * match that was qualified with an incorrect alias, in which case
    3331             :      * closestfirst will be set (so hint is the same as generic fuzzy case).
    3332             :      */
    3333         202 :     if (state->rfirst && AttributeNumberIsValid(state->first))
    3334          36 :         closestfirst = strVal(list_nth(state->rfirst->eref->colnames,
    3335             :                                        state->first - 1));
    3336             : 
    3337         202 :     if (!state->rsecond)
    3338             :     {
    3339             :         /*
    3340             :          * Handle case where there is zero or one column suggestions to hint,
    3341             :          * including exact matches referenced but not visible.
    3342             :          */
    3343         198 :         ereport(ERROR,
    3344             :                 (errcode(ERRCODE_UNDEFINED_COLUMN),
    3345             :                  relname ?
    3346             :                  errmsg("column %s.%s does not exist", relname, colname) :
    3347             :                  errmsg("column \"%s\" does not exist", colname),
    3348             :                  state->rfirst ? closestfirst ?
    3349             :                  errhint("Perhaps you meant to reference the column \"%s.%s\".",
    3350             :                          state->rfirst->eref->aliasname, closestfirst) :
    3351             :                  errhint("There is a column named \"%s\" in table \"%s\", but it cannot be referenced from this part of the query.",
    3352             :                          colname, state->rfirst->eref->aliasname) : 0,
    3353             :                  parser_errposition(pstate, location)));
    3354             :     }
    3355             :     else
    3356             :     {
    3357             :         /* Handle case where there are two equally useful column hints */
    3358             :         char       *closestsecond;
    3359             : 
    3360           4 :         closestsecond = strVal(list_nth(state->rsecond->eref->colnames,
    3361             :                                         state->second - 1));
    3362             : 
    3363           4 :         ereport(ERROR,
    3364             :                 (errcode(ERRCODE_UNDEFINED_COLUMN),
    3365             :                  relname ?
    3366             :                  errmsg("column %s.%s does not exist", relname, colname) :
    3367             :                  errmsg("column \"%s\" does not exist", colname),
    3368             :                  errhint("Perhaps you meant to reference the column \"%s.%s\" or the column \"%s.%s\".",
    3369             :                          state->rfirst->eref->aliasname, closestfirst,
    3370             :                          state->rsecond->eref->aliasname, closestsecond),
    3371             :                  parser_errposition(pstate, location)));
    3372             :     }
    3373             : }
    3374             : 
    3375             : 
    3376             : /*
    3377             :  * Examine a fully-parsed query, and return true iff any relation underlying
    3378             :  * the query is a temporary relation (table, view, or materialized view).
    3379             :  */
    3380             : bool
    3381       41478 : isQueryUsingTempRelation(Query *query)
    3382             : {
    3383       41478 :     return isQueryUsingTempRelation_walker((Node *) query, NULL);
    3384             : }
    3385             : 
    3386             : static bool
    3387     4281698 : isQueryUsingTempRelation_walker(Node *node, void *context)
    3388             : {
    3389     4281698 :     if (node == NULL)
    3390     1041356 :         return false;
    3391             : 
    3392     3240342 :     if (IsA(node, Query))
    3393             :     {
    3394       76652 :         Query      *query = (Query *) node;
    3395             :         ListCell   *rtable;
    3396             : 
    3397      291106 :         foreach(rtable, query->rtable)
    3398             :         {
    3399      214526 :             RangeTblEntry *rte = lfirst(rtable);
    3400             : 
    3401      214526 :             if (rte->rtekind == RTE_RELATION)
    3402             :             {
    3403      132428 :                 Relation    rel = table_open(rte->relid, AccessShareLock);
    3404      132428 :                 char        relpersistence = rel->rd_rel->relpersistence;
    3405             : 
    3406      132428 :                 table_close(rel, AccessShareLock);
    3407      132428 :                 if (relpersistence == RELPERSISTENCE_TEMP)
    3408          72 :                     return true;
    3409             :             }
    3410             :         }
    3411             : 
    3412       76580 :         return query_tree_walker(query,
    3413             :                                  isQueryUsingTempRelation_walker,
    3414             :                                  context,
    3415             :                                  QTW_IGNORE_JOINALIASES);
    3416             :     }
    3417             : 
    3418     3163690 :     return expression_tree_walker(node,
    3419             :                                   isQueryUsingTempRelation_walker,
    3420             :                                   context);
    3421             : }

Generated by: LCOV version 1.13