1 /*-------------------------------------------------------------------------
4 * parser support routines dealing with relations
6 * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.126 2006/12/30 21:21:54 tgl Exp $
13 *-------------------------------------------------------------------------
19 #include "access/heapam.h"
20 #include "catalog/heap.h"
21 #include "catalog/namespace.h"
22 #include "catalog/pg_type.h"
24 #include "nodes/makefuncs.h"
25 #include "parser/parsetree.h"
26 #include "parser/parse_expr.h"
27 #include "parser/parse_relation.h"
28 #include "parser/parse_type.h"
29 #include "utils/builtins.h"
30 #include "utils/lsyscache.h"
31 #include "utils/syscache.h"
35 bool add_missing_from;
37 static RangeTblEntry *scanNameSpaceForRefname(ParseState *pstate,
39 static RangeTblEntry *scanNameSpaceForRelid(ParseState *pstate, Oid relid);
40 static bool isLockedRel(ParseState *pstate, char *refname);
41 static void expandRelation(Oid relid, Alias *eref,
42 int rtindex, int sublevels_up,
44 List **colnames, List **colvars);
45 static void expandTupleDesc(TupleDesc tupdesc, Alias *eref,
46 int rtindex, int sublevels_up,
48 List **colnames, List **colvars);
49 static int specialAttNum(const char *attname);
50 static void warnAutoRange(ParseState *pstate, RangeVar *relation,
55 * refnameRangeTblEntry
56 * Given a possibly-qualified refname, look to see if it matches any RTE.
57 * If so, return a pointer to the RangeTblEntry; else return NULL.
59 * Optionally get RTE's nesting depth (0 = current) into *sublevels_up.
60 * If sublevels_up is NULL, only consider items at the current nesting
63 * An unqualified refname (schemaname == NULL) can match any RTE with matching
64 * alias, or matching unqualified relname in the case of alias-less relation
65 * RTEs. It is possible that such a refname matches multiple RTEs in the
66 * nearest nesting level that has a match; if so, we report an error via
69 * A qualified refname (schemaname != NULL) can only match a relation RTE
70 * that (a) has no alias and (b) is for the same relation identified by
71 * schemaname.refname. In this case we convert schemaname.refname to a
72 * relation OID and search by relid, rather than by alias name. This is
73 * peculiar, but it's what SQL92 says to do.
76 refnameRangeTblEntry(ParseState *pstate,
77 const char *schemaname,
81 Oid relId = InvalidOid;
86 if (schemaname != NULL)
90 namespaceId = LookupExplicitNamespace(schemaname);
91 relId = get_relname_relid(refname, namespaceId);
92 if (!OidIsValid(relId))
96 while (pstate != NULL)
98 RangeTblEntry *result;
100 if (OidIsValid(relId))
101 result = scanNameSpaceForRelid(pstate, relId);
103 result = scanNameSpaceForRefname(pstate, refname);
113 pstate = pstate->parentParseState;
119 * Search the query's table namespace for an RTE matching the
120 * given unqualified refname. Return the RTE if a unique match, or NULL
121 * if no match. Raise error if multiple matches.
123 static RangeTblEntry *
124 scanNameSpaceForRefname(ParseState *pstate, const char *refname)
126 RangeTblEntry *result = NULL;
129 foreach(l, pstate->p_relnamespace)
131 RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
133 if (strcmp(rte->eref->aliasname, refname) == 0)
137 (errcode(ERRCODE_AMBIGUOUS_ALIAS),
138 errmsg("table reference \"%s\" is ambiguous",
147 * Search the query's table namespace for a relation RTE matching the
148 * given relation OID. Return the RTE if a unique match, or NULL
149 * if no match. Raise error if multiple matches (which shouldn't
150 * happen if the namespace was checked correctly when it was created).
152 * See the comments for refnameRangeTblEntry to understand why this
153 * acts the way it does.
155 static RangeTblEntry *
156 scanNameSpaceForRelid(ParseState *pstate, Oid relid)
158 RangeTblEntry *result = NULL;
161 foreach(l, pstate->p_relnamespace)
163 RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
165 /* yes, the test for alias == NULL should be there... */
166 if (rte->rtekind == RTE_RELATION &&
167 rte->relid == relid &&
172 (errcode(ERRCODE_AMBIGUOUS_ALIAS),
173 errmsg("table reference %u is ambiguous",
183 * See if any RangeTblEntry could possibly match the RangeVar.
184 * If so, return a pointer to the RangeTblEntry; else return NULL.
186 * This is different from refnameRangeTblEntry in that it considers every
187 * entry in the ParseState's rangetable(s), not only those that are currently
188 * visible in the p_relnamespace lists. This behavior is invalid per the SQL
189 * spec, and it may give ambiguous results (there might be multiple equally
190 * valid matches, but only one will be returned). This must be used ONLY
191 * as a heuristic in giving suitable error messages. See warnAutoRange.
193 * Notice that we consider both matches on actual relation name and matches
196 static RangeTblEntry *
197 searchRangeTable(ParseState *pstate, RangeVar *relation)
199 Oid relId = RangeVarGetRelid(relation, true);
200 char *refname = relation->relname;
202 while (pstate != NULL)
206 foreach(l, pstate->p_rtable)
208 RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
210 if (OidIsValid(relId) &&
211 rte->rtekind == RTE_RELATION &&
214 if (strcmp(rte->eref->aliasname, refname) == 0)
218 pstate = pstate->parentParseState;
224 * Check for relation-name conflicts between two relnamespace lists.
225 * Raise an error if any is found.
227 * Note: we assume that each given argument does not contain conflicts
228 * itself; we just want to know if the two can be merged together.
230 * Per SQL92, two alias-less plain relation RTEs do not conflict even if
231 * they have the same eref->aliasname (ie, same relation name), if they
232 * are for different relation OIDs (implying they are in different schemas).
235 checkNameSpaceConflicts(ParseState *pstate, List *namespace1,
240 foreach(l1, namespace1)
242 RangeTblEntry *rte1 = (RangeTblEntry *) lfirst(l1);
243 const char *aliasname1 = rte1->eref->aliasname;
246 foreach(l2, namespace2)
248 RangeTblEntry *rte2 = (RangeTblEntry *) lfirst(l2);
250 if (strcmp(rte2->eref->aliasname, aliasname1) != 0)
251 continue; /* definitely no conflict */
252 if (rte1->rtekind == RTE_RELATION && rte1->alias == NULL &&
253 rte2->rtekind == RTE_RELATION && rte2->alias == NULL &&
254 rte1->relid != rte2->relid)
255 continue; /* no conflict per SQL92 rule */
257 (errcode(ERRCODE_DUPLICATE_ALIAS),
258 errmsg("table name \"%s\" specified more than once",
265 * given an RTE, return RT index (starting with 1) of the entry,
266 * and optionally get its nesting depth (0 = current). If sublevels_up
267 * is NULL, only consider rels at the current nesting level.
268 * Raises error if RTE not found.
271 RTERangeTablePosn(ParseState *pstate, RangeTblEntry *rte, int *sublevels_up)
279 while (pstate != NULL)
282 foreach(l, pstate->p_rtable)
284 if (rte == (RangeTblEntry *) lfirst(l))
288 pstate = pstate->parentParseState;
295 elog(ERROR, "RTE not found (internal error)");
296 return 0; /* keep compiler quiet */
300 * Given an RT index and nesting depth, find the corresponding RTE.
301 * This is the inverse of RTERangeTablePosn.
304 GetRTEByRangeTablePosn(ParseState *pstate,
308 while (sublevels_up-- > 0)
310 pstate = pstate->parentParseState;
311 Assert(pstate != NULL);
313 Assert(varno > 0 && varno <= list_length(pstate->p_rtable));
314 return rt_fetch(varno, pstate->p_rtable);
319 * Search the column names of a single RTE for the given name.
320 * If found, return an appropriate Var node, else return NULL.
321 * If the name proves ambiguous within this RTE, raise error.
323 * Side effect: if we find a match, mark the RTE as requiring read access.
324 * See comments in setTargetTable().
326 * NOTE: if the RTE is for a join, marking it as requiring read access does
327 * nothing. It might seem that we need to propagate the mark to all the
328 * contained RTEs, but that is not necessary. This is so because a join
329 * expression can only appear in a FROM clause, and any table named in
330 * FROM will be marked as requiring read access from the beginning.
333 scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte, char *colname,
341 * Scan the user column names (or aliases) for a match. Complain if
344 * Note: eref->colnames may include entries for dropped columns, but those
345 * will be empty strings that cannot match any legal SQL identifier, so we
346 * don't bother to test for that case here.
348 * Should this somehow go wrong and we try to access a dropped column,
349 * we'll still catch it by virtue of the checks in
350 * get_rte_attribute_type(), which is called by make_var(). That routine
351 * has to do a cache lookup anyway, so the check there is cheap.
353 foreach(c, rte->eref->colnames)
356 if (strcmp(strVal(lfirst(c)), colname) == 0)
360 (errcode(ERRCODE_AMBIGUOUS_COLUMN),
361 errmsg("column reference \"%s\" is ambiguous",
363 parser_errposition(pstate, location)));
364 result = (Node *) make_var(pstate, rte, attnum);
365 /* Require read access */
366 rte->requiredPerms |= ACL_SELECT;
371 * If we have a unique match, return it. Note that this allows a user
372 * alias to override a system column name (such as OID) without error.
378 * If the RTE represents a real table, consider system column names.
380 if (rte->rtekind == RTE_RELATION)
382 /* quick check to see if name could be a system column */
383 attnum = specialAttNum(colname);
384 if (attnum != InvalidAttrNumber)
386 /* now check to see if column actually is defined */
387 if (SearchSysCacheExists(ATTNUM,
388 ObjectIdGetDatum(rte->relid),
389 Int16GetDatum(attnum),
392 result = (Node *) make_var(pstate, rte, attnum);
393 /* Require read access */
394 rte->requiredPerms |= ACL_SELECT;
404 * Search for an unqualified column name.
405 * If found, return the appropriate Var node (or expression).
406 * If not found, return NULL. If the name proves ambiguous, raise error.
407 * If localonly is true, only names in the innermost query are considered.
410 colNameToVar(ParseState *pstate, char *colname, bool localonly,
414 ParseState *orig_pstate = pstate;
416 while (pstate != NULL)
420 foreach(l, pstate->p_varnamespace)
422 RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
425 /* use orig_pstate here to get the right sublevels_up */
426 newresult = scanRTEForColumn(orig_pstate, rte, colname, location);
432 (errcode(ERRCODE_AMBIGUOUS_COLUMN),
433 errmsg("column reference \"%s\" is ambiguous",
435 parser_errposition(orig_pstate, location)));
440 if (result != NULL || localonly)
441 break; /* found, or don't want to look at parent */
443 pstate = pstate->parentParseState;
451 * Search for a qualified column name: either refname.colname or
452 * schemaname.relname.colname.
454 * If found, return the appropriate Var node.
455 * If not found, return NULL. If the name proves ambiguous, raise error.
458 qualifiedNameToVar(ParseState *pstate,
468 rte = refnameRangeTblEntry(pstate, schemaname, refname, &sublevels_up);
474 rte = addImplicitRTE(pstate, makeRangeVar(schemaname, refname),
478 return scanRTEForColumn(pstate, rte, colname, location);
482 * buildRelationAliases
483 * Construct the eref column name list for a relation RTE.
484 * This code is also used for the case of a function RTE returning
485 * a named composite type.
487 * tupdesc: the physical column information
488 * alias: the user-supplied alias, or NULL if none
489 * eref: the eref Alias to store column names in
491 * eref->colnames is filled in. Also, alias->colnames is rebuilt to insert
492 * empty strings for any dropped columns, so that it will be one-to-one with
493 * physical column numbers.
496 buildRelationAliases(TupleDesc tupdesc, Alias *alias, Alias *eref)
498 int maxattrs = tupdesc->natts;
504 Assert(eref->colnames == NIL);
508 aliaslc = list_head(alias->colnames);
509 numaliases = list_length(alias->colnames);
510 /* We'll rebuild the alias colname list */
511 alias->colnames = NIL;
519 for (varattno = 0; varattno < maxattrs; varattno++)
521 Form_pg_attribute attr = tupdesc->attrs[varattno];
524 if (attr->attisdropped)
526 /* Always insert an empty string for a dropped column */
527 attrname = makeString(pstrdup(""));
529 alias->colnames = lappend(alias->colnames, attrname);
534 /* Use the next user-supplied alias */
535 attrname = (Value *) lfirst(aliaslc);
536 aliaslc = lnext(aliaslc);
537 alias->colnames = lappend(alias->colnames, attrname);
541 attrname = makeString(pstrdup(NameStr(attr->attname)));
542 /* we're done with the alias if any */
545 eref->colnames = lappend(eref->colnames, attrname);
548 /* Too many user-supplied aliases? */
551 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
552 errmsg("table \"%s\" has %d columns available but %d columns specified",
553 eref->aliasname, maxattrs - numdropped, numaliases)));
557 * buildScalarFunctionAlias
558 * Construct the eref column name list for a function RTE,
559 * when the function returns a scalar type (not composite or RECORD).
561 * funcexpr: transformed expression tree for the function call
562 * funcname: function name (used only for error message)
563 * alias: the user-supplied alias, or NULL if none
564 * eref: the eref Alias to store column names in
566 * eref->colnames is filled in.
569 buildScalarFunctionAlias(Node *funcexpr, char *funcname,
570 Alias *alias, Alias *eref)
574 Assert(eref->colnames == NIL);
576 /* Use user-specified column alias if there is one. */
577 if (alias && alias->colnames != NIL)
579 if (list_length(alias->colnames) != 1)
581 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
582 errmsg("too many column aliases specified for function %s",
584 eref->colnames = copyObject(alias->colnames);
589 * If the expression is a simple function call, and the function has a
590 * single OUT parameter that is named, use the parameter's name.
592 if (funcexpr && IsA(funcexpr, FuncExpr))
594 pname = get_func_result_name(((FuncExpr *) funcexpr)->funcid);
597 eref->colnames = list_make1(makeString(pname));
603 * Otherwise use the previously-determined alias (not necessarily the
606 eref->colnames = list_make1(makeString(eref->aliasname));
610 * Add an entry for a relation to the pstate's range table (p_rtable).
612 * If pstate is NULL, we just build an RTE and return it without adding it
615 * Note: formerly this checked for refname conflicts, but that's wrong.
616 * Caller is responsible for checking for conflicts in the appropriate scope.
619 addRangeTableEntry(ParseState *pstate,
625 RangeTblEntry *rte = makeNode(RangeTblEntry);
626 char *refname = alias ? alias->aliasname : relation->relname;
630 rte->rtekind = RTE_RELATION;
634 * Get the rel's OID. This access also ensures that we have an up-to-date
635 * relcache entry for the rel. Since this is typically the first access
636 * to a rel in a statement, be careful to get the right access level
637 * depending on whether we're doing SELECT FOR UPDATE/SHARE.
639 lockmode = isLockedRel(pstate, refname) ? RowShareLock : AccessShareLock;
640 rel = heap_openrv(relation, lockmode);
641 rte->relid = RelationGetRelid(rel);
644 * Build the list of effective column names using user-supplied aliases
645 * and/or actual column names.
647 rte->eref = makeAlias(refname, NIL);
648 buildRelationAliases(rel->rd_att, alias, rte->eref);
651 * Drop the rel refcount, but keep the access lock till end of transaction
652 * so that the table can't be deleted or have its schema modified
655 heap_close(rel, NoLock);
659 * - this RTE should be expanded to include descendant tables,
660 * - this RTE is in the FROM clause,
661 * - this RTE should be checked for appropriate access rights.
663 * The initial default on access checks is always check-for-READ-access,
664 * which is the right thing for all except target tables.
668 rte->inFromCl = inFromCl;
670 rte->requiredPerms = ACL_SELECT;
671 rte->checkAsUser = InvalidOid; /* not set-uid by default, either */
674 * Add completed RTE to pstate's range table list, but not to join list
675 * nor namespace --- caller must do that if appropriate.
678 pstate->p_rtable = lappend(pstate->p_rtable, rte);
684 * Add an entry for a relation to the pstate's range table (p_rtable).
686 * This is just like addRangeTableEntry() except that it makes an RTE
687 * given an already-open relation instead of a RangeVar reference.
690 addRangeTableEntryForRelation(ParseState *pstate,
696 RangeTblEntry *rte = makeNode(RangeTblEntry);
697 char *refname = alias ? alias->aliasname : RelationGetRelationName(rel);
699 rte->rtekind = RTE_RELATION;
701 rte->relid = RelationGetRelid(rel);
704 * Build the list of effective column names using user-supplied aliases
705 * and/or actual column names.
707 rte->eref = makeAlias(refname, NIL);
708 buildRelationAliases(rel->rd_att, alias, rte->eref);
712 * - this RTE should be expanded to include descendant tables,
713 * - this RTE is in the FROM clause,
714 * - this RTE should be checked for appropriate access rights.
716 * The initial default on access checks is always check-for-READ-access,
717 * which is the right thing for all except target tables.
721 rte->inFromCl = inFromCl;
723 rte->requiredPerms = ACL_SELECT;
724 rte->checkAsUser = InvalidOid; /* not set-uid by default, either */
727 * Add completed RTE to pstate's range table list, but not to join list
728 * nor namespace --- caller must do that if appropriate.
731 pstate->p_rtable = lappend(pstate->p_rtable, rte);
737 * Add an entry for a subquery to the pstate's range table (p_rtable).
739 * This is just like addRangeTableEntry() except that it makes a subquery RTE.
740 * Note that an alias clause *must* be supplied.
743 addRangeTableEntryForSubquery(ParseState *pstate,
748 RangeTblEntry *rte = makeNode(RangeTblEntry);
749 char *refname = alias->aliasname;
755 rte->rtekind = RTE_SUBQUERY;
756 rte->relid = InvalidOid;
757 rte->subquery = subquery;
760 eref = copyObject(alias);
761 numaliases = list_length(eref->colnames);
763 /* fill in any unspecified alias columns */
765 foreach(tlistitem, subquery->targetList)
767 TargetEntry *te = (TargetEntry *) lfirst(tlistitem);
772 Assert(varattno == te->resno);
773 if (varattno > numaliases)
777 attrname = pstrdup(te->resname);
778 eref->colnames = lappend(eref->colnames, makeString(attrname));
781 if (varattno < numaliases)
783 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
784 errmsg("table \"%s\" has %d columns available but %d columns specified",
785 refname, varattno, numaliases)));
791 * - this RTE should be expanded to include descendant tables,
792 * - this RTE is in the FROM clause,
793 * - this RTE should be checked for appropriate access rights.
795 * Subqueries are never checked for access rights.
798 rte->inh = false; /* never true for subqueries */
799 rte->inFromCl = inFromCl;
801 rte->requiredPerms = 0;
802 rte->checkAsUser = InvalidOid;
805 * Add completed RTE to pstate's range table list, but not to join list
806 * nor namespace --- caller must do that if appropriate.
809 pstate->p_rtable = lappend(pstate->p_rtable, rte);
815 * Add an entry for a function to the pstate's range table (p_rtable).
817 * This is just like addRangeTableEntry() except that it makes a function RTE.
820 addRangeTableEntryForFunction(ParseState *pstate,
823 RangeFunction *rangefunc,
826 RangeTblEntry *rte = makeNode(RangeTblEntry);
827 TypeFuncClass functypclass;
830 Alias *alias = rangefunc->alias;
831 List *coldeflist = rangefunc->coldeflist;
834 rte->rtekind = RTE_FUNCTION;
835 rte->relid = InvalidOid;
836 rte->subquery = NULL;
837 rte->funcexpr = funcexpr;
838 rte->funccoltypes = NIL;
839 rte->funccoltypmods = NIL;
842 eref = makeAlias(alias ? alias->aliasname : funcname, NIL);
846 * Now determine if the function returns a simple or composite type.
848 functypclass = get_expr_result_type(funcexpr,
853 * A coldeflist is required if the function returns RECORD and hasn't got
854 * a predetermined record type, and is prohibited otherwise.
856 if (coldeflist != NIL)
858 if (functypclass != TYPEFUNC_RECORD)
860 (errcode(ERRCODE_SYNTAX_ERROR),
861 errmsg("a column definition list is only allowed for functions returning \"record\"")));
865 if (functypclass == TYPEFUNC_RECORD)
867 (errcode(ERRCODE_SYNTAX_ERROR),
868 errmsg("a column definition list is required for functions returning \"record\"")));
871 if (functypclass == TYPEFUNC_COMPOSITE)
873 /* Composite data type, e.g. a table's row type */
875 /* Build the column alias list */
876 buildRelationAliases(tupdesc, alias, eref);
878 else if (functypclass == TYPEFUNC_SCALAR)
880 /* Base data type, i.e. scalar */
881 buildScalarFunctionAlias(funcexpr, funcname, alias, eref);
883 else if (functypclass == TYPEFUNC_RECORD)
888 * Use the column definition list to form the alias list and
889 * funccoltypes/funccoltypmods lists.
891 foreach(col, coldeflist)
893 ColumnDef *n = (ColumnDef *) lfirst(col);
898 attrname = pstrdup(n->colname);
899 if (n->typename->setof)
901 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
902 errmsg("column \"%s\" cannot be declared SETOF",
904 attrtype = typenameTypeId(pstate, n->typename);
905 attrtypmod = typenameTypeMod(pstate, n->typename, attrtype);
906 eref->colnames = lappend(eref->colnames, makeString(attrname));
907 rte->funccoltypes = lappend_oid(rte->funccoltypes, attrtype);
908 rte->funccoltypmods = lappend_int(rte->funccoltypmods, attrtypmod);
913 (errcode(ERRCODE_DATATYPE_MISMATCH),
914 errmsg("function \"%s\" in FROM has unsupported return type %s",
915 funcname, format_type_be(funcrettype))));
919 * - this RTE should be expanded to include descendant tables,
920 * - this RTE is in the FROM clause,
921 * - this RTE should be checked for appropriate access rights.
923 * Functions are never checked for access rights (at least, not by
924 * the RTE permissions mechanism).
927 rte->inh = false; /* never true for functions */
928 rte->inFromCl = inFromCl;
930 rte->requiredPerms = 0;
931 rte->checkAsUser = InvalidOid;
934 * Add completed RTE to pstate's range table list, but not to join list
935 * nor namespace --- caller must do that if appropriate.
938 pstate->p_rtable = lappend(pstate->p_rtable, rte);
944 * Add an entry for a VALUES list to the pstate's range table (p_rtable).
946 * This is much like addRangeTableEntry() except that it makes a values RTE.
949 addRangeTableEntryForValues(ParseState *pstate,
954 RangeTblEntry *rte = makeNode(RangeTblEntry);
955 char *refname = alias ? alias->aliasname : pstrdup("*VALUES*");
960 rte->rtekind = RTE_VALUES;
961 rte->relid = InvalidOid;
962 rte->subquery = NULL;
963 rte->values_lists = exprs;
966 eref = alias ? copyObject(alias) : makeAlias(refname, NIL);
968 /* fill in any unspecified alias columns */
969 numcolumns = list_length((List *) linitial(exprs));
970 numaliases = list_length(eref->colnames);
971 while (numaliases < numcolumns)
976 snprintf(attrname, sizeof(attrname), "column%d", numaliases);
977 eref->colnames = lappend(eref->colnames,
978 makeString(pstrdup(attrname)));
980 if (numcolumns < numaliases)
982 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
983 errmsg("VALUES lists \"%s\" have %d columns available but %d columns specified",
984 refname, numcolumns, numaliases)));
990 * - this RTE should be expanded to include descendant tables,
991 * - this RTE is in the FROM clause,
992 * - this RTE should be checked for appropriate access rights.
994 * Subqueries are never checked for access rights.
997 rte->inh = false; /* never true for values RTEs */
998 rte->inFromCl = inFromCl;
999 rte->requiredPerms = 0;
1000 rte->checkAsUser = InvalidOid;
1003 * Add completed RTE to pstate's range table list, but not to join list
1004 * nor namespace --- caller must do that if appropriate.
1007 pstate->p_rtable = lappend(pstate->p_rtable, rte);
1013 * Add an entry for a join to the pstate's range table (p_rtable).
1015 * This is much like addRangeTableEntry() except that it makes a join RTE.
1018 addRangeTableEntryForJoin(ParseState *pstate,
1025 RangeTblEntry *rte = makeNode(RangeTblEntry);
1029 rte->rtekind = RTE_JOIN;
1030 rte->relid = InvalidOid;
1031 rte->subquery = NULL;
1032 rte->jointype = jointype;
1033 rte->joinaliasvars = aliasvars;
1036 eref = alias ? (Alias *) copyObject(alias) : makeAlias("unnamed_join", NIL);
1037 numaliases = list_length(eref->colnames);
1039 /* fill in any unspecified alias columns */
1040 if (numaliases < list_length(colnames))
1041 eref->colnames = list_concat(eref->colnames,
1042 list_copy_tail(colnames, numaliases));
1048 * - this RTE should be expanded to include descendant tables,
1049 * - this RTE is in the FROM clause,
1050 * - this RTE should be checked for appropriate access rights.
1052 * Joins are never checked for access rights.
1055 rte->inh = false; /* never true for joins */
1056 rte->inFromCl = inFromCl;
1058 rte->requiredPerms = 0;
1059 rte->checkAsUser = InvalidOid;
1062 * Add completed RTE to pstate's range table list, but not to join list
1063 * nor namespace --- caller must do that if appropriate.
1066 pstate->p_rtable = lappend(pstate->p_rtable, rte);
1072 * Has the specified refname been selected FOR UPDATE/FOR SHARE?
1074 * Note: we pay no attention to whether it's FOR UPDATE vs FOR SHARE.
1077 isLockedRel(ParseState *pstate, char *refname)
1079 /* Outer loop to check parent query levels as well as this one */
1080 while (pstate != NULL)
1084 foreach(l, pstate->p_locking_clause)
1086 LockingClause *lc = (LockingClause *) lfirst(l);
1088 if (lc->lockedRels == NIL)
1090 /* all tables used in query */
1095 /* just the named tables */
1098 foreach(l2, lc->lockedRels)
1100 char *rname = strVal(lfirst(l2));
1102 if (strcmp(refname, rname) == 0)
1107 pstate = pstate->parentParseState;
1113 * Add the given RTE as a top-level entry in the pstate's join list
1114 * and/or name space lists. (We assume caller has checked for any
1115 * namespace conflicts.)
1118 addRTEtoQuery(ParseState *pstate, RangeTblEntry *rte,
1120 bool addToRelNameSpace, bool addToVarNameSpace)
1124 int rtindex = RTERangeTablePosn(pstate, rte, NULL);
1125 RangeTblRef *rtr = makeNode(RangeTblRef);
1127 rtr->rtindex = rtindex;
1128 pstate->p_joinlist = lappend(pstate->p_joinlist, rtr);
1130 if (addToRelNameSpace)
1131 pstate->p_relnamespace = lappend(pstate->p_relnamespace, rte);
1132 if (addToVarNameSpace)
1133 pstate->p_varnamespace = lappend(pstate->p_varnamespace, rte);
1137 * Add a POSTQUEL-style implicit RTE.
1139 * We assume caller has already checked that there is no RTE or join with
1140 * a conflicting name.
1143 addImplicitRTE(ParseState *pstate, RangeVar *relation, int location)
1147 /* issue warning or error as needed */
1148 warnAutoRange(pstate, relation, location);
1151 * Note that we set inFromCl true, so that the RTE will be listed
1152 * explicitly if the parsetree is ever decompiled by ruleutils.c. This
1153 * provides a migration path for views/rules that were originally written
1154 * with implicit-RTE syntax.
1156 rte = addRangeTableEntry(pstate, relation, NULL, false, true);
1157 /* Add to joinlist and relnamespace, but not varnamespace */
1158 addRTEtoQuery(pstate, rte, true, true, false);
1164 * expandRTE -- expand the columns of a rangetable entry
1166 * This creates lists of an RTE's column names (aliases if provided, else
1167 * real names) and Vars for each column. Only user columns are considered.
1168 * If include_dropped is FALSE then dropped columns are omitted from the
1169 * results. If include_dropped is TRUE then empty strings and NULL constants
1170 * (not Vars!) are returned for dropped columns.
1172 * rtindex and sublevels_up are the varno and varlevelsup values to use
1173 * in the created Vars. Ordinarily rtindex should match the actual position
1174 * of the RTE in its rangetable.
1176 * The output lists go into *colnames and *colvars.
1177 * If only one of the two kinds of output list is needed, pass NULL for the
1178 * output pointer for the unwanted one.
1181 expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up,
1182 bool include_dropped,
1183 List **colnames, List **colvars)
1192 switch (rte->rtekind)
1195 /* Ordinary relation RTE */
1196 expandRelation(rte->relid, rte->eref, rtindex, sublevels_up,
1197 include_dropped, colnames, colvars);
1202 ListCell *aliasp_item = list_head(rte->eref->colnames);
1203 ListCell *tlistitem;
1206 foreach(tlistitem, rte->subquery->targetList)
1208 TargetEntry *te = (TargetEntry *) lfirst(tlistitem);
1213 Assert(varattno == te->resno);
1217 /* Assume there is one alias per target item */
1218 char *label = strVal(lfirst(aliasp_item));
1220 *colnames = lappend(*colnames, makeString(pstrdup(label)));
1221 aliasp_item = lnext(aliasp_item);
1228 varnode = makeVar(rtindex, varattno,
1229 exprType((Node *) te->expr),
1230 exprTypmod((Node *) te->expr),
1233 *colvars = lappend(*colvars, varnode);
1241 TypeFuncClass functypclass;
1245 functypclass = get_expr_result_type(rte->funcexpr,
1248 if (functypclass == TYPEFUNC_COMPOSITE)
1250 /* Composite data type, e.g. a table's row type */
1252 expandTupleDesc(tupdesc, rte->eref, rtindex, sublevels_up,
1253 include_dropped, colnames, colvars);
1255 else if (functypclass == TYPEFUNC_SCALAR)
1257 /* Base data type, i.e. scalar */
1259 *colnames = lappend(*colnames,
1260 linitial(rte->eref->colnames));
1266 varnode = makeVar(rtindex, 1,
1270 *colvars = lappend(*colvars, varnode);
1273 else if (functypclass == TYPEFUNC_RECORD)
1276 *colnames = copyObject(rte->eref->colnames);
1283 forboth(l1, rte->funccoltypes, l2, rte->funccoltypmods)
1285 Oid attrtype = lfirst_oid(l1);
1286 int32 attrtypmod = lfirst_int(l2);
1290 varnode = makeVar(rtindex,
1295 *colvars = lappend(*colvars, varnode);
1301 /* addRangeTableEntryForFunction should've caught this */
1302 elog(ERROR, "function in FROM has unsupported return type");
1309 ListCell *aliasp_item = list_head(rte->eref->colnames);
1313 foreach(lc, (List *) linitial(rte->values_lists))
1315 Node *col = (Node *) lfirst(lc);
1320 /* Assume there is one alias per column */
1321 char *label = strVal(lfirst(aliasp_item));
1323 *colnames = lappend(*colnames,
1324 makeString(pstrdup(label)));
1325 aliasp_item = lnext(aliasp_item);
1332 varnode = makeVar(rtindex, varattno,
1336 *colvars = lappend(*colvars, varnode);
1347 Assert(list_length(rte->eref->colnames) == list_length(rte->joinaliasvars));
1350 forboth(colname, rte->eref->colnames, aliasvar, rte->joinaliasvars)
1352 Node *avar = (Node *) lfirst(aliasvar);
1357 * During ordinary parsing, there will never be any
1358 * deleted columns in the join; but we have to check since
1359 * this routine is also used by the rewriter, and joins
1360 * found in stored rules might have join columns for
1361 * since-deleted columns. This will be signaled by a NULL
1362 * Const in the alias-vars list.
1364 if (IsA(avar, Const))
1366 if (include_dropped)
1369 *colnames = lappend(*colnames,
1370 makeString(pstrdup("")));
1372 *colvars = lappend(*colvars,
1380 char *label = strVal(lfirst(colname));
1382 *colnames = lappend(*colnames,
1383 makeString(pstrdup(label)));
1390 varnode = makeVar(rtindex, varattno,
1395 *colvars = lappend(*colvars, varnode);
1401 elog(ERROR, "unrecognized RTE kind: %d", (int) rte->rtekind);
1406 * expandRelation -- expandRTE subroutine
1409 expandRelation(Oid relid, Alias *eref, int rtindex, int sublevels_up,
1410 bool include_dropped,
1411 List **colnames, List **colvars)
1415 /* Get the tupledesc and turn it over to expandTupleDesc */
1416 rel = relation_open(relid, AccessShareLock);
1417 expandTupleDesc(rel->rd_att, eref, rtindex, sublevels_up, include_dropped,
1419 relation_close(rel, AccessShareLock);
1423 * expandTupleDesc -- expandRTE subroutine
1426 expandTupleDesc(TupleDesc tupdesc, Alias *eref,
1427 int rtindex, int sublevels_up,
1428 bool include_dropped,
1429 List **colnames, List **colvars)
1431 int maxattrs = tupdesc->natts;
1432 int numaliases = list_length(eref->colnames);
1435 for (varattno = 0; varattno < maxattrs; varattno++)
1437 Form_pg_attribute attr = tupdesc->attrs[varattno];
1439 if (attr->attisdropped)
1441 if (include_dropped)
1444 *colnames = lappend(*colnames, makeString(pstrdup("")));
1448 * can't use atttypid here, but it doesn't really matter
1449 * what type the Const claims to be.
1451 *colvars = lappend(*colvars, makeNullConst(INT4OID));
1461 if (varattno < numaliases)
1462 label = strVal(list_nth(eref->colnames, varattno));
1464 label = NameStr(attr->attname);
1465 *colnames = lappend(*colnames, makeString(pstrdup(label)));
1472 varnode = makeVar(rtindex, attr->attnum,
1473 attr->atttypid, attr->atttypmod,
1476 *colvars = lappend(*colvars, varnode);
1483 * Workhorse for "*" expansion: produce a list of targetentries
1484 * for the attributes of the rte
1486 * As with expandRTE, rtindex/sublevels_up determine the varno/varlevelsup
1487 * fields of the Vars produced. pstate->p_next_resno determines the resnos
1488 * assigned to the TLEs.
1491 expandRelAttrs(ParseState *pstate, RangeTblEntry *rte,
1492 int rtindex, int sublevels_up)
1498 List *te_list = NIL;
1500 expandRTE(rte, rtindex, sublevels_up, false,
1503 forboth(name, names, var, vars)
1505 char *label = strVal(lfirst(name));
1506 Node *varnode = (Node *) lfirst(var);
1509 te = makeTargetEntry((Expr *) varnode,
1510 (AttrNumber) pstate->p_next_resno++,
1513 te_list = lappend(te_list, te);
1516 Assert(name == NULL && var == NULL); /* lists not the same length? */
1522 * get_rte_attribute_name
1523 * Get an attribute name from a RangeTblEntry
1525 * This is unlike get_attname() because we use aliases if available.
1526 * In particular, it will work on an RTE for a subselect or join, whereas
1527 * get_attname() only works on real relations.
1529 * "*" is returned if the given attnum is InvalidAttrNumber --- this case
1530 * occurs when a Var represents a whole tuple of a relation.
1533 get_rte_attribute_name(RangeTblEntry *rte, AttrNumber attnum)
1535 if (attnum == InvalidAttrNumber)
1539 * If there is a user-written column alias, use it.
1542 attnum > 0 && attnum <= list_length(rte->alias->colnames))
1543 return strVal(list_nth(rte->alias->colnames, attnum - 1));
1546 * If the RTE is a relation, go to the system catalogs not the
1547 * eref->colnames list. This is a little slower but it will give the
1548 * right answer if the column has been renamed since the eref list was
1549 * built (which can easily happen for rules).
1551 if (rte->rtekind == RTE_RELATION)
1552 return get_relid_attribute_name(rte->relid, attnum);
1555 * Otherwise use the column name from eref. There should always be one.
1557 if (attnum > 0 && attnum <= list_length(rte->eref->colnames))
1558 return strVal(list_nth(rte->eref->colnames, attnum - 1));
1560 /* else caller gave us a bogus attnum */
1561 elog(ERROR, "invalid attnum %d for rangetable entry %s",
1562 attnum, rte->eref->aliasname);
1563 return NULL; /* keep compiler quiet */
1567 * get_rte_attribute_type
1568 * Get attribute type information from a RangeTblEntry
1571 get_rte_attribute_type(RangeTblEntry *rte, AttrNumber attnum,
1572 Oid *vartype, int32 *vartypmod)
1574 switch (rte->rtekind)
1578 /* Plain relation RTE --- get the attribute's type info */
1580 Form_pg_attribute att_tup;
1582 tp = SearchSysCache(ATTNUM,
1583 ObjectIdGetDatum(rte->relid),
1584 Int16GetDatum(attnum),
1586 if (!HeapTupleIsValid(tp)) /* shouldn't happen */
1587 elog(ERROR, "cache lookup failed for attribute %d of relation %u",
1588 attnum, rte->relid);
1589 att_tup = (Form_pg_attribute) GETSTRUCT(tp);
1592 * If dropped column, pretend it ain't there. See notes in
1595 if (att_tup->attisdropped)
1597 (errcode(ERRCODE_UNDEFINED_COLUMN),
1598 errmsg("column \"%s\" of relation \"%s\" does not exist",
1599 NameStr(att_tup->attname),
1600 get_rel_name(rte->relid))));
1601 *vartype = att_tup->atttypid;
1602 *vartypmod = att_tup->atttypmod;
1603 ReleaseSysCache(tp);
1608 /* Subselect RTE --- get type info from subselect's tlist */
1609 TargetEntry *te = get_tle_by_resno(rte->subquery->targetList,
1612 if (te == NULL || te->resjunk)
1613 elog(ERROR, "subquery %s does not have attribute %d",
1614 rte->eref->aliasname, attnum);
1615 *vartype = exprType((Node *) te->expr);
1616 *vartypmod = exprTypmod((Node *) te->expr);
1622 TypeFuncClass functypclass;
1626 functypclass = get_expr_result_type(rte->funcexpr,
1630 if (functypclass == TYPEFUNC_COMPOSITE)
1632 /* Composite data type, e.g. a table's row type */
1633 Form_pg_attribute att_tup;
1636 /* this is probably a can't-happen case */
1637 if (attnum < 1 || attnum > tupdesc->natts)
1639 (errcode(ERRCODE_UNDEFINED_COLUMN),
1640 errmsg("column %d of relation \"%s\" does not exist",
1642 rte->eref->aliasname)));
1644 att_tup = tupdesc->attrs[attnum - 1];
1647 * If dropped column, pretend it ain't there. See notes
1648 * in scanRTEForColumn.
1650 if (att_tup->attisdropped)
1652 (errcode(ERRCODE_UNDEFINED_COLUMN),
1653 errmsg("column \"%s\" of relation \"%s\" does not exist",
1654 NameStr(att_tup->attname),
1655 rte->eref->aliasname)));
1656 *vartype = att_tup->atttypid;
1657 *vartypmod = att_tup->atttypmod;
1659 else if (functypclass == TYPEFUNC_SCALAR)
1661 /* Base data type, i.e. scalar */
1662 *vartype = funcrettype;
1665 else if (functypclass == TYPEFUNC_RECORD)
1667 *vartype = list_nth_oid(rte->funccoltypes, attnum - 1);
1668 *vartypmod = list_nth_int(rte->funccoltypmods, attnum - 1);
1672 /* addRangeTableEntryForFunction should've caught this */
1673 elog(ERROR, "function in FROM has unsupported return type");
1679 /* Values RTE --- get type info from first sublist */
1680 List *collist = (List *) linitial(rte->values_lists);
1683 if (attnum < 1 || attnum > list_length(collist))
1684 elog(ERROR, "values list %s does not have attribute %d",
1685 rte->eref->aliasname, attnum);
1686 col = (Node *) list_nth(collist, attnum - 1);
1687 *vartype = exprType(col);
1688 *vartypmod = exprTypmod(col);
1694 * Join RTE --- get type info from join RTE's alias variable
1698 Assert(attnum > 0 && attnum <= list_length(rte->joinaliasvars));
1699 aliasvar = (Node *) list_nth(rte->joinaliasvars, attnum - 1);
1700 *vartype = exprType(aliasvar);
1701 *vartypmod = exprTypmod(aliasvar);
1705 elog(ERROR, "unrecognized RTE kind: %d", (int) rte->rtekind);
1710 * get_rte_attribute_is_dropped
1711 * Check whether attempted attribute ref is to a dropped column
1714 get_rte_attribute_is_dropped(RangeTblEntry *rte, AttrNumber attnum)
1718 switch (rte->rtekind)
1723 * Plain relation RTE --- get the attribute's catalog entry
1726 Form_pg_attribute att_tup;
1728 tp = SearchSysCache(ATTNUM,
1729 ObjectIdGetDatum(rte->relid),
1730 Int16GetDatum(attnum),
1732 if (!HeapTupleIsValid(tp)) /* shouldn't happen */
1733 elog(ERROR, "cache lookup failed for attribute %d of relation %u",
1734 attnum, rte->relid);
1735 att_tup = (Form_pg_attribute) GETSTRUCT(tp);
1736 result = att_tup->attisdropped;
1737 ReleaseSysCache(tp);
1742 /* Subselect and Values RTEs never have dropped columns */
1748 * A join RTE would not have dropped columns when constructed,
1749 * but one in a stored rule might contain columns that were
1750 * dropped from the underlying tables, if said columns are
1751 * nowhere explicitly referenced in the rule. This will be
1752 * signaled to us by a NULL Const in the joinaliasvars list.
1757 attnum > list_length(rte->joinaliasvars))
1758 elog(ERROR, "invalid varattno %d", attnum);
1759 aliasvar = (Var *) list_nth(rte->joinaliasvars, attnum - 1);
1761 result = IsA(aliasvar, Const);
1767 Oid funcrettype = exprType(rte->funcexpr);
1768 Oid funcrelid = typeidTypeRelid(funcrettype);
1770 if (OidIsValid(funcrelid))
1773 * Composite data type, i.e. a table's row type
1775 * Same as ordinary relation RTE
1778 Form_pg_attribute att_tup;
1780 tp = SearchSysCache(ATTNUM,
1781 ObjectIdGetDatum(funcrelid),
1782 Int16GetDatum(attnum),
1784 if (!HeapTupleIsValid(tp)) /* shouldn't happen */
1785 elog(ERROR, "cache lookup failed for attribute %d of relation %u",
1787 att_tup = (Form_pg_attribute) GETSTRUCT(tp);
1788 result = att_tup->attisdropped;
1789 ReleaseSysCache(tp);
1794 * Must be a base data type, i.e. scalar
1801 elog(ERROR, "unrecognized RTE kind: %d", (int) rte->rtekind);
1802 result = false; /* keep compiler quiet */
1809 * Given a targetlist and a resno, return the matching TargetEntry
1811 * Returns NULL if resno is not present in list.
1813 * Note: we need to search, rather than just indexing with list_nth(),
1814 * because not all tlists are sorted by resno.
1817 get_tle_by_resno(List *tlist, AttrNumber resno)
1823 TargetEntry *tle = (TargetEntry *) lfirst(l);
1825 if (tle->resno == resno)
1832 * Given a Query and rangetable index, return relation's RowMarkClause if any
1834 * Returns NULL if relation is not selected FOR UPDATE/SHARE
1837 get_rowmark(Query *qry, Index rtindex)
1841 foreach(l, qry->rowMarks)
1843 RowMarkClause *rc = (RowMarkClause *) lfirst(l);
1845 if (rc->rti == rtindex)
1852 * given relation and att name, return attnum of variable
1854 * Returns InvalidAttrNumber if the attr doesn't exist (or is dropped).
1856 * This should only be used if the relation is already
1857 * heap_open()'ed. Use the cache version get_attnum()
1858 * for access to non-opened relations.
1861 attnameAttNum(Relation rd, const char *attname, bool sysColOK)
1865 for (i = 0; i < rd->rd_rel->relnatts; i++)
1867 Form_pg_attribute att = rd->rd_att->attrs[i];
1869 if (namestrcmp(&(att->attname), attname) == 0 && !att->attisdropped)
1875 if ((i = specialAttNum(attname)) != InvalidAttrNumber)
1877 if (i != ObjectIdAttributeNumber || rd->rd_rel->relhasoids)
1883 return InvalidAttrNumber;
1888 * Check attribute name to see if it is "special", e.g. "oid".
1889 * - thomas 2000-02-07
1891 * Note: this only discovers whether the name could be a system attribute.
1892 * Caller needs to verify that it really is an attribute of the rel,
1893 * at least in the case of "oid", which is now optional.
1896 specialAttNum(const char *attname)
1898 Form_pg_attribute sysatt;
1900 sysatt = SystemAttributeByName(attname,
1901 true /* "oid" will be accepted */ );
1903 return sysatt->attnum;
1904 return InvalidAttrNumber;
1909 * given attribute id, return name of that attribute
1911 * This should only be used if the relation is already
1912 * heap_open()'ed. Use the cache version get_atttype()
1913 * for access to non-opened relations.
1916 attnumAttName(Relation rd, int attid)
1920 Form_pg_attribute sysatt;
1922 sysatt = SystemAttributeDefinition(attid, rd->rd_rel->relhasoids);
1923 return &sysatt->attname;
1925 if (attid > rd->rd_att->natts)
1926 elog(ERROR, "invalid attribute number %d", attid);
1927 return &rd->rd_att->attrs[attid - 1]->attname;
1931 * given attribute id, return type of that attribute
1933 * This should only be used if the relation is already
1934 * heap_open()'ed. Use the cache version get_atttype()
1935 * for access to non-opened relations.
1938 attnumTypeId(Relation rd, int attid)
1942 Form_pg_attribute sysatt;
1944 sysatt = SystemAttributeDefinition(attid, rd->rd_rel->relhasoids);
1945 return sysatt->atttypid;
1947 if (attid > rd->rd_att->natts)
1948 elog(ERROR, "invalid attribute number %d", attid);
1949 return rd->rd_att->attrs[attid - 1]->atttypid;
1953 * Generate a warning or error about an implicit RTE, if appropriate.
1955 * If ADD_MISSING_FROM is not enabled, raise an error. Otherwise, emit
1959 warnAutoRange(ParseState *pstate, RangeVar *relation, int location)
1963 const char *badAlias = NULL;
1966 * Check to see if there are any potential matches in the query's
1967 * rangetable. This affects the message we provide.
1969 rte = searchRangeTable(pstate, relation);
1972 * If we found a match that has an alias and the alias is visible in the
1973 * namespace, then the problem is probably use of the relation's real name
1974 * instead of its alias, ie "SELECT foo.* FROM foo f". This mistake is
1975 * common enough to justify a specific hint.
1977 * If we found a match that doesn't meet those criteria, assume the
1978 * problem is illegal use of a relation outside its scope, as in the
1979 * MySQL-ism "SELECT ... FROM a, b LEFT JOIN c ON (a.x = c.y)".
1981 if (rte && rte->alias &&
1982 strcmp(rte->eref->aliasname, relation->relname) != 0 &&
1983 refnameRangeTblEntry(pstate, NULL, rte->eref->aliasname,
1984 &sublevels_up) == rte)
1985 badAlias = rte->eref->aliasname;
1987 if (!add_missing_from)
1991 (errcode(ERRCODE_UNDEFINED_TABLE),
1992 errmsg("invalid reference to FROM-clause entry for table \"%s\"",
1995 errhint("Perhaps you meant to reference the table alias \"%s\".",
1997 errhint("There is an entry for table \"%s\", but it cannot be referenced from this part of the query.",
1998 rte->eref->aliasname)),
1999 parser_errposition(pstate, location)));
2002 (errcode(ERRCODE_UNDEFINED_TABLE),
2003 (pstate->parentParseState ?
2004 errmsg("missing FROM-clause entry in subquery for table \"%s\"",
2005 relation->relname) :
2006 errmsg("missing FROM-clause entry for table \"%s\"",
2007 relation->relname)),
2008 parser_errposition(pstate, location)));
2012 /* just issue a warning */
2014 (errcode(ERRCODE_UNDEFINED_TABLE),
2015 (pstate->parentParseState ?
2016 errmsg("adding missing FROM-clause entry in subquery for table \"%s\"",
2017 relation->relname) :
2018 errmsg("adding missing FROM-clause entry for table \"%s\"",
2019 relation->relname)),
2021 errhint("Perhaps you meant to reference the table alias \"%s\".",
2024 errhint("There is an entry for table \"%s\", but it cannot be referenced from this part of the query.",
2025 rte->eref->aliasname) : 0)),
2026 parser_errposition(pstate, location)));