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