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