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