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