LCOV - differential code coverage report
Current view: top level - src/backend/parser - parse_relation.c (source / functions) Coverage Total Hit UNC LBC UIC UBC GBC GIC GNC CBC EUB ECB DUB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 91.2 % 1215 1108 58 31 69 3 20 701 90 297 78 672 3 57
Current Date: 2023-04-08 15:15:32 Functions: 100.0 % 59 59 51 8 55 4
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           TLA  Line data    Source code
       1                 : /*-------------------------------------------------------------------------
       2                 :  *
       3                 :  * parse_relation.c
       4                 :  *    parser support routines dealing with relations
       5                 :  *
       6                 :  * Portions Copyright (c) 1996-2023, 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                 : 
      41                 : /*
      42                 :  * Support for fuzzily matching columns.
      43                 :  *
      44                 :  * This is for building diagnostic messages, where multiple or non-exact
      45                 :  * matching attributes are of interest.
      46                 :  *
      47                 :  * "distance" is the current best fuzzy-match distance if rfirst isn't NULL,
      48                 :  * otherwise it is the maximum acceptable distance plus 1.
      49                 :  *
      50                 :  * rfirst/first record the closest non-exact match so far, and distance
      51                 :  * is its distance from the target name.  If we have found a second non-exact
      52                 :  * match of exactly the same distance, rsecond/second record that.  (If
      53                 :  * we find three of the same distance, we conclude that "distance" is not
      54                 :  * a tight enough bound for a useful hint and clear rfirst/rsecond again.
      55                 :  * Only if we later find something closer will we re-populate rfirst.)
      56                 :  *
      57                 :  * rexact1/exact1 record the location of the first exactly-matching column,
      58                 :  * if any.  If we find multiple exact matches then rexact2/exact2 record
      59                 :  * another one (we don't especially care which).  Currently, these get
      60                 :  * populated independently of the fuzzy-match fields.
      61                 :  */
      62                 : typedef struct
      63                 : {
      64                 :     int         distance;       /* Current or limit distance */
      65                 :     RangeTblEntry *rfirst;      /* RTE of closest non-exact match, or NULL */
      66                 :     AttrNumber  first;          /* Col index in rfirst */
      67                 :     RangeTblEntry *rsecond;     /* RTE of another non-exact match w/same dist */
      68                 :     AttrNumber  second;         /* Col index in rsecond */
      69                 :     RangeTblEntry *rexact1;     /* RTE of first exact match, or NULL */
      70                 :     AttrNumber  exact1;         /* Col index in rexact1 */
      71                 :     RangeTblEntry *rexact2;     /* RTE of second exact match, or NULL */
      72                 :     AttrNumber  exact2;         /* Col index in rexact2 */
      73                 : } FuzzyAttrMatchState;
      74                 : 
      75                 : #define MAX_FUZZY_DISTANCE              3
      76                 : 
      77                 : 
      78                 : static ParseNamespaceItem *scanNameSpaceForRefname(ParseState *pstate,
      79                 :                                                    const char *refname,
      80                 :                                                    int location);
      81                 : static ParseNamespaceItem *scanNameSpaceForRelid(ParseState *pstate, Oid relid,
      82                 :                                                  int location);
      83                 : static void check_lateral_ref_ok(ParseState *pstate, ParseNamespaceItem *nsitem,
      84                 :                                  int location);
      85                 : static int  scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte,
      86                 :                              Alias *eref,
      87                 :                              const char *colname, int location,
      88                 :                              int fuzzy_rte_penalty,
      89                 :                              FuzzyAttrMatchState *fuzzystate);
      90                 : static void markRTEForSelectPriv(ParseState *pstate,
      91                 :                                  int rtindex, AttrNumber col);
      92                 : static void expandRelation(Oid relid, Alias *eref,
      93                 :                            int rtindex, int sublevels_up,
      94                 :                            int location, bool include_dropped,
      95                 :                            List **colnames, List **colvars);
      96                 : static void expandTupleDesc(TupleDesc tupdesc, Alias *eref,
      97                 :                             int count, int offset,
      98                 :                             int rtindex, int sublevels_up,
      99                 :                             int location, bool include_dropped,
     100                 :                             List **colnames, List **colvars);
     101                 : static int  specialAttNum(const char *attname);
     102                 : static bool rte_visible_if_lateral(ParseState *pstate, RangeTblEntry *rte);
     103                 : static bool rte_visible_if_qualified(ParseState *pstate, RangeTblEntry *rte);
     104                 : static bool isQueryUsingTempRelation_walker(Node *node, void *context);
     105                 : 
     106                 : 
     107                 : /*
     108                 :  * refnameNamespaceItem
     109                 :  *    Given a possibly-qualified refname, look to see if it matches any visible
     110                 :  *    namespace item.  If so, return a pointer to the nsitem; else return NULL.
     111                 :  *
     112                 :  *    Optionally get nsitem's nesting depth (0 = current) into *sublevels_up.
     113                 :  *    If sublevels_up is NULL, only consider items at the current nesting
     114                 :  *    level.
     115                 :  *
     116                 :  * An unqualified refname (schemaname == NULL) can match any item with matching
     117                 :  * alias, or matching unqualified relname in the case of alias-less relation
     118                 :  * items.  It is possible that such a refname matches multiple items in the
     119                 :  * nearest nesting level that has a match; if so, we report an error via
     120                 :  * ereport().
     121                 :  *
     122                 :  * A qualified refname (schemaname != NULL) can only match a relation item
     123                 :  * that (a) has no alias and (b) is for the same relation identified by
     124                 :  * schemaname.refname.  In this case we convert schemaname.refname to a
     125                 :  * relation OID and search by relid, rather than by alias name.  This is
     126                 :  * peculiar, but it's what SQL says to do.
     127                 :  */
     128                 : ParseNamespaceItem *
     129 GIC      979785 : refnameNamespaceItem(ParseState *pstate,
     130                 :                      const char *schemaname,
     131                 :                      const char *refname,
     132                 :                      int location,
     133                 :                      int *sublevels_up)
     134                 : {
     135          979785 :     Oid         relId = InvalidOid;
     136                 : 
     137          979785 :     if (sublevels_up)
     138          979785 :         *sublevels_up = 0;
     139                 : 
     140          979785 :     if (schemaname != NULL)
     141                 :     {
     142                 :         Oid         namespaceId;
     143                 : 
     144                 :         /*
     145                 :          * We can use LookupNamespaceNoError() here because we are only
     146                 :          * interested in finding existing RTEs.  Checking USAGE permission on
     147                 :          * the schema is unnecessary since it would have already been checked
     148                 :          * when the RTE was made.  Furthermore, we want to report "RTE not
     149 ECB             :          * found", not "no permissions for schema", if the name happens to
     150                 :          * match a schema name the user hasn't got access to.
     151                 :          */
     152 GIC          39 :         namespaceId = LookupNamespaceNoError(schemaname);
     153              39 :         if (!OidIsValid(namespaceId))
     154              33 :             return NULL;
     155 CBC           6 :         relId = get_relname_relid(refname, namespaceId);
     156 GIC           6 :         if (!OidIsValid(relId))
     157 LBC           0 :             return NULL;
     158 ECB             :     }
     159                 : 
     160 CBC     1020532 :     while (pstate != NULL)
     161                 :     {
     162                 :         ParseNamespaceItem *result;
     163                 : 
     164 GIC     1004306 :         if (OidIsValid(relId))
     165               9 :             result = scanNameSpaceForRelid(pstate, relId, location);
     166                 :         else
     167         1004297 :             result = scanNameSpaceForRefname(pstate, refname, location);
     168                 : 
     169         1004294 :         if (result)
     170          963514 :             return result;
     171                 : 
     172 CBC       40780 :         if (sublevels_up)
     173           40780 :             (*sublevels_up)++;
     174 ECB             :         else
     175 LBC           0 :             break;
     176 ECB             : 
     177 GBC       40780 :         pstate = pstate->parentParseState;
     178                 :     }
     179 GIC       16226 :     return NULL;
     180 ECB             : }
     181                 : 
     182                 : /*
     183                 :  * Search the query's table namespace for an item matching the
     184                 :  * given unqualified refname.  Return the nsitem if a unique match, or NULL
     185                 :  * if no match.  Raise error if multiple matches.
     186                 :  *
     187                 :  * Note: it might seem that we shouldn't have to worry about the possibility
     188                 :  * of multiple matches; after all, the SQL standard disallows duplicate table
     189                 :  * aliases within a given SELECT level.  Historically, however, Postgres has
     190                 :  * been laxer than that.  For example, we allow
     191                 :  *      SELECT ... FROM tab1 x CROSS JOIN (tab2 x CROSS JOIN tab3 y) z
     192                 :  * on the grounds that the aliased join (z) hides the aliases within it,
     193                 :  * therefore there is no conflict between the two RTEs named "x".  However,
     194                 :  * if tab3 is a LATERAL subquery, then from within the subquery both "x"es
     195 EUB             :  * are visible.  Rather than rejecting queries that used to work, we allow
     196                 :  * this situation, and complain only if there's actually an ambiguous
     197 ECB             :  * reference to "x".
     198                 :  */
     199                 : static ParseNamespaceItem *
     200 GIC     1004297 : scanNameSpaceForRefname(ParseState *pstate, const char *refname, int location)
     201                 : {
     202         1004297 :     ParseNamespaceItem *result = NULL;
     203                 :     ListCell   *l;
     204                 : 
     205         5691867 :     foreach(l, pstate->p_namespace)
     206                 :     {
     207         4687582 :         ParseNamespaceItem *nsitem = (ParseNamespaceItem *) lfirst(l);
     208                 : 
     209                 :         /* Ignore columns-only items */
     210         4687582 :         if (!nsitem->p_rel_visible)
     211         1307217 :             continue;
     212                 :         /* If not inside LATERAL, ignore lateral-only items */
     213         3380365 :         if (nsitem->p_lateral_only && !pstate->p_lateral_active)
     214              27 :             continue;
     215                 : 
     216         3380338 :         if (strcmp(nsitem->p_names->aliasname, refname) == 0)
     217                 :         {
     218          963526 :             if (result)
     219               6 :                 ereport(ERROR,
     220 ECB             :                         (errcode(ERRCODE_AMBIGUOUS_ALIAS),
     221                 :                          errmsg("table reference \"%s\" is ambiguous",
     222                 :                                 refname),
     223                 :                          parser_errposition(pstate, location)));
     224 GIC      963520 :             check_lateral_ref_ok(pstate, nsitem, location);
     225 CBC      963514 :             result = nsitem;
     226                 :         }
     227 ECB             :     }
     228 GIC     1004285 :     return result;
     229                 : }
     230 ECB             : 
     231                 : /*
     232                 :  * Search the query's table namespace for a relation item matching the
     233                 :  * given relation OID.  Return the nsitem if a unique match, or NULL
     234                 :  * if no match.  Raise error if multiple matches.
     235                 :  *
     236                 :  * See the comments for refnameNamespaceItem to understand why this
     237                 :  * acts the way it does.
     238                 :  */
     239                 : static ParseNamespaceItem *
     240 GIC           9 : scanNameSpaceForRelid(ParseState *pstate, Oid relid, int location)
     241                 : {
     242               9 :     ParseNamespaceItem *result = NULL;
     243                 :     ListCell   *l;
     244 ECB             : 
     245 CBC          18 :     foreach(l, pstate->p_namespace)
     246                 :     {
     247 GIC           9 :         ParseNamespaceItem *nsitem = (ParseNamespaceItem *) lfirst(l);
     248 CBC           9 :         RangeTblEntry *rte = nsitem->p_rte;
     249                 : 
     250                 :         /* Ignore columns-only items */
     251 GIC           9 :         if (!nsitem->p_rel_visible)
     252 UIC           0 :             continue;
     253                 :         /* If not inside LATERAL, ignore lateral-only items */
     254 GIC           9 :         if (nsitem->p_lateral_only && !pstate->p_lateral_active)
     255 UIC           0 :             continue;
     256                 : 
     257                 :         /* yes, the test for alias == NULL should be there... */
     258 GIC           9 :         if (rte->rtekind == RTE_RELATION &&
     259               9 :             rte->relid == relid &&
     260 CBC           6 :             rte->alias == NULL)
     261                 :         {
     262               6 :             if (result)
     263 UIC           0 :                 ereport(ERROR,
     264                 :                         (errcode(ERRCODE_AMBIGUOUS_ALIAS),
     265 ECB             :                          errmsg("table reference %u is ambiguous",
     266                 :                                 relid),
     267                 :                          parser_errposition(pstate, location)));
     268 CBC           6 :             check_lateral_ref_ok(pstate, nsitem, location);
     269 GIC           6 :             result = nsitem;
     270                 :         }
     271 ECB             :     }
     272 GBC           9 :     return result;
     273                 : }
     274 ECB             : 
     275 EUB             : /*
     276                 :  * Search the query's CTE namespace for a CTE matching the given unqualified
     277                 :  * refname.  Return the CTE (and its levelsup count) if a match, or NULL
     278 ECB             :  * if no match.  We need not worry about multiple matches, since parse_cte.c
     279                 :  * rejects WITH lists containing duplicate CTE names.
     280                 :  */
     281                 : CommonTableExpr *
     282 CBC      205323 : scanNameSpaceForCTE(ParseState *pstate, const char *refname,
     283 EUB             :                     Index *ctelevelsup)
     284                 : {
     285                 :     Index       levelsup;
     286                 : 
     287 GIC      205323 :     for (levelsup = 0;
     288 CBC      495830 :          pstate != NULL;
     289          290507 :          pstate = pstate->parentParseState, levelsup++)
     290                 :     {
     291                 :         ListCell   *lc;
     292 ECB             : 
     293 GIC      296020 :         foreach(lc, pstate->p_ctenamespace)
     294                 :         {
     295            5513 :             CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc);
     296                 : 
     297            5513 :             if (strcmp(cte->ctename, refname) == 0)
     298                 :             {
     299            2565 :                 *ctelevelsup = levelsup;
     300            2565 :                 return cte;
     301                 :             }
     302 ECB             :         }
     303                 :     }
     304 GIC      202758 :     return NULL;
     305                 : }
     306                 : 
     307 ECB             : /*
     308                 :  * Search for a possible "future CTE", that is one that is not yet in scope
     309                 :  * according to the WITH scoping rules.  This has nothing to do with valid
     310                 :  * SQL semantics, but it's important for error reporting purposes.
     311                 :  */
     312                 : static bool
     313 CBC          86 : isFutureCTE(ParseState *pstate, const char *refname)
     314                 : {
     315             178 :     for (; pstate != NULL; pstate = pstate->parentParseState)
     316                 :     {
     317 ECB             :         ListCell   *lc;
     318                 : 
     319 CBC          95 :         foreach(lc, pstate->p_future_ctes)
     320 ECB             :         {
     321 GIC           3 :             CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc);
     322                 : 
     323               3 :             if (strcmp(cte->ctename, refname) == 0)
     324 CBC           3 :                 return true;
     325                 :         }
     326                 :     }
     327 GIC          83 :     return false;
     328                 : }
     329                 : 
     330                 : /*
     331                 :  * Search the query's ephemeral named relation namespace for a relation
     332                 :  * matching the given unqualified refname.
     333 ECB             :  */
     334                 : bool
     335 CBC      250067 : scanNameSpaceForENR(ParseState *pstate, const char *refname)
     336                 : {
     337 GIC      250067 :     return name_matches_visible_ENR(pstate, refname);
     338                 : }
     339 ECB             : 
     340                 : /*
     341                 :  * searchRangeTableForRel
     342                 :  *    See if any RangeTblEntry could possibly match the RangeVar.
     343                 :  *    If so, return a pointer to the RangeTblEntry; else return NULL.
     344                 :  *
     345                 :  * This is different from refnameNamespaceItem in that it considers every
     346                 :  * entry in the ParseState's rangetable(s), not only those that are currently
     347                 :  * visible in the p_namespace list(s).  This behavior is invalid per the SQL
     348                 :  * spec, and it may give ambiguous results (there might be multiple equally
     349                 :  * valid matches, but only one will be returned).  This must be used ONLY
     350                 :  * as a heuristic in giving suitable error messages.  See errorMissingRTE.
     351                 :  *
     352                 :  * Notice that we consider both matches on actual relation (or CTE) name
     353                 :  * and matches on alias.
     354                 :  */
     355                 : static RangeTblEntry *
     356 GIC          54 : searchRangeTableForRel(ParseState *pstate, RangeVar *relation)
     357 ECB             : {
     358 GIC          54 :     const char *refname = relation->relname;
     359              54 :     Oid         relId = InvalidOid;
     360              54 :     CommonTableExpr *cte = NULL;
     361              54 :     bool        isenr = false;
     362              54 :     Index       ctelevelsup = 0;
     363                 :     Index       levelsup;
     364                 : 
     365                 :     /*
     366                 :      * If it's an unqualified name, check for possible CTE matches. A CTE
     367                 :      * hides any real relation matches.  If no CTE, look for a matching
     368                 :      * relation.
     369                 :      *
     370                 :      * NB: It's not critical that RangeVarGetRelid return the correct answer
     371                 :      * here in the face of concurrent DDL.  If it doesn't, the worst case
     372                 :      * scenario is a less-clear error message.  Also, the tables involved in
     373                 :      * the query are already locked, which reduces the number of cases in
     374                 :      * which surprising behavior can occur.  So we do the name lookup
     375                 :      * unlocked.
     376 ECB             :      */
     377 GIC          54 :     if (!relation->schemaname)
     378 ECB             :     {
     379 CBC          54 :         cte = scanNameSpaceForCTE(pstate, refname, &ctelevelsup);
     380              54 :         if (!cte)
     381              54 :             isenr = scanNameSpaceForENR(pstate, refname);
     382 ECB             :     }
     383                 : 
     384 GIC          54 :     if (!cte && !isenr)
     385              54 :         relId = RangeVarGetRelid(relation, NoLock, true);
     386                 : 
     387                 :     /* Now look for RTEs matching either the relation/CTE/ENR or the alias */
     388              54 :     for (levelsup = 0;
     389              78 :          pstate != NULL;
     390              24 :          pstate = pstate->parentParseState, levelsup++)
     391                 :     {
     392                 :         ListCell   *l;
     393                 : 
     394             102 :         foreach(l, pstate->p_rtable)
     395                 :         {
     396              78 :             RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
     397 ECB             : 
     398 GIC          78 :             if (rte->rtekind == RTE_RELATION &&
     399 CBC          57 :                 OidIsValid(relId) &&
     400              57 :                 rte->relid == relId)
     401              45 :                 return rte;
     402 GIC          57 :             if (rte->rtekind == RTE_CTE &&
     403 UIC           0 :                 cte != NULL &&
     404 LBC           0 :                 rte->ctelevelsup + levelsup == ctelevelsup &&
     405               0 :                 strcmp(rte->ctename, refname) == 0)
     406 UIC           0 :                 return rte;
     407 GIC          57 :             if (rte->rtekind == RTE_NAMEDTUPLESTORE &&
     408 LBC           0 :                 isenr &&
     409               0 :                 strcmp(rte->enrname, refname) == 0)
     410               0 :                 return rte;
     411 GIC          57 :             if (strcmp(rte->eref->aliasname, refname) == 0)
     412              24 :                 return rte;
     413                 :         }
     414 ECB             :     }
     415 GIC           9 :     return NULL;
     416 ECB             : }
     417                 : 
     418                 : /*
     419                 :  * Check for relation-name conflicts between two namespace lists.
     420                 :  * Raise an error if any is found.
     421                 :  *
     422                 :  * Note: we assume that each given argument does not contain conflicts
     423 EUB             :  * itself; we just want to know if the two can be merged together.
     424                 :  *
     425                 :  * Per SQL, two alias-less plain relation RTEs do not conflict even if
     426                 :  * they have the same eref->aliasname (ie, same relation name), if they
     427 ECB             :  * are for different relation OIDs (implying they are in different schemas).
     428 EUB             :  *
     429                 :  * We ignore the lateral-only flags in the namespace items: the lists must
     430                 :  * not conflict, even when all items are considered visible.  However,
     431 ECB             :  * columns-only items should be ignored.
     432                 :  */
     433                 : void
     434 GIC      319904 : checkNameSpaceConflicts(ParseState *pstate, List *namespace1,
     435 ECB             :                         List *namespace2)
     436                 : {
     437                 :     ListCell   *l1;
     438                 : 
     439 GIC      620210 :     foreach(l1, namespace1)
     440                 :     {
     441          300312 :         ParseNamespaceItem *nsitem1 = (ParseNamespaceItem *) lfirst(l1);
     442          300312 :         RangeTblEntry *rte1 = nsitem1->p_rte;
     443          300312 :         const char *aliasname1 = nsitem1->p_names->aliasname;
     444                 :         ListCell   *l2;
     445                 : 
     446          300312 :         if (!nsitem1->p_rel_visible)
     447           56536 :             continue;
     448                 : 
     449          535765 :         foreach(l2, namespace2)
     450                 :         {
     451          291995 :             ParseNamespaceItem *nsitem2 = (ParseNamespaceItem *) lfirst(l2);
     452          291995 :             RangeTblEntry *rte2 = nsitem2->p_rte;
     453          291995 :             const char *aliasname2 = nsitem2->p_names->aliasname;
     454 ECB             : 
     455 GIC      291995 :             if (!nsitem2->p_rel_visible)
     456           24090 :                 continue;
     457          267905 :             if (strcmp(aliasname2, aliasname1) != 0)
     458          267899 :                 continue;       /* definitely no conflict */
     459 CBC           6 :             if (rte1->rtekind == RTE_RELATION && rte1->alias == NULL &&
     460 GIC           3 :                 rte2->rtekind == RTE_RELATION && rte2->alias == NULL &&
     461 CBC           3 :                 rte1->relid != rte2->relid)
     462 LBC           0 :                 continue;       /* no conflict per SQL rule */
     463 CBC           6 :             ereport(ERROR,
     464                 :                     (errcode(ERRCODE_DUPLICATE_ALIAS),
     465                 :                      errmsg("table name \"%s\" specified more than once",
     466 ECB             :                             aliasname1)));
     467                 :         }
     468                 :     }
     469 CBC      319898 : }
     470                 : 
     471 ECB             : /*
     472                 :  * Complain if a namespace item is currently disallowed as a LATERAL reference.
     473                 :  * This enforces both SQL:2008's rather odd idea of what to do with a LATERAL
     474                 :  * reference to the wrong side of an outer join, and our own prohibition on
     475                 :  * referencing the target table of an UPDATE or DELETE as a lateral reference
     476                 :  * in a FROM/USING clause.
     477                 :  *
     478                 :  * Note: the pstate should be the same query level the nsitem was found in.
     479                 :  *
     480                 :  * Convenience subroutine to avoid multiple copies of a rather ugly ereport.
     481                 :  */
     482 EUB             : static void
     483 CBC     1328285 : check_lateral_ref_ok(ParseState *pstate, ParseNamespaceItem *nsitem,
     484                 :                      int location)
     485                 : {
     486 GIC     1328285 :     if (nsitem->p_lateral_only && !nsitem->p_lateral_ok)
     487                 :     {
     488                 :         /* SQL:2008 demands this be an error, not an invisible item */
     489 CBC          12 :         RangeTblEntry *rte = nsitem->p_rte;
     490 GIC          12 :         char       *refname = nsitem->p_names->aliasname;
     491                 : 
     492              12 :         ereport(ERROR,
     493                 :                 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
     494                 :                  errmsg("invalid reference to FROM-clause entry for table \"%s\"",
     495                 :                         refname),
     496                 :                  (pstate->p_target_nsitem != NULL &&
     497                 :                   rte == pstate->p_target_nsitem->p_rte) ?
     498                 :                  errhint("There is an entry for table \"%s\", but it cannot be referenced from this part of the query.",
     499                 :                          refname) :
     500                 :                  errdetail("The combining JOIN type must be INNER or LEFT for a LATERAL reference."),
     501                 :                  parser_errposition(pstate, location)));
     502                 :     }
     503 CBC     1328273 : }
     504                 : 
     505                 : /*
     506 ECB             :  * Given an RT index and nesting depth, find the corresponding
     507                 :  * ParseNamespaceItem (there must be one).
     508                 :  */
     509                 : ParseNamespaceItem *
     510 CBC         570 : GetNSItemByRangeTablePosn(ParseState *pstate,
     511                 :                           int varno,
     512 ECB             :                           int sublevels_up)
     513                 : {
     514                 :     ListCell   *lc;
     515                 : 
     516 GIC         570 :     while (sublevels_up-- > 0)
     517                 :     {
     518 UIC           0 :         pstate = pstate->parentParseState;
     519               0 :         Assert(pstate != NULL);
     520                 :     }
     521 GIC         624 :     foreach(lc, pstate->p_namespace)
     522                 :     {
     523 CBC         624 :         ParseNamespaceItem *nsitem = (ParseNamespaceItem *) lfirst(lc);
     524                 : 
     525 GIC         624 :         if (nsitem->p_rtindex == varno)
     526             570 :             return nsitem;
     527                 :     }
     528 UIC           0 :     elog(ERROR, "nsitem not found (internal error)");
     529                 :     return NULL;                /* keep compiler quiet */
     530 ECB             : }
     531                 : 
     532                 : /*
     533                 :  * Given an RT index and nesting depth, find the corresponding RTE.
     534                 :  * (Note that the RTE need not be in the query's namespace.)
     535                 :  */
     536                 : RangeTblEntry *
     537 GIC      532374 : GetRTEByRangeTablePosn(ParseState *pstate,
     538 EUB             :                        int varno,
     539                 :                        int sublevels_up)
     540                 : {
     541 CBC      532781 :     while (sublevels_up-- > 0)
     542                 :     {
     543             407 :         pstate = pstate->parentParseState;
     544 GIC         407 :         Assert(pstate != NULL);
     545 ECB             :     }
     546 CBC      532374 :     Assert(varno > 0 && varno <= list_length(pstate->p_rtable));
     547 GIC      532374 :     return rt_fetch(varno, pstate->p_rtable);
     548 EUB             : }
     549                 : 
     550                 : /*
     551                 :  * Fetch the CTE for a CTE-reference RTE.
     552                 :  *
     553                 :  * rtelevelsup is the number of query levels above the given pstate that the
     554                 :  * RTE came from.
     555                 :  */
     556                 : CommonTableExpr *
     557 CBC        3206 : GetCTEForRTE(ParseState *pstate, RangeTblEntry *rte, int rtelevelsup)
     558                 : {
     559                 :     Index       levelsup;
     560                 :     ListCell   *lc;
     561 ECB             : 
     562 GIC        3206 :     Assert(rte->rtekind == RTE_CTE);
     563 CBC        3206 :     levelsup = rte->ctelevelsup + rtelevelsup;
     564            6333 :     while (levelsup-- > 0)
     565                 :     {
     566            3127 :         pstate = pstate->parentParseState;
     567            3127 :         if (!pstate)            /* shouldn't happen */
     568 UIC           0 :             elog(ERROR, "bad levelsup for CTE \"%s\"", rte->ctename);
     569                 :     }
     570 GIC        5732 :     foreach(lc, pstate->p_ctenamespace)
     571                 :     {
     572            5732 :         CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc);
     573                 : 
     574            5732 :         if (strcmp(cte->ctename, rte->ctename) == 0)
     575            3206 :             return cte;
     576                 :     }
     577 ECB             :     /* shouldn't happen */
     578 UIC           0 :     elog(ERROR, "could not find CTE \"%s\"", rte->ctename);
     579                 :     return NULL;                /* keep compiler quiet */
     580                 : }
     581                 : 
     582 ECB             : /*
     583                 :  * updateFuzzyAttrMatchState
     584                 :  *    Using Levenshtein distance, consider if column is best fuzzy match.
     585                 :  */
     586                 : static void
     587 CBC        1098 : updateFuzzyAttrMatchState(int fuzzy_rte_penalty,
     588 EUB             :                           FuzzyAttrMatchState *fuzzystate, RangeTblEntry *rte,
     589                 :                           const char *actual, const char *match, int attnum)
     590 ECB             : {
     591                 :     int         columndistance;
     592                 :     int         matchlen;
     593                 : 
     594                 :     /* Bail before computing the Levenshtein distance if there's no hope. */
     595 CBC        1098 :     if (fuzzy_rte_penalty > fuzzystate->distance)
     596 GIC          27 :         return;
     597                 : 
     598 EUB             :     /*
     599                 :      * Outright reject dropped columns, which can appear here with apparent
     600                 :      * empty actual names, per remarks within scanRTEForColumn().
     601                 :      */
     602 GIC        1071 :     if (actual[0] == '\0')
     603              63 :         return;
     604                 : 
     605                 :     /* Use Levenshtein to compute match distance. */
     606            1008 :     matchlen = strlen(match);
     607 ECB             :     columndistance =
     608 GIC        1008 :         varstr_levenshtein_less_equal(actual, strlen(actual), match, matchlen,
     609                 :                                       1, 1, 1,
     610            1008 :                                       fuzzystate->distance + 1
     611            1008 :                                       - fuzzy_rte_penalty,
     612                 :                                       true);
     613                 : 
     614                 :     /*
     615 ECB             :      * If more than half the characters are different, don't treat it as a
     616                 :      * match, to avoid making ridiculous suggestions.
     617                 :      */
     618 GIC        1008 :     if (columndistance > matchlen / 2)
     619             579 :         return;
     620                 : 
     621                 :     /*
     622 ECB             :      * From this point on, we can ignore the distinction between the RTE-name
     623                 :      * distance and the column-name distance.
     624                 :      */
     625 GIC         429 :     columndistance += fuzzy_rte_penalty;
     626 ECB             : 
     627                 :     /*
     628                 :      * If the new distance is less than or equal to that of the best match
     629                 :      * found so far, update fuzzystate.
     630                 :      */
     631 CBC         429 :     if (columndistance < fuzzystate->distance)
     632                 :     {
     633                 :         /* Store new lowest observed distance as first/only match */
     634 GIC          57 :         fuzzystate->distance = columndistance;
     635              57 :         fuzzystate->rfirst = rte;
     636              57 :         fuzzystate->first = attnum;
     637              57 :         fuzzystate->rsecond = NULL;
     638 ECB             :     }
     639 GIC         372 :     else if (columndistance == fuzzystate->distance)
     640                 :     {
     641                 :         /* If we already have a match of this distance, update state */
     642 GNC          12 :         if (fuzzystate->rsecond != NULL)
     643                 :         {
     644                 :             /*
     645                 :              * Too many matches at same distance.  Clearly, this value of
     646                 :              * distance is too low a bar, so drop these entries while keeping
     647                 :              * the current distance value, so that only smaller distances will
     648                 :              * be considered interesting.  Only if we find something of lower
     649                 :              * distance will we re-populate rfirst (via the stanza above).
     650                 :              */
     651 GIC           3 :             fuzzystate->rfirst = NULL;
     652 CBC           3 :             fuzzystate->rsecond = NULL;
     653                 :         }
     654 GNC           9 :         else if (fuzzystate->rfirst != NULL)
     655                 :         {
     656                 :             /* Record as provisional second match */
     657 CBC           9 :             fuzzystate->rsecond = rte;
     658 GIC           9 :             fuzzystate->second = attnum;
     659                 :         }
     660                 :         else
     661                 :         {
     662                 :             /*
     663                 :              * Do nothing.  When rfirst is NULL, distance is more than what we
     664                 :              * want to consider acceptable, so we should ignore this match.
     665 ECB             :              */
     666                 :         }
     667                 :     }
     668                 : }
     669                 : 
     670                 : /*
     671                 :  * scanNSItemForColumn
     672                 :  *    Search the column names of a single namespace item for the given name.
     673                 :  *    If found, return an appropriate Var node, else return NULL.
     674                 :  *    If the name proves ambiguous within this nsitem, raise error.
     675                 :  *
     676                 :  * Side effect: if we find a match, mark the corresponding RTE as requiring
     677                 :  * read access for the column.
     678                 :  */
     679                 : Node *
     680 GIC     1389202 : scanNSItemForColumn(ParseState *pstate, ParseNamespaceItem *nsitem,
     681                 :                     int sublevels_up, const char *colname, int location)
     682                 : {
     683         1389202 :     RangeTblEntry *rte = nsitem->p_rte;
     684                 :     int         attnum;
     685                 :     Var        *var;
     686                 : 
     687                 :     /*
     688                 :      * Scan the nsitem's column names (or aliases) for a match.  Complain if
     689                 :      * multiple matches.
     690                 :      */
     691         1389202 :     attnum = scanRTEForColumn(pstate, rte, nsitem->p_names,
     692 ECB             :                               colname, location,
     693                 :                               0, NULL);
     694                 : 
     695 CBC     1389196 :     if (attnum == InvalidAttrNumber)
     696 GIC       80667 :         return NULL;            /* Return NULL if no match */
     697                 : 
     698                 :     /* In constraint check, no system column is allowed except tableOid */
     699         1308529 :     if (pstate->p_expr_kind == EXPR_KIND_CHECK_CONSTRAINT &&
     700               6 :         attnum < InvalidAttrNumber && attnum != TableOidAttributeNumber)
     701               3 :         ereport(ERROR,
     702                 :                 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
     703 ECB             :                  errmsg("system column \"%s\" reference in check constraint is invalid",
     704                 :                         colname),
     705                 :                  parser_errposition(pstate, location)));
     706                 : 
     707                 :     /* In generated column, no system column is allowed except tableOid */
     708 CBC     1308526 :     if (pstate->p_expr_kind == EXPR_KIND_GENERATED_COLUMN &&
     709 GIC          11 :         attnum < InvalidAttrNumber && attnum != TableOidAttributeNumber)
     710               3 :         ereport(ERROR,
     711 ECB             :                 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
     712                 :                  errmsg("cannot use system column \"%s\" in column generation expression",
     713                 :                         colname),
     714                 :                  parser_errposition(pstate, location)));
     715                 : 
     716                 :     /*
     717                 :      * In a MERGE WHEN condition, no system column is allowed except tableOid
     718                 :      */
     719 GIC     1308523 :     if (pstate->p_expr_kind == EXPR_KIND_MERGE_WHEN &&
     720 CBC           6 :         attnum < InvalidAttrNumber && attnum != TableOidAttributeNumber)
     721               3 :         ereport(ERROR,
     722 ECB             :                 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
     723                 :                  errmsg("cannot use system column \"%s\" in MERGE WHEN condition",
     724                 :                         colname),
     725                 :                  parser_errposition(pstate, location)));
     726                 : 
     727                 :     /* Found a valid match, so build a Var */
     728 GIC     1308520 :     if (attnum > InvalidAttrNumber)
     729                 :     {
     730                 :         /* Get attribute data from the ParseNamespaceColumn array */
     731 CBC     1293069 :         ParseNamespaceColumn *nscol = &nsitem->p_nscolumns[attnum - 1];
     732 ECB             : 
     733                 :         /* Complain if dropped column.  See notes in scanRTEForColumn. */
     734 GIC     1293069 :         if (nscol->p_varno == 0)
     735 UIC           0 :             ereport(ERROR,
     736                 :                     (errcode(ERRCODE_UNDEFINED_COLUMN),
     737                 :                      errmsg("column \"%s\" of relation \"%s\" does not exist",
     738                 :                             colname,
     739                 :                             nsitem->p_names->aliasname)));
     740 ECB             : 
     741 GIC     1293069 :         var = makeVar(nscol->p_varno,
     742         1293069 :                       nscol->p_varattno,
     743 ECB             :                       nscol->p_vartype,
     744                 :                       nscol->p_vartypmod,
     745                 :                       nscol->p_varcollid,
     746                 :                       sublevels_up);
     747 EUB             :         /* makeVar doesn't offer parameters for these, so set them by hand: */
     748 GIC     1293069 :         var->varnosyn = nscol->p_varnosyn;
     749         1293069 :         var->varattnosyn = nscol->p_varattnosyn;
     750                 :     }
     751                 :     else
     752                 :     {
     753 ECB             :         /* System column, so use predetermined type data */
     754                 :         const FormData_pg_attribute *sysatt;
     755                 : 
     756 GIC       15451 :         sysatt = SystemAttributeDefinition(attnum);
     757           15451 :         var = makeVar(nsitem->p_rtindex,
     758                 :                       attnum,
     759           15451 :                       sysatt->atttypid,
     760 CBC       15451 :                       sysatt->atttypmod,
     761           15451 :                       sysatt->attcollation,
     762                 :                       sublevels_up);
     763                 :     }
     764 GIC     1308520 :     var->location = location;
     765                 : 
     766                 :     /* Mark Var if it's nulled by any outer joins */
     767 GNC     1308520 :     markNullableIfNeeded(pstate, var);
     768                 : 
     769                 :     /* Require read access to the column */
     770 GIC     1308520 :     markVarForSelectPriv(pstate, var);
     771 ECB             : 
     772 CBC     1308520 :     return (Node *) var;
     773                 : }
     774 ECB             : 
     775                 : /*
     776                 :  * scanRTEForColumn
     777                 :  *    Search the column names of a single RTE for the given name.
     778                 :  *    If found, return the attnum (possibly negative, for a system column);
     779                 :  *    else return InvalidAttrNumber.
     780                 :  *    If the name proves ambiguous within this RTE, raise error.
     781                 :  *
     782                 :  * Actually, we only search the names listed in "eref".  This can be either
     783                 :  * rte->eref, in which case we are indeed searching all the column names,
     784                 :  * or for a join it can be rte->join_using_alias, in which case we are only
     785                 :  * considering the common column names (which are the first N columns of the
     786                 :  * join, so everything works).
     787                 :  *
     788                 :  * pstate and location are passed only for error-reporting purposes.
     789                 :  *
     790                 :  * Side effect: if fuzzystate is non-NULL, check non-system columns
     791                 :  * for an approximate match and update fuzzystate accordingly.
     792                 :  *
     793                 :  * Note: this is factored out of scanNSItemForColumn because error message
     794                 :  * creation may want to check RTEs that are not in the namespace.  To support
     795                 :  * that usage, minimize the number of validity checks performed here.  It's
     796                 :  * okay to complain about ambiguous-name cases, though, since if we are
     797                 :  * working to complain about an invalid name, we've already eliminated that.
     798                 :  */
     799                 : static int
     800 GIC     1389391 : scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte,
     801                 :                  Alias *eref,
     802                 :                  const char *colname, int location,
     803                 :                  int fuzzy_rte_penalty,
     804                 :                  FuzzyAttrMatchState *fuzzystate)
     805                 : {
     806         1389391 :     int         result = InvalidAttrNumber;
     807         1389391 :     int         attnum = 0;
     808                 :     ListCell   *c;
     809                 : 
     810                 :     /*
     811                 :      * Scan the user column names (or aliases) for a match. Complain if
     812                 :      * multiple matches.
     813                 :      *
     814                 :      * Note: eref->colnames may include entries for dropped columns, but those
     815 ECB             :      * will be empty strings that cannot match any legal SQL identifier, so we
     816                 :      * don't bother to test for that case here.
     817                 :      *
     818                 :      * Should this somehow go wrong and we try to access a dropped column,
     819                 :      * we'll still catch it by virtue of the check in scanNSItemForColumn().
     820                 :      * Callers interested in finding match with shortest distance need to
     821                 :      * defend against this directly, though.
     822                 :      */
     823 GIC    28579090 :     foreach(c, eref->colnames)
     824                 :     {
     825        27189705 :         const char *attcolname = strVal(lfirst(c));
     826                 : 
     827        27189705 :         attnum++;
     828        27189705 :         if (strcmp(attcolname, colname) == 0)
     829                 :         {
     830         1293111 :             if (result)
     831               6 :                 ereport(ERROR,
     832                 :                         (errcode(ERRCODE_AMBIGUOUS_COLUMN),
     833                 :                          errmsg("column reference \"%s\" is ambiguous",
     834                 :                                 colname),
     835                 :                          parser_errposition(pstate, location)));
     836         1293105 :             result = attnum;
     837                 :         }
     838 ECB             : 
     839                 :         /* Update fuzzy match state, if provided. */
     840 CBC    27189699 :         if (fuzzystate != NULL)
     841 GIC        1098 :             updateFuzzyAttrMatchState(fuzzy_rte_penalty, fuzzystate,
     842 ECB             :                                       rte, attcolname, colname, attnum);
     843                 :     }
     844                 : 
     845                 :     /*
     846                 :      * If we have a unique match, return it.  Note that this allows a user
     847                 :      * alias to override a system column name (such as OID) without error.
     848                 :      */
     849 GIC     1389385 :     if (result)
     850         1293099 :         return result;
     851 ECB             : 
     852                 :     /*
     853                 :      * If the RTE represents a real relation, consider system column names.
     854                 :      * Composites are only used for pseudo-relations like ON CONFLICT's
     855                 :      * excluded.
     856                 :      */
     857 GIC       96286 :     if (rte->rtekind == RTE_RELATION &&
     858           64907 :         rte->relkind != RELKIND_COMPOSITE_TYPE)
     859                 :     {
     860                 :         /* quick check to see if name could be a system column */
     861           64880 :         attnum = specialAttNum(colname);
     862           64880 :         if (attnum != InvalidAttrNumber)
     863                 :         {
     864 ECB             :             /* now check to see if column actually is defined */
     865 CBC       15469 :             if (SearchSysCacheExists2(ATTNUM,
     866                 :                                       ObjectIdGetDatum(rte->relid),
     867                 :                                       Int16GetDatum(attnum)))
     868 GIC       15469 :                 result = attnum;
     869                 :         }
     870                 :     }
     871                 : 
     872 CBC       96286 :     return result;
     873 ECB             : }
     874                 : 
     875                 : /*
     876                 :  * colNameToVar
     877                 :  *    Search for an unqualified column name.
     878                 :  *    If found, return the appropriate Var node (or expression).
     879                 :  *    If not found, return NULL.  If the name proves ambiguous, raise error.
     880                 :  *    If localonly is true, only names in the innermost query are considered.
     881                 :  */
     882                 : Node *
     883 CBC      396284 : colNameToVar(ParseState *pstate, const char *colname, bool localonly,
     884                 :              int location)
     885                 : {
     886 GIC      396284 :     Node       *result = NULL;
     887 CBC      396284 :     int         sublevels_up = 0;
     888 GIC      396284 :     ParseState *orig_pstate = pstate;
     889                 : 
     890          433392 :     while (pstate != NULL)
     891                 :     {
     892                 :         ListCell   *l;
     893                 : 
     894         1368408 :         foreach(l, pstate->p_namespace)
     895                 :         {
     896          966522 :             ParseNamespaceItem *nsitem = (ParseNamespaceItem *) lfirst(l);
     897                 :             Node       *newresult;
     898 ECB             : 
     899                 :             /* Ignore table-only items */
     900 GIC      966522 :             if (!nsitem->p_cols_visible)
     901 CBC      521211 :                 continue;
     902 ECB             :             /* If not inside LATERAL, ignore lateral-only items */
     903 CBC      445311 :             if (nsitem->p_lateral_only && !pstate->p_lateral_active)
     904 GIC          23 :                 continue;
     905 ECB             : 
     906                 :             /* use orig_pstate here for consistency with other callers */
     907 GIC      445288 :             newresult = scanNSItemForColumn(orig_pstate, nsitem, sublevels_up,
     908                 :                                             colname, location);
     909 ECB             : 
     910 GIC      445276 :             if (newresult)
     911 ECB             :             {
     912 GIC      364771 :                 if (result)
     913              12 :                     ereport(ERROR,
     914                 :                             (errcode(ERRCODE_AMBIGUOUS_COLUMN),
     915 ECB             :                              errmsg("column reference \"%s\" is ambiguous",
     916                 :                                     colname),
     917                 :                              parser_errposition(pstate, location)));
     918 CBC      364759 :                 check_lateral_ref_ok(pstate, nsitem, location);
     919          364753 :                 result = newresult;
     920                 :             }
     921                 :         }
     922 ECB             : 
     923 GIC      401886 :         if (result != NULL || localonly)
     924                 :             break;              /* found, or don't want to look at parent */
     925 ECB             : 
     926 GIC       37108 :         pstate = pstate->parentParseState;
     927 CBC       37108 :         sublevels_up++;
     928 ECB             :     }
     929                 : 
     930 GIC      396254 :     return result;
     931                 : }
     932                 : 
     933 ECB             : /*
     934                 :  * searchRangeTableForCol
     935                 :  *    See if any RangeTblEntry could possibly provide the given column name (or
     936                 :  *    find the best match available).  Returns state with relevant details.
     937                 :  *
     938                 :  * This is different from colNameToVar in that it considers every entry in
     939                 :  * the ParseState's rangetable(s), not only those that are currently visible
     940                 :  * in the p_namespace list(s).  This behavior is invalid per the SQL spec,
     941                 :  * and it may give ambiguous results (since there might be multiple equally
     942                 :  * valid matches).  This must be used ONLY as a heuristic in giving suitable
     943                 :  * error messages.  See errorMissingColumn.
     944                 :  *
     945                 :  * This function is also different in that it will consider approximate
     946                 :  * matches -- if the user entered an alias/column pair that is only slightly
     947                 :  * different from a valid pair, we may be able to infer what they meant to
     948                 :  * type and provide a reasonable hint.  We return a FuzzyAttrMatchState
     949                 :  * struct providing information about both exact and approximate matches.
     950                 :  */
     951                 : static FuzzyAttrMatchState *
     952 GIC         170 : searchRangeTableForCol(ParseState *pstate, const char *alias, const char *colname,
     953                 :                        int location)
     954                 : {
     955             170 :     ParseState *orig_pstate = pstate;
     956             170 :     FuzzyAttrMatchState *fuzzystate = palloc(sizeof(FuzzyAttrMatchState));
     957                 : 
     958             170 :     fuzzystate->distance = MAX_FUZZY_DISTANCE + 1;
     959             170 :     fuzzystate->rfirst = NULL;
     960             170 :     fuzzystate->rsecond = NULL;
     961 GNC         170 :     fuzzystate->rexact1 = NULL;
     962             170 :     fuzzystate->rexact2 = NULL;
     963                 : 
     964 CBC         355 :     while (pstate != NULL)
     965 ECB             :     {
     966                 :         ListCell   *l;
     967                 : 
     968 CBC         401 :         foreach(l, pstate->p_rtable)
     969 ECB             :         {
     970 CBC         216 :             RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
     971             216 :             int         fuzzy_rte_penalty = 0;
     972                 :             int         attnum;
     973                 : 
     974 ECB             :             /*
     975                 :              * Typically, it is not useful to look for matches within join
     976                 :              * RTEs; they effectively duplicate other RTEs for our purposes,
     977                 :              * and if a match is chosen from a join RTE, an unhelpful alias is
     978                 :              * displayed in the final diagnostic message.
     979                 :              */
     980 CBC         216 :             if (rte->rtekind == RTE_JOIN)
     981              27 :                 continue;
     982                 : 
     983                 :             /*
     984                 :              * If the user didn't specify an alias, then matches against one
     985                 :              * RTE are as good as another.  But if the user did specify an
     986                 :              * alias, then we want at least a fuzzy - and preferably an exact
     987                 :              * - match for the range table entry.
     988                 :              */
     989 GIC         189 :             if (alias != NULL)
     990 ECB             :                 fuzzy_rte_penalty =
     991 CBC          54 :                     varstr_levenshtein_less_equal(alias, strlen(alias),
     992 GIC          54 :                                                   rte->eref->aliasname,
     993              54 :                                                   strlen(rte->eref->aliasname),
     994                 :                                                   1, 1, 1,
     995                 :                                                   MAX_FUZZY_DISTANCE + 1,
     996                 :                                                   true);
     997                 : 
     998                 :             /*
     999                 :              * Scan for a matching column, and update fuzzystate.  Non-exact
    1000                 :              * matches are dealt with inside scanRTEForColumn, but exact
    1001                 :              * matches are handled here.  (There won't be more than one exact
    1002                 :              * match in the same RTE, else we'd have thrown error earlier.)
    1003 ECB             :              */
    1004 GNC         189 :             attnum = scanRTEForColumn(orig_pstate, rte, rte->eref,
    1005                 :                                       colname, location,
    1006                 :                                       fuzzy_rte_penalty, fuzzystate);
    1007             189 :             if (attnum != InvalidAttrNumber && fuzzy_rte_penalty == 0)
    1008                 :             {
    1009              30 :                 if (fuzzystate->rexact1 == NULL)
    1010                 :                 {
    1011              21 :                     fuzzystate->rexact1 = rte;
    1012              21 :                     fuzzystate->exact1 = attnum;
    1013                 :                 }
    1014                 :                 else
    1015                 :                 {
    1016                 :                     /* Needn't worry about overwriting previous rexact2 */
    1017               9 :                     fuzzystate->rexact2 = rte;
    1018               9 :                     fuzzystate->exact2 = attnum;
    1019                 :                 }
    1020                 :             }
    1021                 :         }
    1022                 : 
    1023 CBC         185 :         pstate = pstate->parentParseState;
    1024                 :     }
    1025                 : 
    1026             170 :     return fuzzystate;
    1027                 : }
    1028 ECB             : 
    1029                 : /*
    1030                 :  * markNullableIfNeeded
    1031                 :  *      If the RTE referenced by the Var is nullable by outer join(s)
    1032                 :  *      at this point in the query, set var->varnullingrels to show that.
    1033                 :  */
    1034                 : void
    1035 GNC     4787207 : markNullableIfNeeded(ParseState *pstate, Var *var)
    1036                 : {
    1037         4787207 :     int         rtindex = var->varno;
    1038                 :     Bitmapset  *relids;
    1039                 : 
    1040                 :     /* Find the appropriate pstate */
    1041         4816903 :     for (int lv = 0; lv < var->varlevelsup; lv++)
    1042           29696 :         pstate = pstate->parentParseState;
    1043                 : 
    1044                 :     /* Find currently-relevant join relids for the Var's rel */
    1045         4787207 :     if (rtindex > 0 && rtindex <= list_length(pstate->p_nullingrels))
    1046         2304725 :         relids = (Bitmapset *) list_nth(pstate->p_nullingrels, rtindex - 1);
    1047                 :     else
    1048         2482482 :         relids = NULL;
    1049                 : 
    1050                 :     /*
    1051                 :      * Merge with any already-declared nulling rels.  (Typically there won't
    1052                 :      * be any, but let's get it right if there are.)
    1053                 :      */
    1054         4787207 :     if (relids != NULL)
    1055          809130 :         var->varnullingrels = bms_union(var->varnullingrels, relids);
    1056         4787207 : }
    1057                 : 
    1058                 : /*
    1059 ECB             :  * markRTEForSelectPriv
    1060                 :  *     Mark the specified column of the RTE with index rtindex
    1061                 :  *     as requiring SELECT privilege
    1062                 :  *
    1063                 :  * col == InvalidAttrNumber means a "whole row" reference
    1064                 :  */
    1065                 : static void
    1066 CBC     1476562 : markRTEForSelectPriv(ParseState *pstate, int rtindex, AttrNumber col)
    1067                 : {
    1068 GIC     1476562 :     RangeTblEntry *rte = rt_fetch(rtindex, pstate->p_rtable);
    1069                 : 
    1070         1476562 :     if (rte->rtekind == RTE_RELATION)
    1071 ECB             :     {
    1072                 :         RTEPermissionInfo *perminfo;
    1073                 : 
    1074                 :         /* Make sure the rel as a whole is marked for SELECT access */
    1075 GNC     1208300 :         perminfo = getRTEPermissionInfo(pstate->p_rteperminfos, rte);
    1076         1208300 :         perminfo->requiredPerms |= ACL_SELECT;
    1077 ECB             :         /* Must offset the attnum to fit in a bitmapset */
    1078 GNC     1208300 :         perminfo->selectedCols =
    1079         1208300 :             bms_add_member(perminfo->selectedCols,
    1080                 :                            col - FirstLowInvalidHeapAttributeNumber);
    1081                 :     }
    1082 GIC      268262 :     else if (rte->rtekind == RTE_JOIN)
    1083                 :     {
    1084             210 :         if (col == InvalidAttrNumber)
    1085                 :         {
    1086                 :             /*
    1087 ECB             :              * A whole-row reference to a join has to be treated as whole-row
    1088                 :              * references to the two inputs.
    1089                 :              */
    1090                 :             JoinExpr   *j;
    1091                 : 
    1092 GIC           3 :             if (rtindex > 0 && rtindex <= list_length(pstate->p_joinexprs))
    1093 CBC           3 :                 j = list_nth_node(JoinExpr, pstate->p_joinexprs, rtindex - 1);
    1094 ECB             :             else
    1095 UIC           0 :                 j = NULL;
    1096 GIC           3 :             if (j == NULL)
    1097 LBC           0 :                 elog(ERROR, "could not find JoinExpr for whole-row reference");
    1098 ECB             : 
    1099                 :             /* Note: we can't see FromExpr here */
    1100 CBC           3 :             if (IsA(j->larg, RangeTblRef))
    1101                 :             {
    1102 GIC           3 :                 int         varno = ((RangeTblRef *) j->larg)->rtindex;
    1103                 : 
    1104               3 :                 markRTEForSelectPriv(pstate, varno, InvalidAttrNumber);
    1105                 :             }
    1106 LBC           0 :             else if (IsA(j->larg, JoinExpr))
    1107 ECB             :             {
    1108 LBC           0 :                 int         varno = ((JoinExpr *) j->larg)->rtindex;
    1109                 : 
    1110 UIC           0 :                 markRTEForSelectPriv(pstate, varno, InvalidAttrNumber);
    1111                 :             }
    1112                 :             else
    1113               0 :                 elog(ERROR, "unrecognized node type: %d",
    1114                 :                      (int) nodeTag(j->larg));
    1115 GIC           3 :             if (IsA(j->rarg, RangeTblRef))
    1116                 :             {
    1117               3 :                 int         varno = ((RangeTblRef *) j->rarg)->rtindex;
    1118 ECB             : 
    1119 GIC           3 :                 markRTEForSelectPriv(pstate, varno, InvalidAttrNumber);
    1120 ECB             :             }
    1121 UIC           0 :             else if (IsA(j->rarg, JoinExpr))
    1122 ECB             :             {
    1123 UIC           0 :                 int         varno = ((JoinExpr *) j->rarg)->rtindex;
    1124                 : 
    1125               0 :                 markRTEForSelectPriv(pstate, varno, InvalidAttrNumber);
    1126                 :             }
    1127 ECB             :             else
    1128 LBC           0 :                 elog(ERROR, "unrecognized node type: %d",
    1129                 :                      (int) nodeTag(j->rarg));
    1130 ECB             :         }
    1131                 :         else
    1132                 :         {
    1133                 :             /*
    1134                 :              * Join alias Vars for ordinary columns must refer to merged JOIN
    1135                 :              * USING columns.  We don't need to do anything here, because the
    1136                 :              * join input columns will also be referenced in the join's qual
    1137                 :              * clause, and will get marked for select privilege there.
    1138                 :              */
    1139                 :         }
    1140                 :     }
    1141                 :     /* other RTE types don't require privilege marking */
    1142 GIC     1476562 : }
    1143                 : 
    1144 ECB             : /*
    1145                 :  * markVarForSelectPriv
    1146                 :  *     Mark the RTE referenced by the Var as requiring SELECT privilege
    1147 EUB             :  *     for the Var's column (the Var could be a whole-row Var, too)
    1148 ECB             :  */
    1149 EUB             : void
    1150 GIC     1476556 : markVarForSelectPriv(ParseState *pstate, Var *var)
    1151                 : {
    1152 ECB             :     Index       lv;
    1153                 : 
    1154 CBC     1476556 :     Assert(IsA(var, Var));
    1155                 :     /* Find the appropriate pstate if it's an uplevel Var */
    1156         1506252 :     for (lv = 0; lv < var->varlevelsup; lv++)
    1157 GIC       29696 :         pstate = pstate->parentParseState;
    1158 GBC     1476556 :     markRTEForSelectPriv(pstate, var->varno, var->varattno);
    1159 GIC     1476556 : }
    1160 EUB             : 
    1161                 : /*
    1162                 :  * buildRelationAliases
    1163                 :  *      Construct the eref column name list for a relation RTE.
    1164                 :  *      This code is also used for function RTEs.
    1165                 :  *
    1166                 :  * tupdesc: the physical column information
    1167 ECB             :  * alias: the user-supplied alias, or NULL if none
    1168                 :  * eref: the eref Alias to store column names in
    1169                 :  *
    1170                 :  * eref->colnames is filled in.  Also, alias->colnames is rebuilt to insert
    1171                 :  * empty strings for any dropped columns, so that it will be one-to-one with
    1172                 :  * physical column numbers.
    1173 EUB             :  *
    1174                 :  * It is an error for there to be more aliases present than required.
    1175                 :  */
    1176                 : static void
    1177 GBC      451592 : buildRelationAliases(TupleDesc tupdesc, Alias *alias, Alias *eref)
    1178                 : {
    1179 GIC      451592 :     int         maxattrs = tupdesc->natts;
    1180 EUB             :     List       *aliaslist;
    1181                 :     ListCell   *aliaslc;
    1182                 :     int         numaliases;
    1183                 :     int         varattno;
    1184 GIC      451592 :     int         numdropped = 0;
    1185                 : 
    1186          451592 :     Assert(eref->colnames == NIL);
    1187                 : 
    1188          451592 :     if (alias)
    1189                 :     {
    1190          210561 :         aliaslist = alias->colnames;
    1191          210561 :         aliaslc = list_head(aliaslist);
    1192          210561 :         numaliases = list_length(aliaslist);
    1193                 :         /* We'll rebuild the alias colname list */
    1194 CBC      210561 :         alias->colnames = NIL;
    1195                 :     }
    1196                 :     else
    1197                 :     {
    1198 GIC      241031 :         aliaslist = NIL;
    1199          241031 :         aliaslc = NULL;
    1200          241031 :         numaliases = 0;
    1201                 :     }
    1202 ECB             : 
    1203 GIC     5639624 :     for (varattno = 0; varattno < maxattrs; varattno++)
    1204                 :     {
    1205         5188032 :         Form_pg_attribute attr = TupleDescAttr(tupdesc, varattno);
    1206 ECB             :         String     *attrname;
    1207                 : 
    1208 CBC     5188032 :         if (attr->attisdropped)
    1209 ECB             :         {
    1210                 :             /* Always insert an empty string for a dropped column */
    1211 CBC        2604 :             attrname = makeString(pstrdup(""));
    1212 GIC        2604 :             if (aliaslc)
    1213               3 :                 alias->colnames = lappend(alias->colnames, attrname);
    1214            2604 :             numdropped++;
    1215                 :         }
    1216         5185428 :         else if (aliaslc)
    1217                 :         {
    1218                 :             /* Use the next user-supplied alias */
    1219            3023 :             attrname = lfirst_node(String, aliaslc);
    1220            3023 :             aliaslc = lnext(aliaslist, aliaslc);
    1221            3023 :             alias->colnames = lappend(alias->colnames, attrname);
    1222                 :         }
    1223                 :         else
    1224                 :         {
    1225         5182405 :             attrname = makeString(pstrdup(NameStr(attr->attname)));
    1226                 :             /* we're done with the alias if any */
    1227                 :         }
    1228                 : 
    1229 CBC     5188032 :         eref->colnames = lappend(eref->colnames, attrname);
    1230                 :     }
    1231 ECB             : 
    1232                 :     /* Too many user-supplied aliases? */
    1233 GIC      451592 :     if (aliaslc)
    1234               3 :         ereport(ERROR,
    1235                 :                 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
    1236 ECB             :                  errmsg("table \"%s\" has %d columns available but %d columns specified",
    1237                 :                         eref->aliasname, maxattrs - numdropped, numaliases)));
    1238 CBC      451589 : }
    1239                 : 
    1240 ECB             : /*
    1241                 :  * chooseScalarFunctionAlias
    1242                 :  *      Select the column alias for a function in a function RTE,
    1243                 :  *      when the function returns a scalar type (not composite or RECORD).
    1244                 :  *
    1245                 :  * funcexpr: transformed expression tree for the function call
    1246                 :  * funcname: function name (as determined by FigureColname)
    1247                 :  * alias: the user-supplied alias for the RTE, or NULL if none
    1248                 :  * nfuncs: the number of functions appearing in the function RTE
    1249                 :  *
    1250                 :  * Note that the name we choose might be overridden later, if the user-given
    1251                 :  * alias includes column alias names.  That's of no concern here.
    1252                 :  */
    1253                 : static char *
    1254 GIC        8672 : chooseScalarFunctionAlias(Node *funcexpr, char *funcname,
    1255 ECB             :                           Alias *alias, int nfuncs)
    1256                 : {
    1257                 :     char       *pname;
    1258                 : 
    1259                 :     /*
    1260                 :      * If the expression is a simple function call, and the function has a
    1261                 :      * single OUT parameter that is named, use the parameter's name.
    1262                 :      */
    1263 CBC        8672 :     if (funcexpr && IsA(funcexpr, FuncExpr))
    1264 ECB             :     {
    1265 CBC        8666 :         pname = get_func_result_name(((FuncExpr *) funcexpr)->funcid);
    1266            8666 :         if (pname)
    1267 GIC         358 :             return pname;
    1268 ECB             :     }
    1269                 : 
    1270                 :     /*
    1271                 :      * If there's just one function in the RTE, and the user gave an RTE alias
    1272                 :      * name, use that name.  (This makes FROM func() AS foo use "foo" as the
    1273                 :      * column name as well as the table alias.)
    1274                 :      */
    1275 GIC        8314 :     if (nfuncs == 1 && alias)
    1276            6598 :         return alias->aliasname;
    1277 ECB             : 
    1278                 :     /*
    1279                 :      * Otherwise use the function name.
    1280                 :      */
    1281 CBC        1716 :     return funcname;
    1282                 : }
    1283                 : 
    1284                 : /*
    1285 ECB             :  * buildNSItemFromTupleDesc
    1286                 :  *      Build a ParseNamespaceItem, given a tupdesc describing the columns.
    1287                 :  *
    1288                 :  * rte: the new RangeTblEntry for the rel
    1289                 :  * rtindex: its index in the rangetable list
    1290                 :  * perminfo: permission list entry for the rel
    1291                 :  * tupdesc: the physical column information
    1292                 :  */
    1293                 : static ParseNamespaceItem *
    1294 GNC      451589 : buildNSItemFromTupleDesc(RangeTblEntry *rte, Index rtindex,
    1295                 :                          RTEPermissionInfo *perminfo,
    1296                 :                          TupleDesc tupdesc)
    1297                 : {
    1298                 :     ParseNamespaceItem *nsitem;
    1299                 :     ParseNamespaceColumn *nscolumns;
    1300 GIC      451589 :     int         maxattrs = tupdesc->natts;
    1301                 :     int         varattno;
    1302                 : 
    1303                 :     /* colnames must have the same number of entries as the nsitem */
    1304          451589 :     Assert(maxattrs == list_length(rte->eref->colnames));
    1305                 : 
    1306                 :     /* extract per-column data from the tupdesc */
    1307                 :     nscolumns = (ParseNamespaceColumn *)
    1308          451589 :         palloc0(maxattrs * sizeof(ParseNamespaceColumn));
    1309 ECB             : 
    1310 GIC     5639618 :     for (varattno = 0; varattno < maxattrs; varattno++)
    1311                 :     {
    1312         5188029 :         Form_pg_attribute attr = TupleDescAttr(tupdesc, varattno);
    1313                 : 
    1314                 :         /* For a dropped column, just leave the entry as zeroes */
    1315         5188029 :         if (attr->attisdropped)
    1316            2604 :             continue;
    1317                 : 
    1318 CBC     5185425 :         nscolumns[varattno].p_varno = rtindex;
    1319 GIC     5185425 :         nscolumns[varattno].p_varattno = varattno + 1;
    1320 CBC     5185425 :         nscolumns[varattno].p_vartype = attr->atttypid;
    1321         5185425 :         nscolumns[varattno].p_vartypmod = attr->atttypmod;
    1322         5185425 :         nscolumns[varattno].p_varcollid = attr->attcollation;
    1323 GIC     5185425 :         nscolumns[varattno].p_varnosyn = rtindex;
    1324         5185425 :         nscolumns[varattno].p_varattnosyn = varattno + 1;
    1325                 :     }
    1326                 : 
    1327                 :     /* ... and build the nsitem */
    1328          451589 :     nsitem = (ParseNamespaceItem *) palloc(sizeof(ParseNamespaceItem));
    1329          451589 :     nsitem->p_names = rte->eref;
    1330 CBC      451589 :     nsitem->p_rte = rte;
    1331          451589 :     nsitem->p_rtindex = rtindex;
    1332 GNC      451589 :     nsitem->p_perminfo = perminfo;
    1333 GIC      451589 :     nsitem->p_nscolumns = nscolumns;
    1334                 :     /* set default visibility flags; might get changed later */
    1335          451589 :     nsitem->p_rel_visible = true;
    1336          451589 :     nsitem->p_cols_visible = true;
    1337 CBC      451589 :     nsitem->p_lateral_only = false;
    1338 GIC      451589 :     nsitem->p_lateral_ok = true;
    1339                 : 
    1340          451589 :     return nsitem;
    1341                 : }
    1342                 : 
    1343                 : /*
    1344                 :  * buildNSItemFromLists
    1345                 :  *      Build a ParseNamespaceItem, given column type information in lists.
    1346                 :  *
    1347                 :  * rte: the new RangeTblEntry for the rel
    1348                 :  * rtindex: its index in the rangetable list
    1349                 :  * coltypes: per-column datatype OIDs
    1350 ECB             :  * coltypmods: per-column type modifiers
    1351                 :  * colcollation: per-column collation OIDs
    1352                 :  */
    1353                 : static ParseNamespaceItem *
    1354 GIC       54541 : buildNSItemFromLists(RangeTblEntry *rte, Index rtindex,
    1355                 :                      List *coltypes, List *coltypmods, List *colcollations)
    1356 ECB             : {
    1357                 :     ParseNamespaceItem *nsitem;
    1358                 :     ParseNamespaceColumn *nscolumns;
    1359 GIC       54541 :     int         maxattrs = list_length(coltypes);
    1360 ECB             :     int         varattno;
    1361                 :     ListCell   *lct;
    1362                 :     ListCell   *lcm;
    1363                 :     ListCell   *lcc;
    1364                 : 
    1365                 :     /* colnames must have the same number of entries as the nsitem */
    1366 CBC       54541 :     Assert(maxattrs == list_length(rte->eref->colnames));
    1367                 : 
    1368           54541 :     Assert(maxattrs == list_length(coltypmods));
    1369 GIC       54541 :     Assert(maxattrs == list_length(colcollations));
    1370                 : 
    1371 ECB             :     /* extract per-column data from the lists */
    1372                 :     nscolumns = (ParseNamespaceColumn *)
    1373 GIC       54541 :         palloc0(maxattrs * sizeof(ParseNamespaceColumn));
    1374 ECB             : 
    1375 CBC       54541 :     varattno = 0;
    1376          261826 :     forthree(lct, coltypes,
    1377 ECB             :              lcm, coltypmods,
    1378                 :              lcc, colcollations)
    1379                 :     {
    1380 CBC      207285 :         nscolumns[varattno].p_varno = rtindex;
    1381 GIC      207285 :         nscolumns[varattno].p_varattno = varattno + 1;
    1382          207285 :         nscolumns[varattno].p_vartype = lfirst_oid(lct);
    1383          207285 :         nscolumns[varattno].p_vartypmod = lfirst_int(lcm);
    1384 CBC      207285 :         nscolumns[varattno].p_varcollid = lfirst_oid(lcc);
    1385          207285 :         nscolumns[varattno].p_varnosyn = rtindex;
    1386          207285 :         nscolumns[varattno].p_varattnosyn = varattno + 1;
    1387          207285 :         varattno++;
    1388 ECB             :     }
    1389                 : 
    1390                 :     /* ... and build the nsitem */
    1391 CBC       54541 :     nsitem = (ParseNamespaceItem *) palloc(sizeof(ParseNamespaceItem));
    1392           54541 :     nsitem->p_names = rte->eref;
    1393           54541 :     nsitem->p_rte = rte;
    1394           54541 :     nsitem->p_rtindex = rtindex;
    1395 GIC       54541 :     nsitem->p_nscolumns = nscolumns;
    1396 ECB             :     /* set default visibility flags; might get changed later */
    1397 GIC       54541 :     nsitem->p_rel_visible = true;
    1398           54541 :     nsitem->p_cols_visible = true;
    1399           54541 :     nsitem->p_lateral_only = false;
    1400           54541 :     nsitem->p_lateral_ok = true;
    1401                 : 
    1402           54541 :     return nsitem;
    1403                 : }
    1404                 : 
    1405                 : /*
    1406                 :  * Open a table during parse analysis
    1407                 :  *
    1408                 :  * This is essentially just the same as table_openrv(), except that it caters
    1409                 :  * to some parser-specific error reporting needs, notably that it arranges
    1410 ECB             :  * to include the RangeVar's parse location in any resulting error.
    1411                 :  *
    1412                 :  * Note: properly, lockmode should be declared LOCKMODE not int, but that
    1413                 :  * would require importing storage/lock.h into parse_relation.h.  Since
    1414                 :  * LOCKMODE is typedef'd as int anyway, that seems like overkill.
    1415                 :  */
    1416                 : Relation
    1417 GIC      325308 : parserOpenTable(ParseState *pstate, const RangeVar *relation, int lockmode)
    1418                 : {
    1419                 :     Relation    rel;
    1420                 :     ParseCallbackState pcbstate;
    1421                 : 
    1422 CBC      325308 :     setup_parser_errposition_callback(&pcbstate, pstate, relation->location);
    1423 GIC      325308 :     rel = table_openrv_extended(relation, lockmode, true);
    1424 CBC      325307 :     if (rel == NULL)
    1425 ECB             :     {
    1426 GIC          86 :         if (relation->schemaname)
    1427 UIC           0 :             ereport(ERROR,
    1428                 :                     (errcode(ERRCODE_UNDEFINED_TABLE),
    1429 ECB             :                      errmsg("relation \"%s.%s\" does not exist",
    1430                 :                             relation->schemaname, relation->relname)));
    1431                 :         else
    1432                 :         {
    1433                 :             /*
    1434                 :              * An unqualified name might have been meant as a reference to
    1435                 :              * some not-yet-in-scope CTE.  The bare "does not exist" message
    1436                 :              * has proven remarkably unhelpful for figuring out such problems,
    1437                 :              * so we take pains to offer a specific hint.
    1438                 :              */
    1439 CBC          86 :             if (isFutureCTE(pstate, relation->relname))
    1440               3 :                 ereport(ERROR,
    1441 ECB             :                         (errcode(ERRCODE_UNDEFINED_TABLE),
    1442                 :                          errmsg("relation \"%s\" does not exist",
    1443                 :                                 relation->relname),
    1444                 :                          errdetail("There is a WITH item named \"%s\", but it cannot be referenced from this part of the query.",
    1445                 :                                    relation->relname),
    1446                 :                          errhint("Use WITH RECURSIVE, or re-order the WITH items to remove forward references.")));
    1447                 :             else
    1448 CBC          83 :                 ereport(ERROR,
    1449 ECB             :                         (errcode(ERRCODE_UNDEFINED_TABLE),
    1450                 :                          errmsg("relation \"%s\" does not exist",
    1451                 :                                 relation->relname)));
    1452                 :         }
    1453                 :     }
    1454 CBC      325221 :     cancel_parser_errposition_callback(&pcbstate);
    1455          325221 :     return rel;
    1456 ECB             : }
    1457                 : 
    1458                 : /*
    1459                 :  * Add an entry for a relation to the pstate's range table (p_rtable).
    1460                 :  * Then, construct and return a ParseNamespaceItem for the new RTE.
    1461                 :  *
    1462                 :  * We do not link the ParseNamespaceItem into the pstate here; it's the
    1463                 :  * caller's job to do that in the appropriate way.
    1464                 :  *
    1465                 :  * Note: formerly this checked for refname conflicts, but that's wrong.
    1466                 :  * Caller is responsible for checking for conflicts in the appropriate scope.
    1467                 :  */
    1468                 : ParseNamespaceItem *
    1469 GIC      272324 : addRangeTableEntry(ParseState *pstate,
    1470                 :                    RangeVar *relation,
    1471                 :                    Alias *alias,
    1472                 :                    bool inh,
    1473 ECB             :                    bool inFromCl)
    1474                 : {
    1475 GIC      272324 :     RangeTblEntry *rte = makeNode(RangeTblEntry);
    1476                 :     RTEPermissionInfo *perminfo;
    1477          272324 :     char       *refname = alias ? alias->aliasname : relation->relname;
    1478                 :     LOCKMODE    lockmode;
    1479 ECB             :     Relation    rel;
    1480                 :     ParseNamespaceItem *nsitem;
    1481                 : 
    1482 GIC      272324 :     Assert(pstate != NULL);
    1483 ECB             : 
    1484 GBC      272324 :     rte->rtekind = RTE_RELATION;
    1485 GIC      272324 :     rte->alias = alias;
    1486                 : 
    1487                 :     /*
    1488                 :      * Identify the type of lock we'll need on this relation.  It's not the
    1489                 :      * query's target table (that case is handled elsewhere), so we need
    1490                 :      * either RowShareLock if it's locked by FOR UPDATE/SHARE, or plain
    1491                 :      * AccessShareLock otherwise.
    1492                 :      */
    1493          272324 :     lockmode = isLockedRefname(pstate, refname) ? RowShareLock : AccessShareLock;
    1494                 : 
    1495                 :     /*
    1496 ECB             :      * Get the rel's OID.  This access also ensures that we have an up-to-date
    1497                 :      * relcache entry for the rel.  Since this is typically the first access
    1498                 :      * to a rel in a statement, we must open the rel with the proper lockmode.
    1499                 :      */
    1500 GIC      272324 :     rel = parserOpenTable(pstate, relation, lockmode);
    1501          272247 :     rte->relid = RelationGetRelid(rel);
    1502          272247 :     rte->relkind = rel->rd_rel->relkind;
    1503          272247 :     rte->rellockmode = lockmode;
    1504                 : 
    1505 ECB             :     /*
    1506                 :      * Build the list of effective column names using user-supplied aliases
    1507                 :      * and/or actual column names.
    1508                 :      */
    1509 GIC      272247 :     rte->eref = makeAlias(refname, NIL);
    1510          272247 :     buildRelationAliases(rel->rd_att, alias, rte->eref);
    1511 ECB             : 
    1512                 :     /*
    1513                 :      * Set flags and initialize access permissions.
    1514                 :      *
    1515                 :      * The initial default on access checks is always check-for-READ-access,
    1516                 :      * which is the right thing for all except target tables.
    1517                 :      */
    1518 GIC      272244 :     rte->lateral = false;
    1519          272244 :     rte->inh = inh;
    1520          272244 :     rte->inFromCl = inFromCl;
    1521                 : 
    1522 GNC      272244 :     perminfo = addRTEPermissionInfo(&pstate->p_rteperminfos, rte);
    1523          272244 :     perminfo->requiredPerms = ACL_SELECT;
    1524                 : 
    1525                 :     /*
    1526                 :      * Add completed RTE to pstate's range table list, so that we know its
    1527                 :      * index.  But we don't add it to the join list --- caller must do that if
    1528 ECB             :      * appropriate.
    1529                 :      */
    1530 CBC      272244 :     pstate->p_rtable = lappend(pstate->p_rtable, rte);
    1531                 : 
    1532                 :     /*
    1533                 :      * Build a ParseNamespaceItem, but don't add it to the pstate's namespace
    1534                 :      * list --- caller must do that if appropriate.
    1535 ECB             :      */
    1536 GIC      272244 :     nsitem = buildNSItemFromTupleDesc(rte, list_length(pstate->p_rtable),
    1537                 :                                       perminfo, rel->rd_att);
    1538 ECB             : 
    1539                 :     /*
    1540                 :      * Drop the rel refcount, but keep the access lock till end of transaction
    1541                 :      * so that the table can't be deleted or have its schema modified
    1542                 :      * underneath us.
    1543                 :      */
    1544 GIC      272244 :     table_close(rel, NoLock);
    1545                 : 
    1546 CBC      272244 :     return nsitem;
    1547                 : }
    1548                 : 
    1549                 : /*
    1550                 :  * Add an entry for a relation to the pstate's range table (p_rtable).
    1551                 :  * Then, construct and return a ParseNamespaceItem for the new RTE.
    1552                 :  *
    1553 ECB             :  * This is just like addRangeTableEntry() except that it makes an RTE
    1554                 :  * given an already-open relation instead of a RangeVar reference.
    1555                 :  *
    1556                 :  * lockmode is the lock type required for query execution; it must be one
    1557                 :  * of AccessShareLock, RowShareLock, or RowExclusiveLock depending on the
    1558                 :  * RTE's role within the query.  The caller must hold that lock mode
    1559                 :  * or a stronger one.
    1560                 :  *
    1561                 :  * Note: properly, lockmode should be declared LOCKMODE not int, but that
    1562                 :  * would require importing storage/lock.h into parse_relation.h.  Since
    1563                 :  * LOCKMODE is typedef'd as int anyway, that seems like overkill.
    1564                 :  */
    1565                 : ParseNamespaceItem *
    1566 GIC      149611 : addRangeTableEntryForRelation(ParseState *pstate,
    1567                 :                               Relation rel,
    1568                 :                               int lockmode,
    1569                 :                               Alias *alias,
    1570                 :                               bool inh,
    1571 ECB             :                               bool inFromCl)
    1572                 : {
    1573 CBC      149611 :     RangeTblEntry *rte = makeNode(RangeTblEntry);
    1574                 :     RTEPermissionInfo *perminfo;
    1575 GIC      149611 :     char       *refname = alias ? alias->aliasname : RelationGetRelationName(rel);
    1576 ECB             : 
    1577 CBC      149611 :     Assert(pstate != NULL);
    1578                 : 
    1579 GIC      149611 :     Assert(lockmode == AccessShareLock ||
    1580                 :            lockmode == RowShareLock ||
    1581                 :            lockmode == RowExclusiveLock);
    1582          149611 :     Assert(CheckRelationLockedByMe(rel, lockmode, true));
    1583                 : 
    1584 CBC      149611 :     rte->rtekind = RTE_RELATION;
    1585 GIC      149611 :     rte->alias = alias;
    1586          149611 :     rte->relid = RelationGetRelid(rel);
    1587          149611 :     rte->relkind = rel->rd_rel->relkind;
    1588          149611 :     rte->rellockmode = lockmode;
    1589                 : 
    1590 ECB             :     /*
    1591                 :      * Build the list of effective column names using user-supplied aliases
    1592                 :      * and/or actual column names.
    1593                 :      */
    1594 GIC      149611 :     rte->eref = makeAlias(refname, NIL);
    1595          149611 :     buildRelationAliases(rel->rd_att, alias, rte->eref);
    1596                 : 
    1597                 :     /*
    1598                 :      * Set flags and initialize access permissions.
    1599                 :      *
    1600 ECB             :      * The initial default on access checks is always check-for-READ-access,
    1601                 :      * which is the right thing for all except target tables.
    1602                 :      */
    1603 GIC      149611 :     rte->lateral = false;
    1604          149611 :     rte->inh = inh;
    1605          149611 :     rte->inFromCl = inFromCl;
    1606                 : 
    1607 GNC      149611 :     perminfo = addRTEPermissionInfo(&pstate->p_rteperminfos, rte);
    1608          149611 :     perminfo->requiredPerms = ACL_SELECT;
    1609                 : 
    1610                 :     /*
    1611                 :      * Add completed RTE to pstate's range table list, so that we know its
    1612                 :      * index.  But we don't add it to the join list --- caller must do that if
    1613                 :      * appropriate.
    1614                 :      */
    1615 GIC      149611 :     pstate->p_rtable = lappend(pstate->p_rtable, rte);
    1616 ECB             : 
    1617                 :     /*
    1618                 :      * Build a ParseNamespaceItem, but don't add it to the pstate's namespace
    1619                 :      * list --- caller must do that if appropriate.
    1620                 :      */
    1621 GIC      149611 :     return buildNSItemFromTupleDesc(rte, list_length(pstate->p_rtable),
    1622                 :                                     perminfo, rel->rd_att);
    1623 ECB             : }
    1624                 : 
    1625                 : /*
    1626                 :  * Add an entry for a subquery to the pstate's range table (p_rtable).
    1627                 :  * Then, construct and return a ParseNamespaceItem for the new RTE.
    1628                 :  *
    1629                 :  * This is much like addRangeTableEntry() except that it makes a subquery RTE.
    1630                 :  *
    1631                 :  * If the subquery does not have an alias, the auto-generated relation name in
    1632                 :  * the returned ParseNamespaceItem will be marked as not visible, and so only
    1633                 :  * unqualified references to the subquery columns will be allowed, and the
    1634                 :  * relation name will not conflict with others in the pstate's namespace list.
    1635                 :  */
    1636                 : ParseNamespaceItem *
    1637 GIC       47344 : addRangeTableEntryForSubquery(ParseState *pstate,
    1638 ECB             :                               Query *subquery,
    1639                 :                               Alias *alias,
    1640                 :                               bool lateral,
    1641                 :                               bool inFromCl)
    1642                 : {
    1643 GIC       47344 :     RangeTblEntry *rte = makeNode(RangeTblEntry);
    1644                 :     Alias      *eref;
    1645                 :     int         numaliases;
    1646                 :     List       *coltypes,
    1647 ECB             :                *coltypmods,
    1648                 :                *colcollations;
    1649                 :     int         varattno;
    1650                 :     ListCell   *tlistitem;
    1651                 :     ParseNamespaceItem *nsitem;
    1652                 : 
    1653 GIC       47344 :     Assert(pstate != NULL);
    1654                 : 
    1655           47344 :     rte->rtekind = RTE_SUBQUERY;
    1656           47344 :     rte->subquery = subquery;
    1657 CBC       47344 :     rte->alias = alias;
    1658 ECB             : 
    1659 GNC       47344 :     eref = alias ? copyObject(alias) : makeAlias("unnamed_subquery", NIL);
    1660 GIC       47344 :     numaliases = list_length(eref->colnames);
    1661 ECB             : 
    1662                 :     /* fill in any unspecified alias columns, and extract column type info */
    1663 GIC       47344 :     coltypes = coltypmods = colcollations = NIL;
    1664           47344 :     varattno = 0;
    1665          240011 :     foreach(tlistitem, subquery->targetList)
    1666                 :     {
    1667          192667 :         TargetEntry *te = (TargetEntry *) lfirst(tlistitem);
    1668                 : 
    1669 CBC      192667 :         if (te->resjunk)
    1670 GIC         108 :             continue;
    1671          192559 :         varattno++;
    1672          192559 :         Assert(varattno == te->resno);
    1673          192559 :         if (varattno > numaliases)
    1674                 :         {
    1675 ECB             :             char       *attrname;
    1676                 : 
    1677 GIC      158439 :             attrname = pstrdup(te->resname);
    1678          158439 :             eref->colnames = lappend(eref->colnames, makeString(attrname));
    1679                 :         }
    1680          192559 :         coltypes = lappend_oid(coltypes,
    1681          192559 :                                exprType((Node *) te->expr));
    1682          192559 :         coltypmods = lappend_int(coltypmods,
    1683          192559 :                                  exprTypmod((Node *) te->expr));
    1684          192559 :         colcollations = lappend_oid(colcollations,
    1685          192559 :                                     exprCollation((Node *) te->expr));
    1686                 :     }
    1687           47344 :     if (varattno < numaliases)
    1688               3 :         ereport(ERROR,
    1689                 :                 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
    1690                 :                  errmsg("table \"%s\" has %d columns available but %d columns specified",
    1691                 :                         eref->aliasname, varattno, numaliases)));
    1692                 : 
    1693           47341 :     rte->eref = eref;
    1694                 : 
    1695                 :     /*
    1696                 :      * Set flags.
    1697 ECB             :      *
    1698                 :      * Subqueries are never checked for access rights, so no need to perform
    1699                 :      * addRTEPermissionInfo().
    1700                 :      */
    1701 GIC       47341 :     rte->lateral = lateral;
    1702           47341 :     rte->inh = false;            /* never true for subqueries */
    1703           47341 :     rte->inFromCl = inFromCl;
    1704                 : 
    1705 ECB             :     /*
    1706                 :      * Add completed RTE to pstate's range table list, so that we know its
    1707                 :      * index.  But we don't add it to the join list --- caller must do that if
    1708                 :      * appropriate.
    1709                 :      */
    1710 GIC       47341 :     pstate->p_rtable = lappend(pstate->p_rtable, rte);
    1711 ECB             : 
    1712                 :     /*
    1713                 :      * Build a ParseNamespaceItem, but don't add it to the pstate's namespace
    1714                 :      * list --- caller must do that if appropriate.
    1715                 :      */
    1716 GNC       47341 :     nsitem = buildNSItemFromLists(rte, list_length(pstate->p_rtable),
    1717                 :                                   coltypes, coltypmods, colcollations);
    1718                 : 
    1719                 :     /*
    1720                 :      * Mark it visible as a relation name only if it had a user-written alias.
    1721                 :      */
    1722           47341 :     nsitem->p_rel_visible = (alias != NULL);
    1723                 : 
    1724           47341 :     return nsitem;
    1725 ECB             : }
    1726                 : 
    1727                 : /*
    1728                 :  * Add an entry for a function (or functions) to the pstate's range table
    1729                 :  * (p_rtable).  Then, construct and return a ParseNamespaceItem for the new RTE.
    1730                 :  *
    1731                 :  * This is much like addRangeTableEntry() except that it makes a function RTE.
    1732                 :  */
    1733                 : ParseNamespaceItem *
    1734 GIC       29539 : addRangeTableEntryForFunction(ParseState *pstate,
    1735 ECB             :                               List *funcnames,
    1736                 :                               List *funcexprs,
    1737                 :                               List *coldeflists,
    1738                 :                               RangeFunction *rangefunc,
    1739                 :                               bool lateral,
    1740                 :                               bool inFromCl)
    1741                 : {
    1742 CBC       29539 :     RangeTblEntry *rte = makeNode(RangeTblEntry);
    1743           29539 :     Alias      *alias = rangefunc->alias;
    1744                 :     Alias      *eref;
    1745                 :     char       *aliasname;
    1746 GIC       29539 :     int         nfuncs = list_length(funcexprs);
    1747                 :     TupleDesc  *functupdescs;
    1748 ECB             :     TupleDesc   tupdesc;
    1749                 :     ListCell   *lc1,
    1750                 :                *lc2,
    1751                 :                *lc3;
    1752                 :     int         i;
    1753                 :     int         j;
    1754                 :     int         funcno;
    1755                 :     int         natts,
    1756                 :                 totalatts;
    1757                 : 
    1758 CBC       29539 :     Assert(pstate != NULL);
    1759                 : 
    1760 GIC       29539 :     rte->rtekind = RTE_FUNCTION;
    1761           29539 :     rte->relid = InvalidOid;
    1762           29539 :     rte->subquery = NULL;
    1763           29539 :     rte->functions = NIL;        /* we'll fill this list below */
    1764           29539 :     rte->funcordinality = rangefunc->ordinality;
    1765 CBC       29539 :     rte->alias = alias;
    1766                 : 
    1767                 :     /*
    1768                 :      * Choose the RTE alias name.  We default to using the first function's
    1769                 :      * name even when there's more than one; which is maybe arguable but beats
    1770                 :      * using something constant like "table".
    1771 ECB             :      */
    1772 GIC       29539 :     if (alias)
    1773           21285 :         aliasname = alias->aliasname;
    1774                 :     else
    1775            8254 :         aliasname = linitial(funcnames);
    1776                 : 
    1777 CBC       29539 :     eref = makeAlias(aliasname, NIL);
    1778 GIC       29539 :     rte->eref = eref;
    1779 ECB             : 
    1780                 :     /* Process each function ... */
    1781 GIC       29539 :     functupdescs = (TupleDesc *) palloc(nfuncs * sizeof(TupleDesc));
    1782                 : 
    1783           29539 :     totalatts = 0;
    1784           29539 :     funcno = 0;
    1785           59198 :     forthree(lc1, funcexprs, lc2, funcnames, lc3, coldeflists)
    1786                 :     {
    1787           29686 :         Node       *funcexpr = (Node *) lfirst(lc1);
    1788           29686 :         char       *funcname = (char *) lfirst(lc2);
    1789 CBC       29686 :         List       *coldeflist = (List *) lfirst(lc3);
    1790 GIC       29686 :         RangeTblFunction *rtfunc = makeNode(RangeTblFunction);
    1791                 :         TypeFuncClass functypclass;
    1792                 :         Oid         funcrettype;
    1793                 : 
    1794                 :         /* Initialize RangeTblFunction node */
    1795           29686 :         rtfunc->funcexpr = funcexpr;
    1796           29686 :         rtfunc->funccolnames = NIL;
    1797 CBC       29686 :         rtfunc->funccoltypes = NIL;
    1798           29686 :         rtfunc->funccoltypmods = NIL;
    1799 GIC       29686 :         rtfunc->funccolcollations = NIL;
    1800           29686 :         rtfunc->funcparams = NULL;   /* not set until planning */
    1801 ECB             : 
    1802                 :         /*
    1803                 :          * Now determine if the function returns a simple or composite type.
    1804                 :          */
    1805 GIC       29686 :         functypclass = get_expr_result_type(funcexpr,
    1806                 :                                             &funcrettype,
    1807                 :                                             &tupdesc);
    1808                 : 
    1809                 :         /*
    1810                 :          * A coldeflist is required if the function returns RECORD and hasn't
    1811                 :          * got a predetermined record type, and is prohibited otherwise.  This
    1812                 :          * can be a bit confusing, so we expend some effort on delivering a
    1813 ECB             :          * relevant error message.
    1814                 :          */
    1815 CBC       29686 :         if (coldeflist != NIL)
    1816 ECB             :         {
    1817 CBC         371 :             switch (functypclass)
    1818 ECB             :             {
    1819 CBC         362 :                 case TYPEFUNC_RECORD:
    1820 ECB             :                     /* ok */
    1821 GIC         362 :                     break;
    1822               6 :                 case TYPEFUNC_COMPOSITE:
    1823                 :                 case TYPEFUNC_COMPOSITE_DOMAIN:
    1824                 : 
    1825                 :                     /*
    1826                 :                      * If the function's raw result type is RECORD, we must
    1827 ECB             :                      * have resolved it using its OUT parameters.  Otherwise,
    1828                 :                      * it must have a named composite type.
    1829                 :                      */
    1830 CBC           6 :                     if (exprType(funcexpr) == RECORDOID)
    1831 GIC           3 :                         ereport(ERROR,
    1832 ECB             :                                 (errcode(ERRCODE_SYNTAX_ERROR),
    1833                 :                                  errmsg("a column definition list is redundant for a function with OUT parameters"),
    1834                 :                                  parser_errposition(pstate,
    1835                 :                                                     exprLocation((Node *) coldeflist))));
    1836                 :                     else
    1837 GIC           3 :                         ereport(ERROR,
    1838 ECB             :                                 (errcode(ERRCODE_SYNTAX_ERROR),
    1839                 :                                  errmsg("a column definition list is redundant for a function returning a named composite type"),
    1840                 :                                  parser_errposition(pstate,
    1841                 :                                                     exprLocation((Node *) coldeflist))));
    1842                 :                     break;
    1843 CBC           3 :                 default:
    1844               3 :                     ereport(ERROR,
    1845 ECB             :                             (errcode(ERRCODE_SYNTAX_ERROR),
    1846                 :                              errmsg("a column definition list is only allowed for functions returning \"record\""),
    1847                 :                              parser_errposition(pstate,
    1848                 :                                                 exprLocation((Node *) coldeflist))));
    1849                 :                     break;
    1850                 :             }
    1851                 :         }
    1852                 :         else
    1853                 :         {
    1854 CBC       29315 :             if (functypclass == TYPEFUNC_RECORD)
    1855              15 :                 ereport(ERROR,
    1856                 :                         (errcode(ERRCODE_SYNTAX_ERROR),
    1857                 :                          errmsg("a column definition list is required for functions returning \"record\""),
    1858                 :                          parser_errposition(pstate, exprLocation(funcexpr))));
    1859                 :         }
    1860 ECB             : 
    1861 GIC       29662 :         if (functypclass == TYPEFUNC_COMPOSITE ||
    1862                 :             functypclass == TYPEFUNC_COMPOSITE_DOMAIN)
    1863                 :         {
    1864                 :             /* Composite data type, e.g. a table's row type */
    1865           20625 :             Assert(tupdesc);
    1866                 :         }
    1867            9037 :         else if (functypclass == TYPEFUNC_SCALAR)
    1868                 :         {
    1869                 :             /* Base data type, i.e. scalar */
    1870 CBC        8672 :             tupdesc = CreateTemplateTupleDesc(1);
    1871 GIC       17344 :             TupleDescInitEntry(tupdesc,
    1872 ECB             :                                (AttrNumber) 1,
    1873 GIC        8672 :                                chooseScalarFunctionAlias(funcexpr, funcname,
    1874 ECB             :                                                          alias, nfuncs),
    1875                 :                                funcrettype,
    1876                 :                                exprTypmod(funcexpr),
    1877                 :                                0);
    1878 GIC        8672 :             TupleDescInitEntryCollation(tupdesc,
    1879                 :                                         (AttrNumber) 1,
    1880                 :                                         exprCollation(funcexpr));
    1881                 :         }
    1882             365 :         else if (functypclass == TYPEFUNC_RECORD)
    1883                 :         {
    1884                 :             ListCell   *col;
    1885 ECB             : 
    1886                 :             /*
    1887                 :              * Use the column definition list to construct a tupdesc and fill
    1888                 :              * in the RangeTblFunction's lists.  Limit number of columns to
    1889                 :              * MaxHeapAttributeNumber, because CheckAttributeNamesTypes will.
    1890                 :              */
    1891 GIC         362 :             if (list_length(coldeflist) > MaxHeapAttributeNumber)
    1892 LBC           0 :                 ereport(ERROR,
    1893                 :                         (errcode(ERRCODE_TOO_MANY_COLUMNS),
    1894                 :                          errmsg("column definition lists can have at most %d entries",
    1895                 :                                 MaxHeapAttributeNumber),
    1896                 :                          parser_errposition(pstate,
    1897                 :                                             exprLocation((Node *) coldeflist))));
    1898 CBC         362 :             tupdesc = CreateTemplateTupleDesc(list_length(coldeflist));
    1899             362 :             i = 1;
    1900 GIC        1210 :             foreach(col, coldeflist)
    1901                 :             {
    1902             848 :                 ColumnDef  *n = (ColumnDef *) lfirst(col);
    1903                 :                 char       *attrname;
    1904                 :                 Oid         attrtype;
    1905                 :                 int32       attrtypmod;
    1906                 :                 Oid         attrcollation;
    1907                 : 
    1908             848 :                 attrname = n->colname;
    1909 CBC         848 :                 if (n->typeName->setof)
    1910 LBC           0 :                     ereport(ERROR,
    1911                 :                             (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
    1912                 :                              errmsg("column \"%s\" cannot be declared SETOF",
    1913                 :                                     attrname),
    1914                 :                              parser_errposition(pstate, n->location)));
    1915 GIC         848 :                 typenameTypeIdAndMod(pstate, n->typeName,
    1916 ECB             :                                      &attrtype, &attrtypmod);
    1917 GIC         848 :                 attrcollation = GetColumnDefCollation(pstate, n, attrtype);
    1918             848 :                 TupleDescInitEntry(tupdesc,
    1919             848 :                                    (AttrNumber) i,
    1920 ECB             :                                    attrname,
    1921                 :                                    attrtype,
    1922                 :                                    attrtypmod,
    1923                 :                                    0);
    1924 GIC         848 :                 TupleDescInitEntryCollation(tupdesc,
    1925 CBC         848 :                                             (AttrNumber) i,
    1926 ECB             :                                             attrcollation);
    1927 GIC         848 :                 rtfunc->funccolnames = lappend(rtfunc->funccolnames,
    1928 CBC         848 :                                                makeString(pstrdup(attrname)));
    1929 GIC         848 :                 rtfunc->funccoltypes = lappend_oid(rtfunc->funccoltypes,
    1930                 :                                                    attrtype);
    1931             848 :                 rtfunc->funccoltypmods = lappend_int(rtfunc->funccoltypmods,
    1932                 :                                                      attrtypmod);
    1933 CBC         848 :                 rtfunc->funccolcollations = lappend_oid(rtfunc->funccolcollations,
    1934                 :                                                         attrcollation);
    1935                 : 
    1936 GIC         848 :                 i++;
    1937 ECB             :             }
    1938                 : 
    1939                 :             /*
    1940                 :              * Ensure that the coldeflist defines a legal set of names (no
    1941                 :              * duplicates, but we needn't worry about system column names) and
    1942                 :              * datatypes.  Although we mostly can't allow pseudo-types, it
    1943                 :              * seems safe to allow RECORD and RECORD[], since values within
    1944                 :              * those type classes are self-identifying at runtime, and the
    1945                 :              * coldeflist doesn't represent anything that will be visible to
    1946                 :              * other sessions.
    1947 EUB             :              */
    1948 GIC         362 :             CheckAttributeNamesTypes(tupdesc, RELKIND_COMPOSITE_TYPE,
    1949                 :                                      CHKATYPE_ANYRECORD);
    1950                 :         }
    1951                 :         else
    1952               3 :             ereport(ERROR,
    1953 ECB             :                     (errcode(ERRCODE_DATATYPE_MISMATCH),
    1954                 :                      errmsg("function \"%s\" in FROM has unsupported return type %s",
    1955                 :                             funcname, format_type_be(funcrettype)),
    1956                 :                      parser_errposition(pstate, exprLocation(funcexpr))));
    1957                 : 
    1958                 :         /* Finish off the RangeTblFunction and add it to the RTE's list */
    1959 GIC       29659 :         rtfunc->funccolcount = tupdesc->natts;
    1960           29659 :         rte->functions = lappend(rte->functions, rtfunc);
    1961                 : 
    1962                 :         /* Save the tupdesc for use below */
    1963 CBC       29659 :         functupdescs[funcno] = tupdesc;
    1964           29659 :         totalatts += tupdesc->natts;
    1965 GBC       29659 :         funcno++;
    1966                 :     }
    1967                 : 
    1968                 :     /*
    1969                 :      * If there's more than one function, or we want an ordinality column, we
    1970 ECB             :      * have to produce a merged tupdesc.
    1971                 :      */
    1972 CBC       29512 :     if (nfuncs > 1 || rangefunc->ordinality)
    1973 ECB             :     {
    1974 CBC         335 :         if (rangefunc->ordinality)
    1975 GIC         299 :             totalatts++;
    1976                 : 
    1977                 :         /* Disallow more columns than will fit in a tuple */
    1978             335 :         if (totalatts > MaxTupleAttributeNumber)
    1979 LBC           0 :             ereport(ERROR,
    1980 ECB             :                     (errcode(ERRCODE_TOO_MANY_COLUMNS),
    1981                 :                      errmsg("functions in FROM can return at most %d columns",
    1982                 :                             MaxTupleAttributeNumber),
    1983                 :                      parser_errposition(pstate,
    1984                 :                                         exprLocation((Node *) funcexprs))));
    1985                 : 
    1986                 :         /* Merge the tuple descs of each function into a composite one */
    1987 GIC         335 :         tupdesc = CreateTemplateTupleDesc(totalatts);
    1988 CBC         335 :         natts = 0;
    1989 GIC         817 :         for (i = 0; i < nfuncs; i++)
    1990                 :         {
    1991 CBC        1239 :             for (j = 1; j <= functupdescs[i]->natts; j++)
    1992 GIC         757 :                 TupleDescCopyEntry(tupdesc, ++natts, functupdescs[i], j);
    1993                 :         }
    1994                 : 
    1995                 :         /* Add the ordinality column if needed */
    1996             335 :         if (rangefunc->ordinality)
    1997                 :         {
    1998             299 :             TupleDescInitEntry(tupdesc,
    1999             299 :                                (AttrNumber) ++natts,
    2000                 :                                "ordinality",
    2001                 :                                INT8OID,
    2002                 :                                -1,
    2003 ECB             :                                0);
    2004                 :             /* no need to set collation */
    2005                 :         }
    2006                 : 
    2007 CBC         335 :         Assert(natts == totalatts);
    2008                 :     }
    2009                 :     else
    2010                 :     {
    2011                 :         /* We can just use the single function's tupdesc as-is */
    2012 GIC       29177 :         tupdesc = functupdescs[0];
    2013                 :     }
    2014 ECB             : 
    2015                 :     /* Use the tupdesc while assigning column aliases for the RTE */
    2016 GIC       29512 :     buildRelationAliases(tupdesc, alias, eref);
    2017                 : 
    2018 ECB             :     /*
    2019                 :      * Set flags and access permissions.
    2020                 :      *
    2021                 :      * Functions are never checked for access rights (at least, not by
    2022                 :      * ExecCheckPermissions()), so no need to perform addRTEPermissionInfo().
    2023                 :      */
    2024 GIC       29512 :     rte->lateral = lateral;
    2025           29512 :     rte->inh = false;            /* never true for functions */
    2026           29512 :     rte->inFromCl = inFromCl;
    2027 ECB             : 
    2028                 :     /*
    2029                 :      * Add completed RTE to pstate's range table list, so that we know its
    2030                 :      * index.  But we don't add it to the join list --- caller must do that if
    2031                 :      * appropriate.
    2032                 :      */
    2033 GIC       29512 :     pstate->p_rtable = lappend(pstate->p_rtable, rte);
    2034                 : 
    2035 ECB             :     /*
    2036                 :      * Build a ParseNamespaceItem, but don't add it to the pstate's namespace
    2037                 :      * list --- caller must do that if appropriate.
    2038                 :      */
    2039 GNC       29512 :     return buildNSItemFromTupleDesc(rte, list_length(pstate->p_rtable), NULL,
    2040 ECB             :                                     tupdesc);
    2041                 : }
    2042                 : 
    2043                 : /*
    2044                 :  * Add an entry for a table function to the pstate's range table (p_rtable).
    2045                 :  * Then, construct and return a ParseNamespaceItem for the new RTE.
    2046                 :  *
    2047                 :  * This is much like addRangeTableEntry() except that it makes a tablefunc RTE.
    2048                 :  */
    2049                 : ParseNamespaceItem *
    2050 GIC         107 : addRangeTableEntryForTableFunc(ParseState *pstate,
    2051                 :                                TableFunc *tf,
    2052                 :                                Alias *alias,
    2053                 :                                bool lateral,
    2054                 :                                bool inFromCl)
    2055 ECB             : {
    2056 GIC         107 :     RangeTblEntry *rte = makeNode(RangeTblEntry);
    2057                 :     char       *refname;
    2058                 :     Alias      *eref;
    2059                 :     int         numaliases;
    2060 ECB             : 
    2061 GIC         107 :     Assert(pstate != NULL);
    2062                 : 
    2063                 :     /* Disallow more columns than will fit in a tuple */
    2064 CBC         107 :     if (list_length(tf->colnames) > MaxTupleAttributeNumber)
    2065 UIC           0 :         ereport(ERROR,
    2066                 :                 (errcode(ERRCODE_TOO_MANY_COLUMNS),
    2067                 :                  errmsg("functions in FROM can return at most %d columns",
    2068                 :                         MaxTupleAttributeNumber),
    2069                 :                  parser_errposition(pstate,
    2070                 :                                     exprLocation((Node *) tf))));
    2071 GIC         107 :     Assert(list_length(tf->coltypes) == list_length(tf->colnames));
    2072 CBC         107 :     Assert(list_length(tf->coltypmods) == list_length(tf->colnames));
    2073             107 :     Assert(list_length(tf->colcollations) == list_length(tf->colnames));
    2074 ECB             : 
    2075 GIC         107 :     refname = alias ? alias->aliasname : pstrdup("xmltable");
    2076                 : 
    2077             107 :     rte->rtekind = RTE_TABLEFUNC;
    2078             107 :     rte->relid = InvalidOid;
    2079             107 :     rte->subquery = NULL;
    2080             107 :     rte->tablefunc = tf;
    2081 CBC         107 :     rte->coltypes = tf->coltypes;
    2082 GIC         107 :     rte->coltypmods = tf->coltypmods;
    2083             107 :     rte->colcollations = tf->colcollations;
    2084             107 :     rte->alias = alias;
    2085                 : 
    2086             107 :     eref = alias ? copyObject(alias) : makeAlias(refname, NIL);
    2087 CBC         107 :     numaliases = list_length(eref->colnames);
    2088                 : 
    2089                 :     /* fill in any unspecified alias columns */
    2090 GIC         107 :     if (numaliases < list_length(tf->colnames))
    2091             104 :         eref->colnames = list_concat(eref->colnames,
    2092             104 :                                      list_copy_tail(tf->colnames, numaliases));
    2093                 : 
    2094             107 :     if (numaliases > list_length(tf->colnames))
    2095               3 :         ereport(ERROR,
    2096                 :                 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
    2097                 :                  errmsg("%s function has %d columns available but %d columns specified",
    2098 ECB             :                         "XMLTABLE",
    2099                 :                         list_length(tf->colnames), numaliases)));
    2100                 : 
    2101 GIC         104 :     rte->eref = eref;
    2102                 : 
    2103                 :     /*
    2104 ECB             :      * Set flags and access permissions.
    2105                 :      *
    2106                 :      * Tablefuncs are never checked for access rights (at least, not by
    2107                 :      * ExecCheckPermissions()), so no need to perform addRTEPermissionInfo().
    2108                 :      */
    2109 CBC         104 :     rte->lateral = lateral;
    2110 GIC         104 :     rte->inh = false;            /* never true for tablefunc RTEs */
    2111             104 :     rte->inFromCl = inFromCl;
    2112 ECB             : 
    2113                 :     /*
    2114                 :      * Add completed RTE to pstate's range table list, so that we know its
    2115                 :      * index.  But we don't add it to the join list --- caller must do that if
    2116                 :      * appropriate.
    2117                 :      */
    2118 CBC         104 :     pstate->p_rtable = lappend(pstate->p_rtable, rte);
    2119 ECB             : 
    2120                 :     /*
    2121                 :      * Build a ParseNamespaceItem, but don't add it to the pstate's namespace
    2122                 :      * list --- caller must do that if appropriate.
    2123                 :      */
    2124 CBC         104 :     return buildNSItemFromLists(rte, list_length(pstate->p_rtable),
    2125 ECB             :                                 rte->coltypes, rte->coltypmods,
    2126                 :                                 rte->colcollations);
    2127                 : }
    2128                 : 
    2129                 : /*
    2130                 :  * Add an entry for a VALUES list to the pstate's range table (p_rtable).
    2131                 :  * Then, construct and return a ParseNamespaceItem for the new RTE.
    2132                 :  *
    2133                 :  * This is much like addRangeTableEntry() except that it makes a values RTE.
    2134                 :  */
    2135                 : ParseNamespaceItem *
    2136 CBC        4534 : addRangeTableEntryForValues(ParseState *pstate,
    2137                 :                             List *exprs,
    2138                 :                             List *coltypes,
    2139                 :                             List *coltypmods,
    2140                 :                             List *colcollations,
    2141                 :                             Alias *alias,
    2142 ECB             :                             bool lateral,
    2143                 :                             bool inFromCl)
    2144                 : {
    2145 GIC        4534 :     RangeTblEntry *rte = makeNode(RangeTblEntry);
    2146            4534 :     char       *refname = alias ? alias->aliasname : pstrdup("*VALUES*");
    2147                 :     Alias      *eref;
    2148                 :     int         numaliases;
    2149                 :     int         numcolumns;
    2150 ECB             : 
    2151 CBC        4534 :     Assert(pstate != NULL);
    2152 ECB             : 
    2153 GIC        4534 :     rte->rtekind = RTE_VALUES;
    2154            4534 :     rte->relid = InvalidOid;
    2155            4534 :     rte->subquery = NULL;
    2156            4534 :     rte->values_lists = exprs;
    2157            4534 :     rte->coltypes = coltypes;
    2158            4534 :     rte->coltypmods = coltypmods;
    2159 CBC        4534 :     rte->colcollations = colcollations;
    2160 GIC        4534 :     rte->alias = alias;
    2161                 : 
    2162            4534 :     eref = alias ? copyObject(alias) : makeAlias(refname, NIL);
    2163                 : 
    2164                 :     /* fill in any unspecified alias columns */
    2165 CBC        4534 :     numcolumns = list_length((List *) linitial(exprs));
    2166 GIC        4534 :     numaliases = list_length(eref->colnames);
    2167           11855 :     while (numaliases < numcolumns)
    2168                 :     {
    2169                 :         char        attrname[64];
    2170                 : 
    2171            7321 :         numaliases++;
    2172            7321 :         snprintf(attrname, sizeof(attrname), "column%d", numaliases);
    2173            7321 :         eref->colnames = lappend(eref->colnames,
    2174            7321 :                                  makeString(pstrdup(attrname)));
    2175                 :     }
    2176            4534 :     if (numcolumns < numaliases)
    2177 LBC           0 :         ereport(ERROR,
    2178                 :                 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
    2179                 :                  errmsg("VALUES lists \"%s\" have %d columns available but %d columns specified",
    2180                 :                         refname, numcolumns, numaliases)));
    2181                 : 
    2182 GIC        4534 :     rte->eref = eref;
    2183                 : 
    2184                 :     /*
    2185                 :      * Set flags and access permissions.
    2186 ECB             :      *
    2187                 :      * Subqueries are never checked for access rights, so no need to perform
    2188                 :      * addRTEPermissionInfo().
    2189                 :      */
    2190 GIC        4534 :     rte->lateral = lateral;
    2191            4534 :     rte->inh = false;            /* never true for values RTEs */
    2192            4534 :     rte->inFromCl = inFromCl;
    2193 ECB             : 
    2194                 :     /*
    2195                 :      * Add completed RTE to pstate's range table list, so that we know its
    2196                 :      * index.  But we don't add it to the join list --- caller must do that if
    2197                 :      * appropriate.
    2198                 :      */
    2199 GIC        4534 :     pstate->p_rtable = lappend(pstate->p_rtable, rte);
    2200 ECB             : 
    2201                 :     /*
    2202                 :      * Build a ParseNamespaceItem, but don't add it to the pstate's namespace
    2203                 :      * list --- caller must do that if appropriate.
    2204                 :      */
    2205 GIC        4534 :     return buildNSItemFromLists(rte, list_length(pstate->p_rtable),
    2206 ECB             :                                 rte->coltypes, rte->coltypmods,
    2207                 :                                 rte->colcollations);
    2208                 : }
    2209                 : 
    2210                 : /*
    2211                 :  * Add an entry for a join to the pstate's range table (p_rtable).
    2212 EUB             :  * Then, construct and return a ParseNamespaceItem for the new RTE.
    2213                 :  *
    2214                 :  * This is much like addRangeTableEntry() except that it makes a join RTE.
    2215                 :  * Also, it's more convenient for the caller to construct the
    2216                 :  * ParseNamespaceColumn array, so we pass that in.
    2217 ECB             :  */
    2218                 : ParseNamespaceItem *
    2219 GIC       79032 : addRangeTableEntryForJoin(ParseState *pstate,
    2220                 :                           List *colnames,
    2221                 :                           ParseNamespaceColumn *nscolumns,
    2222                 :                           JoinType jointype,
    2223                 :                           int nummergedcols,
    2224                 :                           List *aliasvars,
    2225 ECB             :                           List *leftcols,
    2226                 :                           List *rightcols,
    2227                 :                           Alias *join_using_alias,
    2228                 :                           Alias *alias,
    2229                 :                           bool inFromCl)
    2230                 : {
    2231 GIC       79032 :     RangeTblEntry *rte = makeNode(RangeTblEntry);
    2232                 :     Alias      *eref;
    2233                 :     int         numaliases;
    2234 ECB             :     ParseNamespaceItem *nsitem;
    2235                 : 
    2236 GIC       79032 :     Assert(pstate != NULL);
    2237                 : 
    2238                 :     /*
    2239                 :      * Fail if join has too many columns --- we must be able to reference any
    2240 ECB             :      * of the columns with an AttrNumber.
    2241                 :      */
    2242 GIC       79032 :     if (list_length(aliasvars) > MaxAttrNumber)
    2243 UIC           0 :         ereport(ERROR,
    2244                 :                 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
    2245                 :                  errmsg("joins can have at most %d columns",
    2246                 :                         MaxAttrNumber)));
    2247                 : 
    2248 GIC       79032 :     rte->rtekind = RTE_JOIN;
    2249           79032 :     rte->relid = InvalidOid;
    2250           79032 :     rte->subquery = NULL;
    2251           79032 :     rte->jointype = jointype;
    2252           79032 :     rte->joinmergedcols = nummergedcols;
    2253           79032 :     rte->joinaliasvars = aliasvars;
    2254 CBC       79032 :     rte->joinleftcols = leftcols;
    2255 GIC       79032 :     rte->joinrightcols = rightcols;
    2256           79032 :     rte->join_using_alias = join_using_alias;
    2257           79032 :     rte->alias = alias;
    2258                 : 
    2259           79032 :     eref = alias ? copyObject(alias) : makeAlias("unnamed_join", NIL);
    2260           79032 :     numaliases = list_length(eref->colnames);
    2261                 : 
    2262                 :     /* fill in any unspecified alias columns */
    2263           79032 :     if (numaliases < list_length(colnames))
    2264           78963 :         eref->colnames = list_concat(eref->colnames,
    2265           78963 :                                      list_copy_tail(colnames, numaliases));
    2266 ECB             : 
    2267 GIC       79032 :     if (numaliases > list_length(colnames))
    2268               3 :         ereport(ERROR,
    2269                 :                 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
    2270                 :                  errmsg("join expression \"%s\" has %d columns available but %d columns specified",
    2271 ECB             :                         eref->aliasname, list_length(colnames), numaliases)));
    2272                 : 
    2273 GIC       79029 :     rte->eref = eref;
    2274                 : 
    2275                 :     /*
    2276                 :      * Set flags and access permissions.
    2277 ECB             :      *
    2278                 :      * Joins are never checked for access rights, so no need to perform
    2279                 :      * addRTEPermissionInfo().
    2280                 :      */
    2281 GIC       79029 :     rte->lateral = false;
    2282           79029 :     rte->inh = false;            /* never true for joins */
    2283           79029 :     rte->inFromCl = inFromCl;
    2284 ECB             : 
    2285                 :     /*
    2286                 :      * Add completed RTE to pstate's range table list, so that we know its
    2287                 :      * index.  But we don't add it to the join list --- caller must do that if
    2288                 :      * appropriate.
    2289                 :      */
    2290 GIC       79029 :     pstate->p_rtable = lappend(pstate->p_rtable, rte);
    2291                 : 
    2292 ECB             :     /*
    2293                 :      * Build a ParseNamespaceItem, but don't add it to the pstate's namespace
    2294                 :      * list --- caller must do that if appropriate.
    2295                 :      */
    2296 CBC       79029 :     nsitem = (ParseNamespaceItem *) palloc(sizeof(ParseNamespaceItem));
    2297           79029 :     nsitem->p_names = rte->eref;
    2298 GIC       79029 :     nsitem->p_rte = rte;
    2299 GNC       79029 :     nsitem->p_perminfo = NULL;
    2300 GIC       79029 :     nsitem->p_rtindex = list_length(pstate->p_rtable);
    2301           79029 :     nsitem->p_nscolumns = nscolumns;
    2302                 :     /* set default visibility flags; might get changed later */
    2303 CBC       79029 :     nsitem->p_rel_visible = true;
    2304 GIC       79029 :     nsitem->p_cols_visible = true;
    2305           79029 :     nsitem->p_lateral_only = false;
    2306           79029 :     nsitem->p_lateral_ok = true;
    2307                 : 
    2308           79029 :     return nsitem;
    2309                 : }
    2310                 : 
    2311 ECB             : /*
    2312                 :  * Add an entry for a CTE reference to the pstate's range table (p_rtable).
    2313                 :  * Then, construct and return a ParseNamespaceItem for the new RTE.
    2314                 :  *
    2315                 :  * This is much like addRangeTableEntry() except that it makes a CTE RTE.
    2316                 :  */
    2317                 : ParseNamespaceItem *
    2318 GIC        2565 : addRangeTableEntryForCTE(ParseState *pstate,
    2319                 :                          CommonTableExpr *cte,
    2320 ECB             :                          Index levelsup,
    2321                 :                          RangeVar *rv,
    2322                 :                          bool inFromCl)
    2323                 : {
    2324 GIC        2565 :     RangeTblEntry *rte = makeNode(RangeTblEntry);
    2325            2565 :     Alias      *alias = rv->alias;
    2326 CBC        2565 :     char       *refname = alias ? alias->aliasname : cte->ctename;
    2327 ECB             :     Alias      *eref;
    2328                 :     int         numaliases;
    2329                 :     int         varattno;
    2330                 :     ListCell   *lc;
    2331 CBC        2565 :     int         n_dontexpand_columns = 0;
    2332                 :     ParseNamespaceItem *psi;
    2333 ECB             : 
    2334 CBC        2565 :     Assert(pstate != NULL);
    2335 ECB             : 
    2336 CBC        2565 :     rte->rtekind = RTE_CTE;
    2337 GIC        2565 :     rte->ctename = cte->ctename;
    2338 CBC        2565 :     rte->ctelevelsup = levelsup;
    2339                 : 
    2340                 :     /* Self-reference if and only if CTE's parse analysis isn't completed */
    2341 GIC        2565 :     rte->self_reference = !IsA(cte->ctequery, Query);
    2342            2565 :     Assert(cte->cterecursive || !rte->self_reference);
    2343                 :     /* Bump the CTE's refcount if this isn't a self-reference */
    2344            2565 :     if (!rte->self_reference)
    2345            2139 :         cte->cterefcount++;
    2346                 : 
    2347                 :     /*
    2348 ECB             :      * We throw error if the CTE is INSERT/UPDATE/DELETE without RETURNING.
    2349                 :      * This won't get checked in case of a self-reference, but that's OK
    2350                 :      * because data-modifying CTEs aren't allowed to be recursive anyhow.
    2351                 :      */
    2352 GIC        2565 :     if (IsA(cte->ctequery, Query))
    2353                 :     {
    2354 CBC        2139 :         Query      *ctequery = (Query *) cte->ctequery;
    2355 ECB             : 
    2356 CBC        2139 :         if (ctequery->commandType != CMD_SELECT &&
    2357 GIC         132 :             ctequery->returningList == NIL)
    2358               3 :             ereport(ERROR,
    2359                 :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    2360                 :                      errmsg("WITH query \"%s\" does not have a RETURNING clause",
    2361 ECB             :                             cte->ctename),
    2362                 :                      parser_errposition(pstate, rv->location)));
    2363                 :     }
    2364                 : 
    2365 GIC        2562 :     rte->coltypes = list_copy(cte->ctecoltypes);
    2366 CBC        2562 :     rte->coltypmods = list_copy(cte->ctecoltypmods);
    2367            2562 :     rte->colcollations = list_copy(cte->ctecolcollations);
    2368 ECB             : 
    2369 GIC        2562 :     rte->alias = alias;
    2370            2562 :     if (alias)
    2371 CBC         488 :         eref = copyObject(alias);
    2372 ECB             :     else
    2373 GIC        2074 :         eref = makeAlias(refname, NIL);
    2374 CBC        2562 :     numaliases = list_length(eref->colnames);
    2375 ECB             : 
    2376                 :     /* fill in any unspecified alias columns */
    2377 GIC        2562 :     varattno = 0;
    2378            9313 :     foreach(lc, cte->ctecolnames)
    2379                 :     {
    2380            6751 :         varattno++;
    2381            6751 :         if (varattno > numaliases)
    2382 CBC        6727 :             eref->colnames = lappend(eref->colnames, lfirst(lc));
    2383                 :     }
    2384            2562 :     if (varattno < numaliases)
    2385 UIC           0 :         ereport(ERROR,
    2386 ECB             :                 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
    2387                 :                  errmsg("table \"%s\" has %d columns available but %d columns specified",
    2388                 :                         refname, varattno, numaliases)));
    2389                 : 
    2390 GIC        2562 :     rte->eref = eref;
    2391                 : 
    2392            2562 :     if (cte->search_clause)
    2393                 :     {
    2394             105 :         rte->eref->colnames = lappend(rte->eref->colnames, makeString(cte->search_clause->search_seq_column));
    2395 CBC         105 :         if (cte->search_clause->search_breadth_first)
    2396              36 :             rte->coltypes = lappend_oid(rte->coltypes, RECORDOID);
    2397 ECB             :         else
    2398 GIC          69 :             rte->coltypes = lappend_oid(rte->coltypes, RECORDARRAYOID);
    2399 CBC         105 :         rte->coltypmods = lappend_int(rte->coltypmods, -1);
    2400             105 :         rte->colcollations = lappend_oid(rte->colcollations, InvalidOid);
    2401 ECB             : 
    2402 GIC         105 :         n_dontexpand_columns += 1;
    2403 ECB             :     }
    2404                 : 
    2405 GIC        2562 :     if (cte->cycle_clause)
    2406                 :     {
    2407 CBC          93 :         rte->eref->colnames = lappend(rte->eref->colnames, makeString(cte->cycle_clause->cycle_mark_column));
    2408              93 :         rte->coltypes = lappend_oid(rte->coltypes, cte->cycle_clause->cycle_mark_type);
    2409 GIC          93 :         rte->coltypmods = lappend_int(rte->coltypmods, cte->cycle_clause->cycle_mark_typmod);
    2410 CBC          93 :         rte->colcollations = lappend_oid(rte->colcollations, cte->cycle_clause->cycle_mark_collation);
    2411 ECB             : 
    2412 CBC          93 :         rte->eref->colnames = lappend(rte->eref->colnames, makeString(cte->cycle_clause->cycle_path_column));
    2413 GIC          93 :         rte->coltypes = lappend_oid(rte->coltypes, RECORDARRAYOID);
    2414 CBC          93 :         rte->coltypmods = lappend_int(rte->coltypmods, -1);
    2415 GBC          93 :         rte->colcollations = lappend_oid(rte->colcollations, InvalidOid);
    2416                 : 
    2417 GIC          93 :         n_dontexpand_columns += 2;
    2418                 :     }
    2419                 : 
    2420 ECB             :     /*
    2421                 :      * Set flags and access permissions.
    2422                 :      *
    2423                 :      * Subqueries are never checked for access rights, so no need to perform
    2424                 :      * addRTEPermissionInfo().
    2425                 :      */
    2426 CBC        2562 :     rte->lateral = false;
    2427            2562 :     rte->inh = false;            /* never true for subqueries */
    2428 GIC        2562 :     rte->inFromCl = inFromCl;
    2429 ECB             : 
    2430                 :     /*
    2431                 :      * Add completed RTE to pstate's range table list, so that we know its
    2432                 :      * index.  But we don't add it to the join list --- caller must do that if
    2433                 :      * appropriate.
    2434                 :      */
    2435 GIC        2562 :     pstate->p_rtable = lappend(pstate->p_rtable, rte);
    2436 ECB             : 
    2437                 :     /*
    2438                 :      * Build a ParseNamespaceItem, but don't add it to the pstate's namespace
    2439                 :      * list --- caller must do that if appropriate.
    2440                 :      */
    2441 CBC        2562 :     psi = buildNSItemFromLists(rte, list_length(pstate->p_rtable),
    2442                 :                                rte->coltypes, rte->coltypmods,
    2443                 :                                rte->colcollations);
    2444                 : 
    2445                 :     /*
    2446                 :      * The columns added by search and cycle clauses are not included in star
    2447                 :      * expansion in queries contained in the CTE.
    2448                 :      */
    2449 GIC        2562 :     if (rte->ctelevelsup > 0)
    2450 CBC        1969 :         for (int i = 0; i < n_dontexpand_columns; i++)
    2451             177 :             psi->p_nscolumns[list_length(psi->p_names->colnames) - 1 - i].p_dontexpand = true;
    2452 ECB             : 
    2453 GIC        2562 :     return psi;
    2454                 : }
    2455                 : 
    2456                 : /*
    2457                 :  * Add an entry for an ephemeral named relation reference to the pstate's
    2458                 :  * range table (p_rtable).
    2459 ECB             :  * Then, construct and return a ParseNamespaceItem for the new RTE.
    2460                 :  *
    2461                 :  * It is expected that the RangeVar, which up until now is only known to be an
    2462                 :  * ephemeral named relation, will (in conjunction with the QueryEnvironment in
    2463                 :  * the ParseState), create a RangeTblEntry for a specific *kind* of ephemeral
    2464                 :  * named relation, based on enrtype.
    2465                 :  *
    2466                 :  * This is much like addRangeTableEntry() except that it makes an RTE for an
    2467                 :  * ephemeral named relation.
    2468                 :  */
    2469                 : ParseNamespaceItem *
    2470 GIC         222 : addRangeTableEntryForENR(ParseState *pstate,
    2471                 :                          RangeVar *rv,
    2472                 :                          bool inFromCl)
    2473 ECB             : {
    2474 CBC         222 :     RangeTblEntry *rte = makeNode(RangeTblEntry);
    2475             222 :     Alias      *alias = rv->alias;
    2476 GIC         222 :     char       *refname = alias ? alias->aliasname : rv->relname;
    2477 ECB             :     EphemeralNamedRelationMetadata enrmd;
    2478                 :     TupleDesc   tupdesc;
    2479                 :     int         attno;
    2480                 : 
    2481 GIC         222 :     Assert(pstate != NULL);
    2482             222 :     enrmd = get_visible_ENR(pstate, rv->relname);
    2483             222 :     Assert(enrmd != NULL);
    2484                 : 
    2485             222 :     switch (enrmd->enrtype)
    2486                 :     {
    2487             222 :         case ENR_NAMED_TUPLESTORE:
    2488             222 :             rte->rtekind = RTE_NAMEDTUPLESTORE;
    2489             222 :             break;
    2490                 : 
    2491 UIC           0 :         default:
    2492               0 :             elog(ERROR, "unexpected enrtype: %d", enrmd->enrtype);
    2493                 :             return NULL;        /* for fussy compilers */
    2494 ECB             :     }
    2495                 : 
    2496                 :     /*
    2497                 :      * Record dependency on a relation.  This allows plans to be invalidated
    2498                 :      * if they access transition tables linked to a table that is altered.
    2499                 :      */
    2500 CBC         222 :     rte->relid = enrmd->reliddesc;
    2501                 : 
    2502                 :     /*
    2503                 :      * Build the list of effective column names using user-supplied aliases
    2504                 :      * and/or actual column names.
    2505 ECB             :      */
    2506 CBC         222 :     tupdesc = ENRMetadataGetTupDesc(enrmd);
    2507             222 :     rte->eref = makeAlias(refname, NIL);
    2508 GIC         222 :     buildRelationAliases(tupdesc, alias, rte->eref);
    2509 ECB             : 
    2510                 :     /* Record additional data for ENR, including column type info */
    2511 CBC         222 :     rte->enrname = enrmd->name;
    2512             222 :     rte->enrtuples = enrmd->enrtuples;
    2513             222 :     rte->coltypes = NIL;
    2514 GIC         222 :     rte->coltypmods = NIL;
    2515 GBC         222 :     rte->colcollations = NIL;
    2516             729 :     for (attno = 1; attno <= tupdesc->natts; ++attno)
    2517                 :     {
    2518 GIC         507 :         Form_pg_attribute att = TupleDescAttr(tupdesc, attno - 1);
    2519                 : 
    2520             507 :         if (att->attisdropped)
    2521                 :         {
    2522                 :             /* Record zeroes for a dropped column */
    2523               9 :             rte->coltypes = lappend_oid(rte->coltypes, InvalidOid);
    2524 CBC           9 :             rte->coltypmods = lappend_int(rte->coltypmods, 0);
    2525 GIC           9 :             rte->colcollations = lappend_oid(rte->colcollations, InvalidOid);
    2526                 :         }
    2527                 :         else
    2528                 :         {
    2529                 :             /* Let's just make sure we can tell this isn't dropped */
    2530 CBC         498 :             if (att->atttypid == InvalidOid)
    2531 LBC           0 :                 elog(ERROR, "atttypid is invalid for non-dropped column in \"%s\"",
    2532 ECB             :                      rv->relname);
    2533 GIC         498 :             rte->coltypes = lappend_oid(rte->coltypes, att->atttypid);
    2534             498 :             rte->coltypmods = lappend_int(rte->coltypmods, att->atttypmod);
    2535 CBC         498 :             rte->colcollations = lappend_oid(rte->colcollations,
    2536 ECB             :                                              att->attcollation);
    2537                 :         }
    2538                 :     }
    2539                 : 
    2540                 :     /*
    2541                 :      * Set flags and access permissions.
    2542                 :      *
    2543                 :      * ENRs are never checked for access rights, so no need to perform
    2544                 :      * addRTEPermissionInfo().
    2545                 :      */
    2546 GIC         222 :     rte->lateral = false;
    2547             222 :     rte->inh = false;            /* never true for ENRs */
    2548 CBC         222 :     rte->inFromCl = inFromCl;
    2549 ECB             : 
    2550                 :     /*
    2551                 :      * Add completed RTE to pstate's range table list, so that we know its
    2552 EUB             :      * index.  But we don't add it to the join list --- caller must do that if
    2553                 :      * appropriate.
    2554 ECB             :      */
    2555 CBC         222 :     pstate->p_rtable = lappend(pstate->p_rtable, rte);
    2556 ECB             : 
    2557                 :     /*
    2558                 :      * Build a ParseNamespaceItem, but don't add it to the pstate's namespace
    2559                 :      * list --- caller must do that if appropriate.
    2560                 :      */
    2561 GNC         222 :     return buildNSItemFromTupleDesc(rte, list_length(pstate->p_rtable), NULL,
    2562                 :                                     tupdesc);
    2563                 : }
    2564                 : 
    2565                 : 
    2566                 : /*
    2567 ECB             :  * Has the specified refname been selected FOR UPDATE/FOR SHARE?
    2568                 :  *
    2569                 :  * This is used when we have not yet done transformLockingClause, but need
    2570                 :  * to know the correct lock to take during initial opening of relations.
    2571                 :  *
    2572                 :  * Note that refname may be NULL (for a subquery without an alias), in which
    2573                 :  * case the relation can't be locked by name, but it might still be locked if
    2574                 :  * a locking clause requests that all tables be locked.
    2575                 :  *
    2576                 :  * Note: we pay no attention to whether it's FOR UPDATE vs FOR SHARE,
    2577                 :  * since the table-level lock is the same either way.
    2578                 :  */
    2579                 : bool
    2580 CBC      287643 : isLockedRefname(ParseState *pstate, const char *refname)
    2581                 : {
    2582                 :     ListCell   *l;
    2583                 : 
    2584                 :     /*
    2585                 :      * If we are in a subquery specified as locked FOR UPDATE/SHARE from
    2586 ECB             :      * parent level, then act as though there's a generic FOR UPDATE here.
    2587                 :      */
    2588 GIC      287643 :     if (pstate->p_locked_from_parent)
    2589               2 :         return true;
    2590                 : 
    2591          287831 :     foreach(l, pstate->p_locking_clause)
    2592                 :     {
    2593            2558 :         LockingClause *lc = (LockingClause *) lfirst(l);
    2594                 : 
    2595            2558 :         if (lc->lockedRels == NIL)
    2596                 :         {
    2597                 :             /* all tables used in query */
    2598            2368 :             return true;
    2599                 :         }
    2600 GNC        1688 :         else if (refname != NULL)
    2601                 :         {
    2602                 :             /* just the named tables */
    2603                 :             ListCell   *l2;
    2604                 : 
    2605 CBC        1884 :             foreach(l2, lc->lockedRels)
    2606                 :             {
    2607 GIC        1697 :                 RangeVar   *thisrel = (RangeVar *) lfirst(l2);
    2608                 : 
    2609            1697 :                 if (strcmp(refname, thisrel->relname) == 0)
    2610            1498 :                     return true;
    2611                 :             }
    2612                 :         }
    2613 ECB             :     }
    2614 CBC      285273 :     return false;
    2615                 : }
    2616 ECB             : 
    2617                 : /*
    2618                 :  * Add the given nsitem/RTE as a top-level entry in the pstate's join list
    2619                 :  * and/or namespace list.  (We assume caller has checked for any
    2620                 :  * namespace conflicts.)  The nsitem is always marked as unconditionally
    2621                 :  * visible, that is, not LATERAL-only.
    2622                 :  */
    2623                 : void
    2624 GIC      122479 : addNSItemToQuery(ParseState *pstate, ParseNamespaceItem *nsitem,
    2625 ECB             :                  bool addToJoinList,
    2626                 :                  bool addToRelNameSpace, bool addToVarNameSpace)
    2627                 : {
    2628 GIC      122479 :     if (addToJoinList)
    2629                 :     {
    2630 CBC       24848 :         RangeTblRef *rtr = makeNode(RangeTblRef);
    2631                 : 
    2632           24848 :         rtr->rtindex = nsitem->p_rtindex;
    2633 GIC       24848 :         pstate->p_joinlist = lappend(pstate->p_joinlist, rtr);
    2634 ECB             :     }
    2635 CBC      122479 :     if (addToRelNameSpace || addToVarNameSpace)
    2636                 :     {
    2637                 :         /* Set the new nsitem's visibility flags correctly */
    2638 GIC      114677 :         nsitem->p_rel_visible = addToRelNameSpace;
    2639 CBC      114677 :         nsitem->p_cols_visible = addToVarNameSpace;
    2640 GIC      114677 :         nsitem->p_lateral_only = false;
    2641          114677 :         nsitem->p_lateral_ok = true;
    2642          114677 :         pstate->p_namespace = lappend(pstate->p_namespace, nsitem);
    2643                 :     }
    2644          122479 : }
    2645                 : 
    2646                 : /*
    2647                 :  * expandRTE -- expand the columns of a rangetable entry
    2648                 :  *
    2649 ECB             :  * This creates lists of an RTE's column names (aliases if provided, else
    2650                 :  * real names) and Vars for each column.  Only user columns are considered.
    2651                 :  * If include_dropped is false then dropped columns are omitted from the
    2652                 :  * results.  If include_dropped is true then empty strings and NULL constants
    2653                 :  * (not Vars!) are returned for dropped columns.
    2654                 :  *
    2655                 :  * rtindex, sublevels_up, and location are the varno, varlevelsup, and location
    2656                 :  * values to use in the created Vars.  Ordinarily rtindex should match the
    2657                 :  * actual position of the RTE in its rangetable.
    2658                 :  *
    2659                 :  * The output lists go into *colnames and *colvars.
    2660                 :  * If only one of the two kinds of output list is needed, pass NULL for the
    2661                 :  * output pointer for the unwanted one.
    2662                 :  */
    2663                 : void
    2664 CBC        8366 : expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up,
    2665 ECB             :           int location, bool include_dropped,
    2666                 :           List **colnames, List **colvars)
    2667                 : {
    2668                 :     int         varattno;
    2669                 : 
    2670 GIC        8366 :     if (colnames)
    2671             521 :         *colnames = NIL;
    2672            8366 :     if (colvars)
    2673            8099 :         *colvars = NIL;
    2674                 : 
    2675            8366 :     switch (rte->rtekind)
    2676                 :     {
    2677              27 :         case RTE_RELATION:
    2678                 :             /* Ordinary relation RTE */
    2679              27 :             expandRelation(rte->relid, rte->eref,
    2680                 :                            rtindex, sublevels_up, location,
    2681                 :                            include_dropped, colnames, colvars);
    2682              27 :             break;
    2683             227 :         case RTE_SUBQUERY:
    2684                 :             {
    2685                 :                 /* Subquery RTE */
    2686             227 :                 ListCell   *aliasp_item = list_head(rte->eref->colnames);
    2687                 :                 ListCell   *tlistitem;
    2688                 : 
    2689 CBC         227 :                 varattno = 0;
    2690 GIC         832 :                 foreach(tlistitem, rte->subquery->targetList)
    2691                 :                 {
    2692             605 :                     TargetEntry *te = (TargetEntry *) lfirst(tlistitem);
    2693                 : 
    2694             605 :                     if (te->resjunk)
    2695 LBC           0 :                         continue;
    2696 CBC         605 :                     varattno++;
    2697             605 :                     Assert(varattno == te->resno);
    2698 ECB             : 
    2699                 :                     /*
    2700                 :                      * Formerly it was possible for the subquery tlist to have
    2701                 :                      * more non-junk entries than the colnames list does (if
    2702                 :                      * this RTE has been expanded from a view that has more
    2703                 :                      * columns than it did when the current query was parsed).
    2704                 :                      * Now that ApplyRetrieveRule cleans up such cases, we
    2705                 :                      * shouldn't see that anymore, but let's just check.
    2706                 :                      */
    2707 GIC         605 :                     if (!aliasp_item)
    2708 UNC           0 :                         elog(ERROR, "too few column names for subquery %s",
    2709                 :                              rte->eref->aliasname);
    2710 ECB             : 
    2711 CBC         605 :                     if (colnames)
    2712                 :                     {
    2713             605 :                         char       *label = strVal(lfirst(aliasp_item));
    2714                 : 
    2715             605 :                         *colnames = lappend(*colnames, makeString(pstrdup(label)));
    2716 EUB             :                     }
    2717 ECB             : 
    2718 CBC         605 :                     if (colvars)
    2719                 :                     {
    2720                 :                         Var        *varnode;
    2721                 : 
    2722 GIC         605 :                         varnode = makeVar(rtindex, varattno,
    2723             605 :                                           exprType((Node *) te->expr),
    2724             605 :                                           exprTypmod((Node *) te->expr),
    2725             605 :                                           exprCollation((Node *) te->expr),
    2726                 :                                           sublevels_up);
    2727             605 :                         varnode->location = location;
    2728 ECB             : 
    2729 GBC         605 :                         *colvars = lappend(*colvars, varnode);
    2730                 :                     }
    2731                 : 
    2732 CBC         605 :                     aliasp_item = lnext(rte->eref->colnames, aliasp_item);
    2733                 :                 }
    2734 ECB             :             }
    2735 GIC         227 :             break;
    2736 CBC        7184 :         case RTE_FUNCTION:
    2737                 :             {
    2738                 :                 /* Function RTE */
    2739            7184 :                 int         atts_done = 0;
    2740                 :                 ListCell   *lc;
    2741                 : 
    2742 GIC       14410 :                 foreach(lc, rte->functions)
    2743 ECB             :                 {
    2744 CBC        7226 :                     RangeTblFunction *rtfunc = (RangeTblFunction *) lfirst(lc);
    2745 ECB             :                     TypeFuncClass functypclass;
    2746                 :                     Oid         funcrettype;
    2747                 :                     TupleDesc   tupdesc;
    2748                 : 
    2749 GIC        7226 :                     functypclass = get_expr_result_type(rtfunc->funcexpr,
    2750 ECB             :                                                         &funcrettype,
    2751                 :                                                         &tupdesc);
    2752 GIC        7226 :                     if (functypclass == TYPEFUNC_COMPOSITE ||
    2753 ECB             :                         functypclass == TYPEFUNC_COMPOSITE_DOMAIN)
    2754                 :                     {
    2755                 :                         /* Composite data type, e.g. a table's row type */
    2756 CBC        4235 :                         Assert(tupdesc);
    2757            4235 :                         expandTupleDesc(tupdesc, rte->eref,
    2758                 :                                         rtfunc->funccolcount, atts_done,
    2759                 :                                         rtindex, sublevels_up, location,
    2760 ECB             :                                         include_dropped, colnames, colvars);
    2761                 :                     }
    2762 GIC        2991 :                     else if (functypclass == TYPEFUNC_SCALAR)
    2763 ECB             :                     {
    2764                 :                         /* Base data type, i.e. scalar */
    2765 CBC        2980 :                         if (colnames)
    2766 GIC         141 :                             *colnames = lappend(*colnames,
    2767             141 :                                                 list_nth(rte->eref->colnames,
    2768                 :                                                          atts_done));
    2769                 : 
    2770 CBC        2980 :                         if (colvars)
    2771                 :                         {
    2772                 :                             Var        *varnode;
    2773 ECB             : 
    2774 GIC        2839 :                             varnode = makeVar(rtindex, atts_done + 1,
    2775                 :                                               funcrettype,
    2776            2839 :                                               exprTypmod(rtfunc->funcexpr),
    2777 CBC        2839 :                                               exprCollation(rtfunc->funcexpr),
    2778 ECB             :                                               sublevels_up);
    2779 GIC        2839 :                             varnode->location = location;
    2780                 : 
    2781            2839 :                             *colvars = lappend(*colvars, varnode);
    2782                 :                         }
    2783 ECB             :                     }
    2784 GIC          11 :                     else if (functypclass == TYPEFUNC_RECORD)
    2785                 :                     {
    2786 CBC          11 :                         if (colnames)
    2787 ECB             :                         {
    2788                 :                             List       *namelist;
    2789                 : 
    2790                 :                             /* extract appropriate subset of column list */
    2791 CBC           3 :                             namelist = list_copy_tail(rte->eref->colnames,
    2792                 :                                                       atts_done);
    2793 GIC           3 :                             namelist = list_truncate(namelist,
    2794                 :                                                      rtfunc->funccolcount);
    2795 CBC           3 :                             *colnames = list_concat(*colnames, namelist);
    2796                 :                         }
    2797 ECB             : 
    2798 CBC          11 :                         if (colvars)
    2799                 :                         {
    2800 ECB             :                             ListCell   *l1;
    2801                 :                             ListCell   *l2;
    2802                 :                             ListCell   *l3;
    2803 GIC           8 :                             int         attnum = atts_done;
    2804                 : 
    2805 CBC          32 :                             forthree(l1, rtfunc->funccoltypes,
    2806                 :                                      l2, rtfunc->funccoltypmods,
    2807 ECB             :                                      l3, rtfunc->funccolcollations)
    2808                 :                             {
    2809 GIC          24 :                                 Oid         attrtype = lfirst_oid(l1);
    2810              24 :                                 int32       attrtypmod = lfirst_int(l2);
    2811              24 :                                 Oid         attrcollation = lfirst_oid(l3);
    2812 ECB             :                                 Var        *varnode;
    2813                 : 
    2814 CBC          24 :                                 attnum++;
    2815 GIC          24 :                                 varnode = makeVar(rtindex,
    2816 ECB             :                                                   attnum,
    2817                 :                                                   attrtype,
    2818                 :                                                   attrtypmod,
    2819                 :                                                   attrcollation,
    2820                 :                                                   sublevels_up);
    2821 GIC          24 :                                 varnode->location = location;
    2822              24 :                                 *colvars = lappend(*colvars, varnode);
    2823                 :                             }
    2824 ECB             :                         }
    2825                 :                     }
    2826                 :                     else
    2827                 :                     {
    2828                 :                         /* addRangeTableEntryForFunction should've caught this */
    2829 UIC           0 :                         elog(ERROR, "function in FROM has unsupported return type");
    2830 ECB             :                     }
    2831 CBC        7226 :                     atts_done += rtfunc->funccolcount;
    2832 ECB             :                 }
    2833                 : 
    2834                 :                 /* Append the ordinality column if any */
    2835 CBC        7184 :                 if (rte->funcordinality)
    2836 ECB             :                 {
    2837 GIC         177 :                     if (colnames)
    2838               9 :                         *colnames = lappend(*colnames,
    2839               9 :                                             llast(rte->eref->colnames));
    2840                 : 
    2841             177 :                     if (colvars)
    2842 ECB             :                     {
    2843 CBC         168 :                         Var        *varnode = makeVar(rtindex,
    2844 GIC         168 :                                                       atts_done + 1,
    2845                 :                                                       INT8OID,
    2846                 :                                                       -1,
    2847                 :                                                       InvalidOid,
    2848                 :                                                       sublevels_up);
    2849                 : 
    2850 GBC         168 :                         *colvars = lappend(*colvars, varnode);
    2851                 :                     }
    2852 ECB             :                 }
    2853                 :             }
    2854 GIC        7184 :             break;
    2855               6 :         case RTE_JOIN:
    2856 ECB             :             {
    2857                 :                 /* Join RTE */
    2858                 :                 ListCell   *colname;
    2859                 :                 ListCell   *aliasvar;
    2860                 : 
    2861 GIC           6 :                 Assert(list_length(rte->eref->colnames) == list_length(rte->joinaliasvars));
    2862 ECB             : 
    2863 GIC           6 :                 varattno = 0;
    2864 CBC          30 :                 forboth(colname, rte->eref->colnames, aliasvar, rte->joinaliasvars)
    2865 ECB             :                 {
    2866 GIC          24 :                     Node       *avar = (Node *) lfirst(aliasvar);
    2867                 : 
    2868              24 :                     varattno++;
    2869                 : 
    2870                 :                     /*
    2871 ECB             :                      * During ordinary parsing, there will never be any
    2872                 :                      * deleted columns in the join.  While this function is
    2873                 :                      * also used by the rewriter and planner, they do not
    2874                 :                      * currently call it on any JOIN RTEs.  Therefore, this
    2875                 :                      * next bit is dead code, but it seems prudent to handle
    2876                 :                      * the case correctly anyway.
    2877                 :                      */
    2878 GIC          24 :                     if (avar == NULL)
    2879                 :                     {
    2880 UIC           0 :                         if (include_dropped)
    2881                 :                         {
    2882 LBC           0 :                             if (colnames)
    2883 UIC           0 :                                 *colnames = lappend(*colnames,
    2884 LBC           0 :                                                     makeString(pstrdup("")));
    2885               0 :                             if (colvars)
    2886                 :                             {
    2887 ECB             :                                 /*
    2888                 :                                  * Can't use join's column type here (it might
    2889                 :                                  * be dropped!); but it doesn't really matter
    2890                 :                                  * what type the Const claims to be.
    2891                 :                                  */
    2892 UIC           0 :                                 *colvars = lappend(*colvars,
    2893               0 :                                                    makeNullConst(INT4OID, -1,
    2894                 :                                                                  InvalidOid));
    2895                 :                             }
    2896                 :                         }
    2897               0 :                         continue;
    2898                 :                     }
    2899 ECB             : 
    2900 GIC          24 :                     if (colnames)
    2901 EUB             :                     {
    2902 UIC           0 :                         char       *label = strVal(lfirst(colname));
    2903 EUB             : 
    2904 UBC           0 :                         *colnames = lappend(*colnames,
    2905               0 :                                             makeString(pstrdup(label)));
    2906 EUB             :                     }
    2907                 : 
    2908 GIC          24 :                     if (colvars)
    2909                 :                     {
    2910                 :                         Var        *varnode;
    2911                 : 
    2912                 :                         /*
    2913 EUB             :                          * If the joinaliasvars entry is a simple Var, just
    2914                 :                          * copy it (with adjustment of varlevelsup and
    2915                 :                          * location); otherwise it is a JOIN USING column and
    2916                 :                          * we must generate a join alias Var.  This matches
    2917                 :                          * the results that expansion of "join.*" by
    2918                 :                          * expandNSItemVars would have produced, if we had
    2919                 :                          * access to the ParseNamespaceItem for the join.
    2920                 :                          */
    2921 CBC          24 :                         if (IsA(avar, Var))
    2922                 :                         {
    2923 GBC          24 :                             varnode = copyObject((Var *) avar);
    2924 GIC          24 :                             varnode->varlevelsup = sublevels_up;
    2925 EUB             :                         }
    2926                 :                         else
    2927 UIC           0 :                             varnode = makeVar(rtindex, varattno,
    2928                 :                                               exprType(avar),
    2929 ECB             :                                               exprTypmod(avar),
    2930                 :                                               exprCollation(avar),
    2931                 :                                               sublevels_up);
    2932 GIC          24 :                         varnode->location = location;
    2933                 : 
    2934              24 :                         *colvars = lappend(*colvars, varnode);
    2935                 :                     }
    2936                 :                 }
    2937                 :             }
    2938               6 :             break;
    2939             922 :         case RTE_TABLEFUNC:
    2940                 :         case RTE_VALUES:
    2941                 :         case RTE_CTE:
    2942 ECB             :         case RTE_NAMEDTUPLESTORE:
    2943                 :             {
    2944                 :                 /* Tablefunc, Values, CTE, or ENR RTE */
    2945 CBC         922 :                 ListCell   *aliasp_item = list_head(rte->eref->colnames);
    2946                 :                 ListCell   *lct;
    2947                 :                 ListCell   *lcm;
    2948 EUB             :                 ListCell   *lcc;
    2949                 : 
    2950 GIC         922 :                 varattno = 0;
    2951            2899 :                 forthree(lct, rte->coltypes,
    2952                 :                          lcm, rte->coltypmods,
    2953 ECB             :                          lcc, rte->colcollations)
    2954                 :                 {
    2955 CBC        1977 :                     Oid         coltype = lfirst_oid(lct);
    2956 GIC        1977 :                     int32       coltypmod = lfirst_int(lcm);
    2957            1977 :                     Oid         colcoll = lfirst_oid(lcc);
    2958                 : 
    2959 CBC        1977 :                     varattno++;
    2960 ECB             : 
    2961 GIC        1977 :                     if (colnames)
    2962                 :                     {
    2963                 :                         /* Assume there is one alias per output column */
    2964 UIC           0 :                         if (OidIsValid(coltype))
    2965                 :                         {
    2966 LBC           0 :                             char       *label = strVal(lfirst(aliasp_item));
    2967                 : 
    2968 UIC           0 :                             *colnames = lappend(*colnames,
    2969               0 :                                                 makeString(pstrdup(label)));
    2970                 :                         }
    2971 LBC           0 :                         else if (include_dropped)
    2972               0 :                             *colnames = lappend(*colnames,
    2973 UIC           0 :                                                 makeString(pstrdup("")));
    2974                 : 
    2975               0 :                         aliasp_item = lnext(rte->eref->colnames, aliasp_item);
    2976 ECB             :                     }
    2977                 : 
    2978 CBC        1977 :                     if (colvars)
    2979                 :                     {
    2980            1977 :                         if (OidIsValid(coltype))
    2981                 :                         {
    2982 ECB             :                             Var        *varnode;
    2983                 : 
    2984 GIC        1977 :                             varnode = makeVar(rtindex, varattno,
    2985 EUB             :                                               coltype, coltypmod, colcoll,
    2986                 :                                               sublevels_up);
    2987 GBC        1977 :                             varnode->location = location;
    2988                 : 
    2989            1977 :                             *colvars = lappend(*colvars, varnode);
    2990 EUB             :                         }
    2991 UIC           0 :                         else if (include_dropped)
    2992 EUB             :                         {
    2993                 :                             /*
    2994                 :                              * It doesn't really matter what type the Const
    2995                 :                              * claims to be.
    2996                 :                              */
    2997 UIC           0 :                             *colvars = lappend(*colvars,
    2998               0 :                                                makeNullConst(INT4OID, -1,
    2999 ECB             :                                                              InvalidOid));
    3000                 :                         }
    3001                 :                     }
    3002                 :                 }
    3003                 :             }
    3004 GIC         922 :             break;
    3005 LBC           0 :         case RTE_RESULT:
    3006                 :             /* These expose no columns, so nothing to do */
    3007 UIC           0 :             break;
    3008 LBC           0 :         default:
    3009 UIC           0 :             elog(ERROR, "unrecognized RTE kind: %d", (int) rte->rtekind);
    3010 ECB             :     }
    3011 GIC        8366 : }
    3012 EUB             : 
    3013                 : /*
    3014                 :  * expandRelation -- expandRTE subroutine
    3015                 :  */
    3016                 : static void
    3017 GIC          27 : expandRelation(Oid relid, Alias *eref, int rtindex, int sublevels_up,
    3018 EUB             :                int location, bool include_dropped,
    3019                 :                List **colnames, List **colvars)
    3020                 : {
    3021                 :     Relation    rel;
    3022                 : 
    3023                 :     /* Get the tupledesc and turn it over to expandTupleDesc */
    3024 GIC          27 :     rel = relation_open(relid, AccessShareLock);
    3025 CBC          27 :     expandTupleDesc(rel->rd_att, eref, rel->rd_att->natts, 0,
    3026 EUB             :                     rtindex, sublevels_up,
    3027                 :                     location, include_dropped,
    3028                 :                     colnames, colvars);
    3029 GBC          27 :     relation_close(rel, AccessShareLock);
    3030              27 : }
    3031                 : 
    3032 ECB             : /*
    3033                 :  * expandTupleDesc -- expandRTE subroutine
    3034                 :  *
    3035                 :  * Generate names and/or Vars for the first "count" attributes of the tupdesc,
    3036                 :  * and append them to colnames/colvars.  "offset" is added to the varattno
    3037                 :  * that each Var would otherwise have, and we also skip the first "offset"
    3038                 :  * entries in eref->colnames.  (These provisions allow use of this code for
    3039                 :  * an individual composite-returning function in an RTE_FUNCTION RTE.)
    3040                 :  */
    3041                 : static void
    3042 GIC        4262 : expandTupleDesc(TupleDesc tupdesc, Alias *eref, int count, int offset,
    3043                 :                 int rtindex, int sublevels_up,
    3044                 :                 int location, bool include_dropped,
    3045 ECB             :                 List **colnames, List **colvars)
    3046                 : {
    3047                 :     ListCell   *aliascell;
    3048                 :     int         varattno;
    3049                 : 
    3050 CBC        4262 :     aliascell = (offset < list_length(eref->colnames)) ?
    3051            4262 :         list_nth_cell(eref->colnames, offset) : NULL;
    3052                 : 
    3053 GIC        4262 :     Assert(count <= tupdesc->natts);
    3054           31368 :     for (varattno = 0; varattno < count; varattno++)
    3055                 :     {
    3056           27106 :         Form_pg_attribute attr = TupleDescAttr(tupdesc, varattno);
    3057                 : 
    3058           27106 :         if (attr->attisdropped)
    3059                 :         {
    3060              21 :             if (include_dropped)
    3061                 :             {
    3062              21 :                 if (colnames)
    3063 CBC          21 :                     *colnames = lappend(*colnames, makeString(pstrdup("")));
    3064 GIC          21 :                 if (colvars)
    3065                 :                 {
    3066                 :                     /*
    3067                 :                      * can't use atttypid here, but it doesn't really matter
    3068                 :                      * what type the Const claims to be.
    3069                 :                      */
    3070 UIC           0 :                     *colvars = lappend(*colvars,
    3071 LBC           0 :                                        makeNullConst(INT4OID, -1, InvalidOid));
    3072 ECB             :                 }
    3073                 :             }
    3074 CBC          21 :             if (aliascell)
    3075              21 :                 aliascell = lnext(eref->colnames, aliascell);
    3076 GIC          21 :             continue;
    3077 ECB             :         }
    3078                 : 
    3079 CBC       27085 :         if (colnames)
    3080                 :         {
    3081 ECB             :             char       *label;
    3082                 : 
    3083 CBC        1662 :             if (aliascell)
    3084 ECB             :             {
    3085 CBC        1662 :                 label = strVal(lfirst(aliascell));
    3086 GIC        1662 :                 aliascell = lnext(eref->colnames, aliascell);
    3087                 :             }
    3088                 :             else
    3089                 :             {
    3090                 :                 /* If we run out of aliases, use the underlying name */
    3091 UBC           0 :                 label = NameStr(attr->attname);
    3092 EUB             :             }
    3093 GIC        1662 :             *colnames = lappend(*colnames, makeString(pstrdup(label)));
    3094                 :         }
    3095 ECB             : 
    3096 CBC       27085 :         if (colvars)
    3097 ECB             :         {
    3098                 :             Var        *varnode;
    3099                 : 
    3100 CBC       25492 :             varnode = makeVar(rtindex, varattno + offset + 1,
    3101                 :                               attr->atttypid, attr->atttypmod,
    3102                 :                               attr->attcollation,
    3103                 :                               sublevels_up);
    3104           25492 :             varnode->location = location;
    3105                 : 
    3106           25492 :             *colvars = lappend(*colvars, varnode);
    3107 ECB             :         }
    3108                 :     }
    3109 GIC        4262 : }
    3110                 : 
    3111                 : /*
    3112 EUB             :  * expandNSItemVars
    3113                 :  *    Produce a list of Vars, and optionally a list of column names,
    3114 ECB             :  *    for the non-dropped columns of the nsitem.
    3115                 :  *
    3116                 :  * The emitted Vars are marked with the given sublevels_up and location.
    3117                 :  *
    3118                 :  * If colnames isn't NULL, a list of String items for the columns is stored
    3119                 :  * there; note that it's just a subset of the RTE's eref list, and hence
    3120                 :  * the list elements mustn't be modified.
    3121                 :  */
    3122                 : List *
    3123 GNC       36291 : expandNSItemVars(ParseState *pstate, ParseNamespaceItem *nsitem,
    3124                 :                  int sublevels_up, int location,
    3125 ECB             :                  List **colnames)
    3126                 : {
    3127 CBC       36291 :     List       *result = NIL;
    3128                 :     int         colindex;
    3129                 :     ListCell   *lc;
    3130 ECB             : 
    3131 GIC       36291 :     if (colnames)
    3132           34193 :         *colnames = NIL;
    3133           36291 :     colindex = 0;
    3134          188243 :     foreach(lc, nsitem->p_names->colnames)
    3135                 :     {
    3136          151952 :         String     *colnameval = lfirst(lc);
    3137          151952 :         const char *colname = strVal(colnameval);
    3138          151952 :         ParseNamespaceColumn *nscol = nsitem->p_nscolumns + colindex;
    3139                 : 
    3140          151952 :         if (nscol->p_dontexpand)
    3141                 :         {
    3142                 :             /* skip */
    3143                 :         }
    3144 CBC      151943 :         else if (colname[0])
    3145                 :         {
    3146                 :             Var        *var;
    3147                 : 
    3148          151419 :             Assert(nscol->p_varno > 0);
    3149 GIC      151419 :             var = makeVar(nscol->p_varno,
    3150          151419 :                           nscol->p_varattno,
    3151                 :                           nscol->p_vartype,
    3152 ECB             :                           nscol->p_vartypmod,
    3153                 :                           nscol->p_varcollid,
    3154                 :                           sublevels_up);
    3155                 :             /* makeVar doesn't offer parameters for these, so set by hand: */
    3156 GIC      151419 :             var->varnosyn = nscol->p_varnosyn;
    3157 CBC      151419 :             var->varattnosyn = nscol->p_varattnosyn;
    3158          151419 :             var->location = location;
    3159                 : 
    3160                 :             /* ... and update varnullingrels */
    3161 GNC      151419 :             markNullableIfNeeded(pstate, var);
    3162                 : 
    3163 CBC      151419 :             result = lappend(result, var);
    3164 GIC      151419 :             if (colnames)
    3165 CBC      147775 :                 *colnames = lappend(*colnames, colnameval);
    3166                 :         }
    3167                 :         else
    3168                 :         {
    3169 ECB             :             /* dropped column, ignore */
    3170 GIC         524 :             Assert(nscol->p_varno == 0);
    3171                 :         }
    3172          151952 :         colindex++;
    3173 ECB             :     }
    3174 CBC       36291 :     return result;
    3175 ECB             : }
    3176                 : 
    3177                 : /*
    3178                 :  * expandNSItemAttrs -
    3179                 :  *    Workhorse for "*" expansion: produce a list of targetentries
    3180                 :  *    for the attributes of the nsitem
    3181                 :  *
    3182                 :  * pstate->p_next_resno determines the resnos assigned to the TLEs.
    3183                 :  * The referenced columns are marked as requiring SELECT access, if
    3184                 :  * caller requests that.
    3185                 :  */
    3186                 : List *
    3187 GIC       34193 : expandNSItemAttrs(ParseState *pstate, ParseNamespaceItem *nsitem,
    3188 ECB             :                   int sublevels_up, bool require_col_privs, int location)
    3189                 : {
    3190 CBC       34193 :     RangeTblEntry *rte = nsitem->p_rte;
    3191 GNC       34193 :     RTEPermissionInfo *perminfo = nsitem->p_perminfo;
    3192                 :     List       *names,
    3193                 :                *vars;
    3194                 :     ListCell   *name,
    3195                 :                *var;
    3196 CBC       34193 :     List       *te_list = NIL;
    3197                 : 
    3198 GNC       34193 :     vars = expandNSItemVars(pstate, nsitem, sublevels_up, location, &names);
    3199                 : 
    3200 ECB             :     /*
    3201                 :      * Require read access to the table.  This is normally redundant with the
    3202                 :      * markVarForSelectPriv calls below, but not if the table has zero
    3203                 :      * columns.  We need not do anything if the nsitem is for a join: its
    3204                 :      * component tables will have been marked ACL_SELECT when they were added
    3205                 :      * to the rangetable.  (This step changes things only for the target
    3206                 :      * relation of UPDATE/DELETE, which cannot be under a join.)
    3207                 :      */
    3208 GIC       34193 :     if (rte->rtekind == RTE_RELATION)
    3209                 :     {
    3210 GNC       20143 :         Assert(perminfo != NULL);
    3211           20143 :         perminfo->requiredPerms |= ACL_SELECT;
    3212                 :     }
    3213                 : 
    3214 GIC      181968 :     forboth(name, names, var, vars)
    3215                 :     {
    3216 CBC      147775 :         char       *label = strVal(lfirst(name));
    3217 GIC      147775 :         Var        *varnode = (Var *) lfirst(var);
    3218                 :         TargetEntry *te;
    3219 ECB             : 
    3220 CBC      147775 :         te = makeTargetEntry((Expr *) varnode,
    3221 GIC      147775 :                              (AttrNumber) pstate->p_next_resno++,
    3222                 :                              label,
    3223                 :                              false);
    3224          147775 :         te_list = lappend(te_list, te);
    3225 ECB             : 
    3226 GIC      147775 :         if (require_col_privs)
    3227 ECB             :         {
    3228                 :             /* Require read access to each column */
    3229 GIC      147775 :             markVarForSelectPriv(pstate, varnode);
    3230                 :         }
    3231                 :     }
    3232                 : 
    3233           34193 :     Assert(name == NULL && var == NULL);    /* lists not the same length? */
    3234                 : 
    3235           34193 :     return te_list;
    3236                 : }
    3237 ECB             : 
    3238                 : /*
    3239                 :  * get_rte_attribute_name
    3240                 :  *      Get an attribute name from a RangeTblEntry
    3241                 :  *
    3242                 :  * This is unlike get_attname() because we use aliases if available.
    3243                 :  * In particular, it will work on an RTE for a subselect or join, whereas
    3244                 :  * get_attname() only works on real relations.
    3245                 :  *
    3246                 :  * "*" is returned if the given attnum is InvalidAttrNumber --- this case
    3247                 :  * occurs when a Var represents a whole tuple of a relation.
    3248                 :  *
    3249                 :  * It is caller's responsibility to not call this on a dropped attribute.
    3250                 :  * (You will get some answer for such cases, but it might not be sensible.)
    3251                 :  */
    3252                 : char *
    3253 CBC         658 : get_rte_attribute_name(RangeTblEntry *rte, AttrNumber attnum)
    3254                 : {
    3255             658 :     if (attnum == InvalidAttrNumber)
    3256 UIC           0 :         return "*";
    3257                 : 
    3258 ECB             :     /*
    3259                 :      * If there is a user-written column alias, use it.
    3260                 :      */
    3261 GIC         658 :     if (rte->alias &&
    3262 CBC          27 :         attnum > 0 && attnum <= list_length(rte->alias->colnames))
    3263 UIC           0 :         return strVal(list_nth(rte->alias->colnames, attnum - 1));
    3264 ECB             : 
    3265                 :     /*
    3266                 :      * If the RTE is a relation, go to the system catalogs not the
    3267                 :      * eref->colnames list.  This is a little slower but it will give the
    3268                 :      * right answer if the column has been renamed since the eref list was
    3269                 :      * built (which can easily happen for rules).
    3270                 :      */
    3271 GIC         658 :     if (rte->rtekind == RTE_RELATION)
    3272             643 :         return get_attname(rte->relid, attnum, false);
    3273                 : 
    3274                 :     /*
    3275                 :      * Otherwise use the column name from eref.  There should always be one.
    3276                 :      */
    3277              15 :     if (attnum > 0 && attnum <= list_length(rte->eref->colnames))
    3278              15 :         return strVal(list_nth(rte->eref->colnames, attnum - 1));
    3279                 : 
    3280                 :     /* else caller gave us a bogus attnum */
    3281 UIC           0 :     elog(ERROR, "invalid attnum %d for rangetable entry %s",
    3282 ECB             :          attnum, rte->eref->aliasname);
    3283                 :     return NULL;                /* keep compiler quiet */
    3284                 : }
    3285 EUB             : 
    3286                 : /*
    3287                 :  * get_rte_attribute_is_dropped
    3288                 :  *      Check whether attempted attribute ref is to a dropped column
    3289                 :  */
    3290 ECB             : bool
    3291 CBC      223022 : get_rte_attribute_is_dropped(RangeTblEntry *rte, AttrNumber attnum)
    3292 EUB             : {
    3293                 :     bool        result;
    3294                 : 
    3295 GIC      223022 :     switch (rte->rtekind)
    3296                 :     {
    3297          169910 :         case RTE_RELATION:
    3298                 :             {
    3299                 :                 /*
    3300 ECB             :                  * Plain relation RTE --- get the attribute's catalog entry
    3301                 :                  */
    3302                 :                 HeapTuple   tp;
    3303                 :                 Form_pg_attribute att_tup;
    3304                 : 
    3305 GIC      169910 :                 tp = SearchSysCache2(ATTNUM,
    3306 ECB             :                                      ObjectIdGetDatum(rte->relid),
    3307                 :                                      Int16GetDatum(attnum));
    3308 GIC      169910 :                 if (!HeapTupleIsValid(tp))  /* shouldn't happen */
    3309 UIC           0 :                     elog(ERROR, "cache lookup failed for attribute %d of relation %u",
    3310 EUB             :                          attnum, rte->relid);
    3311 GIC      169910 :                 att_tup = (Form_pg_attribute) GETSTRUCT(tp);
    3312          169910 :                 result = att_tup->attisdropped;
    3313          169910 :                 ReleaseSysCache(tp);
    3314                 :             }
    3315          169910 :             break;
    3316             138 :         case RTE_SUBQUERY:
    3317                 :         case RTE_TABLEFUNC:
    3318                 :         case RTE_VALUES:
    3319                 :         case RTE_CTE:
    3320 ECB             : 
    3321                 :             /*
    3322                 :              * Subselect, Table Functions, Values, CTE RTEs never have dropped
    3323                 :              * columns
    3324                 :              */
    3325 GIC         138 :             result = false;
    3326 CBC         138 :             break;
    3327 UIC           0 :         case RTE_NAMEDTUPLESTORE:
    3328                 :             {
    3329                 :                 /* Check dropped-ness by testing for valid coltype */
    3330               0 :                 if (attnum <= 0 ||
    3331               0 :                     attnum > list_length(rte->coltypes))
    3332               0 :                     elog(ERROR, "invalid varattno %d", attnum);
    3333               0 :                 result = !OidIsValid((list_nth_oid(rte->coltypes, attnum - 1)));
    3334 ECB             :             }
    3335 UIC           0 :             break;
    3336               0 :         case RTE_JOIN:
    3337 ECB             :             {
    3338 EUB             :                 /*
    3339                 :                  * A join RTE would not have dropped columns when constructed,
    3340 ECB             :                  * but one in a stored rule might contain columns that were
    3341                 :                  * dropped from the underlying tables, if said columns are
    3342                 :                  * nowhere explicitly referenced in the rule.  This will be
    3343                 :                  * signaled to us by a null pointer in the joinaliasvars list.
    3344                 :                  */
    3345                 :                 Var        *aliasvar;
    3346                 : 
    3347 UIC           0 :                 if (attnum <= 0 ||
    3348               0 :                     attnum > list_length(rte->joinaliasvars))
    3349               0 :                     elog(ERROR, "invalid varattno %d", attnum);
    3350               0 :                 aliasvar = (Var *) list_nth(rte->joinaliasvars, attnum - 1);
    3351                 : 
    3352               0 :                 result = (aliasvar == NULL);
    3353                 :             }
    3354 LBC           0 :             break;
    3355 CBC       52974 :         case RTE_FUNCTION:
    3356 EUB             :             {
    3357                 :                 /* Function RTE */
    3358                 :                 ListCell   *lc;
    3359 GBC       52974 :                 int         atts_done = 0;
    3360 EUB             : 
    3361                 :                 /*
    3362                 :                  * Dropped attributes are only possible with functions that
    3363                 :                  * return named composite types.  In such a case we have to
    3364                 :                  * look up the result type to see if it currently has this
    3365                 :                  * column dropped.  So first, loop over the funcs until we
    3366                 :                  * find the one that covers the requested column.
    3367                 :                  */
    3368 GIC       53004 :                 foreach(lc, rte->functions)
    3369                 :                 {
    3370           52992 :                     RangeTblFunction *rtfunc = (RangeTblFunction *) lfirst(lc);
    3371                 : 
    3372           52992 :                     if (attnum > atts_done &&
    3373           52992 :                         attnum <= atts_done + rtfunc->funccolcount)
    3374                 :                     {
    3375                 :                         TupleDesc   tupdesc;
    3376 EUB             : 
    3377 GBC       52962 :                         tupdesc = get_expr_result_tupdesc(rtfunc->funcexpr,
    3378 EUB             :                                                           true);
    3379 GBC       52962 :                         if (tupdesc)
    3380                 :                         {
    3381 EUB             :                             /* Composite data type, e.g. a table's row type */
    3382                 :                             Form_pg_attribute att_tup;
    3383                 : 
    3384 CBC       52938 :                             Assert(tupdesc);
    3385 GIC       52938 :                             Assert(attnum - atts_done <= tupdesc->natts);
    3386           52938 :                             att_tup = TupleDescAttr(tupdesc,
    3387                 :                                                     attnum - atts_done - 1);
    3388 CBC       52962 :                             return att_tup->attisdropped;
    3389                 :                         }
    3390                 :                         /* Otherwise, it can't have any dropped columns */
    3391 GIC          24 :                         return false;
    3392                 :                     }
    3393              30 :                     atts_done += rtfunc->funccolcount;
    3394                 :                 }
    3395                 : 
    3396                 :                 /* If we get here, must be looking for the ordinality column */
    3397 CBC          12 :                 if (rte->funcordinality && attnum == atts_done + 1)
    3398 GIC          12 :                     return false;
    3399 ECB             : 
    3400                 :                 /* this probably can't happen ... */
    3401 LBC           0 :                 ereport(ERROR,
    3402 ECB             :                         (errcode(ERRCODE_UNDEFINED_COLUMN),
    3403                 :                          errmsg("column %d of relation \"%s\" does not exist",
    3404                 :                                 attnum,
    3405                 :                                 rte->eref->aliasname)));
    3406                 :                 result = false; /* keep compiler quiet */
    3407                 :             }
    3408                 :             break;
    3409 UIC           0 :         case RTE_RESULT:
    3410                 :             /* this probably can't happen ... */
    3411               0 :             ereport(ERROR,
    3412                 :                     (errcode(ERRCODE_UNDEFINED_COLUMN),
    3413 ECB             :                      errmsg("column %d of relation \"%s\" does not exist",
    3414                 :                             attnum,
    3415                 :                             rte->eref->aliasname)));
    3416                 :             result = false;     /* keep compiler quiet */
    3417                 :             break;
    3418 UIC           0 :         default:
    3419               0 :             elog(ERROR, "unrecognized RTE kind: %d", (int) rte->rtekind);
    3420 ECB             :             result = false;     /* keep compiler quiet */
    3421                 :     }
    3422                 : 
    3423 GIC      170048 :     return result;
    3424                 : }
    3425                 : 
    3426 ECB             : /*
    3427                 :  * Given a targetlist and a resno, return the matching TargetEntry
    3428                 :  *
    3429                 :  * Returns NULL if resno is not present in list.
    3430 EUB             :  *
    3431                 :  * Note: we need to search, rather than just indexing with list_nth(),
    3432                 :  * because not all tlists are sorted by resno.
    3433                 :  */
    3434                 : TargetEntry *
    3435 GIC      119594 : get_tle_by_resno(List *tlist, AttrNumber resno)
    3436                 : {
    3437                 :     ListCell   *l;
    3438 EUB             : 
    3439 GIC      383801 :     foreach(l, tlist)
    3440 EUB             :     {
    3441 GIC      383558 :         TargetEntry *tle = (TargetEntry *) lfirst(l);
    3442                 : 
    3443          383558 :         if (tle->resno == resno)
    3444          119351 :             return tle;
    3445                 :     }
    3446             243 :     return NULL;
    3447 EUB             : }
    3448                 : 
    3449                 : /*
    3450                 :  * Given a Query and rangetable index, return relation's RowMarkClause if any
    3451                 :  *
    3452 ECB             :  * Returns NULL if relation is not selected FOR UPDATE/SHARE
    3453                 :  */
    3454                 : RowMarkClause *
    3455 GIC        9461 : get_parse_rowmark(Query *qry, Index rtindex)
    3456                 : {
    3457                 :     ListCell   *l;
    3458                 : 
    3459            9579 :     foreach(l, qry->rowMarks)
    3460                 :     {
    3461             166 :         RowMarkClause *rc = (RowMarkClause *) lfirst(l);
    3462                 : 
    3463             166 :         if (rc->rti == rtindex)
    3464 CBC          48 :             return rc;
    3465                 :     }
    3466 GIC        9413 :     return NULL;
    3467                 : }
    3468 ECB             : 
    3469                 : /*
    3470                 :  *  given relation and att name, return attnum of variable
    3471                 :  *
    3472                 :  *  Returns InvalidAttrNumber if the attr doesn't exist (or is dropped).
    3473                 :  *
    3474                 :  *  This should only be used if the relation is already
    3475                 :  *  table_open()'ed.  Use the cache version get_attnum()
    3476                 :  *  for access to non-opened relations.
    3477                 :  */
    3478                 : int
    3479 GIC       33833 : attnameAttNum(Relation rd, const char *attname, bool sysColOK)
    3480                 : {
    3481                 :     int         i;
    3482                 : 
    3483          161290 :     for (i = 0; i < RelationGetNumberOfAttributes(rd); i++)
    3484 ECB             :     {
    3485 GIC      161241 :         Form_pg_attribute att = TupleDescAttr(rd->rd_att, i);
    3486                 : 
    3487          161241 :         if (namestrcmp(&(att->attname), attname) == 0 && !att->attisdropped)
    3488 CBC       33784 :             return i + 1;
    3489                 :     }
    3490 ECB             : 
    3491 GIC          49 :     if (sysColOK)
    3492 ECB             :     {
    3493 CBC           6 :         if ((i = specialAttNum(attname)) != InvalidAttrNumber)
    3494 UIC           0 :             return i;
    3495 ECB             :     }
    3496                 : 
    3497                 :     /* on failure */
    3498 GIC          49 :     return InvalidAttrNumber;
    3499                 : }
    3500                 : 
    3501                 : /* specialAttNum()
    3502                 :  *
    3503                 :  * Check attribute name to see if it is "special", e.g. "xmin".
    3504                 :  * - thomas 2000-02-07
    3505                 :  *
    3506                 :  * Note: this only discovers whether the name could be a system attribute.
    3507                 :  * Caller needs to ensure that it really is an attribute of the rel.
    3508 ECB             :  */
    3509                 : static int
    3510 GIC       64886 : specialAttNum(const char *attname)
    3511                 : {
    3512 ECB             :     const FormData_pg_attribute *sysatt;
    3513                 : 
    3514 CBC       64886 :     sysatt = SystemAttributeByName(attname);
    3515 GIC       64886 :     if (sysatt != NULL)
    3516 CBC       15469 :         return sysatt->attnum;
    3517           49417 :     return InvalidAttrNumber;
    3518                 : }
    3519                 : 
    3520 ECB             : 
    3521                 : /*
    3522                 :  * given attribute id, return name of that attribute
    3523 EUB             :  *
    3524                 :  *  This should only be used if the relation is already
    3525                 :  *  table_open()'ed.  Use the cache version get_atttype()
    3526                 :  *  for access to non-opened relations.
    3527 ECB             :  */
    3528                 : const NameData *
    3529 GIC        5576 : attnumAttName(Relation rd, int attid)
    3530                 : {
    3531            5576 :     if (attid <= 0)
    3532                 :     {
    3533                 :         const FormData_pg_attribute *sysatt;
    3534                 : 
    3535 UIC           0 :         sysatt = SystemAttributeDefinition(attid);
    3536               0 :         return &sysatt->attname;
    3537                 :     }
    3538 GIC        5576 :     if (attid > rd->rd_att->natts)
    3539 LBC           0 :         elog(ERROR, "invalid attribute number %d", attid);
    3540 GIC        5576 :     return &TupleDescAttr(rd->rd_att, attid - 1)->attname;
    3541                 : }
    3542                 : 
    3543 ECB             : /*
    3544                 :  * given attribute id, return type of that attribute
    3545                 :  *
    3546                 :  *  This should only be used if the relation is already
    3547                 :  *  table_open()'ed.  Use the cache version get_atttype()
    3548                 :  *  for access to non-opened relations.
    3549                 :  */
    3550                 : Oid
    3551 GIC      228177 : attnumTypeId(Relation rd, int attid)
    3552                 : {
    3553          228177 :     if (attid <= 0)
    3554                 :     {
    3555                 :         const FormData_pg_attribute *sysatt;
    3556                 : 
    3557 UIC           0 :         sysatt = SystemAttributeDefinition(attid);
    3558 LBC           0 :         return sysatt->atttypid;
    3559                 :     }
    3560 CBC      228177 :     if (attid > rd->rd_att->natts)
    3561 UIC           0 :         elog(ERROR, "invalid attribute number %d", attid);
    3562 GIC      228177 :     return TupleDescAttr(rd->rd_att, attid - 1)->atttypid;
    3563                 : }
    3564 EUB             : 
    3565                 : /*
    3566                 :  * given attribute id, return collation of that attribute
    3567 ECB             :  *
    3568 EUB             :  *  This should only be used if the relation is already table_open()'ed.
    3569 ECB             :  */
    3570                 : Oid
    3571 GIC        2222 : attnumCollationId(Relation rd, int attid)
    3572                 : {
    3573            2222 :     if (attid <= 0)
    3574                 :     {
    3575                 :         /* All system attributes are of noncollatable types. */
    3576 UIC           0 :         return InvalidOid;
    3577                 :     }
    3578 GIC        2222 :     if (attid > rd->rd_att->natts)
    3579 UIC           0 :         elog(ERROR, "invalid attribute number %d", attid);
    3580 CBC        2222 :     return TupleDescAttr(rd->rd_att, attid - 1)->attcollation;
    3581                 : }
    3582 ECB             : 
    3583                 : /*
    3584                 :  * Generate a suitable error about a missing RTE.
    3585                 :  *
    3586 EUB             :  * Since this is a very common type of error, we work rather hard to
    3587                 :  * produce a helpful message.
    3588                 :  */
    3589 ECB             : void
    3590 GBC          54 : errorMissingRTE(ParseState *pstate, RangeVar *relation)
    3591 ECB             : {
    3592                 :     RangeTblEntry *rte;
    3593 GIC          54 :     const char *badAlias = NULL;
    3594                 : 
    3595                 :     /*
    3596                 :      * Check to see if there are any potential matches in the query's
    3597                 :      * rangetable.  (Note: cases involving a bad schema name in the RangeVar
    3598                 :      * will throw error immediately here.  That seems OK.)
    3599                 :      */
    3600 CBC          54 :     rte = searchRangeTableForRel(pstate, relation);
    3601                 : 
    3602 ECB             :     /*
    3603                 :      * If we found a match that has an alias and the alias is visible in the
    3604                 :      * namespace, then the problem is probably use of the relation's real name
    3605 EUB             :      * instead of its alias, ie "SELECT foo.* FROM foo f". This mistake is
    3606                 :      * common enough to justify a specific hint.
    3607 ECB             :      *
    3608 EUB             :      * If we found a match that doesn't meet those criteria, assume the
    3609 ECB             :      * problem is illegal use of a relation outside its scope, as in the
    3610                 :      * MySQL-ism "SELECT ... FROM a, b LEFT JOIN c ON (a.x = c.y)".
    3611                 :      */
    3612 GIC          54 :     if (rte && rte->alias &&
    3613              36 :         strcmp(rte->eref->aliasname, relation->relname) != 0)
    3614                 :     {
    3615                 :         ParseNamespaceItem *nsitem;
    3616                 :         int         sublevels_up;
    3617                 : 
    3618              12 :         nsitem = refnameNamespaceItem(pstate, NULL, rte->eref->aliasname,
    3619 ECB             :                                       relation->location,
    3620                 :                                       &sublevels_up);
    3621 GIC          12 :         if (nsitem && nsitem->p_rte == rte)
    3622 CBC          12 :             badAlias = rte->eref->aliasname;
    3623                 :     }
    3624                 : 
    3625                 :     /* If it looks like the user forgot to use an alias, hint about that */
    3626 GNC          54 :     if (badAlias)
    3627 GIC          12 :         ereport(ERROR,
    3628                 :                 (errcode(ERRCODE_UNDEFINED_TABLE),
    3629                 :                  errmsg("invalid reference to FROM-clause entry for table \"%s\"",
    3630 ECB             :                         relation->relname),
    3631                 :                  errhint("Perhaps you meant to reference the table alias \"%s\".",
    3632                 :                          badAlias),
    3633                 :                  parser_errposition(pstate, relation->location)));
    3634                 :     /* Hint about case where we found an (inaccessible) exact match */
    3635 GNC          42 :     else if (rte)
    3636              33 :         ereport(ERROR,
    3637                 :                 (errcode(ERRCODE_UNDEFINED_TABLE),
    3638                 :                  errmsg("invalid reference to FROM-clause entry for table \"%s\"",
    3639                 :                         relation->relname),
    3640                 :                  errdetail("There is an entry for table \"%s\", but it cannot be referenced from this part of the query.",
    3641                 :                            rte->eref->aliasname),
    3642                 :                  rte_visible_if_lateral(pstate, rte) ?
    3643                 :                  errhint("To reference that table, you must mark this subquery with LATERAL.") : 0,
    3644                 :                  parser_errposition(pstate, relation->location)));
    3645                 :     /* Else, we have nothing to offer but the bald statement of error */
    3646                 :     else
    3647 GIC           9 :         ereport(ERROR,
    3648                 :                 (errcode(ERRCODE_UNDEFINED_TABLE),
    3649                 :                  errmsg("missing FROM-clause entry for table \"%s\"",
    3650                 :                         relation->relname),
    3651 ECB             :                  parser_errposition(pstate, relation->location)));
    3652                 : }
    3653                 : 
    3654                 : /*
    3655                 :  * Generate a suitable error about a missing column.
    3656                 :  *
    3657                 :  * Since this is a very common type of error, we work rather hard to
    3658                 :  * produce a helpful message.
    3659                 :  */
    3660                 : void
    3661 CBC         170 : errorMissingColumn(ParseState *pstate,
    3662                 :                    const char *relname, const char *colname, int location)
    3663                 : {
    3664                 :     FuzzyAttrMatchState *state;
    3665 ECB             : 
    3666                 :     /*
    3667                 :      * Search the entire rtable looking for possible matches.  If we find one,
    3668                 :      * emit a hint about it.
    3669                 :      */
    3670 CBC         170 :     state = searchRangeTableForCol(pstate, relname, colname, location);
    3671 ECB             : 
    3672                 :     /*
    3673                 :      * If there are exact match(es), they must be inaccessible for some
    3674                 :      * reason.
    3675                 :      */
    3676 GNC         170 :     if (state->rexact1)
    3677                 :     {
    3678                 :         /*
    3679                 :          * We don't try too hard when there's multiple inaccessible exact
    3680                 :          * matches, but at least be sure that we don't misleadingly suggest
    3681                 :          * that there's only one.
    3682                 :          */
    3683              21 :         if (state->rexact2)
    3684               6 :             ereport(ERROR,
    3685                 :                     (errcode(ERRCODE_UNDEFINED_COLUMN),
    3686                 :                      relname ?
    3687                 :                      errmsg("column %s.%s does not exist", relname, colname) :
    3688                 :                      errmsg("column \"%s\" does not exist", colname),
    3689                 :                      errdetail("There are columns named \"%s\", but they are in tables that cannot be referenced from this part of the query.",
    3690                 :                                colname),
    3691                 :                      !relname ? errhint("Try using a table-qualified name.") : 0,
    3692                 :                      parser_errposition(pstate, location)));
    3693                 :         /* Single exact match, so try to determine why it's inaccessible. */
    3694              15 :         ereport(ERROR,
    3695                 :                 (errcode(ERRCODE_UNDEFINED_COLUMN),
    3696                 :                  relname ?
    3697                 :                  errmsg("column %s.%s does not exist", relname, colname) :
    3698                 :                  errmsg("column \"%s\" does not exist", colname),
    3699                 :                  errdetail("There is a column named \"%s\" in table \"%s\", but it cannot be referenced from this part of the query.",
    3700                 :                            colname, state->rexact1->eref->aliasname),
    3701                 :                  rte_visible_if_lateral(pstate, state->rexact1) ?
    3702                 :                  errhint("To reference that column, you must mark this subquery with LATERAL.") :
    3703                 :                  (!relname && rte_visible_if_qualified(pstate, state->rexact1)) ?
    3704                 :                  errhint("To reference that column, you must use a table-qualified name.") : 0,
    3705                 :                  parser_errposition(pstate, location)));
    3706                 :     }
    3707                 : 
    3708             149 :     if (!state->rsecond)
    3709                 :     {
    3710                 :         /* If we found no match at all, we have little to report */
    3711             143 :         if (!state->rfirst)
    3712             122 :             ereport(ERROR,
    3713                 :                     (errcode(ERRCODE_UNDEFINED_COLUMN),
    3714                 :                      relname ?
    3715                 :                      errmsg("column %s.%s does not exist", relname, colname) :
    3716                 :                      errmsg("column \"%s\" does not exist", colname),
    3717                 :                      parser_errposition(pstate, location)));
    3718                 :         /* Handle case where we have a single alternative spelling to offer */
    3719 GIC          21 :         ereport(ERROR,
    3720                 :                 (errcode(ERRCODE_UNDEFINED_COLUMN),
    3721                 :                  relname ?
    3722                 :                  errmsg("column %s.%s does not exist", relname, colname) :
    3723                 :                  errmsg("column \"%s\" does not exist", colname),
    3724                 :                  errhint("Perhaps you meant to reference the column \"%s.%s\".",
    3725                 :                          state->rfirst->eref->aliasname,
    3726                 :                          strVal(list_nth(state->rfirst->eref->colnames,
    3727                 :                                          state->first - 1))),
    3728                 :                  parser_errposition(pstate, location)));
    3729                 :     }
    3730                 :     else
    3731                 :     {
    3732 ECB             :         /* Handle case where there are two equally useful column hints */
    3733 CBC           6 :         ereport(ERROR,
    3734                 :                 (errcode(ERRCODE_UNDEFINED_COLUMN),
    3735                 :                  relname ?
    3736                 :                  errmsg("column %s.%s does not exist", relname, colname) :
    3737                 :                  errmsg("column \"%s\" does not exist", colname),
    3738                 :                  errhint("Perhaps you meant to reference the column \"%s.%s\" or the column \"%s.%s\".",
    3739                 :                          state->rfirst->eref->aliasname,
    3740                 :                          strVal(list_nth(state->rfirst->eref->colnames,
    3741                 :                                          state->first - 1)),
    3742                 :                          state->rsecond->eref->aliasname,
    3743                 :                          strVal(list_nth(state->rsecond->eref->colnames,
    3744                 :                                          state->second - 1))),
    3745 ECB             :                  parser_errposition(pstate, location)));
    3746                 :     }
    3747                 : }
    3748                 : 
    3749                 : /*
    3750                 :  * Find ParseNamespaceItem for RTE, if it's visible at all.
    3751                 :  * We assume an RTE couldn't appear more than once in the namespace lists.
    3752                 :  */
    3753                 : static ParseNamespaceItem *
    3754 GNC          57 : findNSItemForRTE(ParseState *pstate, RangeTblEntry *rte)
    3755                 : {
    3756             108 :     while (pstate != NULL)
    3757                 :     {
    3758                 :         ListCell   *l;
    3759                 : 
    3760             138 :         foreach(l, pstate->p_namespace)
    3761                 :         {
    3762              87 :             ParseNamespaceItem *nsitem = (ParseNamespaceItem *) lfirst(l);
    3763                 : 
    3764              87 :             if (nsitem->p_rte == rte)
    3765              39 :                 return nsitem;
    3766                 :         }
    3767              51 :         pstate = pstate->parentParseState;
    3768                 :     }
    3769              18 :     return NULL;
    3770                 : }
    3771                 : 
    3772                 : /*
    3773                 :  * Would this RTE be visible, if only the user had written LATERAL?
    3774                 :  *
    3775                 :  * This is a helper for deciding whether to issue a HINT about LATERAL.
    3776                 :  * As such, it doesn't need to be 100% accurate; the HINT could be useful
    3777                 :  * even if it's not quite right.  Hence, we don't delve into fine points
    3778                 :  * about whether a found nsitem has the appropriate one of p_rel_visible or
    3779                 :  * p_cols_visible set.
    3780                 :  */
    3781                 : static bool
    3782              48 : rte_visible_if_lateral(ParseState *pstate, RangeTblEntry *rte)
    3783                 : {
    3784                 :     ParseNamespaceItem *nsitem;
    3785                 : 
    3786                 :     /* If LATERAL *is* active, we're clearly barking up the wrong tree */
    3787              48 :     if (pstate->p_lateral_active)
    3788 UNC           0 :         return false;
    3789 GNC          48 :     nsitem = findNSItemForRTE(pstate, rte);
    3790              48 :     if (nsitem)
    3791                 :     {
    3792                 :         /* Found it, report whether it's LATERAL-only */
    3793              33 :         return nsitem->p_lateral_only && nsitem->p_lateral_ok;
    3794                 :     }
    3795              15 :     return false;
    3796                 : }
    3797                 : 
    3798                 : /*
    3799                 :  * Would columns in this RTE be visible if qualified?
    3800                 :  */
    3801                 : static bool
    3802               9 : rte_visible_if_qualified(ParseState *pstate, RangeTblEntry *rte)
    3803                 : {
    3804               9 :     ParseNamespaceItem *nsitem = findNSItemForRTE(pstate, rte);
    3805                 : 
    3806               9 :     if (nsitem)
    3807                 :     {
    3808                 :         /* Found it, report whether it's relation-only */
    3809               6 :         return nsitem->p_rel_visible && !nsitem->p_cols_visible;
    3810                 :     }
    3811               3 :     return false;
    3812                 : }
    3813                 : 
    3814                 : 
    3815                 : /*
    3816                 :  * Examine a fully-parsed query, and return true iff any relation underlying
    3817                 :  * the query is a temporary relation (table, view, or materialized view).
    3818                 :  */
    3819                 : bool
    3820 CBC       44197 : isQueryUsingTempRelation(Query *query)
    3821                 : {
    3822 GIC       44197 :     return isQueryUsingTempRelation_walker((Node *) query, NULL);
    3823                 : }
    3824                 : 
    3825                 : static bool
    3826         4503631 : isQueryUsingTempRelation_walker(Node *node, void *context)
    3827                 : {
    3828         4503631 :     if (node == NULL)
    3829         1150078 :         return false;
    3830                 : 
    3831         3353553 :     if (IsA(node, Query))
    3832                 :     {
    3833           79739 :         Query      *query = (Query *) node;
    3834 ECB             :         ListCell   *rtable;
    3835                 : 
    3836 GIC      299641 :         foreach(rtable, query->rtable)
    3837 ECB             :         {
    3838 CBC      219956 :             RangeTblEntry *rte = lfirst(rtable);
    3839                 : 
    3840 GIC      219956 :             if (rte->rtekind == RTE_RELATION)
    3841                 :             {
    3842          135095 :                 Relation    rel = table_open(rte->relid, AccessShareLock);
    3843          135095 :                 char        relpersistence = rel->rd_rel->relpersistence;
    3844                 : 
    3845 CBC      135095 :                 table_close(rel, AccessShareLock);
    3846 GIC      135095 :                 if (relpersistence == RELPERSISTENCE_TEMP)
    3847              54 :                     return true;
    3848                 :             }
    3849                 :         }
    3850                 : 
    3851           79685 :         return query_tree_walker(query,
    3852                 :                                  isQueryUsingTempRelation_walker,
    3853                 :                                  context,
    3854                 :                                  QTW_IGNORE_JOINALIASES);
    3855                 :     }
    3856                 : 
    3857         3273814 :     return expression_tree_walker(node,
    3858                 :                                   isQueryUsingTempRelation_walker,
    3859 ECB             :                                   context);
    3860                 : }
    3861                 : 
    3862                 : /*
    3863                 :  * addRTEPermissionInfo
    3864                 :  *      Creates RTEPermissionInfo for a given RTE and adds it into the
    3865                 :  *      provided list.
    3866                 :  *
    3867                 :  * Returns the RTEPermissionInfo and sets rte->perminfoindex.
    3868                 :  */
    3869                 : RTEPermissionInfo *
    3870 GNC      790711 : addRTEPermissionInfo(List **rteperminfos, RangeTblEntry *rte)
    3871                 : {
    3872                 :     RTEPermissionInfo *perminfo;
    3873                 : 
    3874          790711 :     Assert(OidIsValid(rte->relid));
    3875          790711 :     Assert(rte->perminfoindex == 0);
    3876                 : 
    3877                 :     /* Nope, so make one and add to the list. */
    3878          790711 :     perminfo = makeNode(RTEPermissionInfo);
    3879          790711 :     perminfo->relid = rte->relid;
    3880          790711 :     perminfo->inh = rte->inh;
    3881                 :     /* Other information is set by fetching the node as and where needed. */
    3882                 : 
    3883          790711 :     *rteperminfos = lappend(*rteperminfos, perminfo);
    3884                 : 
    3885                 :     /* Note its index (1-based!) */
    3886          790711 :     rte->perminfoindex = list_length(*rteperminfos);
    3887                 : 
    3888          790711 :     return perminfo;
    3889                 : }
    3890                 : 
    3891                 : /*
    3892                 :  * getRTEPermissionInfo
    3893                 :  *      Find RTEPermissionInfo for a given relation in the provided list.
    3894                 :  *
    3895                 :  * This is a simple list_nth() operation, though it's good to have the
    3896                 :  * function for the various sanity checks.
    3897                 :  */
    3898                 : RTEPermissionInfo *
    3899         1817237 : getRTEPermissionInfo(List *rteperminfos, RangeTblEntry *rte)
    3900                 : {
    3901                 :     RTEPermissionInfo *perminfo;
    3902                 : 
    3903         1817237 :     if (rte->perminfoindex == 0 ||
    3904         1817237 :         rte->perminfoindex > list_length(rteperminfos))
    3905 UNC           0 :         elog(ERROR, "invalid perminfoindex %u in RTE with relid %u",
    3906                 :              rte->perminfoindex, rte->relid);
    3907 GNC     1817237 :     perminfo = list_nth_node(RTEPermissionInfo, rteperminfos,
    3908                 :                              rte->perminfoindex - 1);
    3909         1817237 :     if (perminfo->relid != rte->relid)
    3910 UNC           0 :         elog(ERROR, "permission info at index %u (with relid=%u) does not match provided RTE (with relid=%u)",
    3911                 :              rte->perminfoindex, perminfo->relid, rte->relid);
    3912                 : 
    3913 GNC     1817237 :     return perminfo;
    3914                 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a