Header And Logo

PostgreSQL
| The world's most advanced open source database.

parse_target.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * parse_target.c
00004  *    handle target lists
00005  *
00006  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00007  * Portions Copyright (c) 1994, Regents of the University of California
00008  *
00009  *
00010  * IDENTIFICATION
00011  *    src/backend/parser/parse_target.c
00012  *
00013  *-------------------------------------------------------------------------
00014  */
00015 #include "postgres.h"
00016 
00017 #include "catalog/pg_type.h"
00018 #include "commands/dbcommands.h"
00019 #include "funcapi.h"
00020 #include "miscadmin.h"
00021 #include "nodes/makefuncs.h"
00022 #include "nodes/nodeFuncs.h"
00023 #include "parser/parsetree.h"
00024 #include "parser/parse_coerce.h"
00025 #include "parser/parse_expr.h"
00026 #include "parser/parse_func.h"
00027 #include "parser/parse_relation.h"
00028 #include "parser/parse_target.h"
00029 #include "parser/parse_type.h"
00030 #include "utils/builtins.h"
00031 #include "utils/lsyscache.h"
00032 #include "utils/rel.h"
00033 #include "utils/typcache.h"
00034 
00035 
00036 static void markTargetListOrigin(ParseState *pstate, TargetEntry *tle,
00037                      Var *var, int levelsup);
00038 static Node *transformAssignmentIndirection(ParseState *pstate,
00039                                Node *basenode,
00040                                const char *targetName,
00041                                bool targetIsArray,
00042                                Oid targetTypeId,
00043                                int32 targetTypMod,
00044                                Oid targetCollation,
00045                                ListCell *indirection,
00046                                Node *rhs,
00047                                int location);
00048 static Node *transformAssignmentSubscripts(ParseState *pstate,
00049                               Node *basenode,
00050                               const char *targetName,
00051                               Oid targetTypeId,
00052                               int32 targetTypMod,
00053                               Oid targetCollation,
00054                               List *subscripts,
00055                               bool isSlice,
00056                               ListCell *next_indirection,
00057                               Node *rhs,
00058                               int location);
00059 static List *ExpandColumnRefStar(ParseState *pstate, ColumnRef *cref,
00060                     bool make_target_entry);
00061 static List *ExpandAllTables(ParseState *pstate, int location);
00062 static List *ExpandIndirectionStar(ParseState *pstate, A_Indirection *ind,
00063                       bool make_target_entry, ParseExprKind exprKind);
00064 static List *ExpandSingleTable(ParseState *pstate, RangeTblEntry *rte,
00065                   int location, bool make_target_entry);
00066 static List *ExpandRowReference(ParseState *pstate, Node *expr,
00067                    bool make_target_entry);
00068 static int  FigureColnameInternal(Node *node, char **name);
00069 
00070 
00071 /*
00072  * transformTargetEntry()
00073  *  Transform any ordinary "expression-type" node into a targetlist entry.
00074  *  This is exported so that parse_clause.c can generate targetlist entries
00075  *  for ORDER/GROUP BY items that are not already in the targetlist.
00076  *
00077  * node     the (untransformed) parse tree for the value expression.
00078  * expr     the transformed expression, or NULL if caller didn't do it yet.
00079  * exprKind expression kind (EXPR_KIND_SELECT_TARGET, etc)
00080  * colname  the column name to be assigned, or NULL if none yet set.
00081  * resjunk  true if the target should be marked resjunk, ie, it is not
00082  *          wanted in the final projected tuple.
00083  */
00084 TargetEntry *
00085 transformTargetEntry(ParseState *pstate,
00086                      Node *node,
00087                      Node *expr,
00088                      ParseExprKind exprKind,
00089                      char *colname,
00090                      bool resjunk)
00091 {
00092     /* Transform the node if caller didn't do it already */
00093     if (expr == NULL)
00094         expr = transformExpr(pstate, node, exprKind);
00095 
00096     if (colname == NULL && !resjunk)
00097     {
00098         /*
00099          * Generate a suitable column name for a column without any explicit
00100          * 'AS ColumnName' clause.
00101          */
00102         colname = FigureColname(node);
00103     }
00104 
00105     return makeTargetEntry((Expr *) expr,
00106                            (AttrNumber) pstate->p_next_resno++,
00107                            colname,
00108                            resjunk);
00109 }
00110 
00111 
00112 /*
00113  * transformTargetList()
00114  * Turns a list of ResTarget's into a list of TargetEntry's.
00115  *
00116  * At this point, we don't care whether we are doing SELECT, UPDATE,
00117  * or RETURNING; we just transform the given expressions (the "val" fields).
00118  * However, our subroutines care, so we need the exprKind parameter.
00119  */
00120 List *
00121 transformTargetList(ParseState *pstate, List *targetlist,
00122                     ParseExprKind exprKind)
00123 {
00124     List       *p_target = NIL;
00125     ListCell   *o_target;
00126 
00127     foreach(o_target, targetlist)
00128     {
00129         ResTarget  *res = (ResTarget *) lfirst(o_target);
00130 
00131         /*
00132          * Check for "something.*".  Depending on the complexity of the
00133          * "something", the star could appear as the last field in ColumnRef,
00134          * or as the last indirection item in A_Indirection.
00135          */
00136         if (IsA(res->val, ColumnRef))
00137         {
00138             ColumnRef  *cref = (ColumnRef *) res->val;
00139 
00140             if (IsA(llast(cref->fields), A_Star))
00141             {
00142                 /* It is something.*, expand into multiple items */
00143                 p_target = list_concat(p_target,
00144                                        ExpandColumnRefStar(pstate, cref,
00145                                                            true));
00146                 continue;
00147             }
00148         }
00149         else if (IsA(res->val, A_Indirection))
00150         {
00151             A_Indirection *ind = (A_Indirection *) res->val;
00152 
00153             if (IsA(llast(ind->indirection), A_Star))
00154             {
00155                 /* It is something.*, expand into multiple items */
00156                 p_target = list_concat(p_target,
00157                                        ExpandIndirectionStar(pstate, ind,
00158                                                              true, exprKind));
00159                 continue;
00160             }
00161         }
00162 
00163         /*
00164          * Not "something.*", so transform as a single expression
00165          */
00166         p_target = lappend(p_target,
00167                            transformTargetEntry(pstate,
00168                                                 res->val,
00169                                                 NULL,
00170                                                 exprKind,
00171                                                 res->name,
00172                                                 false));
00173     }
00174 
00175     return p_target;
00176 }
00177 
00178 
00179 /*
00180  * transformExpressionList()
00181  *
00182  * This is the identical transformation to transformTargetList, except that
00183  * the input list elements are bare expressions without ResTarget decoration,
00184  * and the output elements are likewise just expressions without TargetEntry
00185  * decoration.  We use this for ROW() and VALUES() constructs.
00186  */
00187 List *
00188 transformExpressionList(ParseState *pstate, List *exprlist,
00189                         ParseExprKind exprKind)
00190 {
00191     List       *result = NIL;
00192     ListCell   *lc;
00193 
00194     foreach(lc, exprlist)
00195     {
00196         Node       *e = (Node *) lfirst(lc);
00197 
00198         /*
00199          * Check for "something.*".  Depending on the complexity of the
00200          * "something", the star could appear as the last field in ColumnRef,
00201          * or as the last indirection item in A_Indirection.
00202          */
00203         if (IsA(e, ColumnRef))
00204         {
00205             ColumnRef  *cref = (ColumnRef *) e;
00206 
00207             if (IsA(llast(cref->fields), A_Star))
00208             {
00209                 /* It is something.*, expand into multiple items */
00210                 result = list_concat(result,
00211                                      ExpandColumnRefStar(pstate, cref,
00212                                                          false));
00213                 continue;
00214             }
00215         }
00216         else if (IsA(e, A_Indirection))
00217         {
00218             A_Indirection *ind = (A_Indirection *) e;
00219 
00220             if (IsA(llast(ind->indirection), A_Star))
00221             {
00222                 /* It is something.*, expand into multiple items */
00223                 result = list_concat(result,
00224                                      ExpandIndirectionStar(pstate, ind,
00225                                                            false, exprKind));
00226                 continue;
00227             }
00228         }
00229 
00230         /*
00231          * Not "something.*", so transform as a single expression
00232          */
00233         result = lappend(result,
00234                          transformExpr(pstate, e, exprKind));
00235     }
00236 
00237     return result;
00238 }
00239 
00240 
00241 /*
00242  * markTargetListOrigins()
00243  *      Mark targetlist columns that are simple Vars with the source
00244  *      table's OID and column number.
00245  *
00246  * Currently, this is done only for SELECT targetlists, since we only
00247  * need the info if we are going to send it to the frontend.
00248  */
00249 void
00250 markTargetListOrigins(ParseState *pstate, List *targetlist)
00251 {
00252     ListCell   *l;
00253 
00254     foreach(l, targetlist)
00255     {
00256         TargetEntry *tle = (TargetEntry *) lfirst(l);
00257 
00258         markTargetListOrigin(pstate, tle, (Var *) tle->expr, 0);
00259     }
00260 }
00261 
00262 /*
00263  * markTargetListOrigin()
00264  *      If 'var' is a Var of a plain relation, mark 'tle' with its origin
00265  *
00266  * levelsup is an extra offset to interpret the Var's varlevelsup correctly.
00267  *
00268  * This is split out so it can recurse for join references.  Note that we
00269  * do not drill down into views, but report the view as the column owner.
00270  */
00271 static void
00272 markTargetListOrigin(ParseState *pstate, TargetEntry *tle,
00273                      Var *var, int levelsup)
00274 {
00275     int         netlevelsup;
00276     RangeTblEntry *rte;
00277     AttrNumber  attnum;
00278 
00279     if (var == NULL || !IsA(var, Var))
00280         return;
00281     netlevelsup = var->varlevelsup + levelsup;
00282     rte = GetRTEByRangeTablePosn(pstate, var->varno, netlevelsup);
00283     attnum = var->varattno;
00284 
00285     switch (rte->rtekind)
00286     {
00287         case RTE_RELATION:
00288             /* It's a table or view, report it */
00289             tle->resorigtbl = rte->relid;
00290             tle->resorigcol = attnum;
00291             break;
00292         case RTE_SUBQUERY:
00293             /* Subselect-in-FROM: copy up from the subselect */
00294             if (attnum != InvalidAttrNumber)
00295             {
00296                 TargetEntry *ste = get_tle_by_resno(rte->subquery->targetList,
00297                                                     attnum);
00298 
00299                 if (ste == NULL || ste->resjunk)
00300                     elog(ERROR, "subquery %s does not have attribute %d",
00301                          rte->eref->aliasname, attnum);
00302                 tle->resorigtbl = ste->resorigtbl;
00303                 tle->resorigcol = ste->resorigcol;
00304             }
00305             break;
00306         case RTE_JOIN:
00307             /* Join RTE --- recursively inspect the alias variable */
00308             if (attnum != InvalidAttrNumber)
00309             {
00310                 Var        *aliasvar;
00311 
00312                 Assert(attnum > 0 && attnum <= list_length(rte->joinaliasvars));
00313                 aliasvar = (Var *) list_nth(rte->joinaliasvars, attnum - 1);
00314                 markTargetListOrigin(pstate, tle, aliasvar, netlevelsup);
00315             }
00316             break;
00317         case RTE_FUNCTION:
00318         case RTE_VALUES:
00319             /* not a simple relation, leave it unmarked */
00320             break;
00321         case RTE_CTE:
00322 
00323             /*
00324              * CTE reference: copy up from the subquery, if possible. If the
00325              * RTE is a recursive self-reference then we can't do anything
00326              * because we haven't finished analyzing it yet. However, it's no
00327              * big loss because we must be down inside the recursive term of a
00328              * recursive CTE, and so any markings on the current targetlist
00329              * are not going to affect the results anyway.
00330              */
00331             if (attnum != InvalidAttrNumber && !rte->self_reference)
00332             {
00333                 CommonTableExpr *cte = GetCTEForRTE(pstate, rte, netlevelsup);
00334                 TargetEntry *ste;
00335 
00336                 ste = get_tle_by_resno(GetCTETargetList(cte), attnum);
00337                 if (ste == NULL || ste->resjunk)
00338                     elog(ERROR, "subquery %s does not have attribute %d",
00339                          rte->eref->aliasname, attnum);
00340                 tle->resorigtbl = ste->resorigtbl;
00341                 tle->resorigcol = ste->resorigcol;
00342             }
00343             break;
00344     }
00345 }
00346 
00347 
00348 /*
00349  * transformAssignedExpr()
00350  *  This is used in INSERT and UPDATE statements only.  It prepares an
00351  *  expression for assignment to a column of the target table.
00352  *  This includes coercing the given value to the target column's type
00353  *  (if necessary), and dealing with any subfield names or subscripts
00354  *  attached to the target column itself.  The input expression has
00355  *  already been through transformExpr().
00356  *
00357  * pstate       parse state
00358  * expr         expression to be modified
00359  * exprKind     indicates which type of statement we're dealing with
00360  * colname      target column name (ie, name of attribute to be assigned to)
00361  * attrno       target attribute number
00362  * indirection  subscripts/field names for target column, if any
00363  * location     error cursor position for the target column, or -1
00364  *
00365  * Returns the modified expression.
00366  *
00367  * Note: location points at the target column name (SET target or INSERT
00368  * column name list entry), and must therefore be -1 in an INSERT that
00369  * omits the column name list.  So we should usually prefer to use
00370  * exprLocation(expr) for errors that can happen in a default INSERT.
00371  */
00372 Expr *
00373 transformAssignedExpr(ParseState *pstate,
00374                       Expr *expr,
00375                       ParseExprKind exprKind,
00376                       char *colname,
00377                       int attrno,
00378                       List *indirection,
00379                       int location)
00380 {
00381     Relation    rd = pstate->p_target_relation;
00382     Oid         type_id;        /* type of value provided */
00383     Oid         attrtype;       /* type of target column */
00384     int32       attrtypmod;
00385     Oid         attrcollation;  /* collation of target column */
00386     ParseExprKind sv_expr_kind;
00387 
00388     /*
00389      * Save and restore identity of expression type we're parsing.  We must
00390      * set p_expr_kind here because we can parse subscripts without going
00391      * through transformExpr().
00392      */
00393     Assert(exprKind != EXPR_KIND_NONE);
00394     sv_expr_kind = pstate->p_expr_kind;
00395     pstate->p_expr_kind = exprKind;
00396 
00397     Assert(rd != NULL);
00398     if (attrno <= 0)
00399         ereport(ERROR,
00400                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
00401                  errmsg("cannot assign to system column \"%s\"",
00402                         colname),
00403                  parser_errposition(pstate, location)));
00404     attrtype = attnumTypeId(rd, attrno);
00405     attrtypmod = rd->rd_att->attrs[attrno - 1]->atttypmod;
00406     attrcollation = rd->rd_att->attrs[attrno - 1]->attcollation;
00407 
00408     /*
00409      * If the expression is a DEFAULT placeholder, insert the attribute's
00410      * type/typmod/collation into it so that exprType etc will report the
00411      * right things.  (We expect that the eventually substituted default
00412      * expression will in fact have this type and typmod.  The collation
00413      * likely doesn't matter, but let's set it correctly anyway.)  Also,
00414      * reject trying to update a subfield or array element with DEFAULT, since
00415      * there can't be any default for portions of a column.
00416      */
00417     if (expr && IsA(expr, SetToDefault))
00418     {
00419         SetToDefault *def = (SetToDefault *) expr;
00420 
00421         def->typeId = attrtype;
00422         def->typeMod = attrtypmod;
00423         def->collation = attrcollation;
00424         if (indirection)
00425         {
00426             if (IsA(linitial(indirection), A_Indices))
00427                 ereport(ERROR,
00428                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
00429                          errmsg("cannot set an array element to DEFAULT"),
00430                          parser_errposition(pstate, location)));
00431             else
00432                 ereport(ERROR,
00433                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
00434                          errmsg("cannot set a subfield to DEFAULT"),
00435                          parser_errposition(pstate, location)));
00436         }
00437     }
00438 
00439     /* Now we can use exprType() safely. */
00440     type_id = exprType((Node *) expr);
00441 
00442     /*
00443      * If there is indirection on the target column, prepare an array or
00444      * subfield assignment expression.  This will generate a new column value
00445      * that the source value has been inserted into, which can then be placed
00446      * in the new tuple constructed by INSERT or UPDATE.
00447      */
00448     if (indirection)
00449     {
00450         Node       *colVar;
00451 
00452         if (pstate->p_is_insert)
00453         {
00454             /*
00455              * The command is INSERT INTO table (col.something) ... so there
00456              * is not really a source value to work with. Insert a NULL
00457              * constant as the source value.
00458              */
00459             colVar = (Node *) makeNullConst(attrtype, attrtypmod,
00460                                             attrcollation);
00461         }
00462         else
00463         {
00464             /*
00465              * Build a Var for the column to be updated.
00466              */
00467             colVar = (Node *) make_var(pstate,
00468                                        pstate->p_target_rangetblentry,
00469                                        attrno,
00470                                        location);
00471         }
00472 
00473         expr = (Expr *)
00474             transformAssignmentIndirection(pstate,
00475                                            colVar,
00476                                            colname,
00477                                            false,
00478                                            attrtype,
00479                                            attrtypmod,
00480                                            attrcollation,
00481                                            list_head(indirection),
00482                                            (Node *) expr,
00483                                            location);
00484     }
00485     else
00486     {
00487         /*
00488          * For normal non-qualified target column, do type checking and
00489          * coercion.
00490          */
00491         Node       *orig_expr = (Node *) expr;
00492 
00493         expr = (Expr *)
00494             coerce_to_target_type(pstate,
00495                                   orig_expr, type_id,
00496                                   attrtype, attrtypmod,
00497                                   COERCION_ASSIGNMENT,
00498                                   COERCE_IMPLICIT_CAST,
00499                                   -1);
00500         if (expr == NULL)
00501             ereport(ERROR,
00502                     (errcode(ERRCODE_DATATYPE_MISMATCH),
00503                      errmsg("column \"%s\" is of type %s"
00504                             " but expression is of type %s",
00505                             colname,
00506                             format_type_be(attrtype),
00507                             format_type_be(type_id)),
00508                  errhint("You will need to rewrite or cast the expression."),
00509                      parser_errposition(pstate, exprLocation(orig_expr))));
00510     }
00511 
00512     pstate->p_expr_kind = sv_expr_kind;
00513 
00514     return expr;
00515 }
00516 
00517 
00518 /*
00519  * updateTargetListEntry()
00520  *  This is used in UPDATE statements only. It prepares an UPDATE
00521  *  TargetEntry for assignment to a column of the target table.
00522  *  This includes coercing the given value to the target column's type
00523  *  (if necessary), and dealing with any subfield names or subscripts
00524  *  attached to the target column itself.
00525  *
00526  * pstate       parse state
00527  * tle          target list entry to be modified
00528  * colname      target column name (ie, name of attribute to be assigned to)
00529  * attrno       target attribute number
00530  * indirection  subscripts/field names for target column, if any
00531  * location     error cursor position (should point at column name), or -1
00532  */
00533 void
00534 updateTargetListEntry(ParseState *pstate,
00535                       TargetEntry *tle,
00536                       char *colname,
00537                       int attrno,
00538                       List *indirection,
00539                       int location)
00540 {
00541     /* Fix up expression as needed */
00542     tle->expr = transformAssignedExpr(pstate,
00543                                       tle->expr,
00544                                       EXPR_KIND_UPDATE_TARGET,
00545                                       colname,
00546                                       attrno,
00547                                       indirection,
00548                                       location);
00549 
00550     /*
00551      * Set the resno to identify the target column --- the rewriter and
00552      * planner depend on this.  We also set the resname to identify the target
00553      * column, but this is only for debugging purposes; it should not be
00554      * relied on.  (In particular, it might be out of date in a stored rule.)
00555      */
00556     tle->resno = (AttrNumber) attrno;
00557     tle->resname = colname;
00558 }
00559 
00560 
00561 /*
00562  * Process indirection (field selection or subscripting) of the target
00563  * column in INSERT/UPDATE.  This routine recurses for multiple levels
00564  * of indirection --- but note that several adjacent A_Indices nodes in
00565  * the indirection list are treated as a single multidimensional subscript
00566  * operation.
00567  *
00568  * In the initial call, basenode is a Var for the target column in UPDATE,
00569  * or a null Const of the target's type in INSERT.  In recursive calls,
00570  * basenode is NULL, indicating that a substitute node should be consed up if
00571  * needed.
00572  *
00573  * targetName is the name of the field or subfield we're assigning to, and
00574  * targetIsArray is true if we're subscripting it.  These are just for
00575  * error reporting.
00576  *
00577  * targetTypeId, targetTypMod, targetCollation indicate the datatype and
00578  * collation of the object to be assigned to (initially the target column,
00579  * later some subobject).
00580  *
00581  * indirection is the sublist remaining to process.  When it's NULL, we're
00582  * done recursing and can just coerce and return the RHS.
00583  *
00584  * rhs is the already-transformed value to be assigned; note it has not been
00585  * coerced to any particular type.
00586  *
00587  * location is the cursor error position for any errors.  (Note: this points
00588  * to the head of the target clause, eg "foo" in "foo.bar[baz]".  Later we
00589  * might want to decorate indirection cells with their own location info,
00590  * in which case the location argument could probably be dropped.)
00591  */
00592 static Node *
00593 transformAssignmentIndirection(ParseState *pstate,
00594                                Node *basenode,
00595                                const char *targetName,
00596                                bool targetIsArray,
00597                                Oid targetTypeId,
00598                                int32 targetTypMod,
00599                                Oid targetCollation,
00600                                ListCell *indirection,
00601                                Node *rhs,
00602                                int location)
00603 {
00604     Node       *result;
00605     List       *subscripts = NIL;
00606     bool        isSlice = false;
00607     ListCell   *i;
00608 
00609     if (indirection && !basenode)
00610     {
00611         /* Set up a substitution.  We reuse CaseTestExpr for this. */
00612         CaseTestExpr *ctest = makeNode(CaseTestExpr);
00613 
00614         ctest->typeId = targetTypeId;
00615         ctest->typeMod = targetTypMod;
00616         ctest->collation = targetCollation;
00617         basenode = (Node *) ctest;
00618     }
00619 
00620     /*
00621      * We have to split any field-selection operations apart from
00622      * subscripting.  Adjacent A_Indices nodes have to be treated as a single
00623      * multidimensional subscript operation.
00624      */
00625     for_each_cell(i, indirection)
00626     {
00627         Node       *n = lfirst(i);
00628 
00629         if (IsA(n, A_Indices))
00630         {
00631             subscripts = lappend(subscripts, n);
00632             if (((A_Indices *) n)->lidx != NULL)
00633                 isSlice = true;
00634         }
00635         else if (IsA(n, A_Star))
00636         {
00637             ereport(ERROR,
00638                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
00639                      errmsg("row expansion via \"*\" is not supported here"),
00640                      parser_errposition(pstate, location)));
00641         }
00642         else
00643         {
00644             FieldStore *fstore;
00645             Oid         typrelid;
00646             AttrNumber  attnum;
00647             Oid         fieldTypeId;
00648             int32       fieldTypMod;
00649             Oid         fieldCollation;
00650 
00651             Assert(IsA(n, String));
00652 
00653             /* process subscripts before this field selection */
00654             if (subscripts)
00655             {
00656                 /* recurse, and then return because we're done */
00657                 return transformAssignmentSubscripts(pstate,
00658                                                      basenode,
00659                                                      targetName,
00660                                                      targetTypeId,
00661                                                      targetTypMod,
00662                                                      targetCollation,
00663                                                      subscripts,
00664                                                      isSlice,
00665                                                      i,
00666                                                      rhs,
00667                                                      location);
00668             }
00669 
00670             /* No subscripts, so can process field selection here */
00671 
00672             typrelid = typeidTypeRelid(targetTypeId);
00673             if (!typrelid)
00674                 ereport(ERROR,
00675                         (errcode(ERRCODE_DATATYPE_MISMATCH),
00676                          errmsg("cannot assign to field \"%s\" of column \"%s\" because its type %s is not a composite type",
00677                                 strVal(n), targetName,
00678                                 format_type_be(targetTypeId)),
00679                          parser_errposition(pstate, location)));
00680 
00681             attnum = get_attnum(typrelid, strVal(n));
00682             if (attnum == InvalidAttrNumber)
00683                 ereport(ERROR,
00684                         (errcode(ERRCODE_UNDEFINED_COLUMN),
00685                          errmsg("cannot assign to field \"%s\" of column \"%s\" because there is no such column in data type %s",
00686                                 strVal(n), targetName,
00687                                 format_type_be(targetTypeId)),
00688                          parser_errposition(pstate, location)));
00689             if (attnum < 0)
00690                 ereport(ERROR,
00691                         (errcode(ERRCODE_UNDEFINED_COLUMN),
00692                          errmsg("cannot assign to system column \"%s\"",
00693                                 strVal(n)),
00694                          parser_errposition(pstate, location)));
00695 
00696             get_atttypetypmodcoll(typrelid, attnum,
00697                                 &fieldTypeId, &fieldTypMod, &fieldCollation);
00698 
00699             /* recurse to create appropriate RHS for field assign */
00700             rhs = transformAssignmentIndirection(pstate,
00701                                                  NULL,
00702                                                  strVal(n),
00703                                                  false,
00704                                                  fieldTypeId,
00705                                                  fieldTypMod,
00706                                                  fieldCollation,
00707                                                  lnext(i),
00708                                                  rhs,
00709                                                  location);
00710 
00711             /* and build a FieldStore node */
00712             fstore = makeNode(FieldStore);
00713             fstore->arg = (Expr *) basenode;
00714             fstore->newvals = list_make1(rhs);
00715             fstore->fieldnums = list_make1_int(attnum);
00716             fstore->resulttype = targetTypeId;
00717 
00718             return (Node *) fstore;
00719         }
00720     }
00721 
00722     /* process trailing subscripts, if any */
00723     if (subscripts)
00724     {
00725         /* recurse, and then return because we're done */
00726         return transformAssignmentSubscripts(pstate,
00727                                              basenode,
00728                                              targetName,
00729                                              targetTypeId,
00730                                              targetTypMod,
00731                                              targetCollation,
00732                                              subscripts,
00733                                              isSlice,
00734                                              NULL,
00735                                              rhs,
00736                                              location);
00737     }
00738 
00739     /* base case: just coerce RHS to match target type ID */
00740 
00741     result = coerce_to_target_type(pstate,
00742                                    rhs, exprType(rhs),
00743                                    targetTypeId, targetTypMod,
00744                                    COERCION_ASSIGNMENT,
00745                                    COERCE_IMPLICIT_CAST,
00746                                    -1);
00747     if (result == NULL)
00748     {
00749         if (targetIsArray)
00750             ereport(ERROR,
00751                     (errcode(ERRCODE_DATATYPE_MISMATCH),
00752                      errmsg("array assignment to \"%s\" requires type %s"
00753                             " but expression is of type %s",
00754                             targetName,
00755                             format_type_be(targetTypeId),
00756                             format_type_be(exprType(rhs))),
00757                  errhint("You will need to rewrite or cast the expression."),
00758                      parser_errposition(pstate, location)));
00759         else
00760             ereport(ERROR,
00761                     (errcode(ERRCODE_DATATYPE_MISMATCH),
00762                      errmsg("subfield \"%s\" is of type %s"
00763                             " but expression is of type %s",
00764                             targetName,
00765                             format_type_be(targetTypeId),
00766                             format_type_be(exprType(rhs))),
00767                  errhint("You will need to rewrite or cast the expression."),
00768                      parser_errposition(pstate, location)));
00769     }
00770 
00771     return result;
00772 }
00773 
00774 /*
00775  * helper for transformAssignmentIndirection: process array assignment
00776  */
00777 static Node *
00778 transformAssignmentSubscripts(ParseState *pstate,
00779                               Node *basenode,
00780                               const char *targetName,
00781                               Oid targetTypeId,
00782                               int32 targetTypMod,
00783                               Oid targetCollation,
00784                               List *subscripts,
00785                               bool isSlice,
00786                               ListCell *next_indirection,
00787                               Node *rhs,
00788                               int location)
00789 {
00790     Node       *result;
00791     Oid         arrayType;
00792     int32       arrayTypMod;
00793     Oid         elementTypeId;
00794     Oid         typeNeeded;
00795     Oid         collationNeeded;
00796 
00797     Assert(subscripts != NIL);
00798 
00799     /* Identify the actual array type and element type involved */
00800     arrayType = targetTypeId;
00801     arrayTypMod = targetTypMod;
00802     elementTypeId = transformArrayType(&arrayType, &arrayTypMod);
00803 
00804     /* Identify type that RHS must provide */
00805     typeNeeded = isSlice ? arrayType : elementTypeId;
00806 
00807     /*
00808      * Array normally has same collation as elements, but there's an
00809      * exception: we might be subscripting a domain over an array type. In
00810      * that case use collation of the base type.
00811      */
00812     if (arrayType == targetTypeId)
00813         collationNeeded = targetCollation;
00814     else
00815         collationNeeded = get_typcollation(arrayType);
00816 
00817     /* recurse to create appropriate RHS for array assign */
00818     rhs = transformAssignmentIndirection(pstate,
00819                                          NULL,
00820                                          targetName,
00821                                          true,
00822                                          typeNeeded,
00823                                          arrayTypMod,
00824                                          collationNeeded,
00825                                          next_indirection,
00826                                          rhs,
00827                                          location);
00828 
00829     /* process subscripts */
00830     result = (Node *) transformArraySubscripts(pstate,
00831                                                basenode,
00832                                                arrayType,
00833                                                elementTypeId,
00834                                                arrayTypMod,
00835                                                subscripts,
00836                                                rhs);
00837 
00838     /* If target was a domain over array, need to coerce up to the domain */
00839     if (arrayType != targetTypeId)
00840     {
00841         result = coerce_to_target_type(pstate,
00842                                        result, exprType(result),
00843                                        targetTypeId, targetTypMod,
00844                                        COERCION_ASSIGNMENT,
00845                                        COERCE_IMPLICIT_CAST,
00846                                        -1);
00847         /* probably shouldn't fail, but check */
00848         if (result == NULL)
00849             ereport(ERROR,
00850                     (errcode(ERRCODE_CANNOT_COERCE),
00851                      errmsg("cannot cast type %s to %s",
00852                             format_type_be(exprType(result)),
00853                             format_type_be(targetTypeId)),
00854                      parser_errposition(pstate, location)));
00855     }
00856 
00857     return result;
00858 }
00859 
00860 
00861 /*
00862  * checkInsertTargets -
00863  *    generate a list of INSERT column targets if not supplied, or
00864  *    test supplied column names to make sure they are in target table.
00865  *    Also return an integer list of the columns' attribute numbers.
00866  */
00867 List *
00868 checkInsertTargets(ParseState *pstate, List *cols, List **attrnos)
00869 {
00870     *attrnos = NIL;
00871 
00872     if (cols == NIL)
00873     {
00874         /*
00875          * Generate default column list for INSERT.
00876          */
00877         Form_pg_attribute *attr = pstate->p_target_relation->rd_att->attrs;
00878         int         numcol = pstate->p_target_relation->rd_rel->relnatts;
00879         int         i;
00880 
00881         for (i = 0; i < numcol; i++)
00882         {
00883             ResTarget  *col;
00884 
00885             if (attr[i]->attisdropped)
00886                 continue;
00887 
00888             col = makeNode(ResTarget);
00889             col->name = pstrdup(NameStr(attr[i]->attname));
00890             col->indirection = NIL;
00891             col->val = NULL;
00892             col->location = -1;
00893             cols = lappend(cols, col);
00894             *attrnos = lappend_int(*attrnos, i + 1);
00895         }
00896     }
00897     else
00898     {
00899         /*
00900          * Do initial validation of user-supplied INSERT column list.
00901          */
00902         Bitmapset  *wholecols = NULL;
00903         Bitmapset  *partialcols = NULL;
00904         ListCell   *tl;
00905 
00906         foreach(tl, cols)
00907         {
00908             ResTarget  *col = (ResTarget *) lfirst(tl);
00909             char       *name = col->name;
00910             int         attrno;
00911 
00912             /* Lookup column name, ereport on failure */
00913             attrno = attnameAttNum(pstate->p_target_relation, name, false);
00914             if (attrno == InvalidAttrNumber)
00915                 ereport(ERROR,
00916                         (errcode(ERRCODE_UNDEFINED_COLUMN),
00917                     errmsg("column \"%s\" of relation \"%s\" does not exist",
00918                            name,
00919                          RelationGetRelationName(pstate->p_target_relation)),
00920                          parser_errposition(pstate, col->location)));
00921 
00922             /*
00923              * Check for duplicates, but only of whole columns --- we allow
00924              * INSERT INTO foo (col.subcol1, col.subcol2)
00925              */
00926             if (col->indirection == NIL)
00927             {
00928                 /* whole column; must not have any other assignment */
00929                 if (bms_is_member(attrno, wholecols) ||
00930                     bms_is_member(attrno, partialcols))
00931                     ereport(ERROR,
00932                             (errcode(ERRCODE_DUPLICATE_COLUMN),
00933                              errmsg("column \"%s\" specified more than once",
00934                                     name),
00935                              parser_errposition(pstate, col->location)));
00936                 wholecols = bms_add_member(wholecols, attrno);
00937             }
00938             else
00939             {
00940                 /* partial column; must not have any whole assignment */
00941                 if (bms_is_member(attrno, wholecols))
00942                     ereport(ERROR,
00943                             (errcode(ERRCODE_DUPLICATE_COLUMN),
00944                              errmsg("column \"%s\" specified more than once",
00945                                     name),
00946                              parser_errposition(pstate, col->location)));
00947                 partialcols = bms_add_member(partialcols, attrno);
00948             }
00949 
00950             *attrnos = lappend_int(*attrnos, attrno);
00951         }
00952     }
00953 
00954     return cols;
00955 }
00956 
00957 /*
00958  * ExpandColumnRefStar()
00959  *      Transforms foo.* into a list of expressions or targetlist entries.
00960  *
00961  * This handles the case where '*' appears as the last or only item in a
00962  * ColumnRef.  The code is shared between the case of foo.* at the top level
00963  * in a SELECT target list (where we want TargetEntry nodes in the result)
00964  * and foo.* in a ROW() or VALUES() construct (where we want just bare
00965  * expressions).
00966  *
00967  * The referenced columns are marked as requiring SELECT access.
00968  */
00969 static List *
00970 ExpandColumnRefStar(ParseState *pstate, ColumnRef *cref,
00971                     bool make_target_entry)
00972 {
00973     List       *fields = cref->fields;
00974     int         numnames = list_length(fields);
00975 
00976     if (numnames == 1)
00977     {
00978         /*
00979          * Target item is a bare '*', expand all tables
00980          *
00981          * (e.g., SELECT * FROM emp, dept)
00982          *
00983          * Since the grammar only accepts bare '*' at top level of SELECT, we
00984          * need not handle the make_target_entry==false case here.
00985          */
00986         Assert(make_target_entry);
00987         return ExpandAllTables(pstate, cref->location);
00988     }
00989     else
00990     {
00991         /*
00992          * Target item is relation.*, expand that table
00993          *
00994          * (e.g., SELECT emp.*, dname FROM emp, dept)
00995          *
00996          * Note: this code is a lot like transformColumnRef; it's tempting to
00997          * call that instead and then replace the resulting whole-row Var with
00998          * a list of Vars.  However, that would leave us with the RTE's
00999          * selectedCols bitmap showing the whole row as needing select
01000          * permission, as well as the individual columns.  That would be
01001          * incorrect (since columns added later shouldn't need select
01002          * permissions).  We could try to remove the whole-row permission bit
01003          * after the fact, but duplicating code is less messy.
01004          */
01005         char       *nspname = NULL;
01006         char       *relname = NULL;
01007         RangeTblEntry *rte = NULL;
01008         int         levels_up;
01009         enum
01010         {
01011             CRSERR_NO_RTE,
01012             CRSERR_WRONG_DB,
01013             CRSERR_TOO_MANY
01014         }           crserr = CRSERR_NO_RTE;
01015 
01016         /*
01017          * Give the PreParseColumnRefHook, if any, first shot.  If it returns
01018          * non-null then we should use that expression.
01019          */
01020         if (pstate->p_pre_columnref_hook != NULL)
01021         {
01022             Node       *node;
01023 
01024             node = (*pstate->p_pre_columnref_hook) (pstate, cref);
01025             if (node != NULL)
01026                 return ExpandRowReference(pstate, node, make_target_entry);
01027         }
01028 
01029         switch (numnames)
01030         {
01031             case 2:
01032                 relname = strVal(linitial(fields));
01033                 rte = refnameRangeTblEntry(pstate, nspname, relname,
01034                                            cref->location,
01035                                            &levels_up);
01036                 break;
01037             case 3:
01038                 nspname = strVal(linitial(fields));
01039                 relname = strVal(lsecond(fields));
01040                 rte = refnameRangeTblEntry(pstate, nspname, relname,
01041                                            cref->location,
01042                                            &levels_up);
01043                 break;
01044             case 4:
01045                 {
01046                     char       *catname = strVal(linitial(fields));
01047 
01048                     /*
01049                      * We check the catalog name and then ignore it.
01050                      */
01051                     if (strcmp(catname, get_database_name(MyDatabaseId)) != 0)
01052                     {
01053                         crserr = CRSERR_WRONG_DB;
01054                         break;
01055                     }
01056                     nspname = strVal(lsecond(fields));
01057                     relname = strVal(lthird(fields));
01058                     rte = refnameRangeTblEntry(pstate, nspname, relname,
01059                                                cref->location,
01060                                                &levels_up);
01061                     break;
01062                 }
01063             default:
01064                 crserr = CRSERR_TOO_MANY;
01065                 break;
01066         }
01067 
01068         /*
01069          * Now give the PostParseColumnRefHook, if any, a chance. We cheat a
01070          * bit by passing the RangeTblEntry, not a Var, as the planned
01071          * translation.  (A single Var wouldn't be strictly correct anyway.
01072          * This convention allows hooks that really care to know what is
01073          * happening.)
01074          */
01075         if (pstate->p_post_columnref_hook != NULL)
01076         {
01077             Node       *node;
01078 
01079             node = (*pstate->p_post_columnref_hook) (pstate, cref,
01080                                                      (Node *) rte);
01081             if (node != NULL)
01082             {
01083                 if (rte != NULL)
01084                     ereport(ERROR,
01085                             (errcode(ERRCODE_AMBIGUOUS_COLUMN),
01086                              errmsg("column reference \"%s\" is ambiguous",
01087                                     NameListToString(cref->fields)),
01088                              parser_errposition(pstate, cref->location)));
01089                 return ExpandRowReference(pstate, node, make_target_entry);
01090             }
01091         }
01092 
01093         /*
01094          * Throw error if no translation found.
01095          */
01096         if (rte == NULL)
01097         {
01098             switch (crserr)
01099             {
01100                 case CRSERR_NO_RTE:
01101                     errorMissingRTE(pstate, makeRangeVar(nspname, relname,
01102                                                          cref->location));
01103                     break;
01104                 case CRSERR_WRONG_DB:
01105                     ereport(ERROR,
01106                             (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
01107                              errmsg("cross-database references are not implemented: %s",
01108                                     NameListToString(cref->fields)),
01109                              parser_errposition(pstate, cref->location)));
01110                     break;
01111                 case CRSERR_TOO_MANY:
01112                     ereport(ERROR,
01113                             (errcode(ERRCODE_SYNTAX_ERROR),
01114                              errmsg("improper qualified name (too many dotted names): %s",
01115                                     NameListToString(cref->fields)),
01116                              parser_errposition(pstate, cref->location)));
01117                     break;
01118             }
01119         }
01120 
01121         /*
01122          * OK, expand the RTE into fields.
01123          */
01124         return ExpandSingleTable(pstate, rte, cref->location, make_target_entry);
01125     }
01126 }
01127 
01128 /*
01129  * ExpandAllTables()
01130  *      Transforms '*' (in the target list) into a list of targetlist entries.
01131  *
01132  * tlist entries are generated for each relation visible for unqualified
01133  * column name access.  We do not consider qualified-name-only entries because
01134  * that would include input tables of aliasless JOINs, NEW/OLD pseudo-entries,
01135  * etc.
01136  *
01137  * The referenced relations/columns are marked as requiring SELECT access.
01138  */
01139 static List *
01140 ExpandAllTables(ParseState *pstate, int location)
01141 {
01142     List       *target = NIL;
01143     bool        found_table = false;
01144     ListCell   *l;
01145 
01146     foreach(l, pstate->p_namespace)
01147     {
01148         ParseNamespaceItem *nsitem = (ParseNamespaceItem *) lfirst(l);
01149         RangeTblEntry *rte = nsitem->p_rte;
01150 
01151         /* Ignore table-only items */
01152         if (!nsitem->p_cols_visible)
01153             continue;
01154         /* Should not have any lateral-only items when parsing targetlist */
01155         Assert(!nsitem->p_lateral_only);
01156         /* Remember we found a p_cols_visible item */
01157         found_table = true;
01158 
01159         target = list_concat(target,
01160                              expandRelAttrs(pstate,
01161                                             rte,
01162                                             RTERangeTablePosn(pstate, rte,
01163                                                               NULL),
01164                                             0,
01165                                             location));
01166     }
01167 
01168     /*
01169      * Check for "SELECT *;".  We do it this way, rather than checking for
01170      * target == NIL, because we want to allow SELECT * FROM a zero_column
01171      * table.
01172      */
01173     if (!found_table)
01174         ereport(ERROR,
01175                 (errcode(ERRCODE_SYNTAX_ERROR),
01176                  errmsg("SELECT * with no tables specified is not valid"),
01177                  parser_errposition(pstate, location)));
01178 
01179     return target;
01180 }
01181 
01182 /*
01183  * ExpandIndirectionStar()
01184  *      Transforms foo.* into a list of expressions or targetlist entries.
01185  *
01186  * This handles the case where '*' appears as the last item in A_Indirection.
01187  * The code is shared between the case of foo.* at the top level in a SELECT
01188  * target list (where we want TargetEntry nodes in the result) and foo.* in
01189  * a ROW() or VALUES() construct (where we want just bare expressions).
01190  * For robustness, we use a separate "make_target_entry" flag to control
01191  * this rather than relying on exprKind.
01192  */
01193 static List *
01194 ExpandIndirectionStar(ParseState *pstate, A_Indirection *ind,
01195                       bool make_target_entry, ParseExprKind exprKind)
01196 {
01197     Node       *expr;
01198 
01199     /* Strip off the '*' to create a reference to the rowtype object */
01200     ind = copyObject(ind);
01201     ind->indirection = list_truncate(ind->indirection,
01202                                      list_length(ind->indirection) - 1);
01203 
01204     /* And transform that */
01205     expr = transformExpr(pstate, (Node *) ind, exprKind);
01206 
01207     /* Expand the rowtype expression into individual fields */
01208     return ExpandRowReference(pstate, expr, make_target_entry);
01209 }
01210 
01211 /*
01212  * ExpandSingleTable()
01213  *      Transforms foo.* into a list of expressions or targetlist entries.
01214  *
01215  * This handles the case where foo has been determined to be a simple
01216  * reference to an RTE, so we can just generate Vars for the expressions.
01217  *
01218  * The referenced columns are marked as requiring SELECT access.
01219  */
01220 static List *
01221 ExpandSingleTable(ParseState *pstate, RangeTblEntry *rte,
01222                   int location, bool make_target_entry)
01223 {
01224     int         sublevels_up;
01225     int         rtindex;
01226 
01227     rtindex = RTERangeTablePosn(pstate, rte, &sublevels_up);
01228 
01229     if (make_target_entry)
01230     {
01231         /* expandRelAttrs handles permissions marking */
01232         return expandRelAttrs(pstate, rte, rtindex, sublevels_up,
01233                               location);
01234     }
01235     else
01236     {
01237         List       *vars;
01238         ListCell   *l;
01239 
01240         expandRTE(rte, rtindex, sublevels_up, location, false,
01241                   NULL, &vars);
01242 
01243         /*
01244          * Require read access to the table.  This is normally redundant with
01245          * the markVarForSelectPriv calls below, but not if the table has zero
01246          * columns.
01247          */
01248         rte->requiredPerms |= ACL_SELECT;
01249 
01250         /* Require read access to each column */
01251         foreach(l, vars)
01252         {
01253             Var        *var = (Var *) lfirst(l);
01254 
01255             markVarForSelectPriv(pstate, var, rte);
01256         }
01257 
01258         return vars;
01259     }
01260 }
01261 
01262 /*
01263  * ExpandRowReference()
01264  *      Transforms foo.* into a list of expressions or targetlist entries.
01265  *
01266  * This handles the case where foo is an arbitrary expression of composite
01267  * type.
01268  */
01269 static List *
01270 ExpandRowReference(ParseState *pstate, Node *expr,
01271                    bool make_target_entry)
01272 {
01273     List       *result = NIL;
01274     TupleDesc   tupleDesc;
01275     int         numAttrs;
01276     int         i;
01277 
01278     /*
01279      * If the rowtype expression is a whole-row Var, we can expand the fields
01280      * as simple Vars.  Note: if the RTE is a relation, this case leaves us
01281      * with the RTE's selectedCols bitmap showing the whole row as needing
01282      * select permission, as well as the individual columns.  However, we can
01283      * only get here for weird notations like (table.*).*, so it's not worth
01284      * trying to clean up --- arguably, the permissions marking is correct
01285      * anyway for such cases.
01286      */
01287     if (IsA(expr, Var) &&
01288         ((Var *) expr)->varattno == InvalidAttrNumber)
01289     {
01290         Var        *var = (Var *) expr;
01291         RangeTblEntry *rte;
01292 
01293         rte = GetRTEByRangeTablePosn(pstate, var->varno, var->varlevelsup);
01294         return ExpandSingleTable(pstate, rte, var->location, make_target_entry);
01295     }
01296 
01297     /*
01298      * Otherwise we have to do it the hard way.  Our current implementation is
01299      * to generate multiple copies of the expression and do FieldSelects.
01300      * (This can be pretty inefficient if the expression involves nontrivial
01301      * computation :-(.)
01302      *
01303      * Verify it's a composite type, and get the tupdesc.  We use
01304      * get_expr_result_type() because that can handle references to functions
01305      * returning anonymous record types.  If that fails, use
01306      * lookup_rowtype_tupdesc(), which will almost certainly fail as well, but
01307      * it will give an appropriate error message.
01308      *
01309      * If it's a Var of type RECORD, we have to work even harder: we have to
01310      * find what the Var refers to, and pass that to get_expr_result_type.
01311      * That task is handled by expandRecordVariable().
01312      */
01313     if (IsA(expr, Var) &&
01314         ((Var *) expr)->vartype == RECORDOID)
01315         tupleDesc = expandRecordVariable(pstate, (Var *) expr, 0);
01316     else if (get_expr_result_type(expr, NULL, &tupleDesc) != TYPEFUNC_COMPOSITE)
01317         tupleDesc = lookup_rowtype_tupdesc_copy(exprType(expr),
01318                                                 exprTypmod(expr));
01319     Assert(tupleDesc);
01320 
01321     /* Generate a list of references to the individual fields */
01322     numAttrs = tupleDesc->natts;
01323     for (i = 0; i < numAttrs; i++)
01324     {
01325         Form_pg_attribute att = tupleDesc->attrs[i];
01326         FieldSelect *fselect;
01327 
01328         if (att->attisdropped)
01329             continue;
01330 
01331         fselect = makeNode(FieldSelect);
01332         fselect->arg = (Expr *) copyObject(expr);
01333         fselect->fieldnum = i + 1;
01334         fselect->resulttype = att->atttypid;
01335         fselect->resulttypmod = att->atttypmod;
01336         /* save attribute's collation for parse_collate.c */
01337         fselect->resultcollid = att->attcollation;
01338 
01339         if (make_target_entry)
01340         {
01341             /* add TargetEntry decoration */
01342             TargetEntry *te;
01343 
01344             te = makeTargetEntry((Expr *) fselect,
01345                                  (AttrNumber) pstate->p_next_resno++,
01346                                  pstrdup(NameStr(att->attname)),
01347                                  false);
01348             result = lappend(result, te);
01349         }
01350         else
01351             result = lappend(result, fselect);
01352     }
01353 
01354     return result;
01355 }
01356 
01357 /*
01358  * expandRecordVariable
01359  *      Get the tuple descriptor for a Var of type RECORD, if possible.
01360  *
01361  * Since no actual table or view column is allowed to have type RECORD, such
01362  * a Var must refer to a JOIN or FUNCTION RTE or to a subquery output.  We
01363  * drill down to find the ultimate defining expression and attempt to infer
01364  * the tupdesc from it.  We ereport if we can't determine the tupdesc.
01365  *
01366  * levelsup is an extra offset to interpret the Var's varlevelsup correctly.
01367  */
01368 TupleDesc
01369 expandRecordVariable(ParseState *pstate, Var *var, int levelsup)
01370 {
01371     TupleDesc   tupleDesc;
01372     int         netlevelsup;
01373     RangeTblEntry *rte;
01374     AttrNumber  attnum;
01375     Node       *expr;
01376 
01377     /* Check my caller didn't mess up */
01378     Assert(IsA(var, Var));
01379     Assert(var->vartype == RECORDOID);
01380 
01381     netlevelsup = var->varlevelsup + levelsup;
01382     rte = GetRTEByRangeTablePosn(pstate, var->varno, netlevelsup);
01383     attnum = var->varattno;
01384 
01385     if (attnum == InvalidAttrNumber)
01386     {
01387         /* Whole-row reference to an RTE, so expand the known fields */
01388         List       *names,
01389                    *vars;
01390         ListCell   *lname,
01391                    *lvar;
01392         int         i;
01393 
01394         expandRTE(rte, var->varno, 0, var->location, false,
01395                   &names, &vars);
01396 
01397         tupleDesc = CreateTemplateTupleDesc(list_length(vars), false);
01398         i = 1;
01399         forboth(lname, names, lvar, vars)
01400         {
01401             char       *label = strVal(lfirst(lname));
01402             Node       *varnode = (Node *) lfirst(lvar);
01403 
01404             TupleDescInitEntry(tupleDesc, i,
01405                                label,
01406                                exprType(varnode),
01407                                exprTypmod(varnode),
01408                                0);
01409             TupleDescInitEntryCollation(tupleDesc, i,
01410                                         exprCollation(varnode));
01411             i++;
01412         }
01413         Assert(lname == NULL && lvar == NULL);  /* lists same length? */
01414 
01415         return tupleDesc;
01416     }
01417 
01418     expr = (Node *) var;        /* default if we can't drill down */
01419 
01420     switch (rte->rtekind)
01421     {
01422         case RTE_RELATION:
01423         case RTE_VALUES:
01424 
01425             /*
01426              * This case should not occur: a column of a table or values list
01427              * shouldn't have type RECORD.  Fall through and fail (most
01428              * likely) at the bottom.
01429              */
01430             break;
01431         case RTE_SUBQUERY:
01432             {
01433                 /* Subselect-in-FROM: examine sub-select's output expr */
01434                 TargetEntry *ste = get_tle_by_resno(rte->subquery->targetList,
01435                                                     attnum);
01436 
01437                 if (ste == NULL || ste->resjunk)
01438                     elog(ERROR, "subquery %s does not have attribute %d",
01439                          rte->eref->aliasname, attnum);
01440                 expr = (Node *) ste->expr;
01441                 if (IsA(expr, Var))
01442                 {
01443                     /*
01444                      * Recurse into the sub-select to see what its Var refers
01445                      * to.  We have to build an additional level of ParseState
01446                      * to keep in step with varlevelsup in the subselect.
01447                      */
01448                     ParseState  mypstate;
01449 
01450                     MemSet(&mypstate, 0, sizeof(mypstate));
01451                     mypstate.parentParseState = pstate;
01452                     mypstate.p_rtable = rte->subquery->rtable;
01453                     /* don't bother filling the rest of the fake pstate */
01454 
01455                     return expandRecordVariable(&mypstate, (Var *) expr, 0);
01456                 }
01457                 /* else fall through to inspect the expression */
01458             }
01459             break;
01460         case RTE_JOIN:
01461             /* Join RTE --- recursively inspect the alias variable */
01462             Assert(attnum > 0 && attnum <= list_length(rte->joinaliasvars));
01463             expr = (Node *) list_nth(rte->joinaliasvars, attnum - 1);
01464             if (IsA(expr, Var))
01465                 return expandRecordVariable(pstate, (Var *) expr, netlevelsup);
01466             /* else fall through to inspect the expression */
01467             break;
01468         case RTE_FUNCTION:
01469 
01470             /*
01471              * We couldn't get here unless a function is declared with one of
01472              * its result columns as RECORD, which is not allowed.
01473              */
01474             break;
01475         case RTE_CTE:
01476             /* CTE reference: examine subquery's output expr */
01477             if (!rte->self_reference)
01478             {
01479                 CommonTableExpr *cte = GetCTEForRTE(pstate, rte, netlevelsup);
01480                 TargetEntry *ste;
01481 
01482                 ste = get_tle_by_resno(GetCTETargetList(cte), attnum);
01483                 if (ste == NULL || ste->resjunk)
01484                     elog(ERROR, "subquery %s does not have attribute %d",
01485                          rte->eref->aliasname, attnum);
01486                 expr = (Node *) ste->expr;
01487                 if (IsA(expr, Var))
01488                 {
01489                     /*
01490                      * Recurse into the CTE to see what its Var refers to. We
01491                      * have to build an additional level of ParseState to keep
01492                      * in step with varlevelsup in the CTE; furthermore it
01493                      * could be an outer CTE.
01494                      */
01495                     ParseState  mypstate;
01496                     Index       levelsup;
01497 
01498                     MemSet(&mypstate, 0, sizeof(mypstate));
01499                     /* this loop must work, since GetCTEForRTE did */
01500                     for (levelsup = 0;
01501                          levelsup < rte->ctelevelsup + netlevelsup;
01502                          levelsup++)
01503                         pstate = pstate->parentParseState;
01504                     mypstate.parentParseState = pstate;
01505                     mypstate.p_rtable = ((Query *) cte->ctequery)->rtable;
01506                     /* don't bother filling the rest of the fake pstate */
01507 
01508                     return expandRecordVariable(&mypstate, (Var *) expr, 0);
01509                 }
01510                 /* else fall through to inspect the expression */
01511             }
01512             break;
01513     }
01514 
01515     /*
01516      * We now have an expression we can't expand any more, so see if
01517      * get_expr_result_type() can do anything with it.  If not, pass to
01518      * lookup_rowtype_tupdesc() which will probably fail, but will give an
01519      * appropriate error message while failing.
01520      */
01521     if (get_expr_result_type(expr, NULL, &tupleDesc) != TYPEFUNC_COMPOSITE)
01522         tupleDesc = lookup_rowtype_tupdesc_copy(exprType(expr),
01523                                                 exprTypmod(expr));
01524 
01525     return tupleDesc;
01526 }
01527 
01528 
01529 /*
01530  * FigureColname -
01531  *    if the name of the resulting column is not specified in the target
01532  *    list, we have to guess a suitable name.  The SQL spec provides some
01533  *    guidance, but not much...
01534  *
01535  * Note that the argument is the *untransformed* parse tree for the target
01536  * item.  This is a shade easier to work with than the transformed tree.
01537  */
01538 char *
01539 FigureColname(Node *node)
01540 {
01541     char       *name = NULL;
01542 
01543     (void) FigureColnameInternal(node, &name);
01544     if (name != NULL)
01545         return name;
01546     /* default result if we can't guess anything */
01547     return "?column?";
01548 }
01549 
01550 /*
01551  * FigureIndexColname -
01552  *    choose the name for an expression column in an index
01553  *
01554  * This is actually just like FigureColname, except we return NULL if
01555  * we can't pick a good name.
01556  */
01557 char *
01558 FigureIndexColname(Node *node)
01559 {
01560     char       *name = NULL;
01561 
01562     (void) FigureColnameInternal(node, &name);
01563     return name;
01564 }
01565 
01566 /*
01567  * FigureColnameInternal -
01568  *    internal workhorse for FigureColname
01569  *
01570  * Return value indicates strength of confidence in result:
01571  *      0 - no information
01572  *      1 - second-best name choice
01573  *      2 - good name choice
01574  * The return value is actually only used internally.
01575  * If the result isn't zero, *name is set to the chosen name.
01576  */
01577 static int
01578 FigureColnameInternal(Node *node, char **name)
01579 {
01580     int         strength = 0;
01581 
01582     if (node == NULL)
01583         return strength;
01584 
01585     switch (nodeTag(node))
01586     {
01587         case T_ColumnRef:
01588             {
01589                 char       *fname = NULL;
01590                 ListCell   *l;
01591 
01592                 /* find last field name, if any, ignoring "*" */
01593                 foreach(l, ((ColumnRef *) node)->fields)
01594                 {
01595                     Node       *i = lfirst(l);
01596 
01597                     if (IsA(i, String))
01598                         fname = strVal(i);
01599                 }
01600                 if (fname)
01601                 {
01602                     *name = fname;
01603                     return 2;
01604                 }
01605             }
01606             break;
01607         case T_A_Indirection:
01608             {
01609                 A_Indirection *ind = (A_Indirection *) node;
01610                 char       *fname = NULL;
01611                 ListCell   *l;
01612 
01613                 /* find last field name, if any, ignoring "*" and subscripts */
01614                 foreach(l, ind->indirection)
01615                 {
01616                     Node       *i = lfirst(l);
01617 
01618                     if (IsA(i, String))
01619                         fname = strVal(i);
01620                 }
01621                 if (fname)
01622                 {
01623                     *name = fname;
01624                     return 2;
01625                 }
01626                 return FigureColnameInternal(ind->arg, name);
01627             }
01628             break;
01629         case T_FuncCall:
01630             *name = strVal(llast(((FuncCall *) node)->funcname));
01631             return 2;
01632         case T_A_Expr:
01633             /* make nullif() act like a regular function */
01634             if (((A_Expr *) node)->kind == AEXPR_NULLIF)
01635             {
01636                 *name = "nullif";
01637                 return 2;
01638             }
01639             break;
01640         case T_TypeCast:
01641             strength = FigureColnameInternal(((TypeCast *) node)->arg,
01642                                              name);
01643             if (strength <= 1)
01644             {
01645                 if (((TypeCast *) node)->typeName != NULL)
01646                 {
01647                     *name = strVal(llast(((TypeCast *) node)->typeName->names));
01648                     return 1;
01649                 }
01650             }
01651             break;
01652         case T_CollateClause:
01653             return FigureColnameInternal(((CollateClause *) node)->arg, name);
01654         case T_SubLink:
01655             switch (((SubLink *) node)->subLinkType)
01656             {
01657                 case EXISTS_SUBLINK:
01658                     *name = "exists";
01659                     return 2;
01660                 case ARRAY_SUBLINK:
01661                     *name = "array";
01662                     return 2;
01663                 case EXPR_SUBLINK:
01664                     {
01665                         /* Get column name of the subquery's single target */
01666                         SubLink    *sublink = (SubLink *) node;
01667                         Query      *query = (Query *) sublink->subselect;
01668 
01669                         /*
01670                          * The subquery has probably already been transformed,
01671                          * but let's be careful and check that.  (The reason
01672                          * we can see a transformed subquery here is that
01673                          * transformSubLink is lazy and modifies the SubLink
01674                          * node in-place.)
01675                          */
01676                         if (IsA(query, Query))
01677                         {
01678                             TargetEntry *te = (TargetEntry *) linitial(query->targetList);
01679 
01680                             if (te->resname)
01681                             {
01682                                 *name = te->resname;
01683                                 return 2;
01684                             }
01685                         }
01686                     }
01687                     break;
01688                     /* As with other operator-like nodes, these have no names */
01689                 case ALL_SUBLINK:
01690                 case ANY_SUBLINK:
01691                 case ROWCOMPARE_SUBLINK:
01692                 case CTE_SUBLINK:
01693                     break;
01694             }
01695             break;
01696         case T_CaseExpr:
01697             strength = FigureColnameInternal((Node *) ((CaseExpr *) node)->defresult,
01698                                              name);
01699             if (strength <= 1)
01700             {
01701                 *name = "case";
01702                 return 1;
01703             }
01704             break;
01705         case T_A_ArrayExpr:
01706             /* make ARRAY[] act like a function */
01707             *name = "array";
01708             return 2;
01709         case T_RowExpr:
01710             /* make ROW() act like a function */
01711             *name = "row";
01712             return 2;
01713         case T_CoalesceExpr:
01714             /* make coalesce() act like a regular function */
01715             *name = "coalesce";
01716             return 2;
01717         case T_MinMaxExpr:
01718             /* make greatest/least act like a regular function */
01719             switch (((MinMaxExpr *) node)->op)
01720             {
01721                 case IS_GREATEST:
01722                     *name = "greatest";
01723                     return 2;
01724                 case IS_LEAST:
01725                     *name = "least";
01726                     return 2;
01727             }
01728             break;
01729         case T_XmlExpr:
01730             /* make SQL/XML functions act like a regular function */
01731             switch (((XmlExpr *) node)->op)
01732             {
01733                 case IS_XMLCONCAT:
01734                     *name = "xmlconcat";
01735                     return 2;
01736                 case IS_XMLELEMENT:
01737                     *name = "xmlelement";
01738                     return 2;
01739                 case IS_XMLFOREST:
01740                     *name = "xmlforest";
01741                     return 2;
01742                 case IS_XMLPARSE:
01743                     *name = "xmlparse";
01744                     return 2;
01745                 case IS_XMLPI:
01746                     *name = "xmlpi";
01747                     return 2;
01748                 case IS_XMLROOT:
01749                     *name = "xmlroot";
01750                     return 2;
01751                 case IS_XMLSERIALIZE:
01752                     *name = "xmlserialize";
01753                     return 2;
01754                 case IS_DOCUMENT:
01755                     /* nothing */
01756                     break;
01757             }
01758             break;
01759         case T_XmlSerialize:
01760             *name = "xmlserialize";
01761             return 2;
01762         default:
01763             break;
01764     }
01765 
01766     return strength;
01767 }