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