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