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