Age Owner TLA Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * parse_relation.c
4 : * parser support routines dealing with relations
5 : *
6 : * Portions Copyright (c) 1996-2023, 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 *
1200 tgl 129 GIC 979785 : refnameNamespaceItem(ParseState *pstate,
130 : const char *schemaname,
131 : const char *refname,
132 : int location,
133 : int *sublevels_up)
134 : {
7549 135 979785 : Oid relId = InvalidOid;
136 :
8244 137 979785 : if (sublevels_up)
138 979785 : *sublevels_up = 0;
139 :
7549 140 979785 : 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
4790 bruce 149 ECB : * found", not "no permissions for schema", if the name happens to
150 : * match a schema name the user hasn't got access to.
151 : */
4908 tgl 152 GIC 39 : namespaceId = LookupNamespaceNoError(schemaname);
4729 153 39 : if (!OidIsValid(namespaceId))
4908 154 33 : return NULL;
7549 tgl 155 CBC 6 : relId = get_relname_relid(refname, namespaceId);
7549 tgl 156 GIC 6 : if (!OidIsValid(relId))
7549 tgl 157 LBC 0 : return NULL;
7549 tgl 158 ECB : }
159 :
8454 lockhart 160 CBC 1020532 : while (pstate != NULL)
161 : {
162 : ParseNamespaceItem *result;
163 :
7549 tgl 164 GIC 1004306 : if (OidIsValid(relId))
5333 165 9 : result = scanNameSpaceForRelid(pstate, relId, location);
166 : else
167 1004297 : result = scanNameSpaceForRefname(pstate, refname, location);
168 :
6517 169 1004294 : if (result)
170 963514 : return result;
171 :
8244 tgl 172 CBC 40780 : if (sublevels_up)
173 40780 : (*sublevels_up)++;
8244 tgl 174 ECB : else
8244 tgl 175 LBC 0 : break;
6517 tgl 176 ECB :
6517 tgl 177 GBC 40780 : pstate = pstate->parentParseState;
178 : }
8244 tgl 179 GIC 16226 : return NULL;
8454 lockhart 180 ECB : }
181 :
182 : /*
183 : * Search the query's table namespace for an item matching the
1200 tgl 184 : * given unqualified refname. Return the nsitem if a unique match, or NULL
7549 185 : * if no match. Raise error if multiple matches.
186 : *
3436 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
3436 tgl 195 EUB : * are visible. Rather than rejecting queries that used to work, we allow
196 : * this situation, and complain only if there's actually an ambiguous
3436 tgl 197 ECB : * reference to "x".
198 : */
1200 199 : static ParseNamespaceItem *
5333 tgl 200 GIC 1004297 : scanNameSpaceForRefname(ParseState *pstate, const char *refname, int location)
201 : {
1200 202 1004297 : ParseNamespaceItem *result = NULL;
203 : ListCell *l;
204 :
3896 205 5691867 : foreach(l, pstate->p_namespace)
206 : {
3897 207 4687582 : ParseNamespaceItem *nsitem = (ParseNamespaceItem *) lfirst(l);
208 :
209 : /* Ignore columns-only items */
3896 210 4687582 : if (!nsitem->p_rel_visible)
211 1307217 : continue;
212 : /* If not inside LATERAL, ignore lateral-only items */
3897 213 3380365 : if (nsitem->p_lateral_only && !pstate->p_lateral_active)
214 27 : continue;
215 :
739 peter 216 3380338 : if (strcmp(nsitem->p_names->aliasname, refname) == 0)
217 : {
6517 tgl 218 963526 : if (result)
7204 219 6 : ereport(ERROR,
7204 tgl 220 ECB : (errcode(ERRCODE_AMBIGUOUS_ALIAS),
221 : errmsg("table reference \"%s\" is ambiguous",
5333 222 : refname),
223 : parser_errposition(pstate, location)));
3375 tgl 224 GIC 963520 : check_lateral_ref_ok(pstate, nsitem, location);
1200 tgl 225 CBC 963514 : result = nsitem;
226 : }
8244 tgl 227 ECB : }
8244 tgl 228 GIC 1004285 : return result;
229 : }
8244 tgl 230 ECB :
7549 231 : /*
232 : * Search the query's table namespace for a relation item matching the
1200 233 : * given relation OID. Return the nsitem if a unique match, or NULL
3436 234 : * if no match. Raise error if multiple matches.
235 : *
1200 236 : * See the comments for refnameNamespaceItem to understand why this
237 : * acts the way it does.
7549 238 : */
1200 239 : static ParseNamespaceItem *
5333 tgl 240 GIC 9 : scanNameSpaceForRelid(ParseState *pstate, Oid relid, int location)
241 : {
1200 242 9 : ParseNamespaceItem *result = NULL;
243 : ListCell *l;
7549 tgl 244 ECB :
3896 tgl 245 CBC 18 : foreach(l, pstate->p_namespace)
246 : {
3897 tgl 247 GIC 9 : ParseNamespaceItem *nsitem = (ParseNamespaceItem *) lfirst(l);
3897 tgl 248 CBC 9 : RangeTblEntry *rte = nsitem->p_rte;
249 :
250 : /* Ignore columns-only items */
3896 tgl 251 GIC 9 : if (!nsitem->p_rel_visible)
3896 tgl 252 UIC 0 : continue;
253 : /* If not inside LATERAL, ignore lateral-only items */
3897 tgl 254 GIC 9 : if (nsitem->p_lateral_only && !pstate->p_lateral_active)
3897 tgl 255 UIC 0 : continue;
256 :
257 : /* yes, the test for alias == NULL should be there... */
7549 tgl 258 GIC 9 : if (rte->rtekind == RTE_RELATION &&
259 9 : rte->relid == relid &&
7549 tgl 260 CBC 6 : rte->alias == NULL)
261 : {
6517 262 6 : if (result)
7204 tgl 263 UIC 0 : ereport(ERROR,
264 : (errcode(ERRCODE_AMBIGUOUS_ALIAS),
7204 tgl 265 ECB : errmsg("table reference %u is ambiguous",
266 : relid),
5333 267 : parser_errposition(pstate, location)));
3375 tgl 268 CBC 6 : check_lateral_ref_ok(pstate, nsitem, location);
1200 tgl 269 GIC 6 : result = nsitem;
270 : }
7549 tgl 271 ECB : }
7549 tgl 272 GBC 9 : return result;
273 : }
9266 bruce 274 ECB :
5298 tgl 275 EUB : /*
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
5298 tgl 278 ECB : * 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 *
5298 tgl 282 CBC 205323 : scanNameSpaceForCTE(ParseState *pstate, const char *refname,
5298 tgl 283 EUB : Index *ctelevelsup)
284 : {
285 : Index levelsup;
286 :
5298 tgl 287 GIC 205323 : for (levelsup = 0;
5298 tgl 288 CBC 495830 : pstate != NULL;
289 290507 : pstate = pstate->parentParseState, levelsup++)
290 : {
291 : ListCell *lc;
5298 tgl 292 ECB :
5298 tgl 293 GIC 296020 : foreach(lc, pstate->p_ctenamespace)
294 : {
295 5513 : CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc);
296 :
297 5513 : if (strcmp(cte->ctename, refname) == 0)
298 : {
299 2565 : *ctelevelsup = levelsup;
300 2565 : return cte;
301 : }
5298 tgl 302 ECB : }
303 : }
5298 tgl 304 GIC 202758 : return NULL;
305 : }
306 :
5296 tgl 307 ECB : /*
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
5296 tgl 313 CBC 86 : isFutureCTE(ParseState *pstate, const char *refname)
314 : {
315 178 : for (; pstate != NULL; pstate = pstate->parentParseState)
316 : {
5050 bruce 317 ECB : ListCell *lc;
318 :
5296 tgl 319 CBC 95 : foreach(lc, pstate->p_future_ctes)
5296 tgl 320 ECB : {
5296 tgl 321 GIC 3 : CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc);
322 :
323 3 : if (strcmp(cte->ctename, refname) == 0)
5296 tgl 324 CBC 3 : return true;
325 : }
326 : }
5296 tgl 327 GIC 83 : return false;
328 : }
329 :
330 : /*
331 : * Search the query's ephemeral named relation namespace for a relation
332 : * matching the given unqualified refname.
2200 kgrittn 333 ECB : */
334 : bool
2200 kgrittn 335 CBC 250067 : scanNameSpaceForENR(ParseState *pstate, const char *refname)
336 : {
2200 kgrittn 337 GIC 250067 : return name_matches_visible_ENR(pstate, refname);
338 : }
2200 kgrittn 339 ECB :
340 : /*
3897 tgl 341 : * searchRangeTableForRel
342 : * See if any RangeTblEntry could possibly match the RangeVar.
6298 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
3260 bruce 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 : */
6298 tgl 355 : static RangeTblEntry *
3897 tgl 356 GIC 54 : searchRangeTableForRel(ParseState *pstate, RangeVar *relation)
6298 tgl 357 ECB : {
5298 tgl 358 GIC 54 : const char *refname = relation->relname;
359 54 : Oid relId = InvalidOid;
360 54 : CommonTableExpr *cte = NULL;
2200 kgrittn 361 54 : bool isenr = false;
5298 tgl 362 54 : 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.
5298 tgl 376 ECB : */
5298 tgl 377 GIC 54 : if (!relation->schemaname)
2200 kgrittn 378 ECB : {
5298 tgl 379 CBC 54 : cte = scanNameSpaceForCTE(pstate, refname, &ctelevelsup);
2200 kgrittn 380 54 : if (!cte)
381 54 : isenr = scanNameSpaceForENR(pstate, refname);
2200 kgrittn 382 ECB : }
383 :
2200 kgrittn 384 GIC 54 : if (!cte && !isenr)
4148 rhaas 385 54 : relId = RangeVarGetRelid(relation, NoLock, true);
386 :
387 : /* Now look for RTEs matching either the relation/CTE/ENR or the alias */
5298 tgl 388 54 : for (levelsup = 0;
389 78 : pstate != NULL;
390 24 : pstate = pstate->parentParseState, levelsup++)
391 : {
392 : ListCell *l;
393 :
6298 394 102 : foreach(l, pstate->p_rtable)
395 : {
396 78 : RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
6298 tgl 397 ECB :
5298 tgl 398 GIC 78 : if (rte->rtekind == RTE_RELATION &&
5298 tgl 399 CBC 57 : OidIsValid(relId) &&
6298 400 57 : rte->relid == relId)
401 45 : return rte;
5298 tgl 402 GIC 57 : if (rte->rtekind == RTE_CTE &&
5298 tgl 403 UIC 0 : cte != NULL &&
5298 tgl 404 LBC 0 : rte->ctelevelsup + levelsup == ctelevelsup &&
405 0 : strcmp(rte->ctename, refname) == 0)
5298 tgl 406 UIC 0 : return rte;
2200 kgrittn 407 GIC 57 : if (rte->rtekind == RTE_NAMEDTUPLESTORE &&
2200 kgrittn 408 LBC 0 : isenr &&
409 0 : strcmp(rte->enrname, refname) == 0)
410 0 : return rte;
6298 tgl 411 GIC 57 : if (strcmp(rte->eref->aliasname, refname) == 0)
412 24 : return rte;
413 : }
6298 tgl 414 ECB : }
6298 tgl 415 GIC 9 : return NULL;
6298 tgl 416 ECB : }
417 :
8244 418 : /*
3896 419 : * Check for relation-name conflicts between two namespace lists.
6517 420 : * Raise an error if any is found.
8244 421 : *
8089 422 : * Note: we assume that each given argument does not contain conflicts
8089 tgl 423 EUB : * itself; we just want to know if the two can be merged together.
7549 424 : *
3641 peter_e 425 : * Per SQL, two alias-less plain relation RTEs do not conflict even if
7549 tgl 426 : * they have the same eref->aliasname (ie, same relation name), if they
7549 tgl 427 ECB : * are for different relation OIDs (implying they are in different schemas).
3897 tgl 428 EUB : *
429 : * We ignore the lateral-only flags in the namespace items: the lists must
3896 430 : * not conflict, even when all items are considered visible. However,
3896 tgl 431 ECB : * columns-only items should be ignored.
8417 432 : */
433 : void
6517 tgl 434 GIC 319904 : checkNameSpaceConflicts(ParseState *pstate, List *namespace1,
6517 tgl 435 ECB : List *namespace2)
436 : {
437 : ListCell *l1;
438 :
6517 tgl 439 GIC 620210 : foreach(l1, namespace1)
440 : {
3897 441 300312 : ParseNamespaceItem *nsitem1 = (ParseNamespaceItem *) lfirst(l1);
442 300312 : RangeTblEntry *rte1 = nsitem1->p_rte;
739 peter 443 300312 : const char *aliasname1 = nsitem1->p_names->aliasname;
444 : ListCell *l2;
445 :
3896 tgl 446 300312 : if (!nsitem1->p_rel_visible)
447 56536 : continue;
448 :
6517 449 535765 : foreach(l2, namespace2)
450 : {
3897 451 291995 : ParseNamespaceItem *nsitem2 = (ParseNamespaceItem *) lfirst(l2);
452 291995 : RangeTblEntry *rte2 = nsitem2->p_rte;
739 peter 453 291995 : const char *aliasname2 = nsitem2->p_names->aliasname;
6517 tgl 454 ECB :
3896 tgl 455 GIC 291995 : if (!nsitem2->p_rel_visible)
456 24090 : continue;
739 peter 457 267905 : if (strcmp(aliasname2, aliasname1) != 0)
6517 tgl 458 267899 : continue; /* definitely no conflict */
6517 tgl 459 CBC 6 : if (rte1->rtekind == RTE_RELATION && rte1->alias == NULL &&
6517 tgl 460 GIC 3 : rte2->rtekind == RTE_RELATION && rte2->alias == NULL &&
6517 tgl 461 CBC 3 : rte1->relid != rte2->relid)
3641 peter_e 462 LBC 0 : continue; /* no conflict per SQL rule */
6517 tgl 463 CBC 6 : ereport(ERROR,
464 : (errcode(ERRCODE_DUPLICATE_ALIAS),
465 : errmsg("table name \"%s\" specified more than once",
7188 bruce 466 ECB : aliasname1)));
7549 tgl 467 : }
468 : }
7549 tgl 469 CBC 319898 : }
470 :
3375 tgl 471 ECB : /*
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 : *
1200 478 : * Note: the pstate should be the same query level the nsitem was found in.
479 : *
3375 480 : * Convenience subroutine to avoid multiple copies of a rather ugly ereport.
481 : */
3375 tgl 482 EUB : static void
3375 tgl 483 CBC 1328285 : check_lateral_ref_ok(ParseState *pstate, ParseNamespaceItem *nsitem,
484 : int location)
485 : {
3375 tgl 486 GIC 1328285 : if (nsitem->p_lateral_only && !nsitem->p_lateral_ok)
487 : {
488 : /* SQL:2008 demands this be an error, not an invisible item */
3375 tgl 489 CBC 12 : RangeTblEntry *rte = nsitem->p_rte;
739 peter 490 GIC 12 : char *refname = nsitem->p_names->aliasname;
491 :
3375 tgl 492 12 : 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 : }
3375 tgl 503 CBC 1328273 : }
504 :
505 : /*
1200 tgl 506 ECB : * Given an RT index and nesting depth, find the corresponding
507 : * ParseNamespaceItem (there must be one).
508 : */
509 : ParseNamespaceItem *
1200 tgl 510 CBC 570 : GetNSItemByRangeTablePosn(ParseState *pstate,
511 : int varno,
1200 tgl 512 ECB : int sublevels_up)
513 : {
514 : ListCell *lc;
515 :
1200 tgl 516 GIC 570 : while (sublevels_up-- > 0)
517 : {
8244 tgl 518 UIC 0 : pstate = pstate->parentParseState;
1200 519 0 : Assert(pstate != NULL);
520 : }
1200 tgl 521 GIC 624 : foreach(lc, pstate->p_namespace)
522 : {
1200 tgl 523 CBC 624 : ParseNamespaceItem *nsitem = (ParseNamespaceItem *) lfirst(lc);
524 :
1200 tgl 525 GIC 624 : if (nsitem->p_rtindex == varno)
526 570 : return nsitem;
527 : }
1200 tgl 528 UIC 0 : elog(ERROR, "nsitem not found (internal error)");
529 : return NULL; /* keep compiler quiet */
8244 tgl 530 ECB : }
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 : */
6946 536 : RangeTblEntry *
6946 tgl 537 GIC 532374 : GetRTEByRangeTablePosn(ParseState *pstate,
6946 tgl 538 EUB : int varno,
539 : int sublevels_up)
540 : {
6946 tgl 541 CBC 532781 : while (sublevels_up-- > 0)
542 : {
543 407 : pstate = pstate->parentParseState;
6946 tgl 544 GIC 407 : Assert(pstate != NULL);
6946 tgl 545 ECB : }
6888 neilc 546 CBC 532374 : Assert(varno > 0 && varno <= list_length(pstate->p_rtable));
6946 tgl 547 GIC 532374 : return rt_fetch(varno, pstate->p_rtable);
6946 tgl 548 EUB : }
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 *
5298 tgl 557 CBC 3206 : GetCTEForRTE(ParseState *pstate, RangeTblEntry *rte, int rtelevelsup)
558 : {
559 : Index levelsup;
560 : ListCell *lc;
5300 tgl 561 ECB :
5300 tgl 562 GIC 3206 : Assert(rte->rtekind == RTE_CTE);
5298 tgl 563 CBC 3206 : levelsup = rte->ctelevelsup + rtelevelsup;
5300 564 6333 : while (levelsup-- > 0)
565 : {
566 3127 : pstate = pstate->parentParseState;
567 3127 : if (!pstate) /* shouldn't happen */
5300 tgl 568 UIC 0 : elog(ERROR, "bad levelsup for CTE \"%s\"", rte->ctename);
569 : }
5300 tgl 570 GIC 5732 : foreach(lc, pstate->p_ctenamespace)
571 : {
572 5732 : CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc);
573 :
574 5732 : if (strcmp(cte->ctename, rte->ctename) == 0)
575 3206 : return cte;
576 : }
5300 tgl 577 ECB : /* shouldn't happen */
5300 tgl 578 UIC 0 : elog(ERROR, "could not find CTE \"%s\"", rte->ctename);
579 : return NULL; /* keep compiler quiet */
580 : }
581 :
2951 rhaas 582 ECB : /*
583 : * updateFuzzyAttrMatchState
584 : * Using Levenshtein distance, consider if column is best fuzzy match.
585 : */
586 : static void
2951 rhaas 587 CBC 1098 : updateFuzzyAttrMatchState(int fuzzy_rte_penalty,
2951 rhaas 588 EUB : FuzzyAttrMatchState *fuzzystate, RangeTblEntry *rte,
589 : const char *actual, const char *match, int attnum)
2951 rhaas 590 ECB : {
591 : int columndistance;
2878 bruce 592 : int matchlen;
593 :
2951 rhaas 594 : /* Bail before computing the Levenshtein distance if there's no hope. */
2951 rhaas 595 CBC 1098 : if (fuzzy_rte_penalty > fuzzystate->distance)
2951 rhaas 596 GIC 27 : return;
597 :
2951 rhaas 598 EUB : /*
599 : * Outright reject dropped columns, which can appear here with apparent
600 : * empty actual names, per remarks within scanRTEForColumn().
601 : */
2951 rhaas 602 GIC 1071 : if (actual[0] == '\0')
603 63 : return;
604 :
605 : /* Use Levenshtein to compute match distance. */
606 1008 : matchlen = strlen(match);
2951 rhaas 607 ECB : columndistance =
2951 rhaas 608 GIC 1008 : varstr_levenshtein_less_equal(actual, strlen(actual), match, matchlen,
609 : 1, 1, 1,
610 1008 : fuzzystate->distance + 1
2634 tgl 611 1008 : - fuzzy_rte_penalty,
612 : true);
613 :
614 : /*
2951 rhaas 615 ECB : * If more than half the characters are different, don't treat it as a
616 : * match, to avoid making ridiculous suggestions.
617 : */
2951 rhaas 618 GIC 1008 : if (columndistance > matchlen / 2)
619 579 : return;
620 :
621 : /*
2878 bruce 622 ECB : * From this point on, we can ignore the distinction between the RTE-name
623 : * distance and the column-name distance.
624 : */
2951 rhaas 625 GIC 429 : columndistance += fuzzy_rte_penalty;
2951 rhaas 626 ECB :
627 : /*
628 : * If the new distance is less than or equal to that of the best match
629 : * found so far, update fuzzystate.
630 : */
2951 rhaas 631 CBC 429 : if (columndistance < fuzzystate->distance)
632 : {
633 : /* Store new lowest observed distance as first/only match */
2951 rhaas 634 GIC 57 : fuzzystate->distance = columndistance;
635 57 : fuzzystate->rfirst = rte;
636 57 : fuzzystate->first = attnum;
637 57 : fuzzystate->rsecond = NULL;
2951 rhaas 638 ECB : }
2951 rhaas 639 GIC 372 : else if (columndistance == fuzzystate->distance)
640 : {
641 : /* If we already have a match of this distance, update state */
138 tgl 642 GNC 12 : 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 : */
2951 rhaas 651 GIC 3 : fuzzystate->rfirst = NULL;
2951 rhaas 652 CBC 3 : fuzzystate->rsecond = NULL;
653 : }
138 tgl 654 GNC 9 : else if (fuzzystate->rfirst != NULL)
655 : {
656 : /* Record as provisional second match */
2951 rhaas 657 CBC 9 : fuzzystate->rsecond = rte;
2951 rhaas 658 GIC 9 : 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.
2951 rhaas 665 ECB : */
666 : }
667 : }
668 : }
669 :
1200 tgl 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 *
1200 tgl 680 GIC 1389202 : scanNSItemForColumn(ParseState *pstate, ParseNamespaceItem *nsitem,
681 : int sublevels_up, const char *colname, int location)
682 : {
683 1389202 : 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 : */
739 peter 691 1389202 : attnum = scanRTEForColumn(pstate, rte, nsitem->p_names,
1200 tgl 692 ECB : colname, location,
693 : 0, NULL);
694 :
1200 tgl 695 CBC 1389196 : if (attnum == InvalidAttrNumber)
1200 tgl 696 GIC 80667 : return NULL; /* Return NULL if no match */
697 :
698 : /* In constraint check, no system column is allowed except tableOid */
699 1308529 : if (pstate->p_expr_kind == EXPR_KIND_CHECK_CONSTRAINT &&
700 6 : attnum < InvalidAttrNumber && attnum != TableOidAttributeNumber)
701 3 : ereport(ERROR,
702 : (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
1200 tgl 703 ECB : 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 */
1200 tgl 708 CBC 1308526 : if (pstate->p_expr_kind == EXPR_KIND_GENERATED_COLUMN &&
1200 tgl 709 GIC 11 : attnum < InvalidAttrNumber && attnum != TableOidAttributeNumber)
710 3 : ereport(ERROR,
1200 tgl 711 ECB : (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 : */
377 alvherre 719 GIC 1308523 : if (pstate->p_expr_kind == EXPR_KIND_MERGE_WHEN &&
377 alvherre 720 CBC 6 : attnum < InvalidAttrNumber && attnum != TableOidAttributeNumber)
721 3 : ereport(ERROR,
377 alvherre 722 ECB : (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 */
1193 tgl 728 GIC 1308520 : if (attnum > InvalidAttrNumber)
729 : {
730 : /* Get attribute data from the ParseNamespaceColumn array */
1193 tgl 731 CBC 1293069 : ParseNamespaceColumn *nscol = &nsitem->p_nscolumns[attnum - 1];
1193 tgl 732 ECB :
733 : /* Complain if dropped column. See notes in scanRTEForColumn. */
1193 tgl 734 GIC 1293069 : if (nscol->p_varno == 0)
1193 tgl 735 UIC 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)));
1193 tgl 740 ECB :
1186 tgl 741 GIC 1293069 : var = makeVar(nscol->p_varno,
742 1293069 : nscol->p_varattno,
1193 tgl 743 ECB : nscol->p_vartype,
744 : nscol->p_vartypmod,
745 : nscol->p_varcollid,
746 : sublevels_up);
1186 tgl 747 EUB : /* makeVar doesn't offer parameters for these, so set them by hand: */
1186 tgl 748 GIC 1293069 : var->varnosyn = nscol->p_varnosyn;
749 1293069 : var->varattnosyn = nscol->p_varattnosyn;
750 : }
751 : else
752 : {
1193 tgl 753 ECB : /* System column, so use predetermined type data */
754 : const FormData_pg_attribute *sysatt;
755 :
1193 tgl 756 GIC 15451 : sysatt = SystemAttributeDefinition(attnum);
757 15451 : var = makeVar(nsitem->p_rtindex,
758 : attnum,
759 15451 : sysatt->atttypid,
1193 tgl 760 CBC 15451 : sysatt->atttypmod,
761 15451 : sysatt->attcollation,
762 : sublevels_up);
763 : }
1200 tgl 764 GIC 1308520 : var->location = location;
765 :
766 : /* Mark Var if it's nulled by any outer joins */
69 tgl 767 GNC 1308520 : markNullableIfNeeded(pstate, var);
768 :
769 : /* Require read access to the column */
787 tgl 770 GIC 1308520 : markVarForSelectPriv(pstate, var);
1200 tgl 771 ECB :
1200 tgl 772 CBC 1308520 : return (Node *) var;
773 : }
1200 tgl 774 ECB :
8244 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);
1200 779 : * else return InvalidAttrNumber.
780 : * If the name proves ambiguous within this RTE, raise error.
781 : *
739 peter 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
1200 tgl 800 GIC 1389391 : scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte,
801 : Alias *eref,
802 : const char *colname, int location,
803 : int fuzzy_rte_penalty,
804 : FuzzyAttrMatchState *fuzzystate)
805 : {
806 1389391 : int result = InvalidAttrNumber;
8244 807 1389391 : 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
6385 bruce 815 ECB : * 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
1193 tgl 821 : * defend against this directly, though.
8244 822 : */
739 peter 823 GIC 28579090 : foreach(c, eref->colnames)
824 : {
2951 rhaas 825 27189705 : const char *attcolname = strVal(lfirst(c));
826 :
8244 tgl 827 27189705 : attnum++;
2951 rhaas 828 27189705 : if (strcmp(attcolname, colname) == 0)
829 : {
8244 tgl 830 1293111 : if (result)
7204 831 6 : ereport(ERROR,
832 : (errcode(ERRCODE_AMBIGUOUS_COLUMN),
833 : errmsg("column reference \"%s\" is ambiguous",
834 : colname),
835 : parser_errposition(pstate, location)));
1200 836 1293105 : result = attnum;
837 : }
2951 rhaas 838 ECB :
839 : /* Update fuzzy match state, if provided. */
2951 rhaas 840 CBC 27189699 : if (fuzzystate != NULL)
2951 rhaas 841 GIC 1098 : updateFuzzyAttrMatchState(fuzzy_rte_penalty, fuzzystate,
2951 rhaas 842 ECB : rte, attcolname, colname, attnum);
8244 tgl 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 : */
8244 tgl 849 GIC 1389385 : if (result)
850 1293099 : return result;
9173 bruce 851 ECB :
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
2745 andres 855 : * excluded.
8244 tgl 856 : */
2745 andres 857 GIC 96286 : if (rte->rtekind == RTE_RELATION &&
858 64907 : rte->relkind != RELKIND_COMPOSITE_TYPE)
859 : {
860 : /* quick check to see if name could be a system column */
8244 tgl 861 64880 : attnum = specialAttNum(colname);
862 64880 : if (attnum != InvalidAttrNumber)
863 : {
7912 tgl 864 ECB : /* now check to see if column actually is defined */
4802 rhaas 865 CBC 15469 : if (SearchSysCacheExists2(ATTNUM,
866 : ObjectIdGetDatum(rte->relid),
867 : Int16GetDatum(attnum)))
1200 tgl 868 GIC 15469 : result = attnum;
869 : }
870 : }
871 :
8244 tgl 872 CBC 96286 : return result;
8244 tgl 873 ECB : }
874 :
875 : /*
6930 876 : * colNameToVar
8244 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.
6930 880 : * If localonly is true, only names in the innermost query are considered.
881 : */
882 : Node *
1986 peter_e 883 CBC 396284 : colNameToVar(ParseState *pstate, const char *colname, bool localonly,
884 : int location)
885 : {
8244 tgl 886 GIC 396284 : Node *result = NULL;
1200 tgl 887 CBC 396284 : int sublevels_up = 0;
8244 tgl 888 GIC 396284 : ParseState *orig_pstate = pstate;
889 :
890 433392 : while (pstate != NULL)
891 : {
892 : ListCell *l;
893 :
3896 894 1368408 : foreach(l, pstate->p_namespace)
895 : {
3897 896 966522 : ParseNamespaceItem *nsitem = (ParseNamespaceItem *) lfirst(l);
897 : Node *newresult;
7698 tgl 898 ECB :
899 : /* Ignore table-only items */
3896 tgl 900 GIC 966522 : if (!nsitem->p_cols_visible)
3896 tgl 901 CBC 521211 : continue;
3897 tgl 902 ECB : /* If not inside LATERAL, ignore lateral-only items */
3897 tgl 903 CBC 445311 : if (nsitem->p_lateral_only && !pstate->p_lateral_active)
3897 tgl 904 GIC 23 : continue;
3897 tgl 905 ECB :
906 : /* use orig_pstate here for consistency with other callers */
1200 tgl 907 GIC 445288 : newresult = scanNSItemForColumn(orig_pstate, nsitem, sublevels_up,
908 : colname, location);
8244 tgl 909 ECB :
8244 tgl 910 GIC 445276 : if (newresult)
8244 tgl 911 ECB : {
8244 tgl 912 GIC 364771 : if (result)
7204 913 12 : ereport(ERROR,
914 : (errcode(ERRCODE_AMBIGUOUS_COLUMN),
6385 bruce 915 ECB : errmsg("column reference \"%s\" is ambiguous",
6235 tgl 916 : colname),
917 : parser_errposition(pstate, location)));
3375 tgl 918 CBC 364759 : check_lateral_ref_ok(pstate, nsitem, location);
8244 919 364753 : result = newresult;
920 : }
921 : }
8454 lockhart 922 ECB :
6930 tgl 923 GIC 401886 : if (result != NULL || localonly)
924 : break; /* found, or don't want to look at parent */
8417 tgl 925 ECB :
8417 tgl 926 GIC 37108 : pstate = pstate->parentParseState;
1200 tgl 927 CBC 37108 : sublevels_up++;
9266 bruce 928 ECB : }
929 :
8244 tgl 930 GIC 396254 : return result;
931 : }
932 :
3897 tgl 933 ECB : /*
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 : *
2951 rhaas 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 *
1986 peter_e 952 GIC 170 : searchRangeTableForCol(ParseState *pstate, const char *alias, const char *colname,
953 : int location)
954 : {
3897 tgl 955 170 : ParseState *orig_pstate = pstate;
2951 rhaas 956 170 : FuzzyAttrMatchState *fuzzystate = palloc(sizeof(FuzzyAttrMatchState));
957 :
958 170 : fuzzystate->distance = MAX_FUZZY_DISTANCE + 1;
959 170 : fuzzystate->rfirst = NULL;
960 170 : fuzzystate->rsecond = NULL;
138 tgl 961 GNC 170 : fuzzystate->rexact1 = NULL;
962 170 : fuzzystate->rexact2 = NULL;
963 :
3897 tgl 964 CBC 355 : while (pstate != NULL)
3897 tgl 965 ECB : {
966 : ListCell *l;
967 :
3897 tgl 968 CBC 401 : foreach(l, pstate->p_rtable)
3897 tgl 969 ECB : {
2878 bruce 970 CBC 216 : RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
971 216 : int fuzzy_rte_penalty = 0;
972 : int attnum;
973 :
2951 rhaas 974 ECB : /*
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 : */
2951 rhaas 980 CBC 216 : if (rte->rtekind == RTE_JOIN)
981 27 : 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 : */
2951 rhaas 989 GIC 189 : if (alias != NULL)
2951 rhaas 990 ECB : fuzzy_rte_penalty =
2634 tgl 991 CBC 54 : varstr_levenshtein_less_equal(alias, strlen(alias),
2634 tgl 992 GIC 54 : rte->eref->aliasname,
2118 993 54 : 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.)
2951 rhaas 1003 ECB : */
138 tgl 1004 GNC 189 : attnum = scanRTEForColumn(orig_pstate, rte, rte->eref,
1005 : colname, location,
1006 : fuzzy_rte_penalty, fuzzystate);
1007 189 : if (attnum != InvalidAttrNumber && fuzzy_rte_penalty == 0)
1008 : {
1009 30 : if (fuzzystate->rexact1 == NULL)
1010 : {
1011 21 : fuzzystate->rexact1 = rte;
1012 21 : fuzzystate->exact1 = attnum;
1013 : }
1014 : else
1015 : {
1016 : /* Needn't worry about overwriting previous rexact2 */
1017 9 : fuzzystate->rexact2 = rte;
1018 9 : fuzzystate->exact2 = attnum;
1019 : }
1020 : }
1021 : }
1022 :
3897 tgl 1023 CBC 185 : pstate = pstate->parentParseState;
1024 : }
1025 :
2951 rhaas 1026 170 : return fuzzystate;
1027 : }
3897 tgl 1028 ECB :
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
69 tgl 1035 GNC 4787207 : markNullableIfNeeded(ParseState *pstate, Var *var)
1036 : {
1037 4787207 : int rtindex = var->varno;
1038 : Bitmapset *relids;
1039 :
1040 : /* Find the appropriate pstate */
1041 4816903 : for (int lv = 0; lv < var->varlevelsup; lv++)
1042 29696 : pstate = pstate->parentParseState;
1043 :
1044 : /* Find currently-relevant join relids for the Var's rel */
1045 4787207 : if (rtindex > 0 && rtindex <= list_length(pstate->p_nullingrels))
1046 2304725 : relids = (Bitmapset *) list_nth(pstate->p_nullingrels, rtindex - 1);
1047 : else
1048 2482482 : 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 4787207 : if (relids != NULL)
1055 809130 : var->varnullingrels = bms_union(var->varnullingrels, relids);
1056 4787207 : }
1057 :
1058 : /*
5190 tgl 1059 ECB : * markRTEForSelectPriv
790 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 : */
5190 1065 : static void
790 tgl 1066 CBC 1476562 : markRTEForSelectPriv(ParseState *pstate, int rtindex, AttrNumber col)
1067 : {
790 tgl 1068 GIC 1476562 : RangeTblEntry *rte = rt_fetch(rtindex, pstate->p_rtable);
1069 :
5190 1070 1476562 : if (rte->rtekind == RTE_RELATION)
5190 tgl 1071 ECB : {
1072 : RTEPermissionInfo *perminfo;
1073 :
1074 : /* Make sure the rel as a whole is marked for SELECT access */
124 alvherre 1075 GNC 1208300 : perminfo = getRTEPermissionInfo(pstate->p_rteperminfos, rte);
1076 1208300 : perminfo->requiredPerms |= ACL_SELECT;
5190 tgl 1077 ECB : /* Must offset the attnum to fit in a bitmapset */
124 alvherre 1078 GNC 1208300 : perminfo->selectedCols =
1079 1208300 : bms_add_member(perminfo->selectedCols,
1080 : col - FirstLowInvalidHeapAttributeNumber);
1081 : }
5190 tgl 1082 GIC 268262 : else if (rte->rtekind == RTE_JOIN)
1083 : {
1084 210 : if (col == InvalidAttrNumber)
1085 : {
1086 : /*
5050 bruce 1087 ECB : * A whole-row reference to a join has to be treated as whole-row
1088 : * references to the two inputs.
5190 tgl 1089 : */
1090 : JoinExpr *j;
1091 :
5190 tgl 1092 GIC 3 : if (rtindex > 0 && rtindex <= list_length(pstate->p_joinexprs))
2190 tgl 1093 CBC 3 : j = list_nth_node(JoinExpr, pstate->p_joinexprs, rtindex - 1);
5190 tgl 1094 ECB : else
5190 tgl 1095 UIC 0 : j = NULL;
5190 tgl 1096 GIC 3 : if (j == NULL)
5190 tgl 1097 LBC 0 : elog(ERROR, "could not find JoinExpr for whole-row reference");
5190 tgl 1098 ECB :
1099 : /* Note: we can't see FromExpr here */
5190 tgl 1100 CBC 3 : if (IsA(j->larg, RangeTblRef))
1101 : {
5050 bruce 1102 GIC 3 : int varno = ((RangeTblRef *) j->larg)->rtindex;
1103 :
790 tgl 1104 3 : markRTEForSelectPriv(pstate, varno, InvalidAttrNumber);
1105 : }
5190 tgl 1106 LBC 0 : else if (IsA(j->larg, JoinExpr))
5190 tgl 1107 ECB : {
5050 bruce 1108 LBC 0 : int varno = ((JoinExpr *) j->larg)->rtindex;
1109 :
790 tgl 1110 UIC 0 : markRTEForSelectPriv(pstate, varno, InvalidAttrNumber);
1111 : }
1112 : else
5190 1113 0 : elog(ERROR, "unrecognized node type: %d",
1114 : (int) nodeTag(j->larg));
5190 tgl 1115 GIC 3 : if (IsA(j->rarg, RangeTblRef))
1116 : {
5050 bruce 1117 3 : int varno = ((RangeTblRef *) j->rarg)->rtindex;
5190 tgl 1118 ECB :
790 tgl 1119 GIC 3 : markRTEForSelectPriv(pstate, varno, InvalidAttrNumber);
5190 tgl 1120 ECB : }
5190 tgl 1121 UIC 0 : else if (IsA(j->rarg, JoinExpr))
5190 tgl 1122 ECB : {
5050 bruce 1123 UIC 0 : int varno = ((JoinExpr *) j->rarg)->rtindex;
1124 :
790 tgl 1125 0 : markRTEForSelectPriv(pstate, varno, InvalidAttrNumber);
1126 : }
5190 tgl 1127 ECB : else
5190 tgl 1128 LBC 0 : elog(ERROR, "unrecognized node type: %d",
1129 : (int) nodeTag(j->rarg));
5190 tgl 1130 ECB : }
1131 : else
1132 : {
1133 : /*
1186 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 */
5190 tgl 1142 GIC 1476562 : }
1143 :
5190 tgl 1144 ECB : /*
1145 : * markVarForSelectPriv
1146 : * Mark the RTE referenced by the Var as requiring SELECT privilege
790 tgl 1147 EUB : * for the Var's column (the Var could be a whole-row Var, too)
5190 tgl 1148 ECB : */
5190 tgl 1149 EUB : void
787 tgl 1150 GIC 1476556 : markVarForSelectPriv(ParseState *pstate, Var *var)
1151 : {
5050 bruce 1152 ECB : Index lv;
1153 :
5190 tgl 1154 CBC 1476556 : Assert(IsA(var, Var));
1155 : /* Find the appropriate pstate if it's an uplevel Var */
1156 1506252 : for (lv = 0; lv < var->varlevelsup; lv++)
5190 tgl 1157 GIC 29696 : pstate = pstate->parentParseState;
790 tgl 1158 GBC 1476556 : markRTEForSelectPriv(pstate, var->varno, var->varattno);
5190 tgl 1159 GIC 1476556 : }
5190 tgl 1160 EUB :
1161 : /*
6807 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
6807 tgl 1167 ECB : * 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.
3541 stark 1173 EUB : *
1174 : * It is an error for there to be more aliases present than required.
6807 tgl 1175 : */
1176 : static void
3426 tgl 1177 GBC 451592 : buildRelationAliases(TupleDesc tupdesc, Alias *alias, Alias *eref)
1178 : {
6807 tgl 1179 GIC 451592 : int maxattrs = tupdesc->natts;
1364 tgl 1180 EUB : List *aliaslist;
1181 : ListCell *aliaslc;
1182 : int numaliases;
1183 : int varattno;
6807 tgl 1184 GIC 451592 : int numdropped = 0;
1185 :
1186 451592 : Assert(eref->colnames == NIL);
1187 :
1188 451592 : if (alias)
1189 : {
1364 1190 210561 : aliaslist = alias->colnames;
1191 210561 : aliaslc = list_head(aliaslist);
1192 210561 : numaliases = list_length(aliaslist);
1193 : /* We'll rebuild the alias colname list */
6807 tgl 1194 CBC 210561 : alias->colnames = NIL;
1195 : }
1196 : else
1197 : {
1364 tgl 1198 GIC 241031 : aliaslist = NIL;
6807 1199 241031 : aliaslc = NULL;
1200 241031 : numaliases = 0;
1201 : }
6807 tgl 1202 ECB :
6807 tgl 1203 GIC 5639624 : for (varattno = 0; varattno < maxattrs; varattno++)
1204 : {
2058 andres 1205 5188032 : Form_pg_attribute attr = TupleDescAttr(tupdesc, varattno);
577 peter 1206 ECB : String *attrname;
1207 :
6807 tgl 1208 CBC 5188032 : if (attr->attisdropped)
6807 tgl 1209 ECB : {
1210 : /* Always insert an empty string for a dropped column */
6807 tgl 1211 CBC 2604 : attrname = makeString(pstrdup(""));
6807 tgl 1212 GIC 2604 : if (aliaslc)
1213 3 : alias->colnames = lappend(alias->colnames, attrname);
1214 2604 : numdropped++;
1215 : }
1216 5185428 : else if (aliaslc)
1217 : {
1218 : /* Use the next user-supplied alias */
577 peter 1219 3023 : attrname = lfirst_node(String, aliaslc);
1364 tgl 1220 3023 : aliaslc = lnext(aliaslist, aliaslc);
6807 1221 3023 : alias->colnames = lappend(alias->colnames, attrname);
1222 : }
1223 : else
1224 : {
1225 5182405 : attrname = makeString(pstrdup(NameStr(attr->attname)));
1226 : /* we're done with the alias if any */
1227 : }
1228 :
6807 tgl 1229 CBC 5188032 : eref->colnames = lappend(eref->colnames, attrname);
1230 : }
6807 tgl 1231 ECB :
1232 : /* Too many user-supplied aliases? */
6807 tgl 1233 GIC 451592 : if (aliaslc)
1234 3 : ereport(ERROR,
1235 : (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
6807 tgl 1236 ECB : errmsg("table \"%s\" has %d columns available but %d columns specified",
1237 : eref->aliasname, maxattrs - numdropped, numaliases)));
6807 tgl 1238 CBC 451589 : }
1239 :
6394 tgl 1240 ECB : /*
1241 : * chooseScalarFunctionAlias
3426 1242 : * Select the column alias for a function in a function RTE,
6394 1243 : * when the function returns a scalar type (not composite or RECORD).
1244 : *
1245 : * funcexpr: transformed expression tree for the function call
3426 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.
6394 1252 : */
1253 : static char *
3426 tgl 1254 GIC 8672 : chooseScalarFunctionAlias(Node *funcexpr, char *funcname,
3426 tgl 1255 ECB : 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 : */
3426 tgl 1263 CBC 8672 : if (funcexpr && IsA(funcexpr, FuncExpr))
6394 tgl 1264 ECB : {
3426 tgl 1265 CBC 8666 : pname = get_func_result_name(((FuncExpr *) funcexpr)->funcid);
1266 8666 : if (pname)
3426 tgl 1267 GIC 358 : return pname;
6394 tgl 1268 ECB : }
1269 :
1270 : /*
3426 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 : */
3426 tgl 1275 GIC 8314 : if (nfuncs == 1 && alias)
1276 6598 : return alias->aliasname;
3541 stark 1277 ECB :
1278 : /*
1279 : * Otherwise use the function name.
1280 : */
3426 tgl 1281 CBC 1716 : return funcname;
1282 : }
1283 :
1284 : /*
1193 tgl 1285 ECB : * 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 *
124 alvherre 1294 GNC 451589 : buildNSItemFromTupleDesc(RangeTblEntry *rte, Index rtindex,
1295 : RTEPermissionInfo *perminfo,
1296 : TupleDesc tupdesc)
1297 : {
1298 : ParseNamespaceItem *nsitem;
1299 : ParseNamespaceColumn *nscolumns;
1193 tgl 1300 GIC 451589 : int maxattrs = tupdesc->natts;
1301 : int varattno;
1302 :
1303 : /* colnames must have the same number of entries as the nsitem */
1304 451589 : Assert(maxattrs == list_length(rte->eref->colnames));
1305 :
1306 : /* extract per-column data from the tupdesc */
1307 : nscolumns = (ParseNamespaceColumn *)
1308 451589 : palloc0(maxattrs * sizeof(ParseNamespaceColumn));
1193 tgl 1309 ECB :
1193 tgl 1310 GIC 5639618 : for (varattno = 0; varattno < maxattrs; varattno++)
1311 : {
1312 5188029 : Form_pg_attribute attr = TupleDescAttr(tupdesc, varattno);
1313 :
1314 : /* For a dropped column, just leave the entry as zeroes */
1315 5188029 : if (attr->attisdropped)
1316 2604 : continue;
1317 :
1193 tgl 1318 CBC 5185425 : nscolumns[varattno].p_varno = rtindex;
1193 tgl 1319 GIC 5185425 : nscolumns[varattno].p_varattno = varattno + 1;
1193 tgl 1320 CBC 5185425 : nscolumns[varattno].p_vartype = attr->atttypid;
1321 5185425 : nscolumns[varattno].p_vartypmod = attr->atttypmod;
1322 5185425 : nscolumns[varattno].p_varcollid = attr->attcollation;
1193 tgl 1323 GIC 5185425 : nscolumns[varattno].p_varnosyn = rtindex;
1324 5185425 : nscolumns[varattno].p_varattnosyn = varattno + 1;
1325 : }
1326 :
1327 : /* ... and build the nsitem */
1328 451589 : nsitem = (ParseNamespaceItem *) palloc(sizeof(ParseNamespaceItem));
739 peter 1329 451589 : nsitem->p_names = rte->eref;
1193 tgl 1330 CBC 451589 : nsitem->p_rte = rte;
1331 451589 : nsitem->p_rtindex = rtindex;
124 alvherre 1332 GNC 451589 : nsitem->p_perminfo = perminfo;
1193 tgl 1333 GIC 451589 : nsitem->p_nscolumns = nscolumns;
1334 : /* set default visibility flags; might get changed later */
1335 451589 : nsitem->p_rel_visible = true;
1336 451589 : nsitem->p_cols_visible = true;
1193 tgl 1337 CBC 451589 : nsitem->p_lateral_only = false;
1193 tgl 1338 GIC 451589 : nsitem->p_lateral_ok = true;
1339 :
1340 451589 : 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
1193 tgl 1350 ECB : * coltypmods: per-column type modifiers
1351 : * colcollation: per-column collation OIDs
1352 : */
1353 : static ParseNamespaceItem *
1193 tgl 1354 GIC 54541 : buildNSItemFromLists(RangeTblEntry *rte, Index rtindex,
1355 : List *coltypes, List *coltypmods, List *colcollations)
1193 tgl 1356 ECB : {
1357 : ParseNamespaceItem *nsitem;
1358 : ParseNamespaceColumn *nscolumns;
1193 tgl 1359 GIC 54541 : int maxattrs = list_length(coltypes);
1193 tgl 1360 ECB : int varattno;
1361 : ListCell *lct;
1362 : ListCell *lcm;
1363 : ListCell *lcc;
1364 :
1365 : /* colnames must have the same number of entries as the nsitem */
1193 tgl 1366 CBC 54541 : Assert(maxattrs == list_length(rte->eref->colnames));
1367 :
1368 54541 : Assert(maxattrs == list_length(coltypmods));
1193 tgl 1369 GIC 54541 : Assert(maxattrs == list_length(colcollations));
1370 :
1193 tgl 1371 ECB : /* extract per-column data from the lists */
1372 : nscolumns = (ParseNamespaceColumn *)
1193 tgl 1373 GIC 54541 : palloc0(maxattrs * sizeof(ParseNamespaceColumn));
1193 tgl 1374 ECB :
1193 tgl 1375 CBC 54541 : varattno = 0;
1376 261826 : forthree(lct, coltypes,
1193 tgl 1377 ECB : lcm, coltypmods,
1378 : lcc, colcollations)
1379 : {
1193 tgl 1380 CBC 207285 : nscolumns[varattno].p_varno = rtindex;
1193 tgl 1381 GIC 207285 : nscolumns[varattno].p_varattno = varattno + 1;
1382 207285 : nscolumns[varattno].p_vartype = lfirst_oid(lct);
1383 207285 : nscolumns[varattno].p_vartypmod = lfirst_int(lcm);
1193 tgl 1384 CBC 207285 : nscolumns[varattno].p_varcollid = lfirst_oid(lcc);
1385 207285 : nscolumns[varattno].p_varnosyn = rtindex;
1386 207285 : nscolumns[varattno].p_varattnosyn = varattno + 1;
1387 207285 : varattno++;
1193 tgl 1388 ECB : }
1389 :
1390 : /* ... and build the nsitem */
1193 tgl 1391 CBC 54541 : nsitem = (ParseNamespaceItem *) palloc(sizeof(ParseNamespaceItem));
739 peter 1392 54541 : nsitem->p_names = rte->eref;
1193 tgl 1393 54541 : nsitem->p_rte = rte;
1394 54541 : nsitem->p_rtindex = rtindex;
1193 tgl 1395 GIC 54541 : nsitem->p_nscolumns = nscolumns;
1193 tgl 1396 ECB : /* set default visibility flags; might get changed later */
1193 tgl 1397 GIC 54541 : nsitem->p_rel_visible = true;
1398 54541 : nsitem->p_cols_visible = true;
1399 54541 : nsitem->p_lateral_only = false;
1400 54541 : nsitem->p_lateral_ok = true;
1401 :
1402 54541 : return nsitem;
1403 : }
1404 :
1405 : /*
1406 : * Open a table during parse analysis
1407 : *
1408 : * This is essentially just the same as table_openrv(), except that it caters
1409 : * to some parser-specific error reporting needs, notably that it arranges
5296 tgl 1410 ECB : * to include the RangeVar's parse location in any resulting error.
1411 : *
1412 : * Note: properly, lockmode should be declared LOCKMODE not int, but that
1413 : * would require importing storage/lock.h into parse_relation.h. Since
1414 : * LOCKMODE is typedef'd as int anyway, that seems like overkill.
5333 1415 : */
1416 : Relation
5333 tgl 1417 GIC 325308 : parserOpenTable(ParseState *pstate, const RangeVar *relation, int lockmode)
1418 : {
1419 : Relation rel;
1420 : ParseCallbackState pcbstate;
1421 :
5333 tgl 1422 CBC 325308 : setup_parser_errposition_callback(&pcbstate, pstate, relation->location);
1539 andres 1423 GIC 325308 : rel = table_openrv_extended(relation, lockmode, true);
5296 tgl 1424 CBC 325307 : if (rel == NULL)
5296 tgl 1425 ECB : {
5296 tgl 1426 GIC 86 : if (relation->schemaname)
5296 tgl 1427 UIC 0 : ereport(ERROR,
1428 : (errcode(ERRCODE_UNDEFINED_TABLE),
5296 tgl 1429 ECB : errmsg("relation \"%s.%s\" does not exist",
1430 : relation->schemaname, relation->relname)));
1431 : else
1432 : {
1433 : /*
1434 : * An unqualified name might have been meant as a reference to
1435 : * some not-yet-in-scope CTE. The bare "does not exist" message
1436 : * has proven remarkably unhelpful for figuring out such problems,
1437 : * so we take pains to offer a specific hint.
1438 : */
2001 tgl 1439 CBC 86 : if (isFutureCTE(pstate, relation->relname))
5296 1440 3 : ereport(ERROR,
5296 tgl 1441 ECB : (errcode(ERRCODE_UNDEFINED_TABLE),
1442 : errmsg("relation \"%s\" does not exist",
1443 : relation->relname),
1444 : errdetail("There is a WITH item named \"%s\", but it cannot be referenced from this part of the query.",
1445 : relation->relname),
1446 : errhint("Use WITH RECURSIVE, or re-order the WITH items to remove forward references.")));
1447 : else
5296 tgl 1448 CBC 83 : ereport(ERROR,
5296 tgl 1449 ECB : (errcode(ERRCODE_UNDEFINED_TABLE),
1450 : errmsg("relation \"%s\" does not exist",
1451 : relation->relname)));
1452 : }
1453 : }
5333 tgl 1454 CBC 325221 : cancel_parser_errposition_callback(&pcbstate);
1455 325221 : return rel;
5333 tgl 1456 ECB : }
1457 :
8244 1458 : /*
1459 : * Add an entry for a relation to the pstate's range table (p_rtable).
1460 : * Then, construct and return a ParseNamespaceItem for the new RTE.
1461 : *
1462 : * We do not link the ParseNamespaceItem into the pstate here; it's the
1463 : * caller's job to do that in the appropriate way.
1464 : *
1465 : * Note: formerly this checked for refname conflicts, but that's wrong.
1466 : * Caller is responsible for checking for conflicts in the appropriate scope.
1467 : */
1468 : ParseNamespaceItem *
9266 bruce 1469 GIC 272324 : addRangeTableEntry(ParseState *pstate,
1470 : RangeVar *relation,
1471 : Alias *alias,
1472 : bool inh,
8244 tgl 1473 ECB : bool inFromCl)
1474 : {
8089 tgl 1475 GIC 272324 : RangeTblEntry *rte = makeNode(RangeTblEntry);
1476 : RTEPermissionInfo *perminfo;
7688 1477 272324 : char *refname = alias ? alias->aliasname : relation->relname;
1478 : LOCKMODE lockmode;
8397 bruce 1479 ECB : Relation rel;
1193 tgl 1480 : ParseNamespaceItem *nsitem;
9266 bruce 1481 :
2959 rhaas 1482 GIC 272324 : Assert(pstate != NULL);
2959 rhaas 1483 ECB :
7698 tgl 1484 GBC 272324 : rte->rtekind = RTE_RELATION;
8244 tgl 1485 GIC 272324 : rte->alias = alias;
1486 :
1487 : /*
1488 : * Identify the type of lock we'll need on this relation. It's not the
1489 : * query's target table (that case is handled elsewhere), so we need
1490 : * either RowShareLock if it's locked by FOR UPDATE/SHARE, or plain
1491 : * AccessShareLock otherwise.
1492 : */
1652 1493 272324 : lockmode = isLockedRefname(pstate, refname) ? RowShareLock : AccessShareLock;
1494 :
1495 : /*
6385 bruce 1496 ECB : * Get the rel's OID. This access also ensures that we have an up-to-date
3260 1497 : * relcache entry for the rel. Since this is typically the first access
1498 : * to a rel in a statement, we must open the rel with the proper lockmode.
1499 : */
5333 tgl 1500 GIC 272324 : rel = parserOpenTable(pstate, relation, lockmode);
8454 lockhart 1501 272247 : rte->relid = RelationGetRelid(rel);
4429 tgl 1502 272247 : rte->relkind = rel->rd_rel->relkind;
1652 1503 272247 : rte->rellockmode = lockmode;
1504 :
8187 tgl 1505 ECB : /*
1506 : * Build the list of effective column names using user-supplied aliases
1507 : * and/or actual column names.
1508 : */
6807 tgl 1509 GIC 272247 : rte->eref = makeAlias(refname, NIL);
3426 1510 272247 : buildRelationAliases(rel->rd_att, alias, rte->eref);
7688 tgl 1511 ECB :
3897 1512 : /*
1513 : * Set flags and initialize access permissions.
1514 : *
1515 : * The initial default on access checks is always check-for-READ-access,
1516 : * which is the right thing for all except target tables.
1517 : */
3897 tgl 1518 GIC 272244 : rte->lateral = false;
7688 1519 272244 : rte->inh = inh;
1520 272244 : rte->inFromCl = inFromCl;
1521 :
124 alvherre 1522 GNC 272244 : perminfo = addRTEPermissionInfo(&pstate->p_rteperminfos, rte);
1523 272244 : perminfo->requiredPerms = ACL_SELECT;
1524 :
1525 : /*
1526 : * Add completed RTE to pstate's range table list, so that we know its
1527 : * index. But we don't add it to the join list --- caller must do that if
1193 tgl 1528 ECB : * appropriate.
1529 : */
2959 rhaas 1530 CBC 272244 : pstate->p_rtable = lappend(pstate->p_rtable, rte);
1531 :
1532 : /*
1533 : * Build a ParseNamespaceItem, but don't add it to the pstate's namespace
1534 : * list --- caller must do that if appropriate.
1193 tgl 1535 ECB : */
1193 tgl 1536 GIC 272244 : nsitem = buildNSItemFromTupleDesc(rte, list_length(pstate->p_rtable),
1537 : perminfo, rel->rd_att);
1193 tgl 1538 ECB :
1539 : /*
1540 : * Drop the rel refcount, but keep the access lock till end of transaction
1541 : * so that the table can't be deleted or have its schema modified
1542 : * underneath us.
1543 : */
1193 tgl 1544 GIC 272244 : table_close(rel, NoLock);
1545 :
1193 tgl 1546 CBC 272244 : return nsitem;
1547 : }
1548 :
1549 : /*
1550 : * Add an entry for a relation to the pstate's range table (p_rtable).
1551 : * Then, construct and return a ParseNamespaceItem for the new RTE.
1552 : *
7688 tgl 1553 ECB : * This is just like addRangeTableEntry() except that it makes an RTE
6570 1554 : * given an already-open relation instead of a RangeVar reference.
1652 1555 : *
1556 : * lockmode is the lock type required for query execution; it must be one
1557 : * of AccessShareLock, RowShareLock, or RowExclusiveLock depending on the
1558 : * RTE's role within the query. The caller must hold that lock mode
1559 : * or a stronger one.
1560 : *
1561 : * Note: properly, lockmode should be declared LOCKMODE not int, but that
1562 : * would require importing storage/lock.h into parse_relation.h. Since
1563 : * LOCKMODE is typedef'd as int anyway, that seems like overkill.
1564 : */
1565 : ParseNamespaceItem *
7688 tgl 1566 GIC 149611 : addRangeTableEntryForRelation(ParseState *pstate,
1567 : Relation rel,
1568 : int lockmode,
1569 : Alias *alias,
1570 : bool inh,
7688 tgl 1571 ECB : bool inFromCl)
1572 : {
7688 tgl 1573 CBC 149611 : RangeTblEntry *rte = makeNode(RangeTblEntry);
1574 : RTEPermissionInfo *perminfo;
6570 tgl 1575 GIC 149611 : char *refname = alias ? alias->aliasname : RelationGetRelationName(rel);
7688 tgl 1576 ECB :
2951 rhaas 1577 CBC 149611 : Assert(pstate != NULL);
1578 :
1652 tgl 1579 GIC 149611 : Assert(lockmode == AccessShareLock ||
1580 : lockmode == RowShareLock ||
1581 : lockmode == RowExclusiveLock);
1651 1582 149611 : Assert(CheckRelationLockedByMe(rel, lockmode, true));
1583 :
7688 tgl 1584 CBC 149611 : rte->rtekind = RTE_RELATION;
7688 tgl 1585 GIC 149611 : rte->alias = alias;
6570 1586 149611 : rte->relid = RelationGetRelid(rel);
4429 1587 149611 : rte->relkind = rel->rd_rel->relkind;
1652 1588 149611 : rte->rellockmode = lockmode;
1589 :
7688 tgl 1590 ECB : /*
1591 : * Build the list of effective column names using user-supplied aliases
1592 : * and/or actual column names.
1593 : */
6807 tgl 1594 GIC 149611 : rte->eref = makeAlias(refname, NIL);
3426 1595 149611 : buildRelationAliases(rel->rd_att, alias, rte->eref);
1596 :
1597 : /*
1598 : * Set flags and initialize access permissions.
1599 : *
8227 tgl 1600 ECB : * The initial default on access checks is always check-for-READ-access,
1601 : * which is the right thing for all except target tables.
1602 : */
3897 tgl 1603 GIC 149611 : rte->lateral = false;
9266 bruce 1604 149611 : rte->inh = inh;
1605 149611 : rte->inFromCl = inFromCl;
1606 :
124 alvherre 1607 GNC 149611 : perminfo = addRTEPermissionInfo(&pstate->p_rteperminfos, rte);
1608 149611 : perminfo->requiredPerms = ACL_SELECT;
1609 :
1610 : /*
1611 : * Add completed RTE to pstate's range table list, so that we know its
1612 : * index. But we don't add it to the join list --- caller must do that if
1613 : * appropriate.
1614 : */
2951 rhaas 1615 GIC 149611 : pstate->p_rtable = lappend(pstate->p_rtable, rte);
9266 bruce 1616 ECB :
1617 : /*
1618 : * Build a ParseNamespaceItem, but don't add it to the pstate's namespace
1619 : * list --- caller must do that if appropriate.
1620 : */
1193 tgl 1621 GIC 149611 : return buildNSItemFromTupleDesc(rte, list_length(pstate->p_rtable),
1622 : perminfo, rel->rd_att);
9266 bruce 1623 ECB : }
1624 :
8244 tgl 1625 : /*
1626 : * Add an entry for a subquery to the pstate's range table (p_rtable).
1193 1627 : * Then, construct and return a ParseNamespaceItem for the new RTE.
1628 : *
1629 : * This is much like addRangeTableEntry() except that it makes a subquery RTE.
1630 : *
1631 : * If the subquery does not have an alias, the auto-generated relation name in
1632 : * the returned ParseNamespaceItem will be marked as not visible, and so only
1633 : * unqualified references to the subquery columns will be allowed, and the
1634 : * relation name will not conflict with others in the pstate's namespace list.
1635 : */
1636 : ParseNamespaceItem *
8227 tgl 1637 GIC 47344 : addRangeTableEntryForSubquery(ParseState *pstate,
8227 tgl 1638 ECB : Query *subquery,
7689 1639 : Alias *alias,
3897 1640 : bool lateral,
8227 1641 : bool inFromCl)
1642 : {
8089 tgl 1643 GIC 47344 : RangeTblEntry *rte = makeNode(RangeTblEntry);
1644 : Alias *eref;
1645 : int numaliases;
1646 : List *coltypes,
1193 tgl 1647 ECB : *coltypmods,
1648 : *colcollations;
1649 : int varattno;
1650 : ListCell *tlistitem;
1651 : ParseNamespaceItem *nsitem;
1652 :
2951 rhaas 1653 GIC 47344 : Assert(pstate != NULL);
1654 :
7698 tgl 1655 47344 : rte->rtekind = RTE_SUBQUERY;
8227 1656 47344 : rte->subquery = subquery;
8227 tgl 1657 CBC 47344 : rte->alias = alias;
8227 tgl 1658 ECB :
263 dean.a.rasheed 1659 GNC 47344 : eref = alias ? copyObject(alias) : makeAlias("unnamed_subquery", NIL);
6888 neilc 1660 GIC 47344 : numaliases = list_length(eref->colnames);
8227 tgl 1661 ECB :
1193 1662 : /* fill in any unspecified alias columns, and extract column type info */
1193 tgl 1663 GIC 47344 : coltypes = coltypmods = colcollations = NIL;
8227 1664 47344 : varattno = 0;
1665 240011 : foreach(tlistitem, subquery->targetList)
1666 : {
1667 192667 : TargetEntry *te = (TargetEntry *) lfirst(tlistitem);
1668 :
6577 tgl 1669 CBC 192667 : if (te->resjunk)
8227 tgl 1670 GIC 108 : continue;
1671 192559 : varattno++;
6577 1672 192559 : Assert(varattno == te->resno);
8227 1673 192559 : if (varattno > numaliases)
1674 : {
8227 tgl 1675 ECB : char *attrname;
1676 :
6577 tgl 1677 GIC 158439 : attrname = pstrdup(te->resname);
7689 1678 158439 : eref->colnames = lappend(eref->colnames, makeString(attrname));
1679 : }
1193 1680 192559 : coltypes = lappend_oid(coltypes,
1681 192559 : exprType((Node *) te->expr));
1682 192559 : coltypmods = lappend_int(coltypmods,
1683 192559 : exprTypmod((Node *) te->expr));
1684 192559 : colcollations = lappend_oid(colcollations,
1685 192559 : exprCollation((Node *) te->expr));
1686 : }
8227 1687 47344 : if (varattno < numaliases)
7204 1688 3 : ereport(ERROR,
1689 : (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
1690 : errmsg("table \"%s\" has %d columns available but %d columns specified",
1691 : eref->aliasname, varattno, numaliases)));
1692 :
8227 1693 47341 : rte->eref = eref;
1694 :
1695 : /*
1696 : * Set flags.
8227 tgl 1697 ECB : *
1698 : * Subqueries are never checked for access rights, so no need to perform
1699 : * addRTEPermissionInfo().
1700 : */
3897 tgl 1701 GIC 47341 : rte->lateral = lateral;
8227 1702 47341 : rte->inh = false; /* never true for subqueries */
1703 47341 : rte->inFromCl = inFromCl;
1704 :
8227 tgl 1705 ECB : /*
1706 : * Add completed RTE to pstate's range table list, so that we know its
1193 1707 : * index. But we don't add it to the join list --- caller must do that if
1708 : * appropriate.
1709 : */
2951 rhaas 1710 GIC 47341 : pstate->p_rtable = lappend(pstate->p_rtable, rte);
8227 tgl 1711 ECB :
1193 1712 : /*
1713 : * Build a ParseNamespaceItem, but don't add it to the pstate's namespace
1714 : * list --- caller must do that if appropriate.
1715 : */
263 dean.a.rasheed 1716 GNC 47341 : 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 47341 : nsitem->p_rel_visible = (alias != NULL);
1723 :
1724 47341 : return nsitem;
8227 tgl 1725 ECB : }
1726 :
7637 1727 : /*
3426 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.
7637 1732 : */
1193 1733 : ParseNamespaceItem *
7637 tgl 1734 GIC 29539 : addRangeTableEntryForFunction(ParseState *pstate,
3426 tgl 1735 ECB : List *funcnames,
1736 : List *funcexprs,
1737 : List *coldeflists,
7553 bruce 1738 : RangeFunction *rangefunc,
3897 tgl 1739 : bool lateral,
7637 1740 : bool inFromCl)
1741 : {
7637 tgl 1742 CBC 29539 : RangeTblEntry *rte = makeNode(RangeTblEntry);
7553 bruce 1743 29539 : Alias *alias = rangefunc->alias;
1744 : Alias *eref;
1745 : char *aliasname;
3426 tgl 1746 GIC 29539 : int nfuncs = list_length(funcexprs);
1747 : TupleDesc *functupdescs;
3426 tgl 1748 ECB : TupleDesc tupdesc;
1749 : ListCell *lc1,
1750 : *lc2,
1751 : *lc3;
1752 : int i;
1753 : int j;
1754 : int funcno;
1755 : int natts,
1756 : totalatts;
7637 1757 :
2951 rhaas 1758 CBC 29539 : Assert(pstate != NULL);
1759 :
7637 tgl 1760 GIC 29539 : rte->rtekind = RTE_FUNCTION;
1761 29539 : rte->relid = InvalidOid;
1762 29539 : rte->subquery = NULL;
3426 1763 29539 : rte->functions = NIL; /* we'll fill this list below */
1764 29539 : rte->funcordinality = rangefunc->ordinality;
7637 tgl 1765 CBC 29539 : 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".
6583 tgl 1771 ECB : */
3426 tgl 1772 GIC 29539 : if (alias)
1773 21285 : aliasname = alias->aliasname;
1774 : else
1775 8254 : aliasname = linitial(funcnames);
1776 :
3426 tgl 1777 CBC 29539 : eref = makeAlias(aliasname, NIL);
3426 tgl 1778 GIC 29539 : rte->eref = eref;
3426 tgl 1779 ECB :
1780 : /* Process each function ... */
3426 tgl 1781 GIC 29539 : functupdescs = (TupleDesc *) palloc(nfuncs * sizeof(TupleDesc));
1782 :
1783 29539 : totalatts = 0;
1784 29539 : funcno = 0;
1785 59198 : forthree(lc1, funcexprs, lc2, funcnames, lc3, coldeflists)
1786 : {
1787 29686 : Node *funcexpr = (Node *) lfirst(lc1);
1788 29686 : char *funcname = (char *) lfirst(lc2);
3426 tgl 1789 CBC 29686 : List *coldeflist = (List *) lfirst(lc3);
3426 tgl 1790 GIC 29686 : RangeTblFunction *rtfunc = makeNode(RangeTblFunction);
1791 : TypeFuncClass functypclass;
1792 : Oid funcrettype;
1793 :
1794 : /* Initialize RangeTblFunction node */
1795 29686 : rtfunc->funcexpr = funcexpr;
1796 29686 : rtfunc->funccolnames = NIL;
3426 tgl 1797 CBC 29686 : rtfunc->funccoltypes = NIL;
1798 29686 : rtfunc->funccoltypmods = NIL;
3426 tgl 1799 GIC 29686 : rtfunc->funccolcollations = NIL;
2118 1800 29686 : rtfunc->funcparams = NULL; /* not set until planning */
3426 tgl 1801 ECB :
1802 : /*
1803 : * Now determine if the function returns a simple or composite type.
1804 : */
3426 tgl 1805 GIC 29686 : 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
929 tgl 1813 ECB : * relevant error message.
1814 : */
3426 tgl 1815 CBC 29686 : if (coldeflist != NIL)
3426 tgl 1816 ECB : {
929 tgl 1817 CBC 371 : switch (functypclass)
929 tgl 1818 ECB : {
929 tgl 1819 CBC 362 : case TYPEFUNC_RECORD:
929 tgl 1820 ECB : /* ok */
929 tgl 1821 GIC 362 : break;
1822 6 : case TYPEFUNC_COMPOSITE:
1823 : case TYPEFUNC_COMPOSITE_DOMAIN:
1824 :
1825 : /*
1826 : * If the function's raw result type is RECORD, we must
929 tgl 1827 ECB : * have resolved it using its OUT parameters. Otherwise,
1828 : * it must have a named composite type.
1829 : */
929 tgl 1830 CBC 6 : if (exprType(funcexpr) == RECORDOID)
929 tgl 1831 GIC 3 : ereport(ERROR,
929 tgl 1832 ECB : (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
929 tgl 1837 GIC 3 : ereport(ERROR,
929 tgl 1838 ECB : (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;
929 tgl 1843 CBC 3 : default:
1844 3 : ereport(ERROR,
929 tgl 1845 ECB : (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 : }
3426 1851 : }
1852 : else
1853 : {
3426 tgl 1854 CBC 29315 : if (functypclass == TYPEFUNC_RECORD)
1855 15 : 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 : }
3426 tgl 1860 ECB :
1991 tgl 1861 GIC 29662 : if (functypclass == TYPEFUNC_COMPOSITE ||
1862 : functypclass == TYPEFUNC_COMPOSITE_DOMAIN)
1863 : {
1864 : /* Composite data type, e.g. a table's row type */
3426 1865 20625 : Assert(tupdesc);
1866 : }
1867 9037 : else if (functypclass == TYPEFUNC_SCALAR)
1868 : {
1869 : /* Base data type, i.e. scalar */
1601 andres 1870 CBC 8672 : tupdesc = CreateTemplateTupleDesc(1);
3426 tgl 1871 GIC 17344 : TupleDescInitEntry(tupdesc,
3426 tgl 1872 ECB : (AttrNumber) 1,
3426 tgl 1873 GIC 8672 : chooseScalarFunctionAlias(funcexpr, funcname,
3426 tgl 1874 ECB : alias, nfuncs),
1875 : funcrettype,
1193 1876 : exprTypmod(funcexpr),
3426 1877 : 0);
1193 tgl 1878 GIC 8672 : TupleDescInitEntryCollation(tupdesc,
1879 : (AttrNumber) 1,
1880 : exprCollation(funcexpr));
1881 : }
3426 1882 365 : else if (functypclass == TYPEFUNC_RECORD)
1883 : {
1884 : ListCell *col;
3426 tgl 1885 ECB :
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 : */
251 tgl 1891 GIC 362 : if (list_length(coldeflist) > MaxHeapAttributeNumber)
251 tgl 1892 LBC 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))));
1601 andres 1898 CBC 362 : tupdesc = CreateTemplateTupleDesc(list_length(coldeflist));
3426 tgl 1899 362 : i = 1;
3426 tgl 1900 GIC 1210 : foreach(col, coldeflist)
1901 : {
1902 848 : ColumnDef *n = (ColumnDef *) lfirst(col);
1903 : char *attrname;
1904 : Oid attrtype;
1905 : int32 attrtypmod;
1906 : Oid attrcollation;
1907 :
1908 848 : attrname = n->colname;
3426 tgl 1909 CBC 848 : if (n->typeName->setof)
3426 tgl 1910 LBC 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)));
3426 tgl 1915 GIC 848 : typenameTypeIdAndMod(pstate, n->typeName,
3426 tgl 1916 ECB : &attrtype, &attrtypmod);
3426 tgl 1917 GIC 848 : attrcollation = GetColumnDefCollation(pstate, n, attrtype);
1918 848 : TupleDescInitEntry(tupdesc,
1919 848 : (AttrNumber) i,
3426 tgl 1920 ECB : attrname,
1921 : attrtype,
1922 : attrtypmod,
1923 : 0);
3426 tgl 1924 GIC 848 : TupleDescInitEntryCollation(tupdesc,
3426 tgl 1925 CBC 848 : (AttrNumber) i,
3426 tgl 1926 ECB : attrcollation);
3426 tgl 1927 GIC 848 : rtfunc->funccolnames = lappend(rtfunc->funccolnames,
3426 tgl 1928 CBC 848 : makeString(pstrdup(attrname)));
3426 tgl 1929 GIC 848 : rtfunc->funccoltypes = lappend_oid(rtfunc->funccoltypes,
1930 : attrtype);
1931 848 : rtfunc->funccoltypmods = lappend_int(rtfunc->funccoltypmods,
1932 : attrtypmod);
3426 tgl 1933 CBC 848 : rtfunc->funccolcollations = lappend_oid(rtfunc->funccolcollations,
1934 : attrcollation);
1935 :
3426 tgl 1936 GIC 848 : i++;
3426 tgl 1937 ECB : }
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
1530 1946 : * other sessions.
3426 tgl 1947 EUB : */
1530 tgl 1948 GIC 362 : CheckAttributeNamesTypes(tupdesc, RELKIND_COMPOSITE_TYPE,
1949 : CHKATYPE_ANYRECORD);
1950 : }
1951 : else
7204 1952 3 : ereport(ERROR,
3426 tgl 1953 ECB : (errcode(ERRCODE_DATATYPE_MISMATCH),
2118 1954 : errmsg("function \"%s\" in FROM has unsupported return type %s",
1955 : funcname, format_type_be(funcrettype)),
1956 : parser_errposition(pstate, exprLocation(funcexpr))));
7551 bruce 1957 :
1958 : /* Finish off the RangeTblFunction and add it to the RTE's list */
3426 tgl 1959 GIC 29659 : rtfunc->funccolcount = tupdesc->natts;
1960 29659 : rte->functions = lappend(rte->functions, rtfunc);
1961 :
1962 : /* Save the tupdesc for use below */
3426 tgl 1963 CBC 29659 : functupdescs[funcno] = tupdesc;
1964 29659 : totalatts += tupdesc->natts;
3426 tgl 1965 GBC 29659 : funcno++;
1966 : }
1967 :
1968 : /*
1969 : * If there's more than one function, or we want an ordinality column, we
3426 tgl 1970 ECB : * have to produce a merged tupdesc.
1971 : */
3426 tgl 1972 CBC 29512 : if (nfuncs > 1 || rangefunc->ordinality)
3426 tgl 1973 ECB : {
3541 stark 1974 CBC 335 : if (rangefunc->ordinality)
3426 tgl 1975 GIC 299 : totalatts++;
1976 :
1977 : /* Disallow more columns than will fit in a tuple */
251 1978 335 : if (totalatts > MaxTupleAttributeNumber)
251 tgl 1979 LBC 0 : ereport(ERROR,
251 tgl 1980 ECB : (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 :
3426 1986 : /* Merge the tuple descs of each function into a composite one */
1601 andres 1987 GIC 335 : tupdesc = CreateTemplateTupleDesc(totalatts);
3426 tgl 1988 CBC 335 : natts = 0;
3426 tgl 1989 GIC 817 : for (i = 0; i < nfuncs; i++)
1990 : {
3426 tgl 1991 CBC 1239 : for (j = 1; j <= functupdescs[i]->natts; j++)
3426 tgl 1992 GIC 757 : TupleDescCopyEntry(tupdesc, ++natts, functupdescs[i], j);
1993 : }
1994 :
1995 : /* Add the ordinality column if needed */
1996 335 : if (rangefunc->ordinality)
1997 : {
1998 299 : TupleDescInitEntry(tupdesc,
1999 299 : (AttrNumber) ++natts,
2000 : "ordinality",
2001 : INT8OID,
2002 : -1,
3426 tgl 2003 ECB : 0);
2004 : /* no need to set collation */
2005 : }
2006 :
3426 tgl 2007 CBC 335 : Assert(natts == totalatts);
2008 : }
2009 : else
2010 : {
2011 : /* We can just use the single function's tupdesc as-is */
3426 tgl 2012 GIC 29177 : tupdesc = functupdescs[0];
2013 : }
3426 tgl 2014 ECB :
2015 : /* Use the tupdesc while assigning column aliases for the RTE */
3426 tgl 2016 GIC 29512 : buildRelationAliases(tupdesc, alias, eref);
2017 :
3897 tgl 2018 ECB : /*
2019 : * Set flags and access permissions.
7025 2020 : *
2021 : * Functions are never checked for access rights (at least, not by
2022 : * ExecCheckPermissions()), so no need to perform addRTEPermissionInfo().
2023 : */
3897 tgl 2024 GIC 29512 : rte->lateral = lateral;
7637 2025 29512 : rte->inh = false; /* never true for functions */
2026 29512 : rte->inFromCl = inFromCl;
7637 tgl 2027 ECB :
2028 : /*
2029 : * Add completed RTE to pstate's range table list, so that we know its
2030 : * index. But we don't add it to the join list --- caller must do that if
2031 : * appropriate.
2032 : */
2951 rhaas 2033 GIC 29512 : pstate->p_rtable = lappend(pstate->p_rtable, rte);
2034 :
1193 tgl 2035 ECB : /*
2036 : * Build a ParseNamespaceItem, but don't add it to the pstate's namespace
2037 : * list --- caller must do that if appropriate.
2038 : */
124 alvherre 2039 GNC 29512 : return buildNSItemFromTupleDesc(rte, list_length(pstate->p_rtable), NULL,
1193 tgl 2040 ECB : tupdesc);
2041 : }
2042 :
2043 : /*
2223 alvherre 2044 : * Add an entry for a table function to the pstate's range table (p_rtable).
2045 : * Then, construct and return a ParseNamespaceItem for the new RTE.
2046 : *
2047 : * This is much like addRangeTableEntry() except that it makes a tablefunc RTE.
2048 : */
2049 : ParseNamespaceItem *
2223 alvherre 2050 GIC 107 : addRangeTableEntryForTableFunc(ParseState *pstate,
2051 : TableFunc *tf,
2052 : Alias *alias,
2053 : bool lateral,
2054 : bool inFromCl)
2223 alvherre 2055 ECB : {
2223 alvherre 2056 GIC 107 : RangeTblEntry *rte = makeNode(RangeTblEntry);
2057 : char *refname;
2058 : Alias *eref;
2059 : int numaliases;
2223 alvherre 2060 ECB :
251 tgl 2061 GIC 107 : Assert(pstate != NULL);
2062 :
2063 : /* Disallow more columns than will fit in a tuple */
251 tgl 2064 CBC 107 : if (list_length(tf->colnames) > MaxTupleAttributeNumber)
251 tgl 2065 UIC 0 : ereport(ERROR,
2066 : (errcode(ERRCODE_TOO_MANY_COLUMNS),
2067 : errmsg("functions in FROM can return at most %d columns",
2068 : MaxTupleAttributeNumber),
2069 : parser_errposition(pstate,
2070 : exprLocation((Node *) tf))));
251 tgl 2071 GIC 107 : Assert(list_length(tf->coltypes) == list_length(tf->colnames));
251 tgl 2072 CBC 107 : Assert(list_length(tf->coltypmods) == list_length(tf->colnames));
2073 107 : Assert(list_length(tf->colcollations) == list_length(tf->colnames));
251 tgl 2074 ECB :
207 alvherre 2075 GIC 107 : refname = alias ? alias->aliasname : pstrdup("xmltable");
2076 :
2223 2077 107 : rte->rtekind = RTE_TABLEFUNC;
2078 107 : rte->relid = InvalidOid;
2079 107 : rte->subquery = NULL;
2080 107 : rte->tablefunc = tf;
2223 alvherre 2081 CBC 107 : rte->coltypes = tf->coltypes;
2223 alvherre 2082 GIC 107 : rte->coltypmods = tf->coltypmods;
2083 107 : rte->colcollations = tf->colcollations;
2084 107 : rte->alias = alias;
2085 :
2086 107 : eref = alias ? copyObject(alias) : makeAlias(refname, NIL);
2223 alvherre 2087 CBC 107 : numaliases = list_length(eref->colnames);
2088 :
2089 : /* fill in any unspecified alias columns */
2223 alvherre 2090 GIC 107 : if (numaliases < list_length(tf->colnames))
2091 104 : eref->colnames = list_concat(eref->colnames,
2118 tgl 2092 104 : list_copy_tail(tf->colnames, numaliases));
2093 :
326 alvherre 2094 107 : if (numaliases > list_length(tf->colnames))
2095 3 : ereport(ERROR,
2096 : (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
2097 : errmsg("%s function has %d columns available but %d columns specified",
220 andrew 2098 ECB : "XMLTABLE",
2099 : list_length(tf->colnames), numaliases)));
2100 :
2223 alvherre 2101 GIC 104 : rte->eref = eref;
2102 :
2103 : /*
2223 alvherre 2104 ECB : * Set flags and access permissions.
2105 : *
2106 : * Tablefuncs are never checked for access rights (at least, not by
2107 : * ExecCheckPermissions()), so no need to perform addRTEPermissionInfo().
2108 : */
2223 alvherre 2109 CBC 104 : rte->lateral = lateral;
2223 alvherre 2110 GIC 104 : rte->inh = false; /* never true for tablefunc RTEs */
2111 104 : rte->inFromCl = inFromCl;
2223 alvherre 2112 ECB :
2113 : /*
1193 tgl 2114 : * Add completed RTE to pstate's range table list, so that we know its
2115 : * index. But we don't add it to the join list --- caller must do that if
2116 : * appropriate.
2117 : */
2223 alvherre 2118 CBC 104 : pstate->p_rtable = lappend(pstate->p_rtable, rte);
2223 alvherre 2119 ECB :
1193 tgl 2120 : /*
2121 : * Build a ParseNamespaceItem, but don't add it to the pstate's namespace
2122 : * list --- caller must do that if appropriate.
2123 : */
1193 tgl 2124 CBC 104 : return buildNSItemFromLists(rte, list_length(pstate->p_rtable),
1193 tgl 2125 ECB : rte->coltypes, rte->coltypmods,
2126 : rte->colcollations);
2223 alvherre 2127 : }
2128 :
2129 : /*
2130 : * Add an entry for a VALUES list to the pstate's range table (p_rtable).
1193 tgl 2131 : * Then, construct and return a ParseNamespaceItem for the new RTE.
6094 mail 2132 : *
2133 : * This is much like addRangeTableEntry() except that it makes a values RTE.
2134 : */
1193 tgl 2135 : ParseNamespaceItem *
6094 mail 2136 CBC 4534 : addRangeTableEntryForValues(ParseState *pstate,
2137 : List *exprs,
2138 : List *coltypes,
2139 : List *coltypmods,
2140 : List *colcollations,
2141 : Alias *alias,
3885 tgl 2142 ECB : bool lateral,
2143 : bool inFromCl)
2144 : {
6094 mail 2145 GIC 4534 : RangeTblEntry *rte = makeNode(RangeTblEntry);
2146 4534 : char *refname = alias ? alias->aliasname : pstrdup("*VALUES*");
2147 : Alias *eref;
2148 : int numaliases;
2149 : int numcolumns;
6094 mail 2150 ECB :
2951 rhaas 2151 CBC 4534 : Assert(pstate != NULL);
2951 rhaas 2152 ECB :
6094 mail 2153 GIC 4534 : rte->rtekind = RTE_VALUES;
2154 4534 : rte->relid = InvalidOid;
2155 4534 : rte->subquery = NULL;
2156 4534 : rte->values_lists = exprs;
2313 tgl 2157 4534 : rte->coltypes = coltypes;
2158 4534 : rte->coltypmods = coltypmods;
2313 tgl 2159 CBC 4534 : rte->colcollations = colcollations;
6094 mail 2160 GIC 4534 : rte->alias = alias;
2161 :
2162 4534 : eref = alias ? copyObject(alias) : makeAlias(refname, NIL);
2163 :
2164 : /* fill in any unspecified alias columns */
6094 mail 2165 CBC 4534 : numcolumns = list_length((List *) linitial(exprs));
6094 mail 2166 GIC 4534 : numaliases = list_length(eref->colnames);
2167 11855 : while (numaliases < numcolumns)
2168 : {
2169 : char attrname[64];
2170 :
2171 7321 : numaliases++;
2172 7321 : snprintf(attrname, sizeof(attrname), "column%d", numaliases);
2173 7321 : eref->colnames = lappend(eref->colnames,
2174 7321 : makeString(pstrdup(attrname)));
2175 : }
2176 4534 : if (numcolumns < numaliases)
6094 mail 2177 LBC 0 : ereport(ERROR,
2178 : (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
2179 : errmsg("VALUES lists \"%s\" have %d columns available but %d columns specified",
2180 : refname, numcolumns, numaliases)));
2181 :
6094 mail 2182 GIC 4534 : rte->eref = eref;
2183 :
2184 : /*
2185 : * Set flags and access permissions.
6094 mail 2186 ECB : *
2187 : * Subqueries are never checked for access rights, so no need to perform
2188 : * addRTEPermissionInfo().
2189 : */
3885 tgl 2190 GIC 4534 : rte->lateral = lateral;
6094 mail 2191 4534 : rte->inh = false; /* never true for values RTEs */
2192 4534 : rte->inFromCl = inFromCl;
5190 tgl 2193 ECB :
6094 mail 2194 : /*
1193 tgl 2195 : * Add completed RTE to pstate's range table list, so that we know its
2196 : * index. But we don't add it to the join list --- caller must do that if
2197 : * appropriate.
2198 : */
2951 rhaas 2199 GIC 4534 : pstate->p_rtable = lappend(pstate->p_rtable, rte);
6094 mail 2200 ECB :
1193 tgl 2201 : /*
2202 : * Build a ParseNamespaceItem, but don't add it to the pstate's namespace
2203 : * list --- caller must do that if appropriate.
2204 : */
1193 tgl 2205 GIC 4534 : return buildNSItemFromLists(rte, list_length(pstate->p_rtable),
1193 tgl 2206 ECB : rte->coltypes, rte->coltypmods,
2207 : rte->colcollations);
6094 mail 2208 : }
2209 :
2210 : /*
7698 tgl 2211 : * Add an entry for a join to the pstate's range table (p_rtable).
1193 tgl 2212 EUB : * Then, construct and return a ParseNamespaceItem for the new RTE.
2213 : *
2214 : * This is much like addRangeTableEntry() except that it makes a join RTE.
2215 : * Also, it's more convenient for the caller to construct the
2216 : * ParseNamespaceColumn array, so we pass that in.
7698 tgl 2217 ECB : */
2218 : ParseNamespaceItem *
7698 tgl 2219 GIC 79032 : addRangeTableEntryForJoin(ParseState *pstate,
2220 : List *colnames,
2221 : ParseNamespaceColumn *nscolumns,
2222 : JoinType jointype,
2223 : int nummergedcols,
2224 : List *aliasvars,
1186 tgl 2225 ECB : List *leftcols,
2226 : List *rightcols,
739 peter 2227 : Alias *join_using_alias,
2228 : Alias *alias,
2229 : bool inFromCl)
2230 : {
7698 tgl 2231 GIC 79032 : RangeTblEntry *rte = makeNode(RangeTblEntry);
2232 : Alias *eref;
2233 : int numaliases;
1193 tgl 2234 ECB : ParseNamespaceItem *nsitem;
2235 :
2951 rhaas 2236 GIC 79032 : Assert(pstate != NULL);
2237 :
2238 : /*
2239 : * Fail if join has too many columns --- we must be able to reference any
5050 bruce 2240 ECB : * of the columns with an AttrNumber.
2241 : */
5482 tgl 2242 GIC 79032 : if (list_length(aliasvars) > MaxAttrNumber)
5482 tgl 2243 UIC 0 : ereport(ERROR,
2244 : (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
2245 : errmsg("joins can have at most %d columns",
2246 : MaxAttrNumber)));
2247 :
7698 tgl 2248 GIC 79032 : rte->rtekind = RTE_JOIN;
2249 79032 : rte->relid = InvalidOid;
2250 79032 : rte->subquery = NULL;
2251 79032 : rte->jointype = jointype;
1186 2252 79032 : rte->joinmergedcols = nummergedcols;
7651 2253 79032 : rte->joinaliasvars = aliasvars;
1186 tgl 2254 CBC 79032 : rte->joinleftcols = leftcols;
1186 tgl 2255 GIC 79032 : rte->joinrightcols = rightcols;
739 peter 2256 79032 : rte->join_using_alias = join_using_alias;
7698 tgl 2257 79032 : rte->alias = alias;
2258 :
2222 peter_e 2259 79032 : eref = alias ? copyObject(alias) : makeAlias("unnamed_join", NIL);
6888 neilc 2260 79032 : numaliases = list_length(eref->colnames);
2261 :
2262 : /* fill in any unspecified alias columns */
2263 79032 : if (numaliases < list_length(colnames))
2264 78963 : eref->colnames = list_concat(eref->colnames,
6385 bruce 2265 78963 : list_copy_tail(colnames, numaliases));
7698 tgl 2266 ECB :
326 alvherre 2267 GIC 79032 : if (numaliases > list_length(colnames))
2268 3 : ereport(ERROR,
2269 : (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
2270 : errmsg("join expression \"%s\" has %d columns available but %d columns specified",
326 alvherre 2271 ECB : eref->aliasname, list_length(colnames), numaliases)));
2272 :
7698 tgl 2273 GIC 79029 : rte->eref = eref;
2274 :
2275 : /*
2276 : * Set flags and access permissions.
7698 tgl 2277 ECB : *
2278 : * Joins are never checked for access rights, so no need to perform
2279 : * addRTEPermissionInfo().
2280 : */
3897 tgl 2281 GIC 79029 : rte->lateral = false;
7698 2282 79029 : rte->inh = false; /* never true for joins */
2283 79029 : rte->inFromCl = inFromCl;
7698 tgl 2284 ECB :
2285 : /*
1193 2286 : * Add completed RTE to pstate's range table list, so that we know its
2287 : * index. But we don't add it to the join list --- caller must do that if
2288 : * appropriate.
7698 2289 : */
2951 rhaas 2290 GIC 79029 : pstate->p_rtable = lappend(pstate->p_rtable, rte);
2291 :
1193 tgl 2292 ECB : /*
2293 : * Build a ParseNamespaceItem, but don't add it to the pstate's namespace
2294 : * list --- caller must do that if appropriate.
2295 : */
1193 tgl 2296 CBC 79029 : nsitem = (ParseNamespaceItem *) palloc(sizeof(ParseNamespaceItem));
739 peter 2297 79029 : nsitem->p_names = rte->eref;
1193 tgl 2298 GIC 79029 : nsitem->p_rte = rte;
124 alvherre 2299 GNC 79029 : nsitem->p_perminfo = NULL;
1193 tgl 2300 GIC 79029 : nsitem->p_rtindex = list_length(pstate->p_rtable);
2301 79029 : nsitem->p_nscolumns = nscolumns;
2302 : /* set default visibility flags; might get changed later */
1193 tgl 2303 CBC 79029 : nsitem->p_rel_visible = true;
1193 tgl 2304 GIC 79029 : nsitem->p_cols_visible = true;
2305 79029 : nsitem->p_lateral_only = false;
2306 79029 : nsitem->p_lateral_ok = true;
2307 :
2308 79029 : return nsitem;
2309 : }
2310 :
5300 tgl 2311 ECB : /*
2312 : * Add an entry for a CTE reference to the pstate's range table (p_rtable).
1193 2313 : * Then, construct and return a ParseNamespaceItem for the new RTE.
2314 : *
2315 : * This is much like addRangeTableEntry() except that it makes a CTE RTE.
2316 : */
2317 : ParseNamespaceItem *
5300 tgl 2318 GIC 2565 : addRangeTableEntryForCTE(ParseState *pstate,
2319 : CommonTableExpr *cte,
5300 tgl 2320 ECB : Index levelsup,
2321 : RangeVar *rv,
2322 : bool inFromCl)
2323 : {
5300 tgl 2324 GIC 2565 : RangeTblEntry *rte = makeNode(RangeTblEntry);
4426 2325 2565 : Alias *alias = rv->alias;
5300 tgl 2326 CBC 2565 : char *refname = alias ? alias->aliasname : cte->ctename;
5300 tgl 2327 ECB : Alias *eref;
2328 : int numaliases;
2329 : int varattno;
2330 : ListCell *lc;
797 peter 2331 CBC 2565 : int n_dontexpand_columns = 0;
2332 : ParseNamespaceItem *psi;
5300 tgl 2333 ECB :
2951 rhaas 2334 CBC 2565 : Assert(pstate != NULL);
2951 rhaas 2335 ECB :
5300 tgl 2336 CBC 2565 : rte->rtekind = RTE_CTE;
5300 tgl 2337 GIC 2565 : rte->ctename = cte->ctename;
5300 tgl 2338 CBC 2565 : rte->ctelevelsup = levelsup;
2339 :
2340 : /* Self-reference if and only if CTE's parse analysis isn't completed */
5300 tgl 2341 GIC 2565 : rte->self_reference = !IsA(cte->ctequery, Query);
2342 2565 : Assert(cte->cterecursive || !rte->self_reference);
2343 : /* Bump the CTE's refcount if this isn't a self-reference */
2344 2565 : if (!rte->self_reference)
2345 2139 : cte->cterefcount++;
2346 :
2347 : /*
4426 tgl 2348 ECB : * We throw error if the CTE is INSERT/UPDATE/DELETE without RETURNING.
2349 : * This won't get checked in case of a self-reference, but that's OK
2350 : * because data-modifying CTEs aren't allowed to be recursive anyhow.
2351 : */
4426 tgl 2352 GIC 2565 : if (IsA(cte->ctequery, Query))
2353 : {
4382 bruce 2354 CBC 2139 : Query *ctequery = (Query *) cte->ctequery;
4426 tgl 2355 ECB :
4426 tgl 2356 CBC 2139 : if (ctequery->commandType != CMD_SELECT &&
4426 tgl 2357 GIC 132 : ctequery->returningList == NIL)
2358 3 : ereport(ERROR,
2359 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2360 : errmsg("WITH query \"%s\" does not have a RETURNING clause",
2118 tgl 2361 ECB : cte->ctename),
2362 : parser_errposition(pstate, rv->location)));
2363 : }
4426 2364 :
797 peter 2365 GIC 2562 : rte->coltypes = list_copy(cte->ctecoltypes);
797 peter 2366 CBC 2562 : rte->coltypmods = list_copy(cte->ctecoltypmods);
2367 2562 : rte->colcollations = list_copy(cte->ctecolcollations);
5300 tgl 2368 ECB :
5300 tgl 2369 GIC 2562 : rte->alias = alias;
2370 2562 : if (alias)
5300 tgl 2371 CBC 488 : eref = copyObject(alias);
5300 tgl 2372 ECB : else
5300 tgl 2373 GIC 2074 : eref = makeAlias(refname, NIL);
5300 tgl 2374 CBC 2562 : numaliases = list_length(eref->colnames);
5300 tgl 2375 ECB :
2376 : /* fill in any unspecified alias columns */
5300 tgl 2377 GIC 2562 : varattno = 0;
2378 9313 : foreach(lc, cte->ctecolnames)
2379 : {
2380 6751 : varattno++;
2381 6751 : if (varattno > numaliases)
5300 tgl 2382 CBC 6727 : eref->colnames = lappend(eref->colnames, lfirst(lc));
2383 : }
2384 2562 : if (varattno < numaliases)
5300 tgl 2385 UIC 0 : ereport(ERROR,
5300 tgl 2386 ECB : (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
2387 : errmsg("table \"%s\" has %d columns available but %d columns specified",
2388 : refname, varattno, numaliases)));
2389 :
5300 tgl 2390 GIC 2562 : rte->eref = eref;
2391 :
797 peter 2392 2562 : if (cte->search_clause)
2393 : {
2394 105 : rte->eref->colnames = lappend(rte->eref->colnames, makeString(cte->search_clause->search_seq_column));
797 peter 2395 CBC 105 : if (cte->search_clause->search_breadth_first)
2396 36 : rte->coltypes = lappend_oid(rte->coltypes, RECORDOID);
797 peter 2397 ECB : else
797 peter 2398 GIC 69 : rte->coltypes = lappend_oid(rte->coltypes, RECORDARRAYOID);
797 peter 2399 CBC 105 : rte->coltypmods = lappend_int(rte->coltypmods, -1);
2400 105 : rte->colcollations = lappend_oid(rte->colcollations, InvalidOid);
797 peter 2401 ECB :
797 peter 2402 GIC 105 : n_dontexpand_columns += 1;
797 peter 2403 ECB : }
2404 :
797 peter 2405 GIC 2562 : if (cte->cycle_clause)
2406 : {
797 peter 2407 CBC 93 : rte->eref->colnames = lappend(rte->eref->colnames, makeString(cte->cycle_clause->cycle_mark_column));
2408 93 : rte->coltypes = lappend_oid(rte->coltypes, cte->cycle_clause->cycle_mark_type);
797 peter 2409 GIC 93 : rte->coltypmods = lappend_int(rte->coltypmods, cte->cycle_clause->cycle_mark_typmod);
797 peter 2410 CBC 93 : rte->colcollations = lappend_oid(rte->colcollations, cte->cycle_clause->cycle_mark_collation);
797 peter 2411 ECB :
797 peter 2412 CBC 93 : rte->eref->colnames = lappend(rte->eref->colnames, makeString(cte->cycle_clause->cycle_path_column));
797 peter 2413 GIC 93 : rte->coltypes = lappend_oid(rte->coltypes, RECORDARRAYOID);
797 peter 2414 CBC 93 : rte->coltypmods = lappend_int(rte->coltypmods, -1);
797 peter 2415 GBC 93 : rte->colcollations = lappend_oid(rte->colcollations, InvalidOid);
2416 :
797 peter 2417 GIC 93 : n_dontexpand_columns += 2;
2418 : }
2419 :
3897 tgl 2420 ECB : /*
2421 : * Set flags and access permissions.
5300 2422 : *
2423 : * Subqueries are never checked for access rights, so no need to perform
2424 : * addRTEPermissionInfo().
2425 : */
3897 tgl 2426 CBC 2562 : rte->lateral = false;
5300 2427 2562 : rte->inh = false; /* never true for subqueries */
5300 tgl 2428 GIC 2562 : rte->inFromCl = inFromCl;
5300 tgl 2429 ECB :
2430 : /*
1193 2431 : * Add completed RTE to pstate's range table list, so that we know its
2432 : * index. But we don't add it to the join list --- caller must do that if
2433 : * appropriate.
5300 2434 : */
2951 rhaas 2435 GIC 2562 : pstate->p_rtable = lappend(pstate->p_rtable, rte);
5300 tgl 2436 ECB :
1193 2437 : /*
2438 : * Build a ParseNamespaceItem, but don't add it to the pstate's namespace
2439 : * list --- caller must do that if appropriate.
2440 : */
797 peter 2441 CBC 2562 : psi = buildNSItemFromLists(rte, list_length(pstate->p_rtable),
2442 : rte->coltypes, rte->coltypmods,
2443 : rte->colcollations);
2444 :
2445 : /*
2446 : * The columns added by search and cycle clauses are not included in star
2447 : * expansion in queries contained in the CTE.
2448 : */
797 peter 2449 GIC 2562 : if (rte->ctelevelsup > 0)
797 peter 2450 CBC 1969 : for (int i = 0; i < n_dontexpand_columns; i++)
739 2451 177 : psi->p_nscolumns[list_length(psi->p_names->colnames) - 1 - i].p_dontexpand = true;
797 peter 2452 ECB :
797 peter 2453 GIC 2562 : return psi;
2454 : }
2455 :
2456 : /*
2457 : * Add an entry for an ephemeral named relation reference to the pstate's
2458 : * range table (p_rtable).
1193 tgl 2459 ECB : * Then, construct and return a ParseNamespaceItem for the new RTE.
2460 : *
2461 : * It is expected that the RangeVar, which up until now is only known to be an
2462 : * ephemeral named relation, will (in conjunction with the QueryEnvironment in
2463 : * the ParseState), create a RangeTblEntry for a specific *kind* of ephemeral
2464 : * named relation, based on enrtype.
2200 kgrittn 2465 : *
2466 : * This is much like addRangeTableEntry() except that it makes an RTE for an
2467 : * ephemeral named relation.
2468 : */
2469 : ParseNamespaceItem *
2200 kgrittn 2470 GIC 222 : addRangeTableEntryForENR(ParseState *pstate,
2471 : RangeVar *rv,
2472 : bool inFromCl)
2200 kgrittn 2473 ECB : {
2200 kgrittn 2474 CBC 222 : RangeTblEntry *rte = makeNode(RangeTblEntry);
2475 222 : Alias *alias = rv->alias;
2200 kgrittn 2476 GIC 222 : char *refname = alias ? alias->aliasname : rv->relname;
2184 tgl 2477 ECB : EphemeralNamedRelationMetadata enrmd;
2478 : TupleDesc tupdesc;
2479 : int attno;
2480 :
2184 tgl 2481 GIC 222 : Assert(pstate != NULL);
2482 222 : enrmd = get_visible_ENR(pstate, rv->relname);
2200 kgrittn 2483 222 : Assert(enrmd != NULL);
2484 :
2485 222 : switch (enrmd->enrtype)
2486 : {
2487 222 : case ENR_NAMED_TUPLESTORE:
2488 222 : rte->rtekind = RTE_NAMEDTUPLESTORE;
2489 222 : break;
2490 :
2200 kgrittn 2491 UIC 0 : default:
2184 tgl 2492 0 : elog(ERROR, "unexpected enrtype: %d", enrmd->enrtype);
2493 : return NULL; /* for fussy compilers */
2200 kgrittn 2494 ECB : }
2495 :
2496 : /*
2497 : * Record dependency on a relation. This allows plans to be invalidated
2498 : * if they access transition tables linked to a table that is altered.
2499 : */
2200 kgrittn 2500 CBC 222 : rte->relid = enrmd->reliddesc;
2501 :
2502 : /*
2503 : * Build the list of effective column names using user-supplied aliases
2504 : * and/or actual column names.
2200 kgrittn 2505 ECB : */
2200 kgrittn 2506 CBC 222 : tupdesc = ENRMetadataGetTupDesc(enrmd);
2507 222 : rte->eref = makeAlias(refname, NIL);
2200 kgrittn 2508 GIC 222 : buildRelationAliases(tupdesc, alias, rte->eref);
2041 tgl 2509 ECB :
2510 : /* Record additional data for ENR, including column type info */
2200 kgrittn 2511 CBC 222 : rte->enrname = enrmd->name;
2512 222 : rte->enrtuples = enrmd->enrtuples;
2513 222 : rte->coltypes = NIL;
2200 kgrittn 2514 GIC 222 : rte->coltypmods = NIL;
2200 kgrittn 2515 GBC 222 : rte->colcollations = NIL;
2516 729 : for (attno = 1; attno <= tupdesc->natts; ++attno)
2517 : {
2058 andres 2518 GIC 507 : Form_pg_attribute att = TupleDescAttr(tupdesc, attno - 1);
2519 :
2041 tgl 2520 507 : if (att->attisdropped)
2521 : {
2522 : /* Record zeroes for a dropped column */
2523 9 : rte->coltypes = lappend_oid(rte->coltypes, InvalidOid);
2041 tgl 2524 CBC 9 : rte->coltypmods = lappend_int(rte->coltypmods, 0);
2041 tgl 2525 GIC 9 : rte->colcollations = lappend_oid(rte->colcollations, InvalidOid);
2526 : }
2527 : else
2528 : {
2529 : /* Let's just make sure we can tell this isn't dropped */
2041 tgl 2530 CBC 498 : if (att->atttypid == InvalidOid)
2041 tgl 2531 LBC 0 : elog(ERROR, "atttypid is invalid for non-dropped column in \"%s\"",
2041 tgl 2532 ECB : rv->relname);
2041 tgl 2533 GIC 498 : rte->coltypes = lappend_oid(rte->coltypes, att->atttypid);
2534 498 : rte->coltypmods = lappend_int(rte->coltypmods, att->atttypmod);
2041 tgl 2535 CBC 498 : rte->colcollations = lappend_oid(rte->colcollations,
2041 tgl 2536 ECB : att->attcollation);
2537 : }
2200 kgrittn 2538 : }
2539 :
2540 : /*
2541 : * Set flags and access permissions.
2542 : *
2543 : * ENRs are never checked for access rights, so no need to perform
2544 : * addRTEPermissionInfo().
2545 : */
2200 kgrittn 2546 GIC 222 : rte->lateral = false;
2547 222 : rte->inh = false; /* never true for ENRs */
2200 kgrittn 2548 CBC 222 : rte->inFromCl = inFromCl;
2200 kgrittn 2549 ECB :
2550 : /*
1193 tgl 2551 : * Add completed RTE to pstate's range table list, so that we know its
1193 tgl 2552 EUB : * index. But we don't add it to the join list --- caller must do that if
2553 : * appropriate.
2200 kgrittn 2554 ECB : */
2184 tgl 2555 CBC 222 : pstate->p_rtable = lappend(pstate->p_rtable, rte);
2200 kgrittn 2556 ECB :
2557 : /*
2558 : * Build a ParseNamespaceItem, but don't add it to the pstate's namespace
2559 : * list --- caller must do that if appropriate.
2560 : */
124 alvherre 2561 GNC 222 : return buildNSItemFromTupleDesc(rte, list_length(pstate->p_rtable), NULL,
2562 : tupdesc);
2563 : }
2564 :
2565 :
2566 : /*
6555 tgl 2567 ECB : * Has the specified refname been selected FOR UPDATE/FOR SHARE?
6188 2568 : *
4912 2569 : * This is used when we have not yet done transformLockingClause, but need
2570 : * to know the correct lock to take during initial opening of relations.
2571 : *
2572 : * Note that refname may be NULL (for a subquery without an alias), in which
2573 : * case the relation can't be locked by name, but it might still be locked if
2574 : * a locking clause requests that all tables be locked.
2575 : *
2576 : * Note: we pay no attention to whether it's FOR UPDATE vs FOR SHARE,
2577 : * since the table-level lock is the same either way.
2578 : */
2579 : bool
4912 tgl 2580 CBC 287643 : isLockedRefname(ParseState *pstate, const char *refname)
2581 : {
2582 : ListCell *l;
2583 :
2584 : /*
2585 : * If we are in a subquery specified as locked FOR UPDATE/SHARE from
4912 tgl 2586 ECB : * parent level, then act as though there's a generic FOR UPDATE here.
2587 : */
4912 tgl 2588 GIC 287643 : if (pstate->p_locked_from_parent)
2589 2 : return true;
2590 :
2591 287831 : foreach(l, pstate->p_locking_clause)
2592 : {
2593 2558 : LockingClause *lc = (LockingClause *) lfirst(l);
2594 :
2595 2558 : if (lc->lockedRels == NIL)
2596 : {
2597 : /* all tables used in query */
2598 2368 : return true;
2599 : }
263 dean.a.rasheed 2600 GNC 1688 : else if (refname != NULL)
2601 : {
2602 : /* just the named tables */
2603 : ListCell *l2;
2604 :
4912 tgl 2605 CBC 1884 : foreach(l2, lc->lockedRels)
2606 : {
4912 tgl 2607 GIC 1697 : RangeVar *thisrel = (RangeVar *) lfirst(l2);
2608 :
2609 1697 : if (strcmp(refname, thisrel->relname) == 0)
2610 1498 : return true;
2611 : }
2612 : }
8187 tgl 2613 ECB : }
8187 tgl 2614 CBC 285273 : return false;
2615 : }
8187 tgl 2616 ECB :
2617 : /*
1193 2618 : * Add the given nsitem/RTE as a top-level entry in the pstate's join list
2619 : * and/or namespace list. (We assume caller has checked for any
2620 : * namespace conflicts.) The nsitem is always marked as unconditionally
2621 : * visible, that is, not LATERAL-only.
2622 : */
8244 2623 : void
1193 tgl 2624 GIC 122479 : addNSItemToQuery(ParseState *pstate, ParseNamespaceItem *nsitem,
1193 tgl 2625 ECB : bool addToJoinList,
2626 : bool addToRelNameSpace, bool addToVarNameSpace)
2627 : {
8089 tgl 2628 GIC 122479 : if (addToJoinList)
2629 : {
6517 tgl 2630 CBC 24848 : RangeTblRef *rtr = makeNode(RangeTblRef);
2631 :
1193 2632 24848 : rtr->rtindex = nsitem->p_rtindex;
8089 tgl 2633 GIC 24848 : pstate->p_joinlist = lappend(pstate->p_joinlist, rtr);
6517 tgl 2634 ECB : }
3897 tgl 2635 CBC 122479 : if (addToRelNameSpace || addToVarNameSpace)
2636 : {
2637 : /* Set the new nsitem's visibility flags correctly */
3896 tgl 2638 GIC 114677 : nsitem->p_rel_visible = addToRelNameSpace;
3896 tgl 2639 CBC 114677 : nsitem->p_cols_visible = addToVarNameSpace;
3897 tgl 2640 GIC 114677 : nsitem->p_lateral_only = false;
2641 114677 : nsitem->p_lateral_ok = true;
3896 2642 114677 : pstate->p_namespace = lappend(pstate->p_namespace, nsitem);
2643 : }
8244 2644 122479 : }
2645 :
2646 : /*
2647 : * expandRTE -- expand the columns of a rangetable entry
2648 : *
6807 tgl 2649 ECB : * This creates lists of an RTE's column names (aliases if provided, else
2650 : * real names) and Vars for each column. Only user columns are considered.
2651 : * If include_dropped is false then dropped columns are omitted from the
2652 : * results. If include_dropped is true then empty strings and NULL constants
2653 : * (not Vars!) are returned for dropped columns.
2654 : *
5333 2655 : * rtindex, sublevels_up, and location are the varno, varlevelsup, and location
2656 : * values to use in the created Vars. Ordinarily rtindex should match the
2657 : * actual position of the RTE in its rangetable.
6807 2658 : *
2659 : * The output lists go into *colnames and *colvars.
8244 2660 : * If only one of the two kinds of output list is needed, pass NULL for the
2661 : * output pointer for the unwanted one.
2662 : */
2663 : void
6518 tgl 2664 CBC 8366 : expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up,
5333 tgl 2665 ECB : int location, bool include_dropped,
8244 2666 : List **colnames, List **colvars)
2667 : {
2668 : int varattno;
8454 lockhart 2669 :
8244 tgl 2670 GIC 8366 : if (colnames)
2671 521 : *colnames = NIL;
2672 8366 : if (colvars)
2673 8099 : *colvars = NIL;
2674 :
7637 2675 8366 : switch (rte->rtekind)
2676 : {
2677 27 : case RTE_RELATION:
2678 : /* Ordinary relation RTE */
5333 2679 27 : expandRelation(rte->relid, rte->eref,
2680 : rtindex, sublevels_up, location,
2681 : include_dropped, colnames, colvars);
7637 2682 27 : break;
2683 227 : case RTE_SUBQUERY:
2684 : {
2685 : /* Subquery RTE */
6797 bruce 2686 227 : ListCell *aliasp_item = list_head(rte->eref->colnames);
2687 : ListCell *tlistitem;
2688 :
7637 tgl 2689 CBC 227 : varattno = 0;
7637 tgl 2690 GIC 832 : foreach(tlistitem, rte->subquery->targetList)
2691 : {
2692 605 : TargetEntry *te = (TargetEntry *) lfirst(tlistitem);
2693 :
6577 2694 605 : if (te->resjunk)
7637 tgl 2695 LBC 0 : continue;
7637 tgl 2696 CBC 605 : varattno++;
6577 2697 605 : Assert(varattno == te->resno);
8227 tgl 2698 ECB :
2699 : /*
2700 : * Formerly it was possible for the subquery tlist to have
2701 : * more non-junk entries than the colnames list does (if
2702 : * this RTE has been expanded from a view that has more
2703 : * columns than it did when the current query was parsed).
2704 : * Now that ApplyRetrieveRule cleans up such cases, we
2705 : * shouldn't see that anymore, but let's just check.
1990 2706 : */
1990 tgl 2707 GIC 605 : if (!aliasp_item)
33 tgl 2708 UNC 0 : elog(ERROR, "too few column names for subquery %s",
2709 : rte->eref->aliasname);
1990 tgl 2710 ECB :
7637 tgl 2711 CBC 605 : if (colnames)
2712 : {
6892 neilc 2713 605 : char *label = strVal(lfirst(aliasp_item));
2714 :
7637 tgl 2715 605 : *colnames = lappend(*colnames, makeString(pstrdup(label)));
7637 tgl 2716 EUB : }
8244 tgl 2717 ECB :
7637 tgl 2718 CBC 605 : if (colvars)
2719 : {
2720 : Var *varnode;
2721 :
7637 tgl 2722 GIC 605 : varnode = makeVar(rtindex, varattno,
6577 2723 605 : exprType((Node *) te->expr),
2724 605 : exprTypmod((Node *) te->expr),
4443 peter_e 2725 605 : exprCollation((Node *) te->expr),
2726 : sublevels_up);
5333 tgl 2727 605 : varnode->location = location;
8227 tgl 2728 ECB :
7637 tgl 2729 GBC 605 : *colvars = lappend(*colvars, varnode);
2730 : }
2731 :
1364 tgl 2732 CBC 605 : aliasp_item = lnext(rte->eref->colnames, aliasp_item);
2733 : }
7637 tgl 2734 ECB : }
7637 tgl 2735 GIC 227 : break;
7637 tgl 2736 CBC 7184 : case RTE_FUNCTION:
2737 : {
2738 : /* Function RTE */
3426 2739 7184 : int atts_done = 0;
2740 : ListCell *lc;
2741 :
3426 tgl 2742 GIC 14410 : foreach(lc, rte->functions)
7637 tgl 2743 ECB : {
3426 tgl 2744 CBC 7226 : RangeTblFunction *rtfunc = (RangeTblFunction *) lfirst(lc);
3426 tgl 2745 ECB : TypeFuncClass functypclass;
2746 : Oid funcrettype;
2747 : TupleDesc tupdesc;
2748 :
3426 tgl 2749 GIC 7226 : functypclass = get_expr_result_type(rtfunc->funcexpr,
3426 tgl 2750 ECB : &funcrettype,
2751 : &tupdesc);
1991 tgl 2752 GIC 7226 : if (functypclass == TYPEFUNC_COMPOSITE ||
1991 tgl 2753 ECB : functypclass == TYPEFUNC_COMPOSITE_DOMAIN)
2754 : {
2755 : /* Composite data type, e.g. a table's row type */
3426 tgl 2756 CBC 4235 : Assert(tupdesc);
2757 4235 : expandTupleDesc(tupdesc, rte->eref,
2758 : rtfunc->funccolcount, atts_done,
2759 : rtindex, sublevels_up, location,
3426 tgl 2760 ECB : include_dropped, colnames, colvars);
2761 : }
3426 tgl 2762 GIC 2991 : else if (functypclass == TYPEFUNC_SCALAR)
7553 bruce 2763 ECB : {
2764 : /* Base data type, i.e. scalar */
3426 tgl 2765 CBC 2980 : if (colnames)
3426 tgl 2766 GIC 141 : *colnames = lappend(*colnames,
2767 141 : list_nth(rte->eref->colnames,
2768 : atts_done));
2769 :
3426 tgl 2770 CBC 2980 : if (colvars)
2771 : {
2772 : Var *varnode;
7553 bruce 2773 ECB :
3426 tgl 2774 GIC 2839 : varnode = makeVar(rtindex, atts_done + 1,
2775 : funcrettype,
1193 2776 2839 : exprTypmod(rtfunc->funcexpr),
3426 tgl 2777 CBC 2839 : exprCollation(rtfunc->funcexpr),
7522 bruce 2778 ECB : sublevels_up);
5333 tgl 2779 GIC 2839 : varnode->location = location;
2780 :
7553 bruce 2781 2839 : *colvars = lappend(*colvars, varnode);
2782 : }
7553 bruce 2783 ECB : }
3426 tgl 2784 GIC 11 : else if (functypclass == TYPEFUNC_RECORD)
2785 : {
3426 tgl 2786 CBC 11 : if (colnames)
3426 tgl 2787 ECB : {
2788 : List *namelist;
2789 :
2790 : /* extract appropriate subset of column list */
3426 tgl 2791 CBC 3 : namelist = list_copy_tail(rte->eref->colnames,
2792 : atts_done);
3426 tgl 2793 GIC 3 : namelist = list_truncate(namelist,
2794 : rtfunc->funccolcount);
3426 tgl 2795 CBC 3 : *colnames = list_concat(*colnames, namelist);
2796 : }
3541 stark 2797 ECB :
3426 tgl 2798 CBC 11 : if (colvars)
2799 : {
3426 tgl 2800 ECB : ListCell *l1;
2801 : ListCell *l2;
2802 : ListCell *l3;
3426 tgl 2803 GIC 8 : int attnum = atts_done;
2804 :
3426 tgl 2805 CBC 32 : forthree(l1, rtfunc->funccoltypes,
2806 : l2, rtfunc->funccoltypmods,
3426 tgl 2807 ECB : l3, rtfunc->funccolcollations)
2808 : {
3426 tgl 2809 GIC 24 : Oid attrtype = lfirst_oid(l1);
2810 24 : int32 attrtypmod = lfirst_int(l2);
2811 24 : Oid attrcollation = lfirst_oid(l3);
3426 tgl 2812 ECB : Var *varnode;
2813 :
3426 tgl 2814 CBC 24 : attnum++;
3426 tgl 2815 GIC 24 : varnode = makeVar(rtindex,
3426 tgl 2816 ECB : attnum,
2817 : attrtype,
2818 : attrtypmod,
2819 : attrcollation,
2820 : sublevels_up);
3426 tgl 2821 GIC 24 : varnode->location = location;
2822 24 : *colvars = lappend(*colvars, varnode);
2823 : }
3426 tgl 2824 ECB : }
2825 : }
2826 : else
2827 : {
2828 : /* addRangeTableEntryForFunction should've caught this */
3426 tgl 2829 UIC 0 : elog(ERROR, "function in FROM has unsupported return type");
3426 tgl 2830 ECB : }
3426 tgl 2831 CBC 7226 : atts_done += rtfunc->funccolcount;
6745 tgl 2832 ECB : }
2833 :
2834 : /* Append the ordinality column if any */
3541 stark 2835 CBC 7184 : if (rte->funcordinality)
3541 stark 2836 ECB : {
3541 stark 2837 GIC 177 : if (colnames)
3426 tgl 2838 9 : *colnames = lappend(*colnames,
2839 9 : llast(rte->eref->colnames));
2840 :
3541 stark 2841 177 : if (colvars)
3541 stark 2842 ECB : {
3426 tgl 2843 CBC 168 : Var *varnode = makeVar(rtindex,
3426 tgl 2844 GIC 168 : atts_done + 1,
2845 : INT8OID,
2846 : -1,
2847 : InvalidOid,
2848 : sublevels_up);
2849 :
3541 stark 2850 GBC 168 : *colvars = lappend(*colvars, varnode);
2851 : }
3541 stark 2852 ECB : }
2853 : }
7637 tgl 2854 GIC 7184 : break;
2855 6 : case RTE_JOIN:
7637 tgl 2856 ECB : {
2857 : /* Join RTE */
6797 bruce 2858 : ListCell *colname;
2859 : ListCell *aliasvar;
6892 neilc 2860 :
6888 neilc 2861 GIC 6 : Assert(list_length(rte->eref->colnames) == list_length(rte->joinaliasvars));
8454 lockhart 2862 ECB :
7637 tgl 2863 GIC 6 : varattno = 0;
6797 bruce 2864 CBC 30 : forboth(colname, rte->eref->colnames, aliasvar, rte->joinaliasvars)
7637 tgl 2865 ECB : {
6519 tgl 2866 GIC 24 : Node *avar = (Node *) lfirst(aliasvar);
2867 :
7637 2868 24 : varattno++;
2869 :
2870 : /*
6807 tgl 2871 ECB : * During ordinary parsing, there will never be any
2872 : * deleted columns in the join. While this function is
2873 : * also used by the rewriter and planner, they do not
2874 : * currently call it on any JOIN RTEs. Therefore, this
1186 2875 : * next bit is dead code, but it seems prudent to handle
2876 : * the case correctly anyway.
2877 : */
3547 tgl 2878 GIC 24 : if (avar == NULL)
2879 : {
6807 tgl 2880 UIC 0 : if (include_dropped)
2881 : {
6807 tgl 2882 LBC 0 : if (colnames)
6807 tgl 2883 UIC 0 : *colnames = lappend(*colnames,
6519 tgl 2884 LBC 0 : makeString(pstrdup("")));
6807 2885 0 : if (colvars)
2886 : {
3547 tgl 2887 ECB : /*
2888 : * Can't use join's column type here (it might
2889 : * be dropped!); but it doesn't really matter
2890 : * what type the Const claims to be.
2891 : */
6807 tgl 2892 UIC 0 : *colvars = lappend(*colvars,
3547 2893 0 : makeNullConst(INT4OID, -1,
2894 : InvalidOid));
2895 : }
2896 : }
6807 2897 0 : continue;
2898 : }
6807 tgl 2899 ECB :
7637 tgl 2900 GIC 24 : if (colnames)
7637 tgl 2901 EUB : {
6892 neilc 2902 UIC 0 : char *label = strVal(lfirst(colname));
9266 bruce 2903 EUB :
6807 tgl 2904 UBC 0 : *colnames = lappend(*colnames,
2905 0 : makeString(pstrdup(label)));
7637 tgl 2906 EUB : }
2907 :
7637 tgl 2908 GIC 24 : if (colvars)
2909 : {
2910 : Var *varnode;
2911 :
2912 : /*
1186 tgl 2913 EUB : * If the joinaliasvars entry is a simple Var, just
2914 : * copy it (with adjustment of varlevelsup and
2915 : * location); otherwise it is a JOIN USING column and
2916 : * we must generate a join alias Var. This matches
2917 : * the results that expansion of "join.*" by
2918 : * expandNSItemVars would have produced, if we had
2919 : * access to the ParseNamespaceItem for the join.
2920 : */
1186 tgl 2921 CBC 24 : if (IsA(avar, Var))
2922 : {
1186 tgl 2923 GBC 24 : varnode = copyObject((Var *) avar);
1186 tgl 2924 GIC 24 : varnode->varlevelsup = sublevels_up;
1186 tgl 2925 EUB : }
2926 : else
1186 tgl 2927 UIC 0 : varnode = makeVar(rtindex, varattno,
2928 : exprType(avar),
1186 tgl 2929 ECB : exprTypmod(avar),
2930 : exprCollation(avar),
2931 : sublevels_up);
5333 tgl 2932 GIC 24 : varnode->location = location;
2933 :
7637 2934 24 : *colvars = lappend(*colvars, varnode);
2935 : }
2936 : }
2937 : }
2938 6 : break;
2223 alvherre 2939 922 : case RTE_TABLEFUNC:
2940 : case RTE_VALUES:
2941 : case RTE_CTE:
2200 kgrittn 2942 ECB : case RTE_NAMEDTUPLESTORE:
2943 : {
2041 tgl 2944 : /* Tablefunc, Values, CTE, or ENR RTE */
5300 tgl 2945 CBC 922 : ListCell *aliasp_item = list_head(rte->eref->colnames);
2946 : ListCell *lct;
2947 : ListCell *lcm;
4443 peter_e 2948 EUB : ListCell *lcc;
2949 :
5300 tgl 2950 GIC 922 : varattno = 0;
2313 2951 2899 : forthree(lct, rte->coltypes,
2952 : lcm, rte->coltypmods,
2313 tgl 2953 ECB : lcc, rte->colcollations)
2954 : {
5050 bruce 2955 CBC 1977 : Oid coltype = lfirst_oid(lct);
5050 bruce 2956 GIC 1977 : int32 coltypmod = lfirst_int(lcm);
4443 peter_e 2957 1977 : Oid colcoll = lfirst_oid(lcc);
2958 :
5300 tgl 2959 CBC 1977 : varattno++;
5300 tgl 2960 ECB :
5300 tgl 2961 GIC 1977 : if (colnames)
2962 : {
2963 : /* Assume there is one alias per output column */
2041 tgl 2964 UIC 0 : if (OidIsValid(coltype))
2965 : {
2041 tgl 2966 LBC 0 : char *label = strVal(lfirst(aliasp_item));
2967 :
2041 tgl 2968 UIC 0 : *colnames = lappend(*colnames,
2969 0 : makeString(pstrdup(label)));
2970 : }
2041 tgl 2971 LBC 0 : else if (include_dropped)
2972 0 : *colnames = lappend(*colnames,
2041 tgl 2973 UIC 0 : makeString(pstrdup("")));
2974 :
1364 2975 0 : aliasp_item = lnext(rte->eref->colnames, aliasp_item);
5300 tgl 2976 ECB : }
2977 :
5300 tgl 2978 CBC 1977 : if (colvars)
2979 : {
2041 2980 1977 : if (OidIsValid(coltype))
2981 : {
2041 tgl 2982 ECB : Var *varnode;
2983 :
2041 tgl 2984 GIC 1977 : varnode = makeVar(rtindex, varattno,
2041 tgl 2985 EUB : coltype, coltypmod, colcoll,
2986 : sublevels_up);
2041 tgl 2987 GBC 1977 : varnode->location = location;
2988 :
2989 1977 : *colvars = lappend(*colvars, varnode);
2041 tgl 2990 EUB : }
2041 tgl 2991 UIC 0 : else if (include_dropped)
2041 tgl 2992 EUB : {
2993 : /*
2994 : * It doesn't really matter what type the Const
2995 : * claims to be.
2996 : */
2041 tgl 2997 UIC 0 : *colvars = lappend(*colvars,
2998 0 : makeNullConst(INT4OID, -1,
2041 tgl 2999 ECB : InvalidOid));
3000 : }
5300 3001 : }
3002 : }
3003 : }
5300 tgl 3004 GIC 922 : break;
1532 tgl 3005 LBC 0 : case RTE_RESULT:
3006 : /* These expose no columns, so nothing to do */
1532 tgl 3007 UIC 0 : break;
7637 tgl 3008 LBC 0 : default:
7204 tgl 3009 UIC 0 : elog(ERROR, "unrecognized RTE kind: %d", (int) rte->rtekind);
7698 tgl 3010 ECB : }
8244 tgl 3011 GIC 8366 : }
8454 lockhart 3012 EUB :
3013 : /*
3014 : * expandRelation -- expandRTE subroutine
3015 : */
3016 : static void
6807 tgl 3017 GIC 27 : expandRelation(Oid relid, Alias *eref, int rtindex, int sublevels_up,
5333 tgl 3018 EUB : int location, bool include_dropped,
6807 3019 : List **colnames, List **colvars)
3020 : {
3021 : Relation rel;
3022 :
3023 : /* Get the tupledesc and turn it over to expandTupleDesc */
6807 tgl 3024 GIC 27 : rel = relation_open(relid, AccessShareLock);
3426 tgl 3025 CBC 27 : expandTupleDesc(rel->rd_att, eref, rel->rd_att->natts, 0,
3426 tgl 3026 EUB : rtindex, sublevels_up,
3027 : location, include_dropped,
6583 3028 : colnames, colvars);
6583 tgl 3029 GBC 27 : relation_close(rel, AccessShareLock);
3030 27 : }
3031 :
6583 tgl 3032 ECB : /*
3033 : * expandTupleDesc -- expandRTE subroutine
3034 : *
3035 : * Generate names and/or Vars for the first "count" attributes of the tupdesc,
3036 : * and append them to colnames/colvars. "offset" is added to the varattno
3037 : * that each Var would otherwise have, and we also skip the first "offset"
3426 3038 : * entries in eref->colnames. (These provisions allow use of this code for
3039 : * an individual composite-returning function in an RTE_FUNCTION RTE.)
3040 : */
3041 : static void
3426 tgl 3042 GIC 4262 : expandTupleDesc(TupleDesc tupdesc, Alias *eref, int count, int offset,
3043 : int rtindex, int sublevels_up,
3044 : int location, bool include_dropped,
6583 tgl 3045 ECB : List **colnames, List **colvars)
3046 : {
3047 : ListCell *aliascell;
3048 : int varattno;
3049 :
1364 tgl 3050 CBC 4262 : aliascell = (offset < list_length(eref->colnames)) ?
3051 4262 : list_nth_cell(eref->colnames, offset) : NULL;
3052 :
3426 tgl 3053 GIC 4262 : Assert(count <= tupdesc->natts);
3054 31368 : for (varattno = 0; varattno < count; varattno++)
3055 : {
2058 andres 3056 27106 : Form_pg_attribute attr = TupleDescAttr(tupdesc, varattno);
3057 :
6807 tgl 3058 27106 : if (attr->attisdropped)
3059 : {
3060 21 : if (include_dropped)
3061 : {
3062 21 : if (colnames)
6807 tgl 3063 CBC 21 : *colnames = lappend(*colnames, makeString(pstrdup("")));
6807 tgl 3064 GIC 21 : if (colvars)
3065 : {
3066 : /*
3067 : * can't use atttypid here, but it doesn't really matter
3068 : * what type the Const claims to be.
3069 : */
4398 tgl 3070 UIC 0 : *colvars = lappend(*colvars,
2118 tgl 3071 LBC 0 : makeNullConst(INT4OID, -1, InvalidOid));
6807 tgl 3072 ECB : }
3073 : }
3426 tgl 3074 CBC 21 : if (aliascell)
1364 3075 21 : aliascell = lnext(eref->colnames, aliascell);
6807 tgl 3076 GIC 21 : continue;
6807 tgl 3077 ECB : }
3078 :
6807 tgl 3079 CBC 27085 : if (colnames)
3080 : {
6807 tgl 3081 ECB : char *label;
3082 :
3426 tgl 3083 CBC 1662 : if (aliascell)
3426 tgl 3084 ECB : {
3426 tgl 3085 CBC 1662 : label = strVal(lfirst(aliascell));
1364 tgl 3086 GIC 1662 : aliascell = lnext(eref->colnames, aliascell);
3087 : }
3088 : else
3089 : {
3090 : /* If we run out of aliases, use the underlying name */
6807 tgl 3091 UBC 0 : label = NameStr(attr->attname);
3426 tgl 3092 EUB : }
6807 tgl 3093 GIC 1662 : *colnames = lappend(*colnames, makeString(pstrdup(label)));
3094 : }
6807 tgl 3095 ECB :
6807 tgl 3096 CBC 27085 : if (colvars)
6807 tgl 3097 ECB : {
3098 : Var *varnode;
3099 :
3426 tgl 3100 CBC 25492 : varnode = makeVar(rtindex, varattno + offset + 1,
3101 : attr->atttypid, attr->atttypmod,
3102 : attr->attcollation,
3103 : sublevels_up);
5333 3104 25492 : varnode->location = location;
3105 :
6807 3106 25492 : *colvars = lappend(*colvars, varnode);
6807 tgl 3107 ECB : }
3108 : }
6807 tgl 3109 GIC 4262 : }
3110 :
3111 : /*
1193 tgl 3112 EUB : * expandNSItemVars
3113 : * Produce a list of Vars, and optionally a list of column names,
1193 tgl 3114 ECB : * for the non-dropped columns of the nsitem.
3115 : *
3116 : * The emitted Vars are marked with the given sublevels_up and location.
3117 : *
3118 : * If colnames isn't NULL, a list of String items for the columns is stored
3119 : * there; note that it's just a subset of the RTE's eref list, and hence
3120 : * the list elements mustn't be modified.
3121 : */
3122 : List *
69 tgl 3123 GNC 36291 : expandNSItemVars(ParseState *pstate, ParseNamespaceItem *nsitem,
3124 : int sublevels_up, int location,
1193 tgl 3125 ECB : List **colnames)
3126 : {
1193 tgl 3127 CBC 36291 : List *result = NIL;
3128 : int colindex;
3129 : ListCell *lc;
1193 tgl 3130 ECB :
1193 tgl 3131 GIC 36291 : if (colnames)
3132 34193 : *colnames = NIL;
3133 36291 : colindex = 0;
739 peter 3134 188243 : foreach(lc, nsitem->p_names->colnames)
3135 : {
577 3136 151952 : String *colnameval = lfirst(lc);
1193 tgl 3137 151952 : const char *colname = strVal(colnameval);
3138 151952 : ParseNamespaceColumn *nscol = nsitem->p_nscolumns + colindex;
3139 :
797 peter 3140 151952 : if (nscol->p_dontexpand)
3141 : {
3142 : /* skip */
3143 : }
797 peter 3144 CBC 151943 : else if (colname[0])
3145 : {
3146 : Var *var;
3147 :
1193 tgl 3148 151419 : Assert(nscol->p_varno > 0);
1186 tgl 3149 GIC 151419 : var = makeVar(nscol->p_varno,
3150 151419 : nscol->p_varattno,
3151 : nscol->p_vartype,
1193 tgl 3152 ECB : nscol->p_vartypmod,
3153 : nscol->p_varcollid,
3154 : sublevels_up);
1186 3155 : /* makeVar doesn't offer parameters for these, so set by hand: */
1186 tgl 3156 GIC 151419 : var->varnosyn = nscol->p_varnosyn;
1186 tgl 3157 CBC 151419 : var->varattnosyn = nscol->p_varattnosyn;
1193 3158 151419 : var->location = location;
3159 :
3160 : /* ... and update varnullingrels */
69 tgl 3161 GNC 151419 : markNullableIfNeeded(pstate, var);
3162 :
1193 tgl 3163 CBC 151419 : result = lappend(result, var);
1193 tgl 3164 GIC 151419 : if (colnames)
1193 tgl 3165 CBC 147775 : *colnames = lappend(*colnames, colnameval);
3166 : }
3167 : else
3168 : {
1193 tgl 3169 ECB : /* dropped column, ignore */
1193 tgl 3170 GIC 524 : Assert(nscol->p_varno == 0);
3171 : }
3172 151952 : colindex++;
1193 tgl 3173 ECB : }
1193 tgl 3174 CBC 36291 : return result;
1193 tgl 3175 ECB : }
3176 :
3177 : /*
3178 : * expandNSItemAttrs -
3179 : * Workhorse for "*" expansion: produce a list of targetentries
3180 : * for the attributes of the nsitem
6518 3181 : *
5333 3182 : * pstate->p_next_resno determines the resnos assigned to the TLEs.
377 alvherre 3183 : * The referenced columns are marked as requiring SELECT access, if
3184 : * caller requests that.
3185 : */
7698 tgl 3186 : List *
1200 tgl 3187 GIC 34193 : expandNSItemAttrs(ParseState *pstate, ParseNamespaceItem *nsitem,
377 alvherre 3188 ECB : int sublevels_up, bool require_col_privs, int location)
8244 tgl 3189 : {
1200 tgl 3190 CBC 34193 : RangeTblEntry *rte = nsitem->p_rte;
124 alvherre 3191 GNC 34193 : RTEPermissionInfo *perminfo = nsitem->p_perminfo;
3192 : List *names,
3193 : *vars;
3194 : ListCell *name,
3195 : *var;
8244 tgl 3196 CBC 34193 : List *te_list = NIL;
3197 :
69 tgl 3198 GNC 34193 : vars = expandNSItemVars(pstate, nsitem, sublevels_up, location, &names);
3199 :
5190 tgl 3200 ECB : /*
3201 : * Require read access to the table. This is normally redundant with the
3202 : * markVarForSelectPriv calls below, but not if the table has zero
3203 : * columns. We need not do anything if the nsitem is for a join: its
3204 : * component tables will have been marked ACL_SELECT when they were added
3205 : * to the rangetable. (This step changes things only for the target
3206 : * relation of UPDATE/DELETE, which cannot be under a join.)
3207 : */
790 tgl 3208 GIC 34193 : if (rte->rtekind == RTE_RELATION)
3209 : {
124 alvherre 3210 GNC 20143 : Assert(perminfo != NULL);
3211 20143 : perminfo->requiredPerms |= ACL_SELECT;
3212 : }
3213 :
6807 tgl 3214 GIC 181968 : forboth(name, names, var, vars)
3215 : {
6892 neilc 3216 CBC 147775 : char *label = strVal(lfirst(name));
5190 tgl 3217 GIC 147775 : Var *varnode = (Var *) lfirst(var);
3218 : TargetEntry *te;
6577 tgl 3219 ECB :
6577 tgl 3220 CBC 147775 : te = makeTargetEntry((Expr *) varnode,
6577 tgl 3221 GIC 147775 : (AttrNumber) pstate->p_next_resno++,
3222 : label,
3223 : false);
8665 3224 147775 : te_list = lappend(te_list, te);
5190 tgl 3225 ECB :
377 alvherre 3226 GIC 147775 : if (require_col_privs)
377 alvherre 3227 ECB : {
3228 : /* Require read access to each column */
377 alvherre 3229 GIC 147775 : markVarForSelectPriv(pstate, varnode);
3230 : }
3231 : }
3232 :
2118 tgl 3233 34193 : Assert(name == NULL && var == NULL); /* lists not the same length? */
3234 :
8665 3235 34193 : return te_list;
3236 : }
9266 bruce 3237 ECB :
3238 : /*
8231 tgl 3239 : * get_rte_attribute_name
3240 : * Get an attribute name from a RangeTblEntry
3241 : *
3242 : * This is unlike get_attname() because we use aliases if available.
7698 3243 : * In particular, it will work on an RTE for a subselect or join, whereas
3244 : * get_attname() only works on real relations.
8089 3245 : *
8026 3246 : * "*" is returned if the given attnum is InvalidAttrNumber --- this case
3247 : * occurs when a Var represents a whole tuple of a relation.
3248 : *
262 3249 : * It is caller's responsibility to not call this on a dropped attribute.
3250 : * (You will get some answer for such cases, but it might not be sensible.)
3251 : */
3252 : char *
8231 tgl 3253 CBC 658 : get_rte_attribute_name(RangeTblEntry *rte, AttrNumber attnum)
3254 : {
8026 3255 658 : if (attnum == InvalidAttrNumber)
8026 tgl 3256 UIC 0 : return "*";
3257 :
8231 tgl 3258 ECB : /*
3259 : * If there is a user-written column alias, use it.
3260 : */
7549 tgl 3261 GIC 658 : if (rte->alias &&
6888 neilc 3262 CBC 27 : attnum > 0 && attnum <= list_length(rte->alias->colnames))
6888 neilc 3263 UIC 0 : return strVal(list_nth(rte->alias->colnames, attnum - 1));
8053 bruce 3264 ECB :
3265 : /*
3266 : * If the RTE is a relation, go to the system catalogs not the
3267 : * eref->colnames list. This is a little slower but it will give the
3268 : * right answer if the column has been renamed since the eref list was
3269 : * built (which can easily happen for rules).
3270 : */
7549 tgl 3271 GIC 658 : if (rte->rtekind == RTE_RELATION)
1882 alvherre 3272 643 : return get_attname(rte->relid, attnum, false);
3273 :
3274 : /*
3275 : * Otherwise use the column name from eref. There should always be one.
3276 : */
6888 neilc 3277 15 : if (attnum > 0 && attnum <= list_length(rte->eref->colnames))
3278 15 : return strVal(list_nth(rte->eref->colnames, attnum - 1));
3279 :
3280 : /* else caller gave us a bogus attnum */
7204 tgl 3281 UIC 0 : elog(ERROR, "invalid attnum %d for rangetable entry %s",
7549 tgl 3282 ECB : attnum, rte->eref->aliasname);
3283 : return NULL; /* keep compiler quiet */
8231 3284 : }
8231 tgl 3285 EUB :
3286 : /*
3287 : * get_rte_attribute_is_dropped
3288 : * Check whether attempted attribute ref is to a dropped column
3289 : */
6809 tgl 3290 ECB : bool
6519 tgl 3291 CBC 223022 : get_rte_attribute_is_dropped(RangeTblEntry *rte, AttrNumber attnum)
7555 tgl 3292 EUB : {
3293 : bool result;
3294 :
7555 tgl 3295 GIC 223022 : switch (rte->rtekind)
3296 : {
3297 169910 : case RTE_RELATION:
3298 : {
3299 : /*
6385 bruce 3300 ECB : * Plain relation RTE --- get the attribute's catalog entry
6797 3301 : */
3302 : HeapTuple tp;
3303 : Form_pg_attribute att_tup;
3304 :
4802 rhaas 3305 GIC 169910 : tp = SearchSysCache2(ATTNUM,
4802 rhaas 3306 ECB : ObjectIdGetDatum(rte->relid),
3307 : Int16GetDatum(attnum));
2118 tgl 3308 GIC 169910 : if (!HeapTupleIsValid(tp)) /* shouldn't happen */
7204 tgl 3309 UIC 0 : elog(ERROR, "cache lookup failed for attribute %d of relation %u",
7204 tgl 3310 EUB : attnum, rte->relid);
7555 tgl 3311 GIC 169910 : att_tup = (Form_pg_attribute) GETSTRUCT(tp);
3312 169910 : result = att_tup->attisdropped;
3313 169910 : ReleaseSysCache(tp);
3314 : }
3315 169910 : break;
3316 138 : case RTE_SUBQUERY:
3317 : case RTE_TABLEFUNC:
3318 : case RTE_VALUES:
3319 : case RTE_CTE:
2223 alvherre 3320 ECB :
3321 : /*
3322 : * Subselect, Table Functions, Values, CTE RTEs never have dropped
3323 : * columns
3324 : */
7555 tgl 3325 GIC 138 : result = false;
7555 tgl 3326 CBC 138 : break;
2200 kgrittn 3327 UIC 0 : case RTE_NAMEDTUPLESTORE:
3328 : {
3329 : /* Check dropped-ness by testing for valid coltype */
2041 tgl 3330 0 : if (attnum <= 0 ||
3331 0 : attnum > list_length(rte->coltypes))
3332 0 : elog(ERROR, "invalid varattno %d", attnum);
3333 0 : result = !OidIsValid((list_nth_oid(rte->coltypes, attnum - 1)));
2200 kgrittn 3334 ECB : }
2200 kgrittn 3335 UIC 0 : break;
6807 tgl 3336 0 : case RTE_JOIN:
6807 tgl 3337 ECB : {
6807 tgl 3338 EUB : /*
3339 : * A join RTE would not have dropped columns when constructed,
6385 bruce 3340 ECB : * but one in a stored rule might contain columns that were
3341 : * dropped from the underlying tables, if said columns are
3342 : * nowhere explicitly referenced in the rule. This will be
3343 : * signaled to us by a null pointer in the joinaliasvars list.
6807 tgl 3344 : */
6797 bruce 3345 : Var *aliasvar;
3346 :
6807 tgl 3347 UIC 0 : if (attnum <= 0 ||
3348 0 : attnum > list_length(rte->joinaliasvars))
3349 0 : elog(ERROR, "invalid varattno %d", attnum);
3350 0 : aliasvar = (Var *) list_nth(rte->joinaliasvars, attnum - 1);
3351 :
3547 3352 0 : result = (aliasvar == NULL);
3353 : }
6807 tgl 3354 LBC 0 : break;
7555 tgl 3355 CBC 52974 : case RTE_FUNCTION:
7555 tgl 3356 EUB : {
3357 : /* Function RTE */
3358 : ListCell *lc;
3426 tgl 3359 GBC 52974 : int atts_done = 0;
7555 tgl 3360 EUB :
3541 stark 3361 : /*
3426 tgl 3362 : * Dropped attributes are only possible with functions that
3363 : * return named composite types. In such a case we have to
3364 : * look up the result type to see if it currently has this
3260 bruce 3365 : * column dropped. So first, loop over the funcs until we
3366 : * find the one that covers the requested column.
3367 : */
3426 tgl 3368 GIC 53004 : foreach(lc, rte->functions)
3369 : {
3370 52992 : RangeTblFunction *rtfunc = (RangeTblFunction *) lfirst(lc);
3371 :
3372 52992 : if (attnum > atts_done &&
3373 52992 : attnum <= atts_done + rtfunc->funccolcount)
3374 : {
3375 : TupleDesc tupdesc;
3426 tgl 3376 EUB :
1991 tgl 3377 GBC 52962 : tupdesc = get_expr_result_tupdesc(rtfunc->funcexpr,
1991 tgl 3378 EUB : true);
1991 tgl 3379 GBC 52962 : if (tupdesc)
3380 : {
3426 tgl 3381 EUB : /* Composite data type, e.g. a table's row type */
3382 : Form_pg_attribute att_tup;
3383 :
3426 tgl 3384 CBC 52938 : Assert(tupdesc);
3426 tgl 3385 GIC 52938 : Assert(attnum - atts_done <= tupdesc->natts);
2058 andres 3386 52938 : att_tup = TupleDescAttr(tupdesc,
3387 : attnum - atts_done - 1);
3426 tgl 3388 CBC 52962 : return att_tup->attisdropped;
3389 : }
3390 : /* Otherwise, it can't have any dropped columns */
3426 tgl 3391 GIC 24 : return false;
3392 : }
3393 30 : atts_done += rtfunc->funccolcount;
3394 : }
3395 :
3396 : /* If we get here, must be looking for the ordinality column */
3426 tgl 3397 CBC 12 : if (rte->funcordinality && attnum == atts_done + 1)
3426 tgl 3398 GIC 12 : return false;
3426 tgl 3399 ECB :
3400 : /* this probably can't happen ... */
3426 tgl 3401 LBC 0 : ereport(ERROR,
3426 tgl 3402 ECB : (errcode(ERRCODE_UNDEFINED_COLUMN),
3403 : errmsg("column %d of relation \"%s\" does not exist",
3404 : attnum,
3405 : rte->eref->aliasname)));
3406 : result = false; /* keep compiler quiet */
3407 : }
7555 3408 : break;
1532 tgl 3409 UIC 0 : case RTE_RESULT:
3410 : /* this probably can't happen ... */
3411 0 : ereport(ERROR,
3412 : (errcode(ERRCODE_UNDEFINED_COLUMN),
1532 tgl 3413 ECB : errmsg("column %d of relation \"%s\" does not exist",
3414 : attnum,
3415 : rte->eref->aliasname)));
3416 : result = false; /* keep compiler quiet */
3417 : break;
7555 tgl 3418 UIC 0 : default:
7204 3419 0 : elog(ERROR, "unrecognized RTE kind: %d", (int) rte->rtekind);
7555 tgl 3420 ECB : result = false; /* keep compiler quiet */
3421 : }
3422 :
7555 tgl 3423 GIC 170048 : return result;
3424 : }
3425 :
7181 tgl 3426 ECB : /*
3427 : * Given a targetlist and a resno, return the matching TargetEntry
3428 : *
3429 : * Returns NULL if resno is not present in list.
7181 tgl 3430 EUB : *
3431 : * Note: we need to search, rather than just indexing with list_nth(),
3432 : * because not all tlists are sorted by resno.
3433 : */
3434 : TargetEntry *
7181 tgl 3435 GIC 119594 : get_tle_by_resno(List *tlist, AttrNumber resno)
3436 : {
3437 : ListCell *l;
7181 tgl 3438 EUB :
6892 neilc 3439 GIC 383801 : foreach(l, tlist)
7181 tgl 3440 EUB : {
6892 neilc 3441 GIC 383558 : TargetEntry *tle = (TargetEntry *) lfirst(l);
3442 :
6577 tgl 3443 383558 : if (tle->resno == resno)
7181 3444 119351 : return tle;
3445 : }
3446 243 : return NULL;
7181 tgl 3447 EUB : }
3448 :
3449 : /*
3450 : * Given a Query and rangetable index, return relation's RowMarkClause if any
3451 : *
6188 tgl 3452 ECB : * Returns NULL if relation is not selected FOR UPDATE/SHARE
3453 : */
3454 : RowMarkClause *
4913 tgl 3455 GIC 9461 : get_parse_rowmark(Query *qry, Index rtindex)
3456 : {
3457 : ListCell *l;
3458 :
6188 3459 9579 : foreach(l, qry->rowMarks)
3460 : {
3461 166 : RowMarkClause *rc = (RowMarkClause *) lfirst(l);
3462 :
3463 166 : if (rc->rti == rtindex)
6188 tgl 3464 CBC 48 : return rc;
3465 : }
6188 tgl 3466 GIC 9413 : return NULL;
3467 : }
6188 tgl 3468 ECB :
3469 : /*
6226 3470 : * given relation and att name, return attnum of variable
3471 : *
3472 : * Returns InvalidAttrNumber if the attr doesn't exist (or is dropped).
9210 bruce 3473 : *
3474 : * This should only be used if the relation is already
1539 andres 3475 : * table_open()'ed. Use the cache version get_attnum()
3476 : * for access to non-opened relations.
3477 : */
3478 : int
7555 tgl 3479 GIC 33833 : attnameAttNum(Relation rd, const char *attname, bool sysColOK)
3480 : {
3481 : int i;
3482 :
1828 teodor 3483 161290 : for (i = 0; i < RelationGetNumberOfAttributes(rd); i++)
7555 tgl 3484 ECB : {
2058 andres 3485 GIC 161241 : Form_pg_attribute att = TupleDescAttr(rd->rd_att, i);
3486 :
7555 tgl 3487 161241 : if (namestrcmp(&(att->attname), attname) == 0 && !att->attisdropped)
8986 bruce 3488 CBC 33784 : return i + 1;
3489 : }
9266 bruce 3490 ECB :
7555 tgl 3491 GIC 49 : if (sysColOK)
7912 tgl 3492 ECB : {
7555 tgl 3493 CBC 6 : if ((i = specialAttNum(attname)) != InvalidAttrNumber)
1601 andres 3494 UIC 0 : return i;
7912 tgl 3495 ECB : }
3496 :
3497 : /* on failure */
6226 tgl 3498 GIC 49 : return InvalidAttrNumber;
3499 : }
3500 :
3501 : /* specialAttNum()
3502 : *
3503 : * Check attribute name to see if it is "special", e.g. "xmin".
3504 : * - thomas 2000-02-07
3505 : *
3506 : * Note: this only discovers whether the name could be a system attribute.
3507 : * Caller needs to ensure that it really is an attribute of the rel.
8454 lockhart 3508 ECB : */
3509 : static int
7555 tgl 3510 GIC 64886 : specialAttNum(const char *attname)
3511 : {
1636 andres 3512 ECB : const FormData_pg_attribute *sysatt;
3513 :
1601 andres 3514 CBC 64886 : sysatt = SystemAttributeByName(attname);
7839 tgl 3515 GIC 64886 : if (sysatt != NULL)
7839 tgl 3516 CBC 15469 : return sysatt->attnum;
8454 lockhart 3517 49417 : return InvalidAttrNumber;
3518 : }
3519 :
8454 lockhart 3520 ECB :
3521 : /*
7838 tgl 3522 : * given attribute id, return name of that attribute
7838 tgl 3523 EUB : *
3524 : * This should only be used if the relation is already
3525 : * table_open()'ed. Use the cache version get_atttype()
3526 : * for access to non-opened relations.
7838 tgl 3527 ECB : */
3528 : const NameData *
7838 tgl 3529 GIC 5576 : attnumAttName(Relation rd, int attid)
3530 : {
3531 5576 : if (attid <= 0)
3532 : {
3533 : const FormData_pg_attribute *sysatt;
3534 :
1601 andres 3535 UIC 0 : sysatt = SystemAttributeDefinition(attid);
7838 tgl 3536 0 : return &sysatt->attname;
3537 : }
7838 tgl 3538 GIC 5576 : if (attid > rd->rd_att->natts)
7204 tgl 3539 LBC 0 : elog(ERROR, "invalid attribute number %d", attid);
2058 andres 3540 GIC 5576 : return &TupleDescAttr(rd->rd_att, attid - 1)->attname;
3541 : }
3542 :
9210 bruce 3543 ECB : /*
7839 tgl 3544 : * given attribute id, return type of that attribute
3545 : *
9210 bruce 3546 : * This should only be used if the relation is already
3547 : * table_open()'ed. Use the cache version get_atttype()
3548 : * for access to non-opened relations.
3549 : */
3550 : Oid
9266 bruce 3551 GIC 228177 : attnumTypeId(Relation rd, int attid)
3552 : {
7839 tgl 3553 228177 : if (attid <= 0)
3554 : {
3555 : const FormData_pg_attribute *sysatt;
3556 :
1601 andres 3557 UIC 0 : sysatt = SystemAttributeDefinition(attid);
7839 tgl 3558 LBC 0 : return sysatt->atttypid;
3559 : }
7838 tgl 3560 CBC 228177 : if (attid > rd->rd_att->natts)
7204 tgl 3561 UIC 0 : elog(ERROR, "invalid attribute number %d", attid);
2058 andres 3562 GIC 228177 : return TupleDescAttr(rd->rd_att, attid - 1)->atttypid;
3563 : }
8345 bruce 3564 EUB :
4381 tgl 3565 : /*
3566 : * given attribute id, return collation of that attribute
4381 tgl 3567 ECB : *
1539 andres 3568 EUB : * This should only be used if the relation is already table_open()'ed.
4381 tgl 3569 ECB : */
3570 : Oid
4381 tgl 3571 GIC 2222 : attnumCollationId(Relation rd, int attid)
3572 : {
3573 2222 : if (attid <= 0)
3574 : {
3575 : /* All system attributes are of noncollatable types. */
4381 tgl 3576 UIC 0 : return InvalidOid;
3577 : }
4381 tgl 3578 GIC 2222 : if (attid > rd->rd_att->natts)
4381 tgl 3579 UIC 0 : elog(ERROR, "invalid attribute number %d", attid);
2058 andres 3580 CBC 2222 : return TupleDescAttr(rd->rd_att, attid - 1)->attcollation;
3581 : }
4381 tgl 3582 ECB :
3583 : /*
3584 : * Generate a suitable error about a missing RTE.
3585 : *
4918 tgl 3586 EUB : * Since this is a very common type of error, we work rather hard to
3587 : * produce a helpful message.
3588 : */
4918 tgl 3589 ECB : void
4918 tgl 3590 GBC 54 : errorMissingRTE(ParseState *pstate, RangeVar *relation)
8345 bruce 3591 ECB : {
3592 : RangeTblEntry *rte;
6298 tgl 3593 GIC 54 : const char *badAlias = NULL;
3594 :
3595 : /*
3596 : * Check to see if there are any potential matches in the query's
3597 : * rangetable. (Note: cases involving a bad schema name in the RangeVar
3598 : * will throw error immediately here. That seems OK.)
3599 : */
3897 tgl 3600 CBC 54 : rte = searchRangeTableForRel(pstate, relation);
3601 :
6298 tgl 3602 ECB : /*
3603 : * If we found a match that has an alias and the alias is visible in the
3604 : * namespace, then the problem is probably use of the relation's real name
6031 bruce 3605 EUB : * instead of its alias, ie "SELECT foo.* FROM foo f". This mistake is
3606 : * common enough to justify a specific hint.
6298 tgl 3607 ECB : *
6298 tgl 3608 EUB : * If we found a match that doesn't meet those criteria, assume the
6298 tgl 3609 ECB : * problem is illegal use of a relation outside its scope, as in the
3610 : * MySQL-ism "SELECT ... FROM a, b LEFT JOIN c ON (a.x = c.y)".
3611 : */
6298 tgl 3612 GIC 54 : if (rte && rte->alias &&
1200 3613 36 : strcmp(rte->eref->aliasname, relation->relname) != 0)
3614 : {
3615 : ParseNamespaceItem *nsitem;
3616 : int sublevels_up;
3617 :
3618 12 : nsitem = refnameNamespaceItem(pstate, NULL, rte->eref->aliasname,
1200 tgl 3619 ECB : relation->location,
3620 : &sublevels_up);
1200 tgl 3621 GIC 12 : if (nsitem && nsitem->p_rte == rte)
1200 tgl 3622 CBC 12 : badAlias = rte->eref->aliasname;
3623 : }
3624 :
3625 : /* If it looks like the user forgot to use an alias, hint about that */
138 tgl 3626 GNC 54 : if (badAlias)
4918 tgl 3627 GIC 12 : ereport(ERROR,
3628 : (errcode(ERRCODE_UNDEFINED_TABLE),
3629 : errmsg("invalid reference to FROM-clause entry for table \"%s\"",
2118 tgl 3630 ECB : relation->relname),
3631 : errhint("Perhaps you meant to reference the table alias \"%s\".",
3632 : badAlias),
3633 : parser_errposition(pstate, relation->location)));
3634 : /* Hint about case where we found an (inaccessible) exact match */
138 tgl 3635 GNC 42 : else if (rte)
3636 33 : ereport(ERROR,
3637 : (errcode(ERRCODE_UNDEFINED_TABLE),
3638 : errmsg("invalid reference to FROM-clause entry for table \"%s\"",
3639 : relation->relname),
3640 : errdetail("There is an entry for table \"%s\", but it cannot be referenced from this part of the query.",
3641 : rte->eref->aliasname),
3642 : rte_visible_if_lateral(pstate, rte) ?
3643 : errhint("To reference that table, you must mark this subquery with LATERAL.") : 0,
3644 : parser_errposition(pstate, relation->location)));
3645 : /* Else, we have nothing to offer but the bald statement of error */
3646 : else
4918 tgl 3647 GIC 9 : ereport(ERROR,
3648 : (errcode(ERRCODE_UNDEFINED_TABLE),
3649 : errmsg("missing FROM-clause entry for table \"%s\"",
3650 : relation->relname),
5333 tgl 3651 ECB : parser_errposition(pstate, relation->location)));
8345 bruce 3652 : }
3653 :
3654 : /*
3655 : * Generate a suitable error about a missing column.
3656 : *
3897 tgl 3657 : * Since this is a very common type of error, we work rather hard to
3658 : * produce a helpful message.
3659 : */
3660 : void
3897 tgl 3661 CBC 170 : errorMissingColumn(ParseState *pstate,
3662 : const char *relname, const char *colname, int location)
3663 : {
3664 : FuzzyAttrMatchState *state;
3897 tgl 3665 ECB :
3666 : /*
3667 : * Search the entire rtable looking for possible matches. If we find one,
3668 : * emit a hint about it.
3669 : */
2951 rhaas 3670 CBC 170 : state = searchRangeTableForCol(pstate, relname, colname, location);
3897 tgl 3671 ECB :
3672 : /*
3673 : * If there are exact match(es), they must be inaccessible for some
3674 : * reason.
3675 : */
138 tgl 3676 GNC 170 : if (state->rexact1)
3677 : {
3678 : /*
3679 : * We don't try too hard when there's multiple inaccessible exact
3680 : * matches, but at least be sure that we don't misleadingly suggest
3681 : * that there's only one.
3682 : */
3683 21 : if (state->rexact2)
3684 6 : ereport(ERROR,
3685 : (errcode(ERRCODE_UNDEFINED_COLUMN),
3686 : relname ?
3687 : errmsg("column %s.%s does not exist", relname, colname) :
3688 : errmsg("column \"%s\" does not exist", colname),
3689 : errdetail("There are columns named \"%s\", but they are in tables that cannot be referenced from this part of the query.",
3690 : colname),
3691 : !relname ? errhint("Try using a table-qualified name.") : 0,
3692 : parser_errposition(pstate, location)));
3693 : /* Single exact match, so try to determine why it's inaccessible. */
3694 15 : ereport(ERROR,
3695 : (errcode(ERRCODE_UNDEFINED_COLUMN),
3696 : relname ?
3697 : errmsg("column %s.%s does not exist", relname, colname) :
3698 : errmsg("column \"%s\" does not exist", colname),
3699 : errdetail("There is a column named \"%s\" in table \"%s\", but it cannot be referenced from this part of the query.",
3700 : colname, state->rexact1->eref->aliasname),
3701 : rte_visible_if_lateral(pstate, state->rexact1) ?
3702 : errhint("To reference that column, you must mark this subquery with LATERAL.") :
3703 : (!relname && rte_visible_if_qualified(pstate, state->rexact1)) ?
3704 : errhint("To reference that column, you must use a table-qualified name.") : 0,
3705 : parser_errposition(pstate, location)));
3706 : }
3707 :
3708 149 : if (!state->rsecond)
3709 : {
3710 : /* If we found no match at all, we have little to report */
3711 143 : if (!state->rfirst)
3712 122 : ereport(ERROR,
3713 : (errcode(ERRCODE_UNDEFINED_COLUMN),
3714 : relname ?
3715 : errmsg("column %s.%s does not exist", relname, colname) :
3716 : errmsg("column \"%s\" does not exist", colname),
3717 : parser_errposition(pstate, location)));
3718 : /* Handle case where we have a single alternative spelling to offer */
2951 rhaas 3719 GIC 21 : ereport(ERROR,
3720 : (errcode(ERRCODE_UNDEFINED_COLUMN),
3721 : relname ?
3722 : errmsg("column %s.%s does not exist", relname, colname) :
3723 : errmsg("column \"%s\" does not exist", colname),
3724 : errhint("Perhaps you meant to reference the column \"%s.%s\".",
3725 : state->rfirst->eref->aliasname,
3726 : strVal(list_nth(state->rfirst->eref->colnames,
3727 : state->first - 1))),
3728 : parser_errposition(pstate, location)));
3729 : }
3730 : else
3731 : {
2951 rhaas 3732 ECB : /* Handle case where there are two equally useful column hints */
2951 rhaas 3733 CBC 6 : ereport(ERROR,
3734 : (errcode(ERRCODE_UNDEFINED_COLUMN),
3735 : relname ?
3736 : errmsg("column %s.%s does not exist", relname, colname) :
3737 : errmsg("column \"%s\" does not exist", colname),
3738 : errhint("Perhaps you meant to reference the column \"%s.%s\" or the column \"%s.%s\".",
3739 : state->rfirst->eref->aliasname,
3740 : strVal(list_nth(state->rfirst->eref->colnames,
3741 : state->first - 1)),
3742 : state->rsecond->eref->aliasname,
3743 : strVal(list_nth(state->rsecond->eref->colnames,
3744 : state->second - 1))),
2951 rhaas 3745 ECB : parser_errposition(pstate, location)));
3746 : }
3747 : }
3748 :
3749 : /*
3750 : * Find ParseNamespaceItem for RTE, if it's visible at all.
3751 : * We assume an RTE couldn't appear more than once in the namespace lists.
3752 : */
3753 : static ParseNamespaceItem *
138 tgl 3754 GNC 57 : findNSItemForRTE(ParseState *pstate, RangeTblEntry *rte)
3755 : {
3756 108 : while (pstate != NULL)
3757 : {
3758 : ListCell *l;
3759 :
3760 138 : foreach(l, pstate->p_namespace)
3761 : {
3762 87 : ParseNamespaceItem *nsitem = (ParseNamespaceItem *) lfirst(l);
3763 :
3764 87 : if (nsitem->p_rte == rte)
3765 39 : return nsitem;
3766 : }
3767 51 : pstate = pstate->parentParseState;
3768 : }
3769 18 : return NULL;
3770 : }
3771 :
3772 : /*
3773 : * Would this RTE be visible, if only the user had written LATERAL?
3774 : *
3775 : * This is a helper for deciding whether to issue a HINT about LATERAL.
3776 : * As such, it doesn't need to be 100% accurate; the HINT could be useful
3777 : * even if it's not quite right. Hence, we don't delve into fine points
3778 : * about whether a found nsitem has the appropriate one of p_rel_visible or
3779 : * p_cols_visible set.
3780 : */
3781 : static bool
3782 48 : rte_visible_if_lateral(ParseState *pstate, RangeTblEntry *rte)
3783 : {
3784 : ParseNamespaceItem *nsitem;
3785 :
3786 : /* If LATERAL *is* active, we're clearly barking up the wrong tree */
3787 48 : if (pstate->p_lateral_active)
138 tgl 3788 UNC 0 : return false;
138 tgl 3789 GNC 48 : nsitem = findNSItemForRTE(pstate, rte);
3790 48 : if (nsitem)
3791 : {
3792 : /* Found it, report whether it's LATERAL-only */
3793 33 : return nsitem->p_lateral_only && nsitem->p_lateral_ok;
3794 : }
3795 15 : return false;
3796 : }
3797 :
3798 : /*
3799 : * Would columns in this RTE be visible if qualified?
3800 : */
3801 : static bool
3802 9 : rte_visible_if_qualified(ParseState *pstate, RangeTblEntry *rte)
3803 : {
3804 9 : ParseNamespaceItem *nsitem = findNSItemForRTE(pstate, rte);
3805 :
3806 9 : if (nsitem)
3807 : {
3808 : /* Found it, report whether it's relation-only */
3809 6 : return nsitem->p_rel_visible && !nsitem->p_cols_visible;
3810 : }
3811 3 : return false;
3812 : }
3813 :
3814 :
3815 : /*
3816 : * Examine a fully-parsed query, and return true iff any relation underlying
3817 : * the query is a temporary relation (table, view, or materialized view).
3818 : */
3819 : bool
3649 tgl 3820 CBC 44197 : isQueryUsingTempRelation(Query *query)
3821 : {
3649 tgl 3822 GIC 44197 : return isQueryUsingTempRelation_walker((Node *) query, NULL);
3823 : }
3824 :
3825 : static bool
3826 4503631 : isQueryUsingTempRelation_walker(Node *node, void *context)
3827 : {
3828 4503631 : if (node == NULL)
3829 1150078 : return false;
3830 :
3831 3353553 : if (IsA(node, Query))
3832 : {
3833 79739 : Query *query = (Query *) node;
3649 tgl 3834 ECB : ListCell *rtable;
3835 :
3649 tgl 3836 GIC 299641 : foreach(rtable, query->rtable)
3649 tgl 3837 ECB : {
3649 tgl 3838 CBC 219956 : RangeTblEntry *rte = lfirst(rtable);
3839 :
3649 tgl 3840 GIC 219956 : if (rte->rtekind == RTE_RELATION)
3841 : {
1539 andres 3842 135095 : Relation rel = table_open(rte->relid, AccessShareLock);
3649 tgl 3843 135095 : char relpersistence = rel->rd_rel->relpersistence;
3844 :
1539 andres 3845 CBC 135095 : table_close(rel, AccessShareLock);
3649 tgl 3846 GIC 135095 : if (relpersistence == RELPERSISTENCE_TEMP)
3847 54 : return true;
3848 : }
3849 : }
3850 :
3851 79685 : return query_tree_walker(query,
3852 : isQueryUsingTempRelation_walker,
3853 : context,
3854 : QTW_IGNORE_JOINALIASES);
3855 : }
3856 :
3857 3273814 : return expression_tree_walker(node,
3858 : isQueryUsingTempRelation_walker,
3649 tgl 3859 ECB : context);
3860 : }
3861 :
3862 : /*
3863 : * addRTEPermissionInfo
3864 : * Creates RTEPermissionInfo for a given RTE and adds it into the
3865 : * provided list.
3866 : *
3867 : * Returns the RTEPermissionInfo and sets rte->perminfoindex.
3868 : */
3869 : RTEPermissionInfo *
124 alvherre 3870 GNC 790711 : addRTEPermissionInfo(List **rteperminfos, RangeTblEntry *rte)
3871 : {
3872 : RTEPermissionInfo *perminfo;
3873 :
81 tgl 3874 790711 : Assert(OidIsValid(rte->relid));
124 alvherre 3875 790711 : Assert(rte->perminfoindex == 0);
3876 :
3877 : /* Nope, so make one and add to the list. */
3878 790711 : perminfo = makeNode(RTEPermissionInfo);
3879 790711 : perminfo->relid = rte->relid;
3880 790711 : perminfo->inh = rte->inh;
3881 : /* Other information is set by fetching the node as and where needed. */
3882 :
3883 790711 : *rteperminfos = lappend(*rteperminfos, perminfo);
3884 :
3885 : /* Note its index (1-based!) */
3886 790711 : rte->perminfoindex = list_length(*rteperminfos);
3887 :
3888 790711 : return perminfo;
3889 : }
3890 :
3891 : /*
3892 : * getRTEPermissionInfo
3893 : * Find RTEPermissionInfo for a given relation in the provided list.
3894 : *
3895 : * This is a simple list_nth() operation, though it's good to have the
3896 : * function for the various sanity checks.
3897 : */
3898 : RTEPermissionInfo *
3899 1817237 : getRTEPermissionInfo(List *rteperminfos, RangeTblEntry *rte)
3900 : {
3901 : RTEPermissionInfo *perminfo;
3902 :
3903 1817237 : if (rte->perminfoindex == 0 ||
3904 1817237 : rte->perminfoindex > list_length(rteperminfos))
58 peter 3905 UNC 0 : elog(ERROR, "invalid perminfoindex %u in RTE with relid %u",
3906 : rte->perminfoindex, rte->relid);
124 alvherre 3907 GNC 1817237 : perminfo = list_nth_node(RTEPermissionInfo, rteperminfos,
3908 : rte->perminfoindex - 1);
3909 1817237 : if (perminfo->relid != rte->relid)
124 alvherre 3910 UNC 0 : elog(ERROR, "permission info at index %u (with relid=%u) does not match provided RTE (with relid=%u)",
3911 : rte->perminfoindex, perminfo->relid, rte->relid);
3912 :
124 alvherre 3913 GNC 1817237 : return perminfo;
3914 : }
|