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