]> granicus.if.org Git - postgresql/blob - src/backend/parser/parse_relation.c
Implement feature of new FE/BE protocol whereby RowDescription identifies
[postgresql] / src / backend / parser / parse_relation.c
1 /*-------------------------------------------------------------------------
2  *
3  * parse_relation.c
4  *        parser support routines dealing with relations
5  *
6  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *        $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.81 2003/04/29 22:13:10 tgl Exp $
12  *
13  *-------------------------------------------------------------------------
14  */
15 #include "postgres.h"
16
17 #include <ctype.h>
18
19 #include "access/heapam.h"
20 #include "access/htup.h"
21 #include "catalog/heap.h"
22 #include "catalog/namespace.h"
23 #include "catalog/pg_type.h"
24 #include "nodes/makefuncs.h"
25 #include "parser/parsetree.h"
26 #include "parser/parse_coerce.h"
27 #include "parser/parse_expr.h"
28 #include "parser/parse_relation.h"
29 #include "parser/parse_type.h"
30 #include "rewrite/rewriteManip.h"
31 #include "utils/builtins.h"
32 #include "utils/lsyscache.h"
33 #include "utils/syscache.h"
34
35
36 static Node *scanNameSpaceForRefname(ParseState *pstate, Node *nsnode,
37                                                 const char *refname);
38 static Node *scanNameSpaceForRelid(ParseState *pstate, Node *nsnode,
39                                           Oid relid);
40 static void scanNameSpaceForConflict(ParseState *pstate, Node *nsnode,
41                                                  RangeTblEntry *rte1, const char *aliasname1);
42 static Node *scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte,
43                                  char *colname);
44 static bool isForUpdate(ParseState *pstate, char *refname);
45 static bool get_rte_attribute_is_dropped(RangeTblEntry *rte,
46                                                          AttrNumber attnum);
47 static int      specialAttNum(const char *attname);
48 static void warnAutoRange(ParseState *pstate, RangeVar *relation);
49
50
51 /*
52  * refnameRangeTblEntry
53  *        Given a possibly-qualified refname, look to see if it matches any RTE.
54  *        If so, return a pointer to the RangeTblEntry; else return NULL.
55  *
56  *        Optionally get RTE's nesting depth (0 = current) into *sublevels_up.
57  *        If sublevels_up is NULL, only consider items at the current nesting
58  *        level.
59  *
60  * An unqualified refname (schemaname == NULL) can match any RTE with matching
61  * alias, or matching unqualified relname in the case of alias-less relation
62  * RTEs.  It is possible that such a refname matches multiple RTEs in the
63  * nearest nesting level that has a match; if so, we report an error via elog.
64  *
65  * A qualified refname (schemaname != NULL) can only match a relation RTE
66  * that (a) has no alias and (b) is for the same relation identified by
67  * schemaname.refname.  In this case we convert schemaname.refname to a
68  * relation OID and search by relid, rather than by alias name.  This is
69  * peculiar, but it's what SQL92 says to do.
70  */
71 RangeTblEntry *
72 refnameRangeTblEntry(ParseState *pstate,
73                                          const char *schemaname,
74                                          const char *refname,
75                                          int *sublevels_up)
76 {
77         Oid                     relId = InvalidOid;
78
79         if (sublevels_up)
80                 *sublevels_up = 0;
81
82         if (schemaname != NULL)
83         {
84                 Oid                     namespaceId;
85
86                 namespaceId = LookupExplicitNamespace(schemaname);
87                 relId = get_relname_relid(refname, namespaceId);
88                 if (!OidIsValid(relId))
89                         return NULL;
90         }
91
92         while (pstate != NULL)
93         {
94                 Node       *nsnode;
95
96                 if (OidIsValid(relId))
97                         nsnode = scanNameSpaceForRelid(pstate,
98                                                                                    (Node *) pstate->p_namespace,
99                                                                                    relId);
100                 else
101                         nsnode = scanNameSpaceForRefname(pstate,
102                                                                                          (Node *) pstate->p_namespace,
103                                                                                          refname);
104
105                 if (nsnode)
106                 {
107                         /* should get an RTE or JoinExpr */
108                         if (IsA(nsnode, RangeTblEntry))
109                                 return (RangeTblEntry *) nsnode;
110                         Assert(IsA(nsnode, JoinExpr));
111                         return rt_fetch(((JoinExpr *) nsnode)->rtindex, pstate->p_rtable);
112                 }
113
114                 pstate = pstate->parentParseState;
115                 if (sublevels_up)
116                         (*sublevels_up)++;
117                 else
118                         break;
119         }
120         return NULL;
121 }
122
123 /*
124  * Recursively search a namespace for an RTE or joinexpr matching the
125  * given unqualified refname.  Return the node if a unique match, or NULL
126  * if no match.  Raise error if multiple matches.
127  *
128  * The top level of p_namespace is a list, and we recurse into any joins
129  * that are not subqueries.
130  */
131 static Node *
132 scanNameSpaceForRefname(ParseState *pstate, Node *nsnode,
133                                                 const char *refname)
134 {
135         Node       *result = NULL;
136         Node       *newresult;
137
138         if (nsnode == NULL)
139                 return NULL;
140         if (IsA(nsnode, RangeTblRef))
141         {
142                 int                     varno = ((RangeTblRef *) nsnode)->rtindex;
143                 RangeTblEntry *rte = rt_fetch(varno, pstate->p_rtable);
144
145                 if (strcmp(rte->eref->aliasname, refname) == 0)
146                         result = (Node *) rte;
147         }
148         else if (IsA(nsnode, JoinExpr))
149         {
150                 JoinExpr   *j = (JoinExpr *) nsnode;
151
152                 if (j->alias)
153                 {
154                         if (strcmp(j->alias->aliasname, refname) == 0)
155                                 return (Node *) j;              /* matched a join alias */
156
157                         /*
158                          * Tables within an aliased join are invisible from outside
159                          * the join, according to the scope rules of SQL92 (the join
160                          * is considered a subquery).  So, stop here.
161                          */
162                         return NULL;
163                 }
164                 result = scanNameSpaceForRefname(pstate, j->larg, refname);
165                 newresult = scanNameSpaceForRefname(pstate, j->rarg, refname);
166                 if (!result)
167                         result = newresult;
168                 else if (newresult)
169                         elog(ERROR, "Table reference \"%s\" is ambiguous", refname);
170         }
171         else if (IsA(nsnode, List))
172         {
173                 List       *l;
174
175                 foreach(l, (List *) nsnode)
176                 {
177                         newresult = scanNameSpaceForRefname(pstate, lfirst(l), refname);
178                         if (!result)
179                                 result = newresult;
180                         else if (newresult)
181                                 elog(ERROR, "Table reference \"%s\" is ambiguous", refname);
182                 }
183         }
184         else
185                 elog(ERROR, "scanNameSpaceForRefname: unexpected node type %d",
186                          nodeTag(nsnode));
187         return result;
188 }
189
190 /*
191  * Recursively search a namespace for a relation RTE matching the
192  * given relation OID.  Return the node if a unique match, or NULL
193  * if no match.  Raise error if multiple matches (which shouldn't
194  * happen if the namespace was checked correctly when it was created).
195  *
196  * The top level of p_namespace is a list, and we recurse into any joins
197  * that are not subqueries.
198  *
199  * See the comments for refnameRangeTblEntry to understand why this
200  * acts the way it does.
201  */
202 static Node *
203 scanNameSpaceForRelid(ParseState *pstate, Node *nsnode, Oid relid)
204 {
205         Node       *result = NULL;
206         Node       *newresult;
207
208         if (nsnode == NULL)
209                 return NULL;
210         if (IsA(nsnode, RangeTblRef))
211         {
212                 int                     varno = ((RangeTblRef *) nsnode)->rtindex;
213                 RangeTblEntry *rte = rt_fetch(varno, pstate->p_rtable);
214
215                 /* yes, the test for alias==NULL should be there... */
216                 if (rte->rtekind == RTE_RELATION &&
217                         rte->relid == relid &&
218                         rte->alias == NULL)
219                         result = (Node *) rte;
220         }
221         else if (IsA(nsnode, JoinExpr))
222         {
223                 JoinExpr   *j = (JoinExpr *) nsnode;
224
225                 if (j->alias)
226                 {
227                         /*
228                          * Tables within an aliased join are invisible from outside
229                          * the join, according to the scope rules of SQL92 (the join
230                          * is considered a subquery).  So, stop here.
231                          */
232                         return NULL;
233                 }
234                 result = scanNameSpaceForRelid(pstate, j->larg, relid);
235                 newresult = scanNameSpaceForRelid(pstate, j->rarg, relid);
236                 if (!result)
237                         result = newresult;
238                 else if (newresult)
239                         elog(ERROR, "Table reference %u is ambiguous", relid);
240         }
241         else if (IsA(nsnode, List))
242         {
243                 List       *l;
244
245                 foreach(l, (List *) nsnode)
246                 {
247                         newresult = scanNameSpaceForRelid(pstate, lfirst(l), relid);
248                         if (!result)
249                                 result = newresult;
250                         else if (newresult)
251                                 elog(ERROR, "Table reference %u is ambiguous", relid);
252                 }
253         }
254         else
255                 elog(ERROR, "scanNameSpaceForRelid: unexpected node type %d",
256                          nodeTag(nsnode));
257         return result;
258 }
259
260 /*
261  * Recursively check for name conflicts between two namespaces or
262  * namespace subtrees.  Raise an error if any is found.
263  *
264  * Works by recursively scanning namespace1 for RTEs and join nodes,
265  * and for each one recursively scanning namespace2 for a match.
266  *
267  * Note: we assume that each given argument does not contain conflicts
268  * itself; we just want to know if the two can be merged together.
269  *
270  * Per SQL92, two alias-less plain relation RTEs do not conflict even if
271  * they have the same eref->aliasname (ie, same relation name), if they
272  * are for different relation OIDs (implying they are in different schemas).
273  */
274 void
275 checkNameSpaceConflicts(ParseState *pstate, Node *namespace1,
276                                                 Node *namespace2)
277 {
278         if (namespace1 == NULL)
279                 return;
280         if (IsA(namespace1, RangeTblRef))
281         {
282                 int                     varno = ((RangeTblRef *) namespace1)->rtindex;
283                 RangeTblEntry *rte = rt_fetch(varno, pstate->p_rtable);
284
285                 if (rte->rtekind == RTE_RELATION && rte->alias == NULL)
286                         scanNameSpaceForConflict(pstate, namespace2,
287                                                                          rte, rte->eref->aliasname);
288                 else
289                         scanNameSpaceForConflict(pstate, namespace2,
290                                                                          NULL, rte->eref->aliasname);
291         }
292         else if (IsA(namespace1, JoinExpr))
293         {
294                 JoinExpr   *j = (JoinExpr *) namespace1;
295
296                 if (j->alias)
297                 {
298                         scanNameSpaceForConflict(pstate, namespace2,
299                                                                          NULL, j->alias->aliasname);
300
301                         /*
302                          * Tables within an aliased join are invisible from outside
303                          * the join, according to the scope rules of SQL92 (the join
304                          * is considered a subquery).  So, stop here.
305                          */
306                         return;
307                 }
308                 checkNameSpaceConflicts(pstate, j->larg, namespace2);
309                 checkNameSpaceConflicts(pstate, j->rarg, namespace2);
310         }
311         else if (IsA(namespace1, List))
312         {
313                 List       *l;
314
315                 foreach(l, (List *) namespace1)
316                         checkNameSpaceConflicts(pstate, lfirst(l), namespace2);
317         }
318         else
319                 elog(ERROR, "checkNameSpaceConflicts: unexpected node type %d",
320                          nodeTag(namespace1));
321 }
322
323 /*
324  * Subroutine for checkNameSpaceConflicts: scan namespace2
325  */
326 static void
327 scanNameSpaceForConflict(ParseState *pstate, Node *nsnode,
328                                                  RangeTblEntry *rte1, const char *aliasname1)
329 {
330         if (nsnode == NULL)
331                 return;
332         if (IsA(nsnode, RangeTblRef))
333         {
334                 int                     varno = ((RangeTblRef *) nsnode)->rtindex;
335                 RangeTblEntry *rte = rt_fetch(varno, pstate->p_rtable);
336
337                 if (strcmp(rte->eref->aliasname, aliasname1) != 0)
338                         return;                         /* definitely no conflict */
339                 if (rte->rtekind == RTE_RELATION && rte->alias == NULL &&
340                         rte1 != NULL && rte->relid != rte1->relid)
341                         return;                         /* no conflict per SQL92 rule */
342                 elog(ERROR, "Table name \"%s\" specified more than once",
343                          aliasname1);
344         }
345         else if (IsA(nsnode, JoinExpr))
346         {
347                 JoinExpr   *j = (JoinExpr *) nsnode;
348
349                 if (j->alias)
350                 {
351                         if (strcmp(j->alias->aliasname, aliasname1) == 0)
352                                 elog(ERROR, "Table name \"%s\" specified more than once",
353                                          aliasname1);
354
355                         /*
356                          * Tables within an aliased join are invisible from outside
357                          * the join, according to the scope rules of SQL92 (the join
358                          * is considered a subquery).  So, stop here.
359                          */
360                         return;
361                 }
362                 scanNameSpaceForConflict(pstate, j->larg, rte1, aliasname1);
363                 scanNameSpaceForConflict(pstate, j->rarg, rte1, aliasname1);
364         }
365         else if (IsA(nsnode, List))
366         {
367                 List       *l;
368
369                 foreach(l, (List *) nsnode)
370                         scanNameSpaceForConflict(pstate, lfirst(l), rte1, aliasname1);
371         }
372         else
373                 elog(ERROR, "scanNameSpaceForConflict: unexpected node type %d",
374                          nodeTag(nsnode));
375 }
376
377 /*
378  * given an RTE, return RT index (starting with 1) of the entry,
379  * and optionally get its nesting depth (0 = current).  If sublevels_up
380  * is NULL, only consider rels at the current nesting level.
381  * Raises error if RTE not found.
382  */
383 int
384 RTERangeTablePosn(ParseState *pstate, RangeTblEntry *rte, int *sublevels_up)
385 {
386         int                     index;
387         List       *temp;
388
389         if (sublevels_up)
390                 *sublevels_up = 0;
391
392         while (pstate != NULL)
393         {
394                 index = 1;
395                 foreach(temp, pstate->p_rtable)
396                 {
397                         if (rte == (RangeTblEntry *) lfirst(temp))
398                                 return index;
399                         index++;
400                 }
401                 pstate = pstate->parentParseState;
402                 if (sublevels_up)
403                         (*sublevels_up)++;
404                 else
405                         break;
406         }
407
408         elog(ERROR, "RTERangeTablePosn: RTE not found (internal error)");
409         return 0;                                       /* keep compiler quiet */
410 }
411
412 /*
413  * scanRTEForColumn
414  *        Search the column names of a single RTE for the given name.
415  *        If found, return an appropriate Var node, else return NULL.
416  *        If the name proves ambiguous within this RTE, raise error.
417  *
418  * Side effect: if we find a match, mark the RTE as requiring read access.
419  * See comments in setTargetTable().
420  *
421  * NOTE: if the RTE is for a join, marking it as requiring read access does
422  * nothing.  It might seem that we need to propagate the mark to all the
423  * contained RTEs, but that is not necessary.  This is so because a join
424  * expression can only appear in a FROM clause, and any table named in
425  * FROM will be marked checkForRead from the beginning.
426  */
427 static Node *
428 scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte, char *colname)
429 {
430         Node       *result = NULL;
431         int                     attnum = 0;
432         List       *c;
433
434         /*
435          * Scan the user column names (or aliases) for a match. Complain if
436          * multiple matches.
437          *
438          * Note: because eref->colnames may include names of dropped columns, we
439          * need to check for non-droppedness before accepting a match. This
440          * takes an extra cache lookup, but we can skip the lookup most of the
441          * time by exploiting the knowledge that dropped columns are assigned
442          * dummy names starting with '.', which is an unusual choice for
443          * actual column names.
444          *
445          * Should the user try to fool us by altering pg_attribute.attname for a
446          * dropped column, we'll still catch it by virtue of the checks in
447          * get_rte_attribute_type(), which is called by make_var().  That
448          * routine has to do a cache lookup anyway, so the check there is
449          * cheap.
450          */
451         foreach(c, rte->eref->colnames)
452         {
453                 attnum++;
454                 if (strcmp(strVal(lfirst(c)), colname) == 0)
455                 {
456                         if (colname[0] == '.' &&        /* see note above */
457                                 get_rte_attribute_is_dropped(rte, attnum))
458                                 continue;
459                         if (result)
460                                 elog(ERROR, "Column reference \"%s\" is ambiguous", colname);
461                         result = (Node *) make_var(pstate, rte, attnum);
462                         rte->checkForRead = true;
463                 }
464         }
465
466         /*
467          * If we have a unique match, return it.  Note that this allows a user
468          * alias to override a system column name (such as OID) without error.
469          */
470         if (result)
471                 return result;
472
473         /*
474          * If the RTE represents a real table, consider system column names.
475          */
476         if (rte->rtekind == RTE_RELATION)
477         {
478                 /* quick check to see if name could be a system column */
479                 attnum = specialAttNum(colname);
480                 if (attnum != InvalidAttrNumber)
481                 {
482                         /* now check to see if column actually is defined */
483                         if (SearchSysCacheExists(ATTNUM,
484                                                                          ObjectIdGetDatum(rte->relid),
485                                                                          Int16GetDatum(attnum),
486                                                                          0, 0))
487                         {
488                                 result = (Node *) make_var(pstate, rte, attnum);
489                                 rte->checkForRead = true;
490                         }
491                 }
492         }
493
494         return result;
495 }
496
497 /*
498  * colnameToVar
499  *        Search for an unqualified column name.
500  *        If found, return the appropriate Var node (or expression).
501  *        If not found, return NULL.  If the name proves ambiguous, raise error.
502  */
503 Node *
504 colnameToVar(ParseState *pstate, char *colname)
505 {
506         Node       *result = NULL;
507         ParseState *orig_pstate = pstate;
508         int                     levels_up = 0;
509
510         while (pstate != NULL)
511         {
512                 List       *ns;
513
514                 /*
515                  * We need to look only at top-level namespace items, and even for
516                  * those, ignore RTEs that are marked as not inFromCl and not the
517                  * query's target relation.
518                  */
519                 foreach(ns, pstate->p_namespace)
520                 {
521                         Node       *nsnode = (Node *) lfirst(ns);
522                         Node       *newresult = NULL;
523
524                         if (IsA(nsnode, RangeTblRef))
525                         {
526                                 int                     varno = ((RangeTblRef *) nsnode)->rtindex;
527                                 RangeTblEntry *rte = rt_fetch(varno, pstate->p_rtable);
528
529                                 if (!rte->inFromCl &&
530                                         rte != pstate->p_target_rangetblentry)
531                                         continue;
532
533                                 /* use orig_pstate here to get the right sublevels_up */
534                                 newresult = scanRTEForColumn(orig_pstate, rte, colname);
535                         }
536                         else if (IsA(nsnode, JoinExpr))
537                         {
538                                 int                     varno = ((JoinExpr *) nsnode)->rtindex;
539                                 RangeTblEntry *rte = rt_fetch(varno, pstate->p_rtable);
540
541                                 /* joins are always inFromCl, so no need to check */
542
543                                 /* use orig_pstate here to get the right sublevels_up */
544                                 newresult = scanRTEForColumn(orig_pstate, rte, colname);
545                         }
546                         else
547                                 elog(ERROR, "colnameToVar: unexpected node type %d",
548                                          nodeTag(nsnode));
549
550                         if (newresult)
551                         {
552                                 if (result)
553                                         elog(ERROR, "Column reference \"%s\" is ambiguous",
554                                                  colname);
555                                 result = newresult;
556                         }
557                 }
558
559                 if (result != NULL)
560                         break;                          /* found */
561
562                 pstate = pstate->parentParseState;
563                 levels_up++;
564         }
565
566         return result;
567 }
568
569 /*
570  * qualifiedNameToVar
571  *        Search for a qualified column name: either refname.colname or
572  *        schemaname.relname.colname.
573  *
574  *        If found, return the appropriate Var node.
575  *        If not found, return NULL.  If the name proves ambiguous, raise error.
576  */
577 Node *
578 qualifiedNameToVar(ParseState *pstate,
579                                    char *schemaname,
580                                    char *refname,
581                                    char *colname,
582                                    bool implicitRTEOK)
583 {
584         RangeTblEntry *rte;
585         int                     sublevels_up;
586
587         rte = refnameRangeTblEntry(pstate, schemaname, refname, &sublevels_up);
588
589         if (rte == NULL)
590         {
591                 if (!implicitRTEOK)
592                         return NULL;
593                 rte = addImplicitRTE(pstate, makeRangeVar(schemaname, refname));
594         }
595
596         return scanRTEForColumn(pstate, rte, colname);
597 }
598
599 /*
600  * Add an entry for a relation to the pstate's range table (p_rtable).
601  *
602  * If pstate is NULL, we just build an RTE and return it without adding it
603  * to an rtable list.
604  *
605  * Note: formerly this checked for refname conflicts, but that's wrong.
606  * Caller is responsible for checking for conflicts in the appropriate scope.
607  */
608 RangeTblEntry *
609 addRangeTableEntry(ParseState *pstate,
610                                    RangeVar *relation,
611                                    Alias *alias,
612                                    bool inh,
613                                    bool inFromCl)
614 {
615         RangeTblEntry *rte = makeNode(RangeTblEntry);
616         char       *refname = alias ? alias->aliasname : relation->relname;
617         LOCKMODE        lockmode;
618         Relation        rel;
619         Alias      *eref;
620         int                     maxattrs;
621         int                     numaliases;
622         int                     varattno;
623
624         rte->rtekind = RTE_RELATION;
625         rte->alias = alias;
626
627         /*
628          * Get the rel's OID.  This access also ensures that we have an
629          * up-to-date relcache entry for the rel.  Since this is typically the
630          * first access to a rel in a statement, be careful to get the right
631          * access level depending on whether we're doing SELECT FOR UPDATE.
632          */
633         lockmode = isForUpdate(pstate, refname) ? RowShareLock : AccessShareLock;
634         rel = heap_openrv(relation, lockmode);
635         rte->relid = RelationGetRelid(rel);
636
637         eref = alias ? (Alias *) copyObject(alias) : makeAlias(refname, NIL);
638         numaliases = length(eref->colnames);
639
640         /*
641          * Since the rel is open anyway, let's check that the number of column
642          * aliases is reasonable. - Thomas 2000-02-04
643          */
644         maxattrs = RelationGetNumberOfAttributes(rel);
645         if (maxattrs < numaliases)
646                 elog(ERROR, "Table \"%s\" has %d columns available but %d columns specified",
647                          RelationGetRelationName(rel), maxattrs, numaliases);
648
649         /* fill in any unspecified alias columns using actual column names */
650         for (varattno = numaliases; varattno < maxattrs; varattno++)
651         {
652                 char       *attrname;
653
654                 attrname = pstrdup(NameStr(rel->rd_att->attrs[varattno]->attname));
655                 eref->colnames = lappend(eref->colnames, makeString(attrname));
656         }
657         rte->eref = eref;
658
659         /*
660          * Drop the rel refcount, but keep the access lock till end of
661          * transaction so that the table can't be deleted or have its schema
662          * modified underneath us.
663          */
664         heap_close(rel, NoLock);
665
666         /*----------
667          * Flags:
668          * - this RTE should be expanded to include descendant tables,
669          * - this RTE is in the FROM clause,
670          * - this RTE should be checked for read/write access rights.
671          *
672          * The initial default on access checks is always check-for-READ-access,
673          * which is the right thing for all except target tables.
674          *----------
675          */
676         rte->inh = inh;
677         rte->inFromCl = inFromCl;
678         rte->checkForRead = true;
679         rte->checkForWrite = false;
680
681         rte->checkAsUser = InvalidOid;          /* not set-uid by default, either */
682
683         /*
684          * Add completed RTE to pstate's range table list, but not to join
685          * list nor namespace --- caller must do that if appropriate.
686          */
687         if (pstate != NULL)
688                 pstate->p_rtable = lappend(pstate->p_rtable, rte);
689
690         return rte;
691 }
692
693 /*
694  * Add an entry for a relation to the pstate's range table (p_rtable).
695  *
696  * This is just like addRangeTableEntry() except that it makes an RTE
697  * given a relation OID instead of a RangeVar reference.
698  *
699  * Note that an alias clause *must* be supplied.
700  */
701 RangeTblEntry *
702 addRangeTableEntryForRelation(ParseState *pstate,
703                                                           Oid relid,
704                                                           Alias *alias,
705                                                           bool inh,
706                                                           bool inFromCl)
707 {
708         RangeTblEntry *rte = makeNode(RangeTblEntry);
709         char       *refname = alias->aliasname;
710         LOCKMODE        lockmode;
711         Relation        rel;
712         Alias      *eref;
713         int                     maxattrs;
714         int                     numaliases;
715         int                     varattno;
716
717         rte->rtekind = RTE_RELATION;
718         rte->alias = alias;
719
720         /*
721          * Get the rel's relcache entry.  This access ensures that we have an
722          * up-to-date relcache entry for the rel.  Since this is typically the
723          * first access to a rel in a statement, be careful to get the right
724          * access level depending on whether we're doing SELECT FOR UPDATE.
725          */
726         lockmode = isForUpdate(pstate, refname) ? RowShareLock : AccessShareLock;
727         rel = heap_open(relid, lockmode);
728         rte->relid = relid;
729
730         eref = (Alias *) copyObject(alias);
731         numaliases = length(eref->colnames);
732
733         /*
734          * Since the rel is open anyway, let's check that the number of column
735          * aliases is reasonable. - Thomas 2000-02-04
736          */
737         maxattrs = RelationGetNumberOfAttributes(rel);
738         if (maxattrs < numaliases)
739                 elog(ERROR, "Table \"%s\" has %d columns available but %d columns specified",
740                          RelationGetRelationName(rel), maxattrs, numaliases);
741
742         /* fill in any unspecified alias columns using actual column names */
743         for (varattno = numaliases; varattno < maxattrs; varattno++)
744         {
745                 char       *attrname;
746
747                 attrname = pstrdup(NameStr(rel->rd_att->attrs[varattno]->attname));
748                 eref->colnames = lappend(eref->colnames, makeString(attrname));
749         }
750         rte->eref = eref;
751
752         /*
753          * Drop the rel refcount, but keep the access lock till end of
754          * transaction so that the table can't be deleted or have its schema
755          * modified underneath us.
756          */
757         heap_close(rel, NoLock);
758
759         /*----------
760          * Flags:
761          * - this RTE should be expanded to include descendant tables,
762          * - this RTE is in the FROM clause,
763          * - this RTE should be checked for read/write access rights.
764          *
765          * The initial default on access checks is always check-for-READ-access,
766          * which is the right thing for all except target tables.
767          *----------
768          */
769         rte->inh = inh;
770         rte->inFromCl = inFromCl;
771         rte->checkForRead = true;
772         rte->checkForWrite = false;
773
774         rte->checkAsUser = InvalidOid;          /* not set-uid by default, either */
775
776         /*
777          * Add completed RTE to pstate's range table list, but not to join
778          * list nor namespace --- caller must do that if appropriate.
779          */
780         if (pstate != NULL)
781                 pstate->p_rtable = lappend(pstate->p_rtable, rte);
782
783         return rte;
784 }
785
786 /*
787  * Add an entry for a subquery to the pstate's range table (p_rtable).
788  *
789  * This is just like addRangeTableEntry() except that it makes a subquery RTE.
790  * Note that an alias clause *must* be supplied.
791  */
792 RangeTblEntry *
793 addRangeTableEntryForSubquery(ParseState *pstate,
794                                                           Query *subquery,
795                                                           Alias *alias,
796                                                           bool inFromCl)
797 {
798         RangeTblEntry *rte = makeNode(RangeTblEntry);
799         char       *refname = alias->aliasname;
800         Alias      *eref;
801         int                     numaliases;
802         int                     varattno;
803         List       *tlistitem;
804
805         rte->rtekind = RTE_SUBQUERY;
806         rte->relid = InvalidOid;
807         rte->subquery = subquery;
808         rte->alias = alias;
809
810         eref = copyObject(alias);
811         numaliases = length(eref->colnames);
812
813         /* fill in any unspecified alias columns */
814         varattno = 0;
815         foreach(tlistitem, subquery->targetList)
816         {
817                 TargetEntry *te = (TargetEntry *) lfirst(tlistitem);
818
819                 if (te->resdom->resjunk)
820                         continue;
821                 varattno++;
822                 Assert(varattno == te->resdom->resno);
823                 if (varattno > numaliases)
824                 {
825                         char       *attrname;
826
827                         attrname = pstrdup(te->resdom->resname);
828                         eref->colnames = lappend(eref->colnames, makeString(attrname));
829                 }
830         }
831         if (varattno < numaliases)
832                 elog(ERROR, "Table \"%s\" has %d columns available but %d columns specified",
833                          refname, varattno, numaliases);
834
835         rte->eref = eref;
836
837         /*----------
838          * Flags:
839          * - this RTE should be expanded to include descendant tables,
840          * - this RTE is in the FROM clause,
841          * - this RTE should be checked for read/write access rights.
842          *
843          * Subqueries are never checked for access rights.
844          *----------
845          */
846         rte->inh = false;                       /* never true for subqueries */
847         rte->inFromCl = inFromCl;
848         rte->checkForRead = false;
849         rte->checkForWrite = false;
850
851         rte->checkAsUser = InvalidOid;
852
853         /*
854          * Add completed RTE to pstate's range table list, but not to join
855          * list nor namespace --- caller must do that if appropriate.
856          */
857         if (pstate != NULL)
858                 pstate->p_rtable = lappend(pstate->p_rtable, rte);
859
860         return rte;
861 }
862
863 /*
864  * Add an entry for a function to the pstate's range table (p_rtable).
865  *
866  * This is just like addRangeTableEntry() except that it makes a function RTE.
867  */
868 RangeTblEntry *
869 addRangeTableEntryForFunction(ParseState *pstate,
870                                                           char *funcname,
871                                                           Node *funcexpr,
872                                                           RangeFunction *rangefunc,
873                                                           bool inFromCl)
874 {
875         RangeTblEntry *rte = makeNode(RangeTblEntry);
876         Oid                     funcrettype = exprType(funcexpr);
877         char            functyptype;
878         Alias      *alias = rangefunc->alias;
879         List       *coldeflist = rangefunc->coldeflist;
880         Alias      *eref;
881         int                     numaliases;
882         int                     varattno;
883
884         rte->rtekind = RTE_FUNCTION;
885         rte->relid = InvalidOid;
886         rte->subquery = NULL;
887         rte->funcexpr = funcexpr;
888         rte->coldeflist = coldeflist;
889         rte->alias = alias;
890
891         eref = alias ? (Alias *) copyObject(alias) : makeAlias(funcname, NIL);
892         rte->eref = eref;
893
894         numaliases = length(eref->colnames);
895
896         /*
897          * Now determine if the function returns a simple or composite type,
898          * and check/add column aliases.
899          */
900         if (coldeflist != NIL)
901         {
902                 /*
903                  * we *only* allow a coldeflist for functions returning a RECORD
904                  * pseudo-type
905                  */
906                 if (funcrettype != RECORDOID)
907                         elog(ERROR, "A column definition list is only allowed for functions returning RECORD");
908         }
909         else
910         {
911                 /*
912                  * ... and a coldeflist is *required* for functions returning a
913                  * RECORD pseudo-type
914                  */
915                 if (funcrettype == RECORDOID)
916                         elog(ERROR, "A column definition list is required for functions returning RECORD");
917         }
918
919         functyptype = get_typtype(funcrettype);
920
921         if (functyptype == 'c')
922         {
923                 /*
924                  * Named composite data type, i.e. a table's row type
925                  */
926                 Oid                     funcrelid = typeidTypeRelid(funcrettype);
927                 Relation        rel;
928                 int                     maxattrs;
929
930                 if (!OidIsValid(funcrelid))
931                         elog(ERROR, "Invalid typrelid for complex type %u",
932                                  funcrettype);
933
934                 /*
935                  * Get the rel's relcache entry.  This access ensures that we have
936                  * an up-to-date relcache entry for the rel.
937                  */
938                 rel = relation_open(funcrelid, AccessShareLock);
939
940                 /*
941                  * Since the rel is open anyway, let's check that the number of
942                  * column aliases is reasonable.
943                  */
944                 maxattrs = RelationGetNumberOfAttributes(rel);
945                 if (maxattrs < numaliases)
946                         elog(ERROR, "Table \"%s\" has %d columns available but %d columns specified",
947                                  RelationGetRelationName(rel), maxattrs, numaliases);
948
949                 /* fill in alias columns using actual column names */
950                 for (varattno = numaliases; varattno < maxattrs; varattno++)
951                 {
952                         char       *attrname;
953
954                         attrname = pstrdup(NameStr(rel->rd_att->attrs[varattno]->attname));
955                         eref->colnames = lappend(eref->colnames, makeString(attrname));
956                 }
957
958                 /*
959                  * Drop the rel refcount, but keep the access lock till end of
960                  * transaction so that the table can't be deleted or have its
961                  * schema modified underneath us.
962                  */
963                 relation_close(rel, NoLock);
964         }
965         else if (functyptype == 'b' || functyptype == 'd')
966         {
967                 /*
968                  * Must be a base data type, i.e. scalar. Just add one alias
969                  * column named for the function.
970                  */
971                 if (numaliases > 1)
972                         elog(ERROR, "Too many column aliases specified for function %s",
973                                  funcname);
974                 if (numaliases == 0)
975                         eref->colnames = makeList1(makeString(eref->aliasname));
976         }
977         else if (functyptype == 'p' && funcrettype == RECORDOID)
978         {
979                 List       *col;
980
981                 /* Use the column definition list to form the alias list */
982                 eref->colnames = NIL;
983                 foreach(col, coldeflist)
984                 {
985                         ColumnDef  *n = lfirst(col);
986                         char       *attrname;
987
988                         attrname = pstrdup(n->colname);
989                         eref->colnames = lappend(eref->colnames, makeString(attrname));
990                 }
991         }
992         else
993                 elog(ERROR, "Unknown kind of return type specified for function %s",
994                          funcname);
995
996         /*----------
997          * Flags:
998          * - this RTE should be expanded to include descendant tables,
999          * - this RTE is in the FROM clause,
1000          * - this RTE should be checked for read/write access rights.
1001          *----------
1002          */
1003         rte->inh = false;                       /* never true for functions */
1004         rte->inFromCl = inFromCl;
1005         rte->checkForRead = true;
1006         rte->checkForWrite = false;
1007
1008         rte->checkAsUser = InvalidOid;
1009
1010         /*
1011          * Add completed RTE to pstate's range table list, but not to join
1012          * list nor namespace --- caller must do that if appropriate.
1013          */
1014         if (pstate != NULL)
1015                 pstate->p_rtable = lappend(pstate->p_rtable, rte);
1016
1017         return rte;
1018 }
1019
1020 /*
1021  * Add an entry for a join to the pstate's range table (p_rtable).
1022  *
1023  * This is much like addRangeTableEntry() except that it makes a join RTE.
1024  */
1025 RangeTblEntry *
1026 addRangeTableEntryForJoin(ParseState *pstate,
1027                                                   List *colnames,
1028                                                   JoinType jointype,
1029                                                   List *aliasvars,
1030                                                   Alias *alias,
1031                                                   bool inFromCl)
1032 {
1033         RangeTblEntry *rte = makeNode(RangeTblEntry);
1034         Alias      *eref;
1035         int                     numaliases;
1036
1037         rte->rtekind = RTE_JOIN;
1038         rte->relid = InvalidOid;
1039         rte->subquery = NULL;
1040         rte->jointype = jointype;
1041         rte->joinaliasvars = aliasvars;
1042         rte->alias = alias;
1043
1044         eref = alias ? (Alias *) copyObject(alias) : makeAlias("unnamed_join", NIL);
1045         numaliases = length(eref->colnames);
1046
1047         /* fill in any unspecified alias columns */
1048         if (numaliases < length(colnames))
1049         {
1050                 while (numaliases-- > 0)
1051                         colnames = lnext(colnames);
1052                 eref->colnames = nconc(eref->colnames, colnames);
1053         }
1054
1055         rte->eref = eref;
1056
1057         /*----------
1058          * Flags:
1059          * - this RTE should be expanded to include descendant tables,
1060          * - this RTE is in the FROM clause,
1061          * - this RTE should be checked for read/write access rights.
1062          *
1063          * Joins are never checked for access rights.
1064          *----------
1065          */
1066         rte->inh = false;                       /* never true for joins */
1067         rte->inFromCl = inFromCl;
1068         rte->checkForRead = false;
1069         rte->checkForWrite = false;
1070
1071         rte->checkAsUser = InvalidOid;
1072
1073         /*
1074          * Add completed RTE to pstate's range table list, but not to join
1075          * list nor namespace --- caller must do that if appropriate.
1076          */
1077         if (pstate != NULL)
1078                 pstate->p_rtable = lappend(pstate->p_rtable, rte);
1079
1080         return rte;
1081 }
1082
1083 /*
1084  * Has the specified refname been selected FOR UPDATE?
1085  */
1086 static bool
1087 isForUpdate(ParseState *pstate, char *refname)
1088 {
1089         /* Outer loop to check parent query levels as well as this one */
1090         while (pstate != NULL)
1091         {
1092                 if (pstate->p_forUpdate != NIL)
1093                 {
1094                         if (lfirst(pstate->p_forUpdate) == NULL)
1095                         {
1096                                 /* all tables used in query */
1097                                 return true;
1098                         }
1099                         else
1100                         {
1101                                 /* just the named tables */
1102                                 List       *l;
1103
1104                                 foreach(l, pstate->p_forUpdate)
1105                                 {
1106                                         char       *rname = strVal(lfirst(l));
1107
1108                                         if (strcmp(refname, rname) == 0)
1109                                                 return true;
1110                                 }
1111                         }
1112                 }
1113                 pstate = pstate->parentParseState;
1114         }
1115         return false;
1116 }
1117
1118 /*
1119  * Add the given RTE as a top-level entry in the pstate's join list
1120  * and/or name space list.      (We assume caller has checked for any
1121  * namespace conflict.)
1122  */
1123 void
1124 addRTEtoQuery(ParseState *pstate, RangeTblEntry *rte,
1125                           bool addToJoinList, bool addToNameSpace)
1126 {
1127         int                     rtindex = RTERangeTablePosn(pstate, rte, NULL);
1128         RangeTblRef *rtr = makeNode(RangeTblRef);
1129
1130         rtr->rtindex = rtindex;
1131
1132         if (addToJoinList)
1133                 pstate->p_joinlist = lappend(pstate->p_joinlist, rtr);
1134         if (addToNameSpace)
1135                 pstate->p_namespace = lappend(pstate->p_namespace, rtr);
1136 }
1137
1138 /*
1139  * Add a POSTQUEL-style implicit RTE.
1140  *
1141  * We assume caller has already checked that there is no RTE or join with
1142  * a conflicting name.
1143  */
1144 RangeTblEntry *
1145 addImplicitRTE(ParseState *pstate, RangeVar *relation)
1146 {
1147         RangeTblEntry *rte;
1148
1149         rte = addRangeTableEntry(pstate, relation, NULL, false, false);
1150         addRTEtoQuery(pstate, rte, true, true);
1151         warnAutoRange(pstate, relation);
1152
1153         return rte;
1154 }
1155
1156 /* expandRTE()
1157  *
1158  * Given a rangetable entry, create lists of its column names (aliases if
1159  * provided, else real names) and Vars for each column.  Only user columns
1160  * are considered, since this is primarily used to expand '*' and determine
1161  * the contents of JOIN tables.
1162  *
1163  * If only one of the two kinds of output list is needed, pass NULL for the
1164  * output pointer for the unwanted one.
1165  */
1166 void
1167 expandRTE(ParseState *pstate, RangeTblEntry *rte,
1168                   List **colnames, List **colvars)
1169 {
1170         int                     rtindex,
1171                                 sublevels_up,
1172                                 varattno;
1173
1174         if (colnames)
1175                 *colnames = NIL;
1176         if (colvars)
1177                 *colvars = NIL;
1178
1179         /* Need the RT index of the entry for creating Vars */
1180         rtindex = RTERangeTablePosn(pstate, rte, &sublevels_up);
1181
1182         switch (rte->rtekind)
1183         {
1184                 case RTE_RELATION:
1185                         {
1186                                 /* Ordinary relation RTE */
1187                                 Relation        rel;
1188                                 int                     maxattrs;
1189                                 int                     numaliases;
1190
1191                                 rel = heap_open(rte->relid, AccessShareLock);
1192                                 maxattrs = RelationGetNumberOfAttributes(rel);
1193                                 numaliases = length(rte->eref->colnames);
1194
1195                                 for (varattno = 0; varattno < maxattrs; varattno++)
1196                                 {
1197                                         Form_pg_attribute attr = rel->rd_att->attrs[varattno];
1198
1199                                         if (attr->attisdropped)
1200                                                 continue;
1201
1202                                         if (colnames)
1203                                         {
1204                                                 char       *label;
1205
1206                                                 if (varattno < numaliases)
1207                                                         label = strVal(nth(varattno, rte->eref->colnames));
1208                                                 else
1209                                                         label = NameStr(attr->attname);
1210                                                 *colnames = lappend(*colnames, makeString(pstrdup(label)));
1211                                         }
1212
1213                                         if (colvars)
1214                                         {
1215                                                 Var                *varnode;
1216
1217                                                 varnode = makeVar(rtindex, attr->attnum,
1218                                                                                   attr->atttypid, attr->atttypmod,
1219                                                                                   sublevels_up);
1220
1221                                                 *colvars = lappend(*colvars, varnode);
1222                                         }
1223                                 }
1224
1225                                 heap_close(rel, AccessShareLock);
1226                         }
1227                         break;
1228                 case RTE_SUBQUERY:
1229                         {
1230                                 /* Subquery RTE */
1231                                 List       *aliasp = rte->eref->colnames;
1232                                 List       *tlistitem;
1233
1234                                 varattno = 0;
1235                                 foreach(tlistitem, rte->subquery->targetList)
1236                                 {
1237                                         TargetEntry *te = (TargetEntry *) lfirst(tlistitem);
1238
1239                                         if (te->resdom->resjunk)
1240                                                 continue;
1241                                         varattno++;
1242                                         Assert(varattno == te->resdom->resno);
1243
1244                                         if (colnames)
1245                                         {
1246                                                 /* Assume there is one alias per target item */
1247                                                 char       *label = strVal(lfirst(aliasp));
1248
1249                                                 *colnames = lappend(*colnames, makeString(pstrdup(label)));
1250                                                 aliasp = lnext(aliasp);
1251                                         }
1252
1253                                         if (colvars)
1254                                         {
1255                                                 Var                *varnode;
1256
1257                                                 varnode = makeVar(rtindex, varattno,
1258                                                                                   te->resdom->restype,
1259                                                                                   te->resdom->restypmod,
1260                                                                                   sublevels_up);
1261
1262                                                 *colvars = lappend(*colvars, varnode);
1263                                         }
1264                                 }
1265                         }
1266                         break;
1267                 case RTE_FUNCTION:
1268                         {
1269                                 /* Function RTE */
1270                                 Oid                     funcrettype = exprType(rte->funcexpr);
1271                                 char            functyptype = get_typtype(funcrettype);
1272                                 List       *coldeflist = rte->coldeflist;
1273
1274                                 if (functyptype == 'c')
1275                                 {
1276                                         /*
1277                                          * Composite data type, i.e. a table's row type Same
1278                                          * as ordinary relation RTE
1279                                          */
1280                                         Oid                     funcrelid = typeidTypeRelid(funcrettype);
1281                                         Relation        rel;
1282                                         int                     maxattrs;
1283                                         int                     numaliases;
1284
1285                                         if (!OidIsValid(funcrelid))
1286                                                 elog(ERROR, "Invalid typrelid for complex type %u",
1287                                                          funcrettype);
1288
1289                                         rel = relation_open(funcrelid, AccessShareLock);
1290                                         maxattrs = RelationGetNumberOfAttributes(rel);
1291                                         numaliases = length(rte->eref->colnames);
1292
1293                                         for (varattno = 0; varattno < maxattrs; varattno++)
1294                                         {
1295                                                 Form_pg_attribute attr = rel->rd_att->attrs[varattno];
1296
1297                                                 if (attr->attisdropped)
1298                                                         continue;
1299
1300                                                 if (colnames)
1301                                                 {
1302                                                         char       *label;
1303
1304                                                         if (varattno < numaliases)
1305                                                                 label = strVal(nth(varattno, rte->eref->colnames));
1306                                                         else
1307                                                                 label = NameStr(attr->attname);
1308                                                         *colnames = lappend(*colnames, makeString(pstrdup(label)));
1309                                                 }
1310
1311                                                 if (colvars)
1312                                                 {
1313                                                         Var                *varnode;
1314
1315                                                         varnode = makeVar(rtindex,
1316                                                                                           attr->attnum,
1317                                                                                           attr->atttypid,
1318                                                                                           attr->atttypmod,
1319                                                                                           sublevels_up);
1320
1321                                                         *colvars = lappend(*colvars, varnode);
1322                                                 }
1323                                         }
1324
1325                                         relation_close(rel, AccessShareLock);
1326                                 }
1327                                 else if (functyptype == 'b' || functyptype == 'd')
1328                                 {
1329                                         /*
1330                                          * Must be a base data type, i.e. scalar
1331                                          */
1332                                         if (colnames)
1333                                                 *colnames = lappend(*colnames,
1334                                                                                         lfirst(rte->eref->colnames));
1335
1336                                         if (colvars)
1337                                         {
1338                                                 Var                *varnode;
1339
1340                                                 varnode = makeVar(rtindex, 1,
1341                                                                                   funcrettype, -1,
1342                                                                                   sublevels_up);
1343
1344                                                 *colvars = lappend(*colvars, varnode);
1345                                         }
1346                                 }
1347                                 else if (functyptype == 'p' && funcrettype == RECORDOID)
1348                                 {
1349                                         List       *col;
1350                                         int                     attnum = 0;
1351
1352                                         foreach(col, coldeflist)
1353                                         {
1354                                                 ColumnDef  *colDef = lfirst(col);
1355
1356                                                 attnum++;
1357                                                 if (colnames)
1358                                                 {
1359                                                         char       *attrname;
1360
1361                                                         attrname = pstrdup(colDef->colname);
1362                                                         *colnames = lappend(*colnames, makeString(attrname));
1363                                                 }
1364
1365                                                 if (colvars)
1366                                                 {
1367                                                         Var                *varnode;
1368                                                         Oid                     atttypid;
1369
1370                                                         atttypid = typenameTypeId(colDef->typename);
1371
1372                                                         varnode = makeVar(rtindex,
1373                                                                                           attnum,
1374                                                                                           atttypid,
1375                                                                                           -1,
1376                                                                                           sublevels_up);
1377
1378                                                         *colvars = lappend(*colvars, varnode);
1379                                                 }
1380                                         }
1381                                 }
1382                                 else
1383                                         elog(ERROR, "Unknown kind of return type specified for function");
1384                         }
1385                         break;
1386                 case RTE_JOIN:
1387                         {
1388                                 /* Join RTE */
1389                                 List       *aliasp = rte->eref->colnames;
1390                                 List       *aliasvars = rte->joinaliasvars;
1391
1392                                 varattno = 0;
1393                                 while (aliasp)
1394                                 {
1395                                         Assert(aliasvars);
1396                                         varattno++;
1397
1398                                         if (colnames)
1399                                         {
1400                                                 char       *label = strVal(lfirst(aliasp));
1401
1402                                                 *colnames = lappend(*colnames, makeString(pstrdup(label)));
1403                                         }
1404
1405                                         if (colvars)
1406                                         {
1407                                                 Node       *aliasvar = (Node *) lfirst(aliasvars);
1408                                                 Var                *varnode;
1409
1410                                                 varnode = makeVar(rtindex, varattno,
1411                                                                                   exprType(aliasvar),
1412                                                                                   exprTypmod(aliasvar),
1413                                                                                   sublevels_up);
1414
1415                                                 *colvars = lappend(*colvars, varnode);
1416                                         }
1417
1418                                         aliasp = lnext(aliasp);
1419                                         aliasvars = lnext(aliasvars);
1420                                 }
1421                                 Assert(aliasvars == NIL);
1422                         }
1423                         break;
1424                 default:
1425                         elog(ERROR, "expandRTE: unsupported RTE kind %d",
1426                                  (int) rte->rtekind);
1427         }
1428 }
1429
1430 /*
1431  * expandRelAttrs -
1432  *        Workhorse for "*" expansion: produce a list of targetentries
1433  *        for the attributes of the rte
1434  */
1435 List *
1436 expandRelAttrs(ParseState *pstate, RangeTblEntry *rte)
1437 {
1438         List       *names,
1439                            *vars;
1440         List       *te_list = NIL;
1441
1442         expandRTE(pstate, rte, &names, &vars);
1443
1444         while (names)
1445         {
1446                 char       *label = strVal(lfirst(names));
1447                 Node       *varnode = (Node *) lfirst(vars);
1448                 TargetEntry *te = makeNode(TargetEntry);
1449
1450                 te->resdom = makeResdom((AttrNumber) pstate->p_next_resno++,
1451                                                                 exprType(varnode),
1452                                                                 exprTypmod(varnode),
1453                                                                 label,
1454                                                                 false);
1455                 te->expr = (Expr *) varnode;
1456                 te_list = lappend(te_list, te);
1457
1458                 names = lnext(names);
1459                 vars = lnext(vars);
1460         }
1461
1462         Assert(vars == NIL);            /* lists not same length? */
1463
1464         return te_list;
1465 }
1466
1467 /*
1468  * get_rte_attribute_name
1469  *              Get an attribute name from a RangeTblEntry
1470  *
1471  * This is unlike get_attname() because we use aliases if available.
1472  * In particular, it will work on an RTE for a subselect or join, whereas
1473  * get_attname() only works on real relations.
1474  *
1475  * "*" is returned if the given attnum is InvalidAttrNumber --- this case
1476  * occurs when a Var represents a whole tuple of a relation.
1477  */
1478 char *
1479 get_rte_attribute_name(RangeTblEntry *rte, AttrNumber attnum)
1480 {
1481         char       *attname;
1482
1483         if (attnum == InvalidAttrNumber)
1484                 return "*";
1485
1486         /*
1487          * If there is a user-written column alias, use it.
1488          */
1489         if (rte->alias &&
1490                 attnum > 0 && attnum <= length(rte->alias->colnames))
1491                 return strVal(nth(attnum - 1, rte->alias->colnames));
1492
1493         /*
1494          * If the RTE is a relation, go to the system catalogs not the
1495          * eref->colnames list.  This is a little slower but it will give the
1496          * right answer if the column has been renamed since the eref list was
1497          * built (which can easily happen for rules).
1498          */
1499         if (rte->rtekind == RTE_RELATION)
1500         {
1501                 attname = get_attname(rte->relid, attnum);
1502                 if (attname == NULL)
1503                         elog(ERROR, "cache lookup of attribute %d in relation %u failed",
1504                                  attnum, rte->relid);
1505                 return attname;
1506         }
1507
1508         /*
1509          * Otherwise use the column name from eref.  There should always be
1510          * one.
1511          */
1512         if (attnum > 0 && attnum <= length(rte->eref->colnames))
1513                 return strVal(nth(attnum - 1, rte->eref->colnames));
1514
1515         elog(ERROR, "Invalid attnum %d for rangetable entry %s",
1516                  attnum, rte->eref->aliasname);
1517         return NULL;                            /* keep compiler quiet */
1518 }
1519
1520 /*
1521  * get_rte_attribute_type
1522  *              Get attribute type information from a RangeTblEntry
1523  */
1524 void
1525 get_rte_attribute_type(RangeTblEntry *rte, AttrNumber attnum,
1526                                            Oid *vartype, int32 *vartypmod)
1527 {
1528         switch (rte->rtekind)
1529         {
1530                 case RTE_RELATION:
1531                         {
1532                                 /* Plain relation RTE --- get the attribute's type info */
1533                                 HeapTuple       tp;
1534                                 Form_pg_attribute att_tup;
1535
1536                                 tp = SearchSysCache(ATTNUM,
1537                                                                         ObjectIdGetDatum(rte->relid),
1538                                                                         Int16GetDatum(attnum),
1539                                                                         0, 0);
1540                                 /* this shouldn't happen... */
1541                                 if (!HeapTupleIsValid(tp))
1542                                         elog(ERROR, "Relation \"%s\" does not have attribute %d",
1543                                                  get_rel_name(rte->relid), attnum);
1544                                 att_tup = (Form_pg_attribute) GETSTRUCT(tp);
1545
1546                                 /*
1547                                  * If dropped column, pretend it ain't there.  See notes
1548                                  * in scanRTEForColumn.
1549                                  */
1550                                 if (att_tup->attisdropped)
1551                                         elog(ERROR, "Relation \"%s\" has no column \"%s\"",
1552                                         get_rel_name(rte->relid), NameStr(att_tup->attname));
1553                                 *vartype = att_tup->atttypid;
1554                                 *vartypmod = att_tup->atttypmod;
1555                                 ReleaseSysCache(tp);
1556                         }
1557                         break;
1558                 case RTE_SUBQUERY:
1559                         {
1560                                 /* Subselect RTE --- get type info from subselect's tlist */
1561                                 List       *tlistitem;
1562
1563                                 foreach(tlistitem, rte->subquery->targetList)
1564                                 {
1565                                         TargetEntry *te = (TargetEntry *) lfirst(tlistitem);
1566
1567                                         if (te->resdom->resjunk || te->resdom->resno != attnum)
1568                                                 continue;
1569                                         *vartype = te->resdom->restype;
1570                                         *vartypmod = te->resdom->restypmod;
1571                                         return;
1572                                 }
1573                                 /* falling off end of list shouldn't happen... */
1574                                 elog(ERROR, "Subquery %s does not have attribute %d",
1575                                          rte->eref->aliasname, attnum);
1576                         }
1577                         break;
1578                 case RTE_FUNCTION:
1579                         {
1580                                 /* Function RTE */
1581                                 Oid                     funcrettype = exprType(rte->funcexpr);
1582                                 char            functyptype = get_typtype(funcrettype);
1583                                 List       *coldeflist = rte->coldeflist;
1584
1585                                 if (functyptype == 'c')
1586                                 {
1587                                         /*
1588                                          * Composite data type, i.e. a table's row type Same
1589                                          * as ordinary relation RTE
1590                                          */
1591                                         Oid                     funcrelid = typeidTypeRelid(funcrettype);
1592                                         HeapTuple       tp;
1593                                         Form_pg_attribute att_tup;
1594
1595                                         if (!OidIsValid(funcrelid))
1596                                                 elog(ERROR, "Invalid typrelid for complex type %u",
1597                                                          funcrettype);
1598
1599                                         tp = SearchSysCache(ATTNUM,
1600                                                                                 ObjectIdGetDatum(funcrelid),
1601                                                                                 Int16GetDatum(attnum),
1602                                                                                 0, 0);
1603                                         /* this shouldn't happen... */
1604                                         if (!HeapTupleIsValid(tp))
1605                                                 elog(ERROR, "Relation \"%s\" does not have attribute %d",
1606                                                          get_rel_name(funcrelid), attnum);
1607                                         att_tup = (Form_pg_attribute) GETSTRUCT(tp);
1608
1609                                         /*
1610                                          * If dropped column, pretend it ain't there.  See
1611                                          * notes in scanRTEForColumn.
1612                                          */
1613                                         if (att_tup->attisdropped)
1614                                                 elog(ERROR, "Relation \"%s\" has no column \"%s\"",
1615                                                          get_rel_name(funcrelid),
1616                                                          NameStr(att_tup->attname));
1617                                         *vartype = att_tup->atttypid;
1618                                         *vartypmod = att_tup->atttypmod;
1619                                         ReleaseSysCache(tp);
1620                                 }
1621                                 else if (functyptype == 'b' || functyptype == 'd')
1622                                 {
1623                                         /*
1624                                          * Must be a base data type, i.e. scalar
1625                                          */
1626                                         *vartype = funcrettype;
1627                                         *vartypmod = -1;
1628                                 }
1629                                 else if (functyptype == 'p' && funcrettype == RECORDOID)
1630                                 {
1631                                         ColumnDef  *colDef = nth(attnum - 1, coldeflist);
1632
1633                                         *vartype = typenameTypeId(colDef->typename);
1634                                         *vartypmod = -1;
1635                                 }
1636                                 else
1637                                         elog(ERROR, "Unknown kind of return type specified for function");
1638                         }
1639                         break;
1640                 case RTE_JOIN:
1641                         {
1642                                 /*
1643                                  * Join RTE --- get type info from join RTE's alias
1644                                  * variable
1645                                  */
1646                                 Node       *aliasvar;
1647
1648                                 Assert(attnum > 0 && attnum <= length(rte->joinaliasvars));
1649                                 aliasvar = (Node *) nth(attnum - 1, rte->joinaliasvars);
1650                                 *vartype = exprType(aliasvar);
1651                                 *vartypmod = exprTypmod(aliasvar);
1652                         }
1653                         break;
1654                 default:
1655                         elog(ERROR, "get_rte_attribute_type: unsupported RTE kind %d",
1656                                  (int) rte->rtekind);
1657         }
1658 }
1659
1660 /*
1661  * get_rte_attribute_is_dropped
1662  *              Check whether attempted attribute ref is to a dropped column
1663  */
1664 static bool
1665 get_rte_attribute_is_dropped(RangeTblEntry *rte, AttrNumber attnum)
1666 {
1667         bool            result;
1668
1669         switch (rte->rtekind)
1670         {
1671                 case RTE_RELATION:
1672                         {
1673                                 /* Plain relation RTE --- get the attribute's type info */
1674                                 HeapTuple       tp;
1675                                 Form_pg_attribute att_tup;
1676
1677                                 tp = SearchSysCache(ATTNUM,
1678                                                                         ObjectIdGetDatum(rte->relid),
1679                                                                         Int16GetDatum(attnum),
1680                                                                         0, 0);
1681                                 /* this shouldn't happen... */
1682                                 if (!HeapTupleIsValid(tp))
1683                                         elog(ERROR, "Relation \"%s\" does not have attribute %d",
1684                                                  get_rel_name(rte->relid), attnum);
1685                                 att_tup = (Form_pg_attribute) GETSTRUCT(tp);
1686                                 result = att_tup->attisdropped;
1687                                 ReleaseSysCache(tp);
1688                         }
1689                         break;
1690                 case RTE_SUBQUERY:
1691                 case RTE_JOIN:
1692                         /* Subselect and join RTEs never have dropped columns */
1693                         result = false;
1694                         break;
1695                 case RTE_FUNCTION:
1696                         {
1697                                 /* Function RTE */
1698                                 Oid                     funcrettype = exprType(rte->funcexpr);
1699                                 Oid                     funcrelid = typeidTypeRelid(funcrettype);
1700
1701                                 if (OidIsValid(funcrelid))
1702                                 {
1703                                         /*
1704                                          * Composite data type, i.e. a table's row type Same
1705                                          * as ordinary relation RTE
1706                                          */
1707                                         HeapTuple       tp;
1708                                         Form_pg_attribute att_tup;
1709
1710                                         tp = SearchSysCache(ATTNUM,
1711                                                                                 ObjectIdGetDatum(funcrelid),
1712                                                                                 Int16GetDatum(attnum),
1713                                                                                 0, 0);
1714                                         /* this shouldn't happen... */
1715                                         if (!HeapTupleIsValid(tp))
1716                                                 elog(ERROR, "Relation %s does not have attribute %d",
1717                                                          get_rel_name(funcrelid), attnum);
1718                                         att_tup = (Form_pg_attribute) GETSTRUCT(tp);
1719                                         result = att_tup->attisdropped;
1720                                         ReleaseSysCache(tp);
1721                                 }
1722                                 else
1723                                 {
1724                                         /*
1725                                          * Must be a base data type, i.e. scalar
1726                                          */
1727                                         result = false;
1728                                 }
1729                         }
1730                         break;
1731                 default:
1732                         elog(ERROR, "get_rte_attribute_is_dropped: unsupported RTE kind %d",
1733                                  (int) rte->rtekind);
1734                         result = false;         /* keep compiler quiet */
1735         }
1736
1737         return result;
1738 }
1739
1740 /*
1741  *      given relation and att name, return id of variable
1742  *
1743  *      This should only be used if the relation is already
1744  *      heap_open()'ed.  Use the cache version get_attnum()
1745  *      for access to non-opened relations.
1746  */
1747 int
1748 attnameAttNum(Relation rd, const char *attname, bool sysColOK)
1749 {
1750         int                     i;
1751
1752         for (i = 0; i < rd->rd_rel->relnatts; i++)
1753         {
1754                 Form_pg_attribute att = rd->rd_att->attrs[i];
1755
1756                 if (namestrcmp(&(att->attname), attname) == 0 && !att->attisdropped)
1757                         return i + 1;
1758         }
1759
1760         if (sysColOK)
1761         {
1762                 if ((i = specialAttNum(attname)) != InvalidAttrNumber)
1763                 {
1764                         if (i != ObjectIdAttributeNumber || rd->rd_rel->relhasoids)
1765                                 return i;
1766                 }
1767         }
1768
1769         /* on failure */
1770         elog(ERROR, "Relation \"%s\" has no column \"%s\"",
1771                  RelationGetRelationName(rd), attname);
1772         return InvalidAttrNumber;       /* lint */
1773 }
1774
1775 /* specialAttNum()
1776  *
1777  * Check attribute name to see if it is "special", e.g. "oid".
1778  * - thomas 2000-02-07
1779  *
1780  * Note: this only discovers whether the name could be a system attribute.
1781  * Caller needs to verify that it really is an attribute of the rel,
1782  * at least in the case of "oid", which is now optional.
1783  */
1784 static int
1785 specialAttNum(const char *attname)
1786 {
1787         Form_pg_attribute sysatt;
1788
1789         sysatt = SystemAttributeByName(attname,
1790                                                                    true /* "oid" will be accepted */ );
1791         if (sysatt != NULL)
1792                 return sysatt->attnum;
1793         return InvalidAttrNumber;
1794 }
1795
1796
1797 /*
1798  * given attribute id, return name of that attribute
1799  *
1800  *      This should only be used if the relation is already
1801  *      heap_open()'ed.  Use the cache version get_atttype()
1802  *      for access to non-opened relations.
1803  */
1804 Name
1805 attnumAttName(Relation rd, int attid)
1806 {
1807         if (attid <= 0)
1808         {
1809                 Form_pg_attribute sysatt;
1810
1811                 sysatt = SystemAttributeDefinition(attid, rd->rd_rel->relhasoids);
1812                 return &sysatt->attname;
1813         }
1814         if (attid > rd->rd_att->natts)
1815                 elog(ERROR, "attnumAttName: invalid attribute number %d", attid);
1816         return &rd->rd_att->attrs[attid - 1]->attname;
1817 }
1818
1819 /*
1820  * given attribute id, return type of that attribute
1821  *
1822  *      This should only be used if the relation is already
1823  *      heap_open()'ed.  Use the cache version get_atttype()
1824  *      for access to non-opened relations.
1825  */
1826 Oid
1827 attnumTypeId(Relation rd, int attid)
1828 {
1829         if (attid <= 0)
1830         {
1831                 Form_pg_attribute sysatt;
1832
1833                 sysatt = SystemAttributeDefinition(attid, rd->rd_rel->relhasoids);
1834                 return sysatt->atttypid;
1835         }
1836         if (attid > rd->rd_att->natts)
1837                 elog(ERROR, "attnumTypeId: invalid attribute number %d", attid);
1838         return rd->rd_att->attrs[attid - 1]->atttypid;
1839 }
1840
1841 /*
1842  * Generate a warning about an implicit RTE, if appropriate.
1843  *
1844  * Our current theory on this is that we should allow "SELECT foo.*"
1845  * but warn about a mixture of explicit and implicit RTEs.
1846  */
1847 static void
1848 warnAutoRange(ParseState *pstate, RangeVar *relation)
1849 {
1850         bool            foundInFromCl = false;
1851         List       *temp;
1852
1853         foreach(temp, pstate->p_rtable)
1854         {
1855                 RangeTblEntry *rte = lfirst(temp);
1856
1857                 if (rte->inFromCl)
1858                 {
1859                         foundInFromCl = true;
1860                         break;
1861                 }
1862         }
1863         if (foundInFromCl)
1864                 elog(NOTICE, "Adding missing FROM-clause entry%s for table \"%s\"",
1865                          pstate->parentParseState != NULL ? " in subquery" : "",
1866                          relation->relname);
1867 }