OSDN Git Service

722fd4cca340995b2eaf223f71c855922075cb9f
[pg-rex/syncrep.git] / src / backend / parser / parse_target.c
1 /*-------------------------------------------------------------------------
2  *
3  * parse_target.c
4  *        handle target lists
5  *
6  * Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *        $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.124 2004/08/29 04:12:42 momjian Exp $
12  *
13  *-------------------------------------------------------------------------
14  */
15 #include "postgres.h"
16
17 #include "commands/dbcommands.h"
18 #include "miscadmin.h"
19 #include "nodes/makefuncs.h"
20 #include "parser/parsetree.h"
21 #include "parser/parse_coerce.h"
22 #include "parser/parse_expr.h"
23 #include "parser/parse_func.h"
24 #include "parser/parse_relation.h"
25 #include "parser/parse_target.h"
26 #include "parser/parse_type.h"
27 #include "utils/builtins.h"
28 #include "utils/lsyscache.h"
29 #include "utils/typcache.h"
30
31
32 static void markTargetListOrigin(ParseState *pstate, Resdom *res, Var *var);
33 static Node *transformAssignmentIndirection(ParseState *pstate,
34                                                            Node *basenode,
35                                                            const char *targetName,
36                                                            bool targetIsArray,
37                                                            Oid targetTypeId,
38                                                            int32 targetTypMod,
39                                                            ListCell *indirection,
40                                                            Node *rhs);
41 static List *ExpandColumnRefStar(ParseState *pstate, ColumnRef *cref);
42 static List *ExpandAllTables(ParseState *pstate);
43 static List *ExpandIndirectionStar(ParseState *pstate, A_Indirection *ind);
44 static char *FigureColname(Node *node);
45 static int      FigureColnameInternal(Node *node, char **name);
46
47
48 /*
49  * transformTargetEntry()
50  *      Transform any ordinary "expression-type" node into a targetlist entry.
51  *      This is exported so that parse_clause.c can generate targetlist entries
52  *      for ORDER/GROUP BY items that are not already in the targetlist.
53  *
54  * node         the (untransformed) parse tree for the value expression.
55  * expr         the transformed expression, or NULL if caller didn't do it yet.
56  * colname      the column name to be assigned, or NULL if none yet set.
57  * resjunk      true if the target should be marked resjunk, ie, it is not
58  *                      wanted in the final projected tuple.
59  */
60 TargetEntry *
61 transformTargetEntry(ParseState *pstate,
62                                          Node *node,
63                                          Node *expr,
64                                          char *colname,
65                                          bool resjunk)
66 {
67         Oid                     type_id;
68         int32           type_mod;
69         Resdom     *resnode;
70
71         /* Transform the node if caller didn't do it already */
72         if (expr == NULL)
73                 expr = transformExpr(pstate, node);
74
75         type_id = exprType(expr);
76         type_mod = exprTypmod(expr);
77
78         if (colname == NULL && !resjunk)
79         {
80                 /*
81                  * Generate a suitable column name for a column without any
82                  * explicit 'AS ColumnName' clause.
83                  */
84                 colname = FigureColname(node);
85         }
86
87         resnode = makeResdom((AttrNumber) pstate->p_next_resno++,
88                                                  type_id,
89                                                  type_mod,
90                                                  colname,
91                                                  resjunk);
92
93         return makeTargetEntry(resnode, (Expr *) expr);
94 }
95
96
97 /*
98  * transformTargetList()
99  * Turns a list of ResTarget's into a list of TargetEntry's.
100  *
101  * At this point, we don't care whether we are doing SELECT, INSERT,
102  * or UPDATE; we just transform the given expressions (the "val" fields).
103  */
104 List *
105 transformTargetList(ParseState *pstate, List *targetlist)
106 {
107         List       *p_target = NIL;
108         ListCell   *o_target;
109
110         foreach(o_target, targetlist)
111         {
112                 ResTarget  *res = (ResTarget *) lfirst(o_target);
113
114                 /*
115                  * Check for "something.*".  Depending on the complexity of the
116                  * "something", the star could appear as the last name in ColumnRef,
117                  * or as the last indirection item in A_Indirection.
118                  */
119                 if (IsA(res->val, ColumnRef))
120                 {
121                         ColumnRef  *cref = (ColumnRef *) res->val;
122
123                         if (strcmp(strVal(llast(cref->fields)), "*") == 0)
124                         {
125                                 /* It is something.*, expand into multiple items */
126                                 p_target = list_concat(p_target,
127                                                                            ExpandColumnRefStar(pstate, cref));
128                                 continue;
129                         }
130                 }
131                 else if (IsA(res->val, A_Indirection))
132                 {
133                         A_Indirection  *ind = (A_Indirection *) res->val;
134                         Node    *lastitem = llast(ind->indirection);
135
136                         if (IsA(lastitem, String) &&
137                                 strcmp(strVal(lastitem), "*") == 0)
138                         {
139                                 /* It is something.*, expand into multiple items */
140                                 p_target = list_concat(p_target,
141                                                                            ExpandIndirectionStar(pstate, ind));
142                                 continue;
143                         }
144                 }
145
146                 /*
147                  * Not "something.*", so transform as a single expression
148                  */
149                 p_target = lappend(p_target,
150                                                    transformTargetEntry(pstate,
151                                                                                                 res->val,
152                                                                                                 NULL,
153                                                                                                 res->name,
154                                                                                                 false));
155         }
156
157         return p_target;
158 }
159
160
161 /*
162  * markTargetListOrigins()
163  *              Mark targetlist columns that are simple Vars with the source
164  *              table's OID and column number.
165  *
166  * Currently, this is done only for SELECT targetlists, since we only
167  * need the info if we are going to send it to the frontend.
168  */
169 void
170 markTargetListOrigins(ParseState *pstate, List *targetlist)
171 {
172         ListCell   *l;
173
174         foreach(l, targetlist)
175         {
176                 TargetEntry *tle = (TargetEntry *) lfirst(l);
177
178                 markTargetListOrigin(pstate, tle->resdom, (Var *) tle->expr);
179         }
180 }
181
182 /*
183  * markTargetListOrigin()
184  *              If 'var' is a Var of a plain relation, mark 'res' with its origin
185  *
186  * This is split out so it can recurse for join references.  Note that we
187  * do not drill down into views, but report the view as the column owner.
188  */
189 static void
190 markTargetListOrigin(ParseState *pstate, Resdom *res, Var *var)
191 {
192         RangeTblEntry *rte;
193         AttrNumber      attnum;
194
195         if (var == NULL || !IsA(var, Var))
196                 return;
197         rte = GetRTEByRangeTablePosn(pstate, var->varno, var->varlevelsup);
198         attnum = var->varattno;
199
200         switch (rte->rtekind)
201         {
202                 case RTE_RELATION:
203                         /* It's a table or view, report it */
204                         res->resorigtbl = rte->relid;
205                         res->resorigcol = attnum;
206                         break;
207                 case RTE_SUBQUERY:
208                         {
209                                 /* Subselect-in-FROM: copy up from the subselect */
210                                 TargetEntry *te = get_tle_by_resno(rte->subquery->targetList,
211                                                                                                    attnum);
212
213                                 if (te == NULL || te->resdom->resjunk)
214                                         elog(ERROR, "subquery %s does not have attribute %d",
215                                                  rte->eref->aliasname, attnum);
216                                 res->resorigtbl = te->resdom->resorigtbl;
217                                 res->resorigcol = te->resdom->resorigcol;
218                         }
219                         break;
220                 case RTE_JOIN:
221                         {
222                                 /* Join RTE --- recursively inspect the alias variable */
223                                 Var                *aliasvar;
224
225                                 Assert(attnum > 0 && attnum <= list_length(rte->joinaliasvars));
226                                 aliasvar = (Var *) list_nth(rte->joinaliasvars, attnum - 1);
227                                 markTargetListOrigin(pstate, res, aliasvar);
228                         }
229                         break;
230                 case RTE_SPECIAL:
231                 case RTE_FUNCTION:
232                         /* not a simple relation, leave it unmarked */
233                         break;
234         }
235 }
236
237
238 /*
239  * updateTargetListEntry()
240  *      This is used in INSERT and UPDATE statements only.      It prepares a
241  *      TargetEntry for assignment to a column of the target table.
242  *      This includes coercing the given value to the target column's type
243  *      (if necessary), and dealing with any subfield names or subscripts
244  *      attached to the target column itself.
245  *
246  * pstate               parse state
247  * tle                  target list entry to be modified
248  * colname              target column name (ie, name of attribute to be assigned to)
249  * attrno               target attribute number
250  * indirection  subscripts/field names for target column, if any
251  */
252 void
253 updateTargetListEntry(ParseState *pstate,
254                                           TargetEntry *tle,
255                                           char *colname,
256                                           int attrno,
257                                           List *indirection)
258 {
259         Oid                     type_id;                /* type of value provided */
260         Oid                     attrtype;               /* type of target column */
261         int32           attrtypmod;
262         Resdom     *resnode = tle->resdom;
263         Relation        rd = pstate->p_target_relation;
264
265         Assert(rd != NULL);
266         if (attrno <= 0)
267                 ereport(ERROR,
268                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
269                                  errmsg("cannot assign to system column \"%s\"",
270                                                 colname)));
271         attrtype = attnumTypeId(rd, attrno);
272         attrtypmod = rd->rd_att->attrs[attrno - 1]->atttypmod;
273
274         /*
275          * If the expression is a DEFAULT placeholder, insert the attribute's
276          * type/typmod into it so that exprType will report the right things.
277          * (We expect that the eventually substituted default expression will
278          * in fact have this type and typmod.)  Also, reject trying to update
279          * a subfield or array element with DEFAULT, since there can't be any
280          * default for portions of a column.
281          */
282         if (tle->expr && IsA(tle->expr, SetToDefault))
283         {
284                 SetToDefault *def = (SetToDefault *) tle->expr;
285
286                 def->typeId = attrtype;
287                 def->typeMod = attrtypmod;
288                 if (indirection)
289                 {
290                         if (IsA(linitial(indirection), A_Indices))
291                                 ereport(ERROR,
292                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
293                                                  errmsg("cannot set an array element to DEFAULT")));
294                         else
295                                 ereport(ERROR,
296                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
297                                                  errmsg("cannot set a subfield to DEFAULT")));
298                 }
299         }
300
301         /* Now we can use exprType() safely. */
302         type_id = exprType((Node *) tle->expr);
303
304         /*
305          * If there is indirection on the target column, prepare an array or
306          * subfield assignment expression.  This will generate a new column value
307          * that the source value has been inserted into, which can then be placed
308          * in the new tuple constructed by INSERT or UPDATE.
309          */
310         if (indirection)
311         {
312                 Node       *colVar;
313
314                 if (pstate->p_is_insert)
315                 {
316                         /*
317                          * The command is INSERT INTO table (col.something) ...
318                          * so there is not really a source value to work with.
319                          * Insert a NULL constant as the source value.
320                          */
321                         colVar = (Node *) makeNullConst(attrtype);
322                 }
323                 else
324                 {
325                         /*
326                          * Build a Var for the column to be updated.
327                          */
328                         colVar = (Node *) make_var(pstate,
329                                                                            pstate->p_target_rangetblentry,
330                                                                            attrno);
331                 }
332
333                 tle->expr = (Expr *)
334                         transformAssignmentIndirection(pstate,
335                                                                                    colVar,
336                                                                                    colname,
337                                                                                    false,
338                                                                                    attrtype,
339                                                                                    attrtypmod,
340                                                                                    list_head(indirection),
341                                                                                    (Node *) tle->expr);
342         }
343         else
344         {
345                 /*
346                  * For normal non-qualified target column, do type checking and
347                  * coercion.
348                  */
349                 tle->expr = (Expr *)
350                         coerce_to_target_type(pstate,
351                                                                   (Node *) tle->expr, type_id,
352                                                                   attrtype, attrtypmod,
353                                                                   COERCION_ASSIGNMENT,
354                                                                   COERCE_IMPLICIT_CAST);
355                 if (tle->expr == NULL)
356                         ereport(ERROR,
357                                         (errcode(ERRCODE_DATATYPE_MISMATCH),
358                                          errmsg("column \"%s\" is of type %s"
359                                                         " but expression is of type %s",
360                                                         colname,
361                                                         format_type_be(attrtype),
362                                                         format_type_be(type_id)),
363                                          errhint("You will need to rewrite or cast the expression.")));
364         }
365
366         /*
367          * The result of the target expression should now match the
368          * destination column's type.
369          */
370         resnode->restype = attrtype;
371         resnode->restypmod = attrtypmod;
372         /*
373          * Set the resno to identify the target column --- the rewriter and
374          * planner depend on this.  We also set the resname to identify the
375          * target column, but this is only for debugging purposes; it should
376          * not be relied on.  (In particular, it might be out of date in a
377          * stored rule.)
378          */
379         resnode->resno = (AttrNumber) attrno;
380         resnode->resname = colname;
381 }
382
383 /*
384  * Process indirection (field selection or subscripting) of the target
385  * column in INSERT/UPDATE.  This routine recurses for multiple levels
386  * of indirection --- but note that several adjacent A_Indices nodes in
387  * the indirection list are treated as a single multidimensional subscript
388  * operation.
389  *
390  * In the initial call, basenode is a Var for the target column in UPDATE,
391  * or a null Const of the target's type in INSERT.  In recursive calls,
392  * basenode is NULL, indicating that a substitute node should be consed up if
393  * needed.
394  *
395  * targetName is the name of the field or subfield we're assigning to, and
396  * targetIsArray is true if we're subscripting it.  These are just for
397  * error reporting.
398  *
399  * targetTypeId and targetTypMod indicate the datatype of the object to
400  * be assigned to (initially the target column, later some subobject).
401  *
402  * indirection is the sublist remaining to process.  When it's NULL, we're
403  * done recursing and can just coerce and return the RHS.
404  *
405  * rhs is the already-transformed value to be assigned; note it has not been
406  * coerced to any particular type.
407  */
408 static Node *
409 transformAssignmentIndirection(ParseState *pstate,
410                                                            Node *basenode,
411                                                            const char *targetName,
412                                                            bool targetIsArray,
413                                                            Oid targetTypeId,
414                                                            int32 targetTypMod,
415                                                            ListCell *indirection,
416                                                            Node *rhs)
417 {
418         Node       *result;
419         List       *subscripts = NIL;
420         bool            isSlice = false;
421         ListCell   *i;
422
423         if (indirection && !basenode)
424         {
425                 /* Set up a substitution.  We reuse CaseTestExpr for this. */
426                 CaseTestExpr *ctest = makeNode(CaseTestExpr);
427
428                 ctest->typeId = targetTypeId;
429                 ctest->typeMod = targetTypMod;
430                 basenode = (Node *) ctest;
431         }
432
433         /*
434          * We have to split any field-selection operations apart from
435          * subscripting.  Adjacent A_Indices nodes have to be treated
436          * as a single multidimensional subscript operation.
437          */
438         for_each_cell(i, indirection)
439         {
440                 Node    *n = lfirst(i);
441
442                 if (IsA(n, A_Indices))
443                 {
444                         subscripts = lappend(subscripts, n);
445                         if (((A_Indices *) n)->lidx != NULL)
446                                 isSlice = true;
447                 }
448                 else
449                 {
450                         FieldStore *fstore;
451                         Oid             typrelid;
452                         AttrNumber attnum;
453                         Oid     fieldTypeId;
454                         int32 fieldTypMod;
455
456                         Assert(IsA(n, String));
457
458                         /* process subscripts before this field selection */
459                         if (subscripts)
460                         {
461                                 Oid elementTypeId = transformArrayType(targetTypeId);
462                                 Oid     typeNeeded = isSlice ? targetTypeId : elementTypeId;
463
464                                 /* recurse to create appropriate RHS for array assign */
465                                 rhs = transformAssignmentIndirection(pstate,
466                                                                                                          NULL,
467                                                                                                          targetName,
468                                                                                                          true,
469                                                                                                          typeNeeded,
470                                                                                                          targetTypMod,
471                                                                                                          i,
472                                                                                                          rhs);
473                                 /* process subscripts */
474                                 return (Node *) transformArraySubscripts(pstate,
475                                                                                                                  basenode,
476                                                                                                                  targetTypeId,
477                                                                                                                  elementTypeId,
478                                                                                                                  targetTypMod,
479                                                                                                                  subscripts,
480                                                                                                                  rhs);
481                         }
482
483                         /* No subscripts, so can process field selection here */
484
485                         typrelid = typeidTypeRelid(targetTypeId);
486                         if (!typrelid)
487                                 ereport(ERROR,
488                                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
489                                                  errmsg("cannot assign to a column of type %s because it is not a composite type",
490                                                                 format_type_be(targetTypeId))));
491
492                         attnum = get_attnum(typrelid, strVal(n));
493                         if (attnum == InvalidAttrNumber)
494                                 ereport(ERROR,
495                                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
496                                                  errmsg("column \"%s\" not found in data type %s",
497                                                                 strVal(n), format_type_be(targetTypeId))));
498                         if (attnum < 0)
499                                 ereport(ERROR,
500                                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
501                                                  errmsg("cannot assign to system column \"%s\"",
502                                                                 strVal(n))));
503
504                         get_atttypetypmod(typrelid, attnum,
505                                                           &fieldTypeId, &fieldTypMod);
506
507                         /* recurse to create appropriate RHS for field assign */
508                         rhs = transformAssignmentIndirection(pstate,
509                                                                                                  NULL,
510                                                                                                  strVal(n),
511                                                                                                  false,
512                                                                                                  fieldTypeId,
513                                                                                                  fieldTypMod,
514                                                                                                  lnext(i),
515                                                                                                  rhs);
516
517                         /* and build a FieldStore node */
518                         fstore = makeNode(FieldStore);
519                         fstore->arg = (Expr *) basenode;
520                         fstore->newvals = list_make1(rhs);
521                         fstore->fieldnums = list_make1_int(attnum);
522                         fstore->resulttype = targetTypeId;
523
524                         return (Node *) fstore;
525                 }
526         }
527
528         /* process trailing subscripts, if any */
529         if (subscripts)
530         {
531                 Oid elementTypeId = transformArrayType(targetTypeId);
532                 Oid     typeNeeded = isSlice ? targetTypeId : elementTypeId;
533
534                 /* recurse to create appropriate RHS for array assign */
535                 rhs = transformAssignmentIndirection(pstate,
536                                                                                          NULL,
537                                                                                          targetName,
538                                                                                          true,
539                                                                                          typeNeeded,
540                                                                                          targetTypMod,
541                                                                                          NULL,
542                                                                                          rhs);
543                 /* process subscripts */
544                 return (Node *) transformArraySubscripts(pstate,
545                                                                                                  basenode,
546                                                                                                  targetTypeId,
547                                                                                                  elementTypeId,
548                                                                                                  targetTypMod,
549                                                                                                  subscripts,
550                                                                                                  rhs);
551         }
552
553         /* base case: just coerce RHS to match target type ID */
554
555         result = coerce_to_target_type(pstate,
556                                                                    rhs, exprType(rhs),
557                                                                    targetTypeId, targetTypMod,
558                                                                    COERCION_ASSIGNMENT,
559                                                                    COERCE_IMPLICIT_CAST);
560         if (result == NULL)
561         {
562                 if (targetIsArray)
563                         ereport(ERROR,
564                                         (errcode(ERRCODE_DATATYPE_MISMATCH),
565                                          errmsg("array assignment to \"%s\" requires type %s"
566                                                         " but expression is of type %s",
567                                                         targetName,
568                                                         format_type_be(targetTypeId),
569                                                         format_type_be(exprType(rhs))),
570                                          errhint("You will need to rewrite or cast the expression.")));
571                 else
572                         ereport(ERROR,
573                                         (errcode(ERRCODE_DATATYPE_MISMATCH),
574                                          errmsg("subfield \"%s\" is of type %s"
575                                                         " but expression is of type %s",
576                                                         targetName,
577                                                         format_type_be(targetTypeId),
578                                                         format_type_be(exprType(rhs))),
579                                          errhint("You will need to rewrite or cast the expression.")));
580         }
581
582         return result;
583 }
584
585
586 /*
587  * checkInsertTargets -
588  *        generate a list of INSERT column targets if not supplied, or
589  *        test supplied column names to make sure they are in target table.
590  *        Also return an integer list of the columns' attribute numbers.
591  */
592 List *
593 checkInsertTargets(ParseState *pstate, List *cols, List **attrnos)
594 {
595         *attrnos = NIL;
596
597         if (cols == NIL)
598         {
599                 /*
600                  * Generate default column list for INSERT.
601                  */
602                 Form_pg_attribute *attr = pstate->p_target_relation->rd_att->attrs;
603                 int                     numcol = pstate->p_target_relation->rd_rel->relnatts;
604                 int                     i;
605
606                 for (i = 0; i < numcol; i++)
607                 {
608                         ResTarget  *col;
609
610                         if (attr[i]->attisdropped)
611                                 continue;
612
613                         col = makeNode(ResTarget);
614                         col->name = pstrdup(NameStr(attr[i]->attname));
615                         col->indirection = NIL;
616                         col->val = NULL;
617                         cols = lappend(cols, col);
618                         *attrnos = lappend_int(*attrnos, i + 1);
619                 }
620         }
621         else
622         {
623                 /*
624                  * Do initial validation of user-supplied INSERT column list.
625                  */
626                 List       *wholecols = NIL;
627                 ListCell   *tl;
628
629                 foreach(tl, cols)
630                 {
631                         ResTarget  *col = (ResTarget *) lfirst(tl);
632                         char       *name = col->name;
633                         int                     attrno;
634
635                         /* Lookup column name, ereport on failure */
636                         attrno = attnameAttNum(pstate->p_target_relation, name, false);
637
638                         /*
639                          * Check for duplicates, but only of whole columns --- we
640                          * allow  INSERT INTO foo (col.subcol1, col.subcol2)
641                          */
642                         if (col->indirection == NIL)
643                         {
644                                 /* whole column; must not have any other assignment */
645                                 if (list_member_int(*attrnos, attrno))
646                                         ereport(ERROR,
647                                                         (errcode(ERRCODE_DUPLICATE_COLUMN),
648                                                          errmsg("column \"%s\" specified more than once",
649                                                                         name)));
650                                 wholecols = lappend_int(wholecols, attrno);
651                         }
652                         else
653                         {
654                                 /* partial column; must not have any whole assignment */
655                                 if (list_member_int(wholecols, attrno))
656                                         ereport(ERROR,
657                                                         (errcode(ERRCODE_DUPLICATE_COLUMN),
658                                                          errmsg("column \"%s\" specified more than once",
659                                                                         name)));
660                         }
661
662                         *attrnos = lappend_int(*attrnos, attrno);
663                 }
664         }
665
666         return cols;
667 }
668
669 /*
670  * ExpandColumnRefStar()
671  *              Turns foo.* (in the target list) into a list of targetlist entries.
672  *
673  * This handles the case where '*' appears as the last or only name in a
674  * ColumnRef.
675  */
676 static List *
677 ExpandColumnRefStar(ParseState *pstate, ColumnRef *cref)
678 {
679         List       *fields = cref->fields;
680         int                     numnames = list_length(fields);
681
682         if (numnames == 1)
683         {
684                 /*
685                  * Target item is a bare '*', expand all tables
686                  *
687                  * (e.g., SELECT * FROM emp, dept)
688                  */
689                 return ExpandAllTables(pstate);
690         }
691         else
692         {
693                 /*
694                  * Target item is relation.*, expand that table
695                  *
696                  * (e.g., SELECT emp.*, dname FROM emp, dept)
697                  */
698                 char       *schemaname;
699                 char       *relname;
700                 RangeTblEntry *rte;
701                 int                     sublevels_up;
702                 int                     rtindex;
703                 List       *rtable;
704
705                 switch (numnames)
706                 {
707                         case 2:
708                                 schemaname = NULL;
709                                 relname = strVal(linitial(fields));
710                                 break;
711                         case 3:
712                                 schemaname = strVal(linitial(fields));
713                                 relname = strVal(lsecond(fields));
714                                 break;
715                         case 4:
716                         {
717                                 char       *name1 = strVal(linitial(fields));
718
719                                 /*
720                                  * We check the catalog name and then ignore
721                                  * it.
722                                  */
723                                 if (strcmp(name1, get_database_name(MyDatabaseId)) != 0)
724                                         ereport(ERROR,
725                                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
726                                                          errmsg("cross-database references are not implemented: %s",
727                                                                         NameListToString(fields))));
728                                 schemaname = strVal(lsecond(fields));
729                                 relname = strVal(lthird(fields));
730                                 break;
731                         }
732                         default:
733                                 ereport(ERROR,
734                                                 (errcode(ERRCODE_SYNTAX_ERROR),
735                                                  errmsg("improper qualified name (too many dotted names): %s",
736                                                                 NameListToString(fields))));
737                                 schemaname = NULL;              /* keep compiler quiet */
738                                 relname = NULL;
739                                 break;
740                 }
741
742                 rte = refnameRangeTblEntry(pstate, schemaname, relname,
743                                                                    &sublevels_up);
744                 if (rte == NULL)
745                         rte = addImplicitRTE(pstate, makeRangeVar(schemaname,
746                                                                                                           relname));
747
748                 rtindex = RTERangeTablePosn(pstate, rte, &sublevels_up);
749                 rtable = GetLevelNRangeTable(pstate, sublevels_up);
750
751                 return expandRelAttrs(pstate, rtable, rtindex, sublevels_up);
752         }
753 }
754
755 /*
756  * ExpandAllTables()
757  *              Turns '*' (in the target list) into a list of targetlist entries.
758  *
759  * tlist entries are generated for each relation appearing at the top level
760  * of the query's namespace, except for RTEs marked not inFromCl.  (These
761  * may include NEW/OLD pseudo-entries, implicit RTEs, etc.)
762  */
763 static List *
764 ExpandAllTables(ParseState *pstate)
765 {
766         List       *target = NIL;
767         bool            found_table = false;
768         ListCell   *ns;
769
770         foreach(ns, pstate->p_namespace)
771         {
772                 Node       *n = (Node *) lfirst(ns);
773                 int                     rtindex;
774                 RangeTblEntry *rte;
775
776                 if (IsA(n, RangeTblRef))
777                         rtindex = ((RangeTblRef *) n)->rtindex;
778                 else if (IsA(n, JoinExpr))
779                         rtindex = ((JoinExpr *) n)->rtindex;
780                 else
781                 {
782                         elog(ERROR, "unrecognized node type: %d", (int) nodeTag(n));
783                         rtindex = 0;                    /* keep compiler quiet */
784                 }
785
786                 /*
787                  * Ignore added-on relations that were not listed in the FROM
788                  * clause.
789                  */
790                 rte = rt_fetch(rtindex, pstate->p_rtable);
791                 if (!rte->inFromCl)
792                         continue;
793
794                 found_table = true;
795                 target = list_concat(target,
796                                                          expandRelAttrs(pstate, pstate->p_rtable,
797                                                                                         rtindex, 0));
798         }
799
800         /* Check for SELECT *; */
801         if (!found_table)
802                 ereport(ERROR,
803                                 (errcode(ERRCODE_SYNTAX_ERROR),
804                           errmsg("SELECT * with no tables specified is not valid")));
805
806         return target;
807 }
808
809 /*
810  * ExpandIndirectionStar()
811  *              Turns foo.* (in the target list) into a list of targetlist entries.
812  *
813  * This handles the case where '*' appears as the last item in A_Indirection.
814  */
815 static List *
816 ExpandIndirectionStar(ParseState *pstate, A_Indirection *ind)
817 {
818         Node       *expr;
819         TupleDesc       tupleDesc;
820         int                     numAttrs;
821         int                     i;
822         List       *te_list = NIL;
823
824         /* Strip off the '*' to create a reference to the rowtype object */
825         ind = copyObject(ind);
826         ind->indirection = list_truncate(ind->indirection,
827                                                                          list_length(ind->indirection) - 1);
828
829         /* And transform that */
830         expr = transformExpr(pstate, (Node *) ind);
831
832         /* Verify it's a composite type, and get the tupdesc */
833         tupleDesc = lookup_rowtype_tupdesc(exprType(expr), exprTypmod(expr));
834
835         /* Generate a list of references to the individual fields */
836         numAttrs = tupleDesc->natts;
837         for (i = 0; i < numAttrs; i++)
838         {
839                 Form_pg_attribute att = tupleDesc->attrs[i];
840                 Node       *fieldnode;
841                 TargetEntry *te;
842
843                 if (att->attisdropped)
844                         continue;
845
846                 /*
847                  * If we got a whole-row Var from the rowtype reference, we can
848                  * expand the fields as simple Vars.  Otherwise we must generate
849                  * multiple copies of the rowtype reference and do FieldSelects.
850                  */
851                 if (IsA(expr, Var) &&
852                         ((Var *) expr)->varattno == InvalidAttrNumber)
853                 {
854                         Var                *var = (Var *) expr;
855
856                         fieldnode = (Node *) makeVar(var->varno,
857                                                                                  i + 1,
858                                                                                  att->atttypid,
859                                                                                  att->atttypmod,
860                                                                                  var->varlevelsup);
861                 }
862                 else
863                 {
864                         FieldSelect *fselect = makeNode(FieldSelect);
865
866                         fselect->arg = (Expr *) copyObject(expr);
867                         fselect->fieldnum = i + 1;
868                         fselect->resulttype = att->atttypid;
869                         fselect->resulttypmod = att->atttypmod;
870
871                         fieldnode = (Node *) fselect;
872                 }
873
874                 te = makeNode(TargetEntry);
875                 te->resdom = makeResdom((AttrNumber) pstate->p_next_resno++,
876                                                                 att->atttypid,
877                                                                 att->atttypmod,
878                                                                 pstrdup(NameStr(att->attname)),
879                                                                 false);
880                 te->expr = (Expr *) fieldnode;
881                 te_list = lappend(te_list, te);
882         }
883
884         return te_list;
885 }
886
887 /*
888  * FigureColname -
889  *        if the name of the resulting column is not specified in the target
890  *        list, we have to guess a suitable name.  The SQL spec provides some
891  *        guidance, but not much...
892  *
893  * Note that the argument is the *untransformed* parse tree for the target
894  * item.  This is a shade easier to work with than the transformed tree.
895  */
896 static char *
897 FigureColname(Node *node)
898 {
899         char       *name = NULL;
900
901         FigureColnameInternal(node, &name);
902         if (name != NULL)
903                 return name;
904         /* default result if we can't guess anything */
905         return "?column?";
906 }
907
908 static int
909 FigureColnameInternal(Node *node, char **name)
910 {
911         int                     strength = 0;
912
913         if (node == NULL)
914                 return strength;
915
916         switch (nodeTag(node))
917         {
918                 case T_ColumnRef:
919                         {
920                                 char       *fname = NULL;
921                                 ListCell   *l;
922
923                                 /* find last field name, if any, ignoring "*" */
924                                 foreach(l, ((ColumnRef *) node)->fields)
925                                 {
926                                         Node   *i = lfirst(l);
927
928                                         if (strcmp(strVal(i), "*") != 0)
929                                                 fname = strVal(i);
930                                 }
931                                 if (fname)
932                                 {
933                                         *name = fname;
934                                         return 2;
935                                 }
936                         }
937                         break;
938                 case T_A_Indirection:
939                         {
940                                 A_Indirection *ind = (A_Indirection *) node;
941                                 char       *fname = NULL;
942                                 ListCell   *l;
943
944                                 /* find last field name, if any, ignoring "*" */
945                                 foreach(l, ind->indirection)
946                                 {
947                                         Node   *i = lfirst(l);
948
949                                         if (IsA(i, String) &&
950                                                 strcmp(strVal(i), "*") != 0)
951                                                 fname = strVal(i);
952                                 }
953                                 if (fname)
954                                 {
955                                         *name = fname;
956                                         return 2;
957                                 }
958                                 return FigureColnameInternal(ind->arg, name);
959                         }
960                         break;
961                 case T_FuncCall:
962                         *name = strVal(llast(((FuncCall *) node)->funcname));
963                         return 2;
964                 case T_A_Expr:
965                         /* make nullif() act like a regular function */
966                         if (((A_Expr *) node)->kind == AEXPR_NULLIF)
967                         {
968                                 *name = "nullif";
969                                 return 2;
970                         }
971                         break;
972                 case T_A_Const:
973                         if (((A_Const *) node)->typename != NULL)
974                         {
975                                 *name = strVal(llast(((A_Const *) node)->typename->names));
976                                 return 1;
977                         }
978                         break;
979                 case T_TypeCast:
980                         strength = FigureColnameInternal(((TypeCast *) node)->arg,
981                                                                                          name);
982                         if (strength <= 1)
983                         {
984                                 if (((TypeCast *) node)->typename != NULL)
985                                 {
986                                         *name = strVal(llast(((TypeCast *) node)->typename->names));
987                                         return 1;
988                                 }
989                         }
990                         break;
991                 case T_CaseExpr:
992                         strength = FigureColnameInternal((Node *) ((CaseExpr *) node)->defresult,
993                                                                                          name);
994                         if (strength <= 1)
995                         {
996                                 *name = "case";
997                                 return 1;
998                         }
999                         break;
1000                 case T_ArrayExpr:
1001                         /* make ARRAY[] act like a function */
1002                         *name = "array";
1003                         return 2;
1004                 case T_RowExpr:
1005                         /* make ROW() act like a function */
1006                         *name = "row";
1007                         return 2;
1008                 case T_CoalesceExpr:
1009                         /* make coalesce() act like a regular function */
1010                         *name = "coalesce";
1011                         return 2;
1012                 default:
1013                         break;
1014         }
1015
1016         return strength;
1017 }