PostgreSQL Source Code  git master
parse_target.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * parse_target.c
4  * handle target lists
5  *
6  * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  * src/backend/parser/parse_target.c
12  *
13  *-------------------------------------------------------------------------
14  */
15 #include "postgres.h"
16 
17 #include "catalog/pg_type.h"
18 #include "commands/dbcommands.h"
19 #include "funcapi.h"
20 #include "miscadmin.h"
21 #include "nodes/makefuncs.h"
22 #include "nodes/nodeFuncs.h"
23 #include "parser/parsetree.h"
24 #include "parser/parse_coerce.h"
25 #include "parser/parse_expr.h"
26 #include "parser/parse_func.h"
27 #include "parser/parse_relation.h"
28 #include "parser/parse_target.h"
29 #include "parser/parse_type.h"
30 #include "utils/builtins.h"
31 #include "utils/lsyscache.h"
32 #include "utils/rel.h"
33 #include "utils/typcache.h"
34 
35 
36 static void markTargetListOrigin(ParseState *pstate, TargetEntry *tle,
37  Var *var, int levelsup);
39  Node *basenode,
40  const char *targetName,
41  bool targetIsSubscripting,
42  Oid targetTypeId,
43  int32 targetTypMod,
44  Oid targetCollation,
45  List *indirection,
46  ListCell *indirection_cell,
47  Node *rhs,
48  int location);
50  Node *basenode,
51  const char *targetName,
52  Oid targetTypeId,
53  int32 targetTypMod,
54  Oid targetCollation,
55  List *subscripts,
56  bool isSlice,
57  List *indirection,
58  ListCell *next_indirection,
59  Node *rhs,
60  int location);
61 static List *ExpandColumnRefStar(ParseState *pstate, ColumnRef *cref,
62  bool make_target_entry);
63 static List *ExpandAllTables(ParseState *pstate, int location);
65  bool make_target_entry, ParseExprKind exprKind);
66 static List *ExpandSingleTable(ParseState *pstate, RangeTblEntry *rte,
67  int location, bool make_target_entry);
68 static List *ExpandRowReference(ParseState *pstate, Node *expr,
69  bool make_target_entry);
70 static int FigureColnameInternal(Node *node, char **name);
71 
72 
73 /*
74  * transformTargetEntry()
75  * Transform any ordinary "expression-type" node into a targetlist entry.
76  * This is exported so that parse_clause.c can generate targetlist entries
77  * for ORDER/GROUP BY items that are not already in the targetlist.
78  *
79  * node the (untransformed) parse tree for the value expression.
80  * expr the transformed expression, or NULL if caller didn't do it yet.
81  * exprKind expression kind (EXPR_KIND_SELECT_TARGET, etc)
82  * colname the column name to be assigned, or NULL if none yet set.
83  * resjunk true if the target should be marked resjunk, ie, it is not
84  * wanted in the final projected tuple.
85  */
88  Node *node,
89  Node *expr,
90  ParseExprKind exprKind,
91  char *colname,
92  bool resjunk)
93 {
94  /* Transform the node if caller didn't do it already */
95  if (expr == NULL)
96  {
97  /*
98  * If it's a SetToDefault node and we should allow that, pass it
99  * through unmodified. (transformExpr will throw the appropriate
100  * error if we're disallowing it.)
101  */
102  if (exprKind == EXPR_KIND_UPDATE_SOURCE && IsA(node, SetToDefault))
103  expr = node;
104  else
105  expr = transformExpr(pstate, node, exprKind);
106  }
107 
108  if (colname == NULL && !resjunk)
109  {
110  /*
111  * Generate a suitable column name for a column without any explicit
112  * 'AS ColumnName' clause.
113  */
114  colname = FigureColname(node);
115  }
116 
117  return makeTargetEntry((Expr *) expr,
118  (AttrNumber) pstate->p_next_resno++,
119  colname,
120  resjunk);
121 }
122 
123 
124 /*
125  * transformTargetList()
126  * Turns a list of ResTarget's into a list of TargetEntry's.
127  *
128  * This code acts mostly the same for SELECT, UPDATE, or RETURNING lists;
129  * the main thing is to transform the given expressions (the "val" fields).
130  * The exprKind parameter distinguishes these cases when necessary.
131  */
132 List *
133 transformTargetList(ParseState *pstate, List *targetlist,
134  ParseExprKind exprKind)
135 {
136  List *p_target = NIL;
137  bool expand_star;
138  ListCell *o_target;
139 
140  /* Shouldn't have any leftover multiassign items at start */
141  Assert(pstate->p_multiassign_exprs == NIL);
142 
143  /* Expand "something.*" in SELECT and RETURNING, but not UPDATE */
144  expand_star = (exprKind != EXPR_KIND_UPDATE_SOURCE);
145 
146  foreach(o_target, targetlist)
147  {
148  ResTarget *res = (ResTarget *) lfirst(o_target);
149 
150  /*
151  * Check for "something.*". Depending on the complexity of the
152  * "something", the star could appear as the last field in ColumnRef,
153  * or as the last indirection item in A_Indirection.
154  */
155  if (expand_star)
156  {
157  if (IsA(res->val, ColumnRef))
158  {
159  ColumnRef *cref = (ColumnRef *) res->val;
160 
161  if (IsA(llast(cref->fields), A_Star))
162  {
163  /* It is something.*, expand into multiple items */
164  p_target = list_concat(p_target,
165  ExpandColumnRefStar(pstate,
166  cref,
167  true));
168  continue;
169  }
170  }
171  else if (IsA(res->val, A_Indirection))
172  {
173  A_Indirection *ind = (A_Indirection *) res->val;
174 
175  if (IsA(llast(ind->indirection), A_Star))
176  {
177  /* It is something.*, expand into multiple items */
178  p_target = list_concat(p_target,
179  ExpandIndirectionStar(pstate,
180  ind,
181  true,
182  exprKind));
183  continue;
184  }
185  }
186  }
187 
188  /*
189  * Not "something.*", or we want to treat that as a plain whole-row
190  * variable, so transform as a single expression
191  */
192  p_target = lappend(p_target,
193  transformTargetEntry(pstate,
194  res->val,
195  NULL,
196  exprKind,
197  res->name,
198  false));
199  }
200 
201  /*
202  * If any multiassign resjunk items were created, attach them to the end
203  * of the targetlist. This should only happen in an UPDATE tlist. We
204  * don't need to worry about numbering of these items; transformUpdateStmt
205  * will set their resnos.
206  */
207  if (pstate->p_multiassign_exprs)
208  {
209  Assert(exprKind == EXPR_KIND_UPDATE_SOURCE);
210  p_target = list_concat(p_target, pstate->p_multiassign_exprs);
211  pstate->p_multiassign_exprs = NIL;
212  }
213 
214  return p_target;
215 }
216 
217 
218 /*
219  * transformExpressionList()
220  *
221  * This is the identical transformation to transformTargetList, except that
222  * the input list elements are bare expressions without ResTarget decoration,
223  * and the output elements are likewise just expressions without TargetEntry
224  * decoration. We use this for ROW() and VALUES() constructs.
225  *
226  * exprKind is not enough to tell us whether to allow SetToDefault, so
227  * an additional flag is needed for that.
228  */
229 List *
231  ParseExprKind exprKind, bool allowDefault)
232 {
233  List *result = NIL;
234  ListCell *lc;
235 
236  foreach(lc, exprlist)
237  {
238  Node *e = (Node *) lfirst(lc);
239 
240  /*
241  * Check for "something.*". Depending on the complexity of the
242  * "something", the star could appear as the last field in ColumnRef,
243  * or as the last indirection item in A_Indirection.
244  */
245  if (IsA(e, ColumnRef))
246  {
247  ColumnRef *cref = (ColumnRef *) e;
248 
249  if (IsA(llast(cref->fields), A_Star))
250  {
251  /* It is something.*, expand into multiple items */
252  result = list_concat(result,
253  ExpandColumnRefStar(pstate, cref,
254  false));
255  continue;
256  }
257  }
258  else if (IsA(e, A_Indirection))
259  {
261 
262  if (IsA(llast(ind->indirection), A_Star))
263  {
264  /* It is something.*, expand into multiple items */
265  result = list_concat(result,
266  ExpandIndirectionStar(pstate, ind,
267  false, exprKind));
268  continue;
269  }
270  }
271 
272  /*
273  * Not "something.*", so transform as a single expression. If it's a
274  * SetToDefault node and we should allow that, pass it through
275  * unmodified. (transformExpr will throw the appropriate error if
276  * we're disallowing it.)
277  */
278  if (allowDefault && IsA(e, SetToDefault))
279  /* do nothing */ ;
280  else
281  e = transformExpr(pstate, e, exprKind);
282 
283  result = lappend(result, e);
284  }
285 
286  /* Shouldn't have any multiassign items here */
287  Assert(pstate->p_multiassign_exprs == NIL);
288 
289  return result;
290 }
291 
292 
293 /*
294  * resolveTargetListUnknowns()
295  * Convert any unknown-type targetlist entries to type TEXT.
296  *
297  * We do this after we've exhausted all other ways of identifying the output
298  * column types of a query.
299  */
300 void
302 {
303  ListCell *l;
304 
305  foreach(l, targetlist)
306  {
307  TargetEntry *tle = (TargetEntry *) lfirst(l);
308  Oid restype = exprType((Node *) tle->expr);
309 
310  if (restype == UNKNOWNOID)
311  {
312  tle->expr = (Expr *) coerce_type(pstate, (Node *) tle->expr,
313  restype, TEXTOID, -1,
316  -1);
317  }
318  }
319 }
320 
321 
322 /*
323  * markTargetListOrigins()
324  * Mark targetlist columns that are simple Vars with the source
325  * table's OID and column number.
326  *
327  * Currently, this is done only for SELECT targetlists and RETURNING lists,
328  * since we only need the info if we are going to send it to the frontend.
329  */
330 void
331 markTargetListOrigins(ParseState *pstate, List *targetlist)
332 {
333  ListCell *l;
334 
335  foreach(l, targetlist)
336  {
337  TargetEntry *tle = (TargetEntry *) lfirst(l);
338 
339  markTargetListOrigin(pstate, tle, (Var *) tle->expr, 0);
340  }
341 }
342 
343 /*
344  * markTargetListOrigin()
345  * If 'var' is a Var of a plain relation, mark 'tle' with its origin
346  *
347  * levelsup is an extra offset to interpret the Var's varlevelsup correctly.
348  *
349  * This is split out so it can recurse for join references. Note that we
350  * do not drill down into views, but report the view as the column owner.
351  */
352 static void
354  Var *var, int levelsup)
355 {
356  int netlevelsup;
357  RangeTblEntry *rte;
359 
360  if (var == NULL || !IsA(var, Var))
361  return;
362  netlevelsup = var->varlevelsup + levelsup;
363  rte = GetRTEByRangeTablePosn(pstate, var->varno, netlevelsup);
364  attnum = var->varattno;
365 
366  switch (rte->rtekind)
367  {
368  case RTE_RELATION:
369  /* It's a table or view, report it */
370  tle->resorigtbl = rte->relid;
371  tle->resorigcol = attnum;
372  break;
373  case RTE_SUBQUERY:
374  /* Subselect-in-FROM: copy up from the subselect */
375  if (attnum != InvalidAttrNumber)
376  {
378  attnum);
379 
380  if (ste == NULL || ste->resjunk)
381  elog(ERROR, "subquery %s does not have attribute %d",
382  rte->eref->aliasname, attnum);
383  tle->resorigtbl = ste->resorigtbl;
384  tle->resorigcol = ste->resorigcol;
385  }
386  break;
387  case RTE_JOIN:
388  /* Join RTE --- recursively inspect the alias variable */
389  if (attnum != InvalidAttrNumber)
390  {
391  Var *aliasvar;
392 
393  Assert(attnum > 0 && attnum <= list_length(rte->joinaliasvars));
394  aliasvar = (Var *) list_nth(rte->joinaliasvars, attnum - 1);
395  /* We intentionally don't strip implicit coercions here */
396  markTargetListOrigin(pstate, tle, aliasvar, netlevelsup);
397  }
398  break;
399  case RTE_FUNCTION:
400  case RTE_VALUES:
401  case RTE_TABLEFUNC:
402  case RTE_NAMEDTUPLESTORE:
403  case RTE_RESULT:
404  /* not a simple relation, leave it unmarked */
405  break;
406  case RTE_CTE:
407 
408  /*
409  * CTE reference: copy up from the subquery, if possible. If the
410  * RTE is a recursive self-reference then we can't do anything
411  * because we haven't finished analyzing it yet. However, it's no
412  * big loss because we must be down inside the recursive term of a
413  * recursive CTE, and so any markings on the current targetlist
414  * are not going to affect the results anyway.
415  */
416  if (attnum != InvalidAttrNumber && !rte->self_reference)
417  {
418  CommonTableExpr *cte = GetCTEForRTE(pstate, rte, netlevelsup);
419  TargetEntry *ste;
420 
421  ste = get_tle_by_resno(GetCTETargetList(cte), attnum);
422  if (ste == NULL || ste->resjunk)
423  elog(ERROR, "subquery %s does not have attribute %d",
424  rte->eref->aliasname, attnum);
425  tle->resorigtbl = ste->resorigtbl;
426  tle->resorigcol = ste->resorigcol;
427  }
428  break;
429  }
430 }
431 
432 
433 /*
434  * transformAssignedExpr()
435  * This is used in INSERT and UPDATE statements only. It prepares an
436  * expression for assignment to a column of the target table.
437  * This includes coercing the given value to the target column's type
438  * (if necessary), and dealing with any subfield names or subscripts
439  * attached to the target column itself. The input expression has
440  * already been through transformExpr().
441  *
442  * pstate parse state
443  * expr expression to be modified
444  * exprKind indicates which type of statement we're dealing with
445  * colname target column name (ie, name of attribute to be assigned to)
446  * attrno target attribute number
447  * indirection subscripts/field names for target column, if any
448  * location error cursor position for the target column, or -1
449  *
450  * Returns the modified expression.
451  *
452  * Note: location points at the target column name (SET target or INSERT
453  * column name list entry), and must therefore be -1 in an INSERT that
454  * omits the column name list. So we should usually prefer to use
455  * exprLocation(expr) for errors that can happen in a default INSERT.
456  */
457 Expr *
459  Expr *expr,
460  ParseExprKind exprKind,
461  const char *colname,
462  int attrno,
463  List *indirection,
464  int location)
465 {
466  Relation rd = pstate->p_target_relation;
467  Oid type_id; /* type of value provided */
468  Oid attrtype; /* type of target column */
469  int32 attrtypmod;
470  Oid attrcollation; /* collation of target column */
471  ParseExprKind sv_expr_kind;
472 
473  /*
474  * Save and restore identity of expression type we're parsing. We must
475  * set p_expr_kind here because we can parse subscripts without going
476  * through transformExpr().
477  */
478  Assert(exprKind != EXPR_KIND_NONE);
479  sv_expr_kind = pstate->p_expr_kind;
480  pstate->p_expr_kind = exprKind;
481 
482  Assert(rd != NULL);
483  if (attrno <= 0)
484  ereport(ERROR,
485  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
486  errmsg("cannot assign to system column \"%s\"",
487  colname),
488  parser_errposition(pstate, location)));
489  attrtype = attnumTypeId(rd, attrno);
490  attrtypmod = TupleDescAttr(rd->rd_att, attrno - 1)->atttypmod;
491  attrcollation = TupleDescAttr(rd->rd_att, attrno - 1)->attcollation;
492 
493  /*
494  * If the expression is a DEFAULT placeholder, insert the attribute's
495  * type/typmod/collation into it so that exprType etc will report the
496  * right things. (We expect that the eventually substituted default
497  * expression will in fact have this type and typmod. The collation
498  * likely doesn't matter, but let's set it correctly anyway.) Also,
499  * reject trying to update a subfield or array element with DEFAULT, since
500  * there can't be any default for portions of a column.
501  */
502  if (expr && IsA(expr, SetToDefault))
503  {
504  SetToDefault *def = (SetToDefault *) expr;
505 
506  def->typeId = attrtype;
507  def->typeMod = attrtypmod;
508  def->collation = attrcollation;
509  if (indirection)
510  {
511  if (IsA(linitial(indirection), A_Indices))
512  ereport(ERROR,
513  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
514  errmsg("cannot set an array element to DEFAULT"),
515  parser_errposition(pstate, location)));
516  else
517  ereport(ERROR,
518  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
519  errmsg("cannot set a subfield to DEFAULT"),
520  parser_errposition(pstate, location)));
521  }
522  }
523 
524  /* Now we can use exprType() safely. */
525  type_id = exprType((Node *) expr);
526 
527  /*
528  * If there is indirection on the target column, prepare an array or
529  * subfield assignment expression. This will generate a new column value
530  * that the source value has been inserted into, which can then be placed
531  * in the new tuple constructed by INSERT or UPDATE.
532  */
533  if (indirection)
534  {
535  Node *colVar;
536 
537  if (pstate->p_is_insert)
538  {
539  /*
540  * The command is INSERT INTO table (col.something) ... so there
541  * is not really a source value to work with. Insert a NULL
542  * constant as the source value.
543  */
544  colVar = (Node *) makeNullConst(attrtype, attrtypmod,
545  attrcollation);
546  }
547  else
548  {
549  /*
550  * Build a Var for the column to be updated.
551  */
552  colVar = (Node *) make_var(pstate,
553  pstate->p_target_rangetblentry,
554  attrno,
555  location);
556  }
557 
558  expr = (Expr *)
560  colVar,
561  colname,
562  false,
563  attrtype,
564  attrtypmod,
565  attrcollation,
566  indirection,
567  list_head(indirection),
568  (Node *) expr,
569  location);
570  }
571  else
572  {
573  /*
574  * For normal non-qualified target column, do type checking and
575  * coercion.
576  */
577  Node *orig_expr = (Node *) expr;
578 
579  expr = (Expr *)
580  coerce_to_target_type(pstate,
581  orig_expr, type_id,
582  attrtype, attrtypmod,
585  -1);
586  if (expr == NULL)
587  ereport(ERROR,
588  (errcode(ERRCODE_DATATYPE_MISMATCH),
589  errmsg("column \"%s\" is of type %s"
590  " but expression is of type %s",
591  colname,
592  format_type_be(attrtype),
593  format_type_be(type_id)),
594  errhint("You will need to rewrite or cast the expression."),
595  parser_errposition(pstate, exprLocation(orig_expr))));
596  }
597 
598  pstate->p_expr_kind = sv_expr_kind;
599 
600  return expr;
601 }
602 
603 
604 /*
605  * updateTargetListEntry()
606  * This is used in UPDATE statements (and ON CONFLICT DO UPDATE)
607  * only. It prepares an UPDATE TargetEntry for assignment to a
608  * column of the target table. This includes coercing the given
609  * value to the target column's type (if necessary), and dealing with
610  * any subfield names or subscripts attached to the target column
611  * itself.
612  *
613  * pstate parse state
614  * tle target list entry to be modified
615  * colname target column name (ie, name of attribute to be assigned to)
616  * attrno target attribute number
617  * indirection subscripts/field names for target column, if any
618  * location error cursor position (should point at column name), or -1
619  */
620 void
622  TargetEntry *tle,
623  char *colname,
624  int attrno,
625  List *indirection,
626  int location)
627 {
628  /* Fix up expression as needed */
629  tle->expr = transformAssignedExpr(pstate,
630  tle->expr,
632  colname,
633  attrno,
634  indirection,
635  location);
636 
637  /*
638  * Set the resno to identify the target column --- the rewriter and
639  * planner depend on this. We also set the resname to identify the target
640  * column, but this is only for debugging purposes; it should not be
641  * relied on. (In particular, it might be out of date in a stored rule.)
642  */
643  tle->resno = (AttrNumber) attrno;
644  tle->resname = colname;
645 }
646 
647 
648 /*
649  * Process indirection (field selection or subscripting) of the target
650  * column in INSERT/UPDATE. This routine recurses for multiple levels
651  * of indirection --- but note that several adjacent A_Indices nodes in
652  * the indirection list are treated as a single multidimensional subscript
653  * operation.
654  *
655  * In the initial call, basenode is a Var for the target column in UPDATE,
656  * or a null Const of the target's type in INSERT. In recursive calls,
657  * basenode is NULL, indicating that a substitute node should be consed up if
658  * needed.
659  *
660  * targetName is the name of the field or subfield we're assigning to, and
661  * targetIsSubscripting is true if we're subscripting it. These are just for
662  * error reporting.
663  *
664  * targetTypeId, targetTypMod, targetCollation indicate the datatype and
665  * collation of the object to be assigned to (initially the target column,
666  * later some subobject).
667  *
668  * indirection is the list of indirection nodes, and indirection_cell is the
669  * start of the sublist remaining to process. When it's NULL, we're done
670  * recursing and can just coerce and return the RHS.
671  *
672  * rhs is the already-transformed value to be assigned; note it has not been
673  * coerced to any particular type.
674  *
675  * location is the cursor error position for any errors. (Note: this points
676  * to the head of the target clause, eg "foo" in "foo.bar[baz]". Later we
677  * might want to decorate indirection cells with their own location info,
678  * in which case the location argument could probably be dropped.)
679  */
680 static Node *
682  Node *basenode,
683  const char *targetName,
684  bool targetIsSubscripting,
685  Oid targetTypeId,
686  int32 targetTypMod,
687  Oid targetCollation,
688  List *indirection,
689  ListCell *indirection_cell,
690  Node *rhs,
691  int location)
692 {
693  Node *result;
694  List *subscripts = NIL;
695  bool isSlice = false;
696  ListCell *i;
697 
698  if (indirection_cell && !basenode)
699  {
700  /*
701  * Set up a substitution. We abuse CaseTestExpr for this. It's safe
702  * to do so because the only nodes that will be above the CaseTestExpr
703  * in the finished expression will be FieldStore and SubscriptingRef
704  * nodes. (There could be other stuff in the tree, but it will be
705  * within other child fields of those node types.)
706  */
708 
709  ctest->typeId = targetTypeId;
710  ctest->typeMod = targetTypMod;
711  ctest->collation = targetCollation;
712  basenode = (Node *) ctest;
713  }
714 
715  /*
716  * We have to split any field-selection operations apart from
717  * subscripting. Adjacent A_Indices nodes have to be treated as a single
718  * multidimensional subscript operation.
719  */
720  for_each_cell(i, indirection, indirection_cell)
721  {
722  Node *n = lfirst(i);
723 
724  if (IsA(n, A_Indices))
725  {
726  subscripts = lappend(subscripts, n);
727  if (((A_Indices *) n)->is_slice)
728  isSlice = true;
729  }
730  else if (IsA(n, A_Star))
731  {
732  ereport(ERROR,
733  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
734  errmsg("row expansion via \"*\" is not supported here"),
735  parser_errposition(pstate, location)));
736  }
737  else
738  {
739  FieldStore *fstore;
740  Oid baseTypeId;
741  int32 baseTypeMod;
742  Oid typrelid;
744  Oid fieldTypeId;
745  int32 fieldTypMod;
746  Oid fieldCollation;
747 
748  Assert(IsA(n, String));
749 
750  /* process subscripts before this field selection */
751  if (subscripts)
752  {
753  /* recurse, and then return because we're done */
754  return transformAssignmentSubscripts(pstate,
755  basenode,
756  targetName,
757  targetTypeId,
758  targetTypMod,
759  targetCollation,
760  subscripts,
761  isSlice,
762  indirection,
763  i,
764  rhs,
765  location);
766  }
767 
768  /* No subscripts, so can process field selection here */
769 
770  /*
771  * Look up the composite type, accounting for possibility that
772  * what we are given is a domain over composite.
773  */
774  baseTypeMod = targetTypMod;
775  baseTypeId = getBaseTypeAndTypmod(targetTypeId, &baseTypeMod);
776 
777  typrelid = typeidTypeRelid(baseTypeId);
778  if (!typrelid)
779  ereport(ERROR,
780  (errcode(ERRCODE_DATATYPE_MISMATCH),
781  errmsg("cannot assign to field \"%s\" of column \"%s\" because its type %s is not a composite type",
782  strVal(n), targetName,
783  format_type_be(targetTypeId)),
784  parser_errposition(pstate, location)));
785 
786  attnum = get_attnum(typrelid, strVal(n));
787  if (attnum == InvalidAttrNumber)
788  ereport(ERROR,
789  (errcode(ERRCODE_UNDEFINED_COLUMN),
790  errmsg("cannot assign to field \"%s\" of column \"%s\" because there is no such column in data type %s",
791  strVal(n), targetName,
792  format_type_be(targetTypeId)),
793  parser_errposition(pstate, location)));
794  if (attnum < 0)
795  ereport(ERROR,
796  (errcode(ERRCODE_UNDEFINED_COLUMN),
797  errmsg("cannot assign to system column \"%s\"",
798  strVal(n)),
799  parser_errposition(pstate, location)));
800 
801  get_atttypetypmodcoll(typrelid, attnum,
802  &fieldTypeId, &fieldTypMod, &fieldCollation);
803 
804  /* recurse to create appropriate RHS for field assign */
805  rhs = transformAssignmentIndirection(pstate,
806  NULL,
807  strVal(n),
808  false,
809  fieldTypeId,
810  fieldTypMod,
811  fieldCollation,
812  indirection,
813  lnext(indirection, i),
814  rhs,
815  location);
816 
817  /* and build a FieldStore node */
818  fstore = makeNode(FieldStore);
819  fstore->arg = (Expr *) basenode;
820  fstore->newvals = list_make1(rhs);
821  fstore->fieldnums = list_make1_int(attnum);
822  fstore->resulttype = baseTypeId;
823 
824  /* If target is a domain, apply constraints */
825  if (baseTypeId != targetTypeId)
826  return coerce_to_domain((Node *) fstore,
827  baseTypeId, baseTypeMod,
828  targetTypeId,
831  location,
832  false);
833 
834  return (Node *) fstore;
835  }
836  }
837 
838  /* process trailing subscripts, if any */
839  if (subscripts)
840  {
841  /* recurse, and then return because we're done */
842  return transformAssignmentSubscripts(pstate,
843  basenode,
844  targetName,
845  targetTypeId,
846  targetTypMod,
847  targetCollation,
848  subscripts,
849  isSlice,
850  indirection,
851  NULL,
852  rhs,
853  location);
854  }
855 
856  /* base case: just coerce RHS to match target type ID */
857 
858  result = coerce_to_target_type(pstate,
859  rhs, exprType(rhs),
860  targetTypeId, targetTypMod,
863  -1);
864  if (result == NULL)
865  {
866  if (targetIsSubscripting)
867  ereport(ERROR,
868  (errcode(ERRCODE_DATATYPE_MISMATCH),
869  errmsg("array assignment to \"%s\" requires type %s"
870  " but expression is of type %s",
871  targetName,
872  format_type_be(targetTypeId),
873  format_type_be(exprType(rhs))),
874  errhint("You will need to rewrite or cast the expression."),
875  parser_errposition(pstate, location)));
876  else
877  ereport(ERROR,
878  (errcode(ERRCODE_DATATYPE_MISMATCH),
879  errmsg("subfield \"%s\" is of type %s"
880  " but expression is of type %s",
881  targetName,
882  format_type_be(targetTypeId),
883  format_type_be(exprType(rhs))),
884  errhint("You will need to rewrite or cast the expression."),
885  parser_errposition(pstate, location)));
886  }
887 
888  return result;
889 }
890 
891 /*
892  * helper for transformAssignmentIndirection: process container assignment
893  */
894 static Node *
896  Node *basenode,
897  const char *targetName,
898  Oid targetTypeId,
899  int32 targetTypMod,
900  Oid targetCollation,
901  List *subscripts,
902  bool isSlice,
903  List *indirection,
904  ListCell *next_indirection,
905  Node *rhs,
906  int location)
907 {
908  Node *result;
909  Oid containerType;
910  int32 containerTypMod;
911  Oid elementTypeId;
912  Oid typeNeeded;
913  Oid collationNeeded;
914 
915  Assert(subscripts != NIL);
916 
917  /* Identify the actual array type and element type involved */
918  containerType = targetTypeId;
919  containerTypMod = targetTypMod;
920  elementTypeId = transformContainerType(&containerType, &containerTypMod);
921 
922  /* Identify type that RHS must provide */
923  typeNeeded = isSlice ? containerType : elementTypeId;
924 
925  /*
926  * container normally has same collation as elements, but there's an
927  * exception: we might be subscripting a domain over a container type. In
928  * that case use collation of the base type.
929  */
930  if (containerType == targetTypeId)
931  collationNeeded = targetCollation;
932  else
933  collationNeeded = get_typcollation(containerType);
934 
935  /* recurse to create appropriate RHS for container assign */
936  rhs = transformAssignmentIndirection(pstate,
937  NULL,
938  targetName,
939  true,
940  typeNeeded,
941  containerTypMod,
942  collationNeeded,
943  indirection,
944  next_indirection,
945  rhs,
946  location);
947 
948  /* process subscripts */
949  result = (Node *) transformContainerSubscripts(pstate,
950  basenode,
951  containerType,
952  elementTypeId,
953  containerTypMod,
954  subscripts,
955  rhs);
956 
957  /* If target was a domain over container, need to coerce up to the domain */
958  if (containerType != targetTypeId)
959  {
960  Oid resulttype = exprType(result);
961 
962  result = coerce_to_target_type(pstate,
963  result, resulttype,
964  targetTypeId, targetTypMod,
967  -1);
968  /* can fail if we had int2vector/oidvector, but not for true domains */
969  if (result == NULL)
970  ereport(ERROR,
971  (errcode(ERRCODE_CANNOT_COERCE),
972  errmsg("cannot cast type %s to %s",
973  format_type_be(resulttype),
974  format_type_be(targetTypeId)),
975  parser_errposition(pstate, location)));
976  }
977 
978  return result;
979 }
980 
981 
982 /*
983  * checkInsertTargets -
984  * generate a list of INSERT column targets if not supplied, or
985  * test supplied column names to make sure they are in target table.
986  * Also return an integer list of the columns' attribute numbers.
987  */
988 List *
989 checkInsertTargets(ParseState *pstate, List *cols, List **attrnos)
990 {
991  *attrnos = NIL;
992 
993  if (cols == NIL)
994  {
995  /*
996  * Generate default column list for INSERT.
997  */
998  int numcol = RelationGetNumberOfAttributes(pstate->p_target_relation);
999 
1000  int i;
1001 
1002  for (i = 0; i < numcol; i++)
1003  {
1004  ResTarget *col;
1005  Form_pg_attribute attr;
1006 
1007  attr = TupleDescAttr(pstate->p_target_relation->rd_att, i);
1008 
1009  if (attr->attisdropped)
1010  continue;
1011 
1012  col = makeNode(ResTarget);
1013  col->name = pstrdup(NameStr(attr->attname));
1014  col->indirection = NIL;
1015  col->val = NULL;
1016  col->location = -1;
1017  cols = lappend(cols, col);
1018  *attrnos = lappend_int(*attrnos, i + 1);
1019  }
1020  }
1021  else
1022  {
1023  /*
1024  * Do initial validation of user-supplied INSERT column list.
1025  */
1026  Bitmapset *wholecols = NULL;
1027  Bitmapset *partialcols = NULL;
1028  ListCell *tl;
1029 
1030  foreach(tl, cols)
1031  {
1032  ResTarget *col = (ResTarget *) lfirst(tl);
1033  char *name = col->name;
1034  int attrno;
1035 
1036  /* Lookup column name, ereport on failure */
1037  attrno = attnameAttNum(pstate->p_target_relation, name, false);
1038  if (attrno == InvalidAttrNumber)
1039  ereport(ERROR,
1040  (errcode(ERRCODE_UNDEFINED_COLUMN),
1041  errmsg("column \"%s\" of relation \"%s\" does not exist",
1042  name,
1044  parser_errposition(pstate, col->location)));
1045 
1046  /*
1047  * Check for duplicates, but only of whole columns --- we allow
1048  * INSERT INTO foo (col.subcol1, col.subcol2)
1049  */
1050  if (col->indirection == NIL)
1051  {
1052  /* whole column; must not have any other assignment */
1053  if (bms_is_member(attrno, wholecols) ||
1054  bms_is_member(attrno, partialcols))
1055  ereport(ERROR,
1056  (errcode(ERRCODE_DUPLICATE_COLUMN),
1057  errmsg("column \"%s\" specified more than once",
1058  name),
1059  parser_errposition(pstate, col->location)));
1060  wholecols = bms_add_member(wholecols, attrno);
1061  }
1062  else
1063  {
1064  /* partial column; must not have any whole assignment */
1065  if (bms_is_member(attrno, wholecols))
1066  ereport(ERROR,
1067  (errcode(ERRCODE_DUPLICATE_COLUMN),
1068  errmsg("column \"%s\" specified more than once",
1069  name),
1070  parser_errposition(pstate, col->location)));
1071  partialcols = bms_add_member(partialcols, attrno);
1072  }
1073 
1074  *attrnos = lappend_int(*attrnos, attrno);
1075  }
1076  }
1077 
1078  return cols;
1079 }
1080 
1081 /*
1082  * ExpandColumnRefStar()
1083  * Transforms foo.* into a list of expressions or targetlist entries.
1084  *
1085  * This handles the case where '*' appears as the last or only item in a
1086  * ColumnRef. The code is shared between the case of foo.* at the top level
1087  * in a SELECT target list (where we want TargetEntry nodes in the result)
1088  * and foo.* in a ROW() or VALUES() construct (where we want just bare
1089  * expressions).
1090  *
1091  * The referenced columns are marked as requiring SELECT access.
1092  */
1093 static List *
1095  bool make_target_entry)
1096 {
1097  List *fields = cref->fields;
1098  int numnames = list_length(fields);
1099 
1100  if (numnames == 1)
1101  {
1102  /*
1103  * Target item is a bare '*', expand all tables
1104  *
1105  * (e.g., SELECT * FROM emp, dept)
1106  *
1107  * Since the grammar only accepts bare '*' at top level of SELECT, we
1108  * need not handle the make_target_entry==false case here.
1109  */
1110  Assert(make_target_entry);
1111  return ExpandAllTables(pstate, cref->location);
1112  }
1113  else
1114  {
1115  /*
1116  * Target item is relation.*, expand that table
1117  *
1118  * (e.g., SELECT emp.*, dname FROM emp, dept)
1119  *
1120  * Note: this code is a lot like transformColumnRef; it's tempting to
1121  * call that instead and then replace the resulting whole-row Var with
1122  * a list of Vars. However, that would leave us with the RTE's
1123  * selectedCols bitmap showing the whole row as needing select
1124  * permission, as well as the individual columns. That would be
1125  * incorrect (since columns added later shouldn't need select
1126  * permissions). We could try to remove the whole-row permission bit
1127  * after the fact, but duplicating code is less messy.
1128  */
1129  char *nspname = NULL;
1130  char *relname = NULL;
1131  RangeTblEntry *rte = NULL;
1132  int levels_up;
1133  enum
1134  {
1135  CRSERR_NO_RTE,
1136  CRSERR_WRONG_DB,
1137  CRSERR_TOO_MANY
1138  } crserr = CRSERR_NO_RTE;
1139 
1140  /*
1141  * Give the PreParseColumnRefHook, if any, first shot. If it returns
1142  * non-null then we should use that expression.
1143  */
1144  if (pstate->p_pre_columnref_hook != NULL)
1145  {
1146  Node *node;
1147 
1148  node = pstate->p_pre_columnref_hook(pstate, cref);
1149  if (node != NULL)
1150  return ExpandRowReference(pstate, node, make_target_entry);
1151  }
1152 
1153  switch (numnames)
1154  {
1155  case 2:
1156  relname = strVal(linitial(fields));
1157  rte = refnameRangeTblEntry(pstate, nspname, relname,
1158  cref->location,
1159  &levels_up);
1160  break;
1161  case 3:
1162  nspname = strVal(linitial(fields));
1163  relname = strVal(lsecond(fields));
1164  rte = refnameRangeTblEntry(pstate, nspname, relname,
1165  cref->location,
1166  &levels_up);
1167  break;
1168  case 4:
1169  {
1170  char *catname = strVal(linitial(fields));
1171 
1172  /*
1173  * We check the catalog name and then ignore it.
1174  */
1175  if (strcmp(catname, get_database_name(MyDatabaseId)) != 0)
1176  {
1177  crserr = CRSERR_WRONG_DB;
1178  break;
1179  }
1180  nspname = strVal(lsecond(fields));
1181  relname = strVal(lthird(fields));
1182  rte = refnameRangeTblEntry(pstate, nspname, relname,
1183  cref->location,
1184  &levels_up);
1185  break;
1186  }
1187  default:
1188  crserr = CRSERR_TOO_MANY;
1189  break;
1190  }
1191 
1192  /*
1193  * Now give the PostParseColumnRefHook, if any, a chance. We cheat a
1194  * bit by passing the RangeTblEntry, not a Var, as the planned
1195  * translation. (A single Var wouldn't be strictly correct anyway.
1196  * This convention allows hooks that really care to know what is
1197  * happening.)
1198  */
1199  if (pstate->p_post_columnref_hook != NULL)
1200  {
1201  Node *node;
1202 
1203  node = pstate->p_post_columnref_hook(pstate, cref,
1204  (Node *) rte);
1205  if (node != NULL)
1206  {
1207  if (rte != NULL)
1208  ereport(ERROR,
1209  (errcode(ERRCODE_AMBIGUOUS_COLUMN),
1210  errmsg("column reference \"%s\" is ambiguous",
1211  NameListToString(cref->fields)),
1212  parser_errposition(pstate, cref->location)));
1213  return ExpandRowReference(pstate, node, make_target_entry);
1214  }
1215  }
1216 
1217  /*
1218  * Throw error if no translation found.
1219  */
1220  if (rte == NULL)
1221  {
1222  switch (crserr)
1223  {
1224  case CRSERR_NO_RTE:
1225  errorMissingRTE(pstate, makeRangeVar(nspname, relname,
1226  cref->location));
1227  break;
1228  case CRSERR_WRONG_DB:
1229  ereport(ERROR,
1230  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1231  errmsg("cross-database references are not implemented: %s",
1232  NameListToString(cref->fields)),
1233  parser_errposition(pstate, cref->location)));
1234  break;
1235  case CRSERR_TOO_MANY:
1236  ereport(ERROR,
1237  (errcode(ERRCODE_SYNTAX_ERROR),
1238  errmsg("improper qualified name (too many dotted names): %s",
1239  NameListToString(cref->fields)),
1240  parser_errposition(pstate, cref->location)));
1241  break;
1242  }
1243  }
1244 
1245  /*
1246  * OK, expand the RTE into fields.
1247  */
1248  return ExpandSingleTable(pstate, rte, cref->location, make_target_entry);
1249  }
1250 }
1251 
1252 /*
1253  * ExpandAllTables()
1254  * Transforms '*' (in the target list) into a list of targetlist entries.
1255  *
1256  * tlist entries are generated for each relation visible for unqualified
1257  * column name access. We do not consider qualified-name-only entries because
1258  * that would include input tables of aliasless JOINs, NEW/OLD pseudo-entries,
1259  * etc.
1260  *
1261  * The referenced relations/columns are marked as requiring SELECT access.
1262  */
1263 static List *
1264 ExpandAllTables(ParseState *pstate, int location)
1265 {
1266  List *target = NIL;
1267  bool found_table = false;
1268  ListCell *l;
1269 
1270  foreach(l, pstate->p_namespace)
1271  {
1272  ParseNamespaceItem *nsitem = (ParseNamespaceItem *) lfirst(l);
1273  RangeTblEntry *rte = nsitem->p_rte;
1274 
1275  /* Ignore table-only items */
1276  if (!nsitem->p_cols_visible)
1277  continue;
1278  /* Should not have any lateral-only items when parsing targetlist */
1279  Assert(!nsitem->p_lateral_only);
1280  /* Remember we found a p_cols_visible item */
1281  found_table = true;
1282 
1283  target = list_concat(target,
1284  expandRelAttrs(pstate,
1285  rte,
1286  RTERangeTablePosn(pstate, rte,
1287  NULL),
1288  0,
1289  location));
1290  }
1291 
1292  /*
1293  * Check for "SELECT *;". We do it this way, rather than checking for
1294  * target == NIL, because we want to allow SELECT * FROM a zero_column
1295  * table.
1296  */
1297  if (!found_table)
1298  ereport(ERROR,
1299  (errcode(ERRCODE_SYNTAX_ERROR),
1300  errmsg("SELECT * with no tables specified is not valid"),
1301  parser_errposition(pstate, location)));
1302 
1303  return target;
1304 }
1305 
1306 /*
1307  * ExpandIndirectionStar()
1308  * Transforms foo.* into a list of expressions or targetlist entries.
1309  *
1310  * This handles the case where '*' appears as the last item in A_Indirection.
1311  * The code is shared between the case of foo.* at the top level in a SELECT
1312  * target list (where we want TargetEntry nodes in the result) and foo.* in
1313  * a ROW() or VALUES() construct (where we want just bare expressions).
1314  * For robustness, we use a separate "make_target_entry" flag to control
1315  * this rather than relying on exprKind.
1316  */
1317 static List *
1319  bool make_target_entry, ParseExprKind exprKind)
1320 {
1321  Node *expr;
1322 
1323  /* Strip off the '*' to create a reference to the rowtype object */
1324  ind = copyObject(ind);
1326  list_length(ind->indirection) - 1);
1327 
1328  /* And transform that */
1329  expr = transformExpr(pstate, (Node *) ind, exprKind);
1330 
1331  /* Expand the rowtype expression into individual fields */
1332  return ExpandRowReference(pstate, expr, make_target_entry);
1333 }
1334 
1335 /*
1336  * ExpandSingleTable()
1337  * Transforms foo.* into a list of expressions or targetlist entries.
1338  *
1339  * This handles the case where foo has been determined to be a simple
1340  * reference to an RTE, so we can just generate Vars for the expressions.
1341  *
1342  * The referenced columns are marked as requiring SELECT access.
1343  */
1344 static List *
1346  int location, bool make_target_entry)
1347 {
1348  int sublevels_up;
1349  int rtindex;
1350 
1351  rtindex = RTERangeTablePosn(pstate, rte, &sublevels_up);
1352 
1353  if (make_target_entry)
1354  {
1355  /* expandRelAttrs handles permissions marking */
1356  return expandRelAttrs(pstate, rte, rtindex, sublevels_up,
1357  location);
1358  }
1359  else
1360  {
1361  List *vars;
1362  ListCell *l;
1363 
1364  expandRTE(rte, rtindex, sublevels_up, location, false,
1365  NULL, &vars);
1366 
1367  /*
1368  * Require read access to the table. This is normally redundant with
1369  * the markVarForSelectPriv calls below, but not if the table has zero
1370  * columns.
1371  */
1372  rte->requiredPerms |= ACL_SELECT;
1373 
1374  /* Require read access to each column */
1375  foreach(l, vars)
1376  {
1377  Var *var = (Var *) lfirst(l);
1378 
1379  markVarForSelectPriv(pstate, var, rte);
1380  }
1381 
1382  return vars;
1383  }
1384 }
1385 
1386 /*
1387  * ExpandRowReference()
1388  * Transforms foo.* into a list of expressions or targetlist entries.
1389  *
1390  * This handles the case where foo is an arbitrary expression of composite
1391  * type.
1392  */
1393 static List *
1395  bool make_target_entry)
1396 {
1397  List *result = NIL;
1398  TupleDesc tupleDesc;
1399  int numAttrs;
1400  int i;
1401 
1402  /*
1403  * If the rowtype expression is a whole-row Var, we can expand the fields
1404  * as simple Vars. Note: if the RTE is a relation, this case leaves us
1405  * with the RTE's selectedCols bitmap showing the whole row as needing
1406  * select permission, as well as the individual columns. However, we can
1407  * only get here for weird notations like (table.*).*, so it's not worth
1408  * trying to clean up --- arguably, the permissions marking is correct
1409  * anyway for such cases.
1410  */
1411  if (IsA(expr, Var) &&
1412  ((Var *) expr)->varattno == InvalidAttrNumber)
1413  {
1414  Var *var = (Var *) expr;
1415  RangeTblEntry *rte;
1416 
1417  rte = GetRTEByRangeTablePosn(pstate, var->varno, var->varlevelsup);
1418  return ExpandSingleTable(pstate, rte, var->location, make_target_entry);
1419  }
1420 
1421  /*
1422  * Otherwise we have to do it the hard way. Our current implementation is
1423  * to generate multiple copies of the expression and do FieldSelects.
1424  * (This can be pretty inefficient if the expression involves nontrivial
1425  * computation :-(.)
1426  *
1427  * Verify it's a composite type, and get the tupdesc.
1428  * get_expr_result_tupdesc() handles this conveniently.
1429  *
1430  * If it's a Var of type RECORD, we have to work even harder: we have to
1431  * find what the Var refers to, and pass that to get_expr_result_tupdesc.
1432  * That task is handled by expandRecordVariable().
1433  */
1434  if (IsA(expr, Var) &&
1435  ((Var *) expr)->vartype == RECORDOID)
1436  tupleDesc = expandRecordVariable(pstate, (Var *) expr, 0);
1437  else
1438  tupleDesc = get_expr_result_tupdesc(expr, false);
1439  Assert(tupleDesc);
1440 
1441  /* Generate a list of references to the individual fields */
1442  numAttrs = tupleDesc->natts;
1443  for (i = 0; i < numAttrs; i++)
1444  {
1445  Form_pg_attribute att = TupleDescAttr(tupleDesc, i);
1446  FieldSelect *fselect;
1447 
1448  if (att->attisdropped)
1449  continue;
1450 
1451  fselect = makeNode(FieldSelect);
1452  fselect->arg = (Expr *) copyObject(expr);
1453  fselect->fieldnum = i + 1;
1454  fselect->resulttype = att->atttypid;
1455  fselect->resulttypmod = att->atttypmod;
1456  /* save attribute's collation for parse_collate.c */
1457  fselect->resultcollid = att->attcollation;
1458 
1459  if (make_target_entry)
1460  {
1461  /* add TargetEntry decoration */
1462  TargetEntry *te;
1463 
1464  te = makeTargetEntry((Expr *) fselect,
1465  (AttrNumber) pstate->p_next_resno++,
1466  pstrdup(NameStr(att->attname)),
1467  false);
1468  result = lappend(result, te);
1469  }
1470  else
1471  result = lappend(result, fselect);
1472  }
1473 
1474  return result;
1475 }
1476 
1477 /*
1478  * expandRecordVariable
1479  * Get the tuple descriptor for a Var of type RECORD, if possible.
1480  *
1481  * Since no actual table or view column is allowed to have type RECORD, such
1482  * a Var must refer to a JOIN or FUNCTION RTE or to a subquery output. We
1483  * drill down to find the ultimate defining expression and attempt to infer
1484  * the tupdesc from it. We ereport if we can't determine the tupdesc.
1485  *
1486  * levelsup is an extra offset to interpret the Var's varlevelsup correctly.
1487  */
1488 TupleDesc
1489 expandRecordVariable(ParseState *pstate, Var *var, int levelsup)
1490 {
1491  TupleDesc tupleDesc;
1492  int netlevelsup;
1493  RangeTblEntry *rte;
1495  Node *expr;
1496 
1497  /* Check my caller didn't mess up */
1498  Assert(IsA(var, Var));
1499  Assert(var->vartype == RECORDOID);
1500 
1501  netlevelsup = var->varlevelsup + levelsup;
1502  rte = GetRTEByRangeTablePosn(pstate, var->varno, netlevelsup);
1503  attnum = var->varattno;
1504 
1505  if (attnum == InvalidAttrNumber)
1506  {
1507  /* Whole-row reference to an RTE, so expand the known fields */
1508  List *names,
1509  *vars;
1510  ListCell *lname,
1511  *lvar;
1512  int i;
1513 
1514  expandRTE(rte, var->varno, 0, var->location, false,
1515  &names, &vars);
1516 
1517  tupleDesc = CreateTemplateTupleDesc(list_length(vars));
1518  i = 1;
1519  forboth(lname, names, lvar, vars)
1520  {
1521  char *label = strVal(lfirst(lname));
1522  Node *varnode = (Node *) lfirst(lvar);
1523 
1524  TupleDescInitEntry(tupleDesc, i,
1525  label,
1526  exprType(varnode),
1527  exprTypmod(varnode),
1528  0);
1529  TupleDescInitEntryCollation(tupleDesc, i,
1530  exprCollation(varnode));
1531  i++;
1532  }
1533  Assert(lname == NULL && lvar == NULL); /* lists same length? */
1534 
1535  return tupleDesc;
1536  }
1537 
1538  expr = (Node *) var; /* default if we can't drill down */
1539 
1540  switch (rte->rtekind)
1541  {
1542  case RTE_RELATION:
1543  case RTE_VALUES:
1544  case RTE_NAMEDTUPLESTORE:
1545  case RTE_RESULT:
1546 
1547  /*
1548  * This case should not occur: a column of a table, values list,
1549  * or ENR shouldn't have type RECORD. Fall through and fail (most
1550  * likely) at the bottom.
1551  */
1552  break;
1553  case RTE_SUBQUERY:
1554  {
1555  /* Subselect-in-FROM: examine sub-select's output expr */
1557  attnum);
1558 
1559  if (ste == NULL || ste->resjunk)
1560  elog(ERROR, "subquery %s does not have attribute %d",
1561  rte->eref->aliasname, attnum);
1562  expr = (Node *) ste->expr;
1563  if (IsA(expr, Var))
1564  {
1565  /*
1566  * Recurse into the sub-select to see what its Var refers
1567  * to. We have to build an additional level of ParseState
1568  * to keep in step with varlevelsup in the subselect.
1569  */
1570  ParseState mypstate;
1571 
1572  MemSet(&mypstate, 0, sizeof(mypstate));
1573  mypstate.parentParseState = pstate;
1574  mypstate.p_rtable = rte->subquery->rtable;
1575  /* don't bother filling the rest of the fake pstate */
1576 
1577  return expandRecordVariable(&mypstate, (Var *) expr, 0);
1578  }
1579  /* else fall through to inspect the expression */
1580  }
1581  break;
1582  case RTE_JOIN:
1583  /* Join RTE --- recursively inspect the alias variable */
1584  Assert(attnum > 0 && attnum <= list_length(rte->joinaliasvars));
1585  expr = (Node *) list_nth(rte->joinaliasvars, attnum - 1);
1586  Assert(expr != NULL);
1587  /* We intentionally don't strip implicit coercions here */
1588  if (IsA(expr, Var))
1589  return expandRecordVariable(pstate, (Var *) expr, netlevelsup);
1590  /* else fall through to inspect the expression */
1591  break;
1592  case RTE_FUNCTION:
1593 
1594  /*
1595  * We couldn't get here unless a function is declared with one of
1596  * its result columns as RECORD, which is not allowed.
1597  */
1598  break;
1599  case RTE_TABLEFUNC:
1600 
1601  /*
1602  * Table function cannot have columns with RECORD type.
1603  */
1604  break;
1605  case RTE_CTE:
1606  /* CTE reference: examine subquery's output expr */
1607  if (!rte->self_reference)
1608  {
1609  CommonTableExpr *cte = GetCTEForRTE(pstate, rte, netlevelsup);
1610  TargetEntry *ste;
1611 
1612  ste = get_tle_by_resno(GetCTETargetList(cte), attnum);
1613  if (ste == NULL || ste->resjunk)
1614  elog(ERROR, "subquery %s does not have attribute %d",
1615  rte->eref->aliasname, attnum);
1616  expr = (Node *) ste->expr;
1617  if (IsA(expr, Var))
1618  {
1619  /*
1620  * Recurse into the CTE to see what its Var refers to. We
1621  * have to build an additional level of ParseState to keep
1622  * in step with varlevelsup in the CTE; furthermore it
1623  * could be an outer CTE.
1624  */
1625  ParseState mypstate;
1626  Index levelsup;
1627 
1628  MemSet(&mypstate, 0, sizeof(mypstate));
1629  /* this loop must work, since GetCTEForRTE did */
1630  for (levelsup = 0;
1631  levelsup < rte->ctelevelsup + netlevelsup;
1632  levelsup++)
1633  pstate = pstate->parentParseState;
1634  mypstate.parentParseState = pstate;
1635  mypstate.p_rtable = ((Query *) cte->ctequery)->rtable;
1636  /* don't bother filling the rest of the fake pstate */
1637 
1638  return expandRecordVariable(&mypstate, (Var *) expr, 0);
1639  }
1640  /* else fall through to inspect the expression */
1641  }
1642  break;
1643  }
1644 
1645  /*
1646  * We now have an expression we can't expand any more, so see if
1647  * get_expr_result_tupdesc() can do anything with it.
1648  */
1649  return get_expr_result_tupdesc(expr, false);
1650 }
1651 
1652 
1653 /*
1654  * FigureColname -
1655  * if the name of the resulting column is not specified in the target
1656  * list, we have to guess a suitable name. The SQL spec provides some
1657  * guidance, but not much...
1658  *
1659  * Note that the argument is the *untransformed* parse tree for the target
1660  * item. This is a shade easier to work with than the transformed tree.
1661  */
1662 char *
1664 {
1665  char *name = NULL;
1666 
1667  (void) FigureColnameInternal(node, &name);
1668  if (name != NULL)
1669  return name;
1670  /* default result if we can't guess anything */
1671  return "?column?";
1672 }
1673 
1674 /*
1675  * FigureIndexColname -
1676  * choose the name for an expression column in an index
1677  *
1678  * This is actually just like FigureColname, except we return NULL if
1679  * we can't pick a good name.
1680  */
1681 char *
1683 {
1684  char *name = NULL;
1685 
1686  (void) FigureColnameInternal(node, &name);
1687  return name;
1688 }
1689 
1690 /*
1691  * FigureColnameInternal -
1692  * internal workhorse for FigureColname
1693  *
1694  * Return value indicates strength of confidence in result:
1695  * 0 - no information
1696  * 1 - second-best name choice
1697  * 2 - good name choice
1698  * The return value is actually only used internally.
1699  * If the result isn't zero, *name is set to the chosen name.
1700  */
1701 static int
1703 {
1704  int strength = 0;
1705 
1706  if (node == NULL)
1707  return strength;
1708 
1709  switch (nodeTag(node))
1710  {
1711  case T_ColumnRef:
1712  {
1713  char *fname = NULL;
1714  ListCell *l;
1715 
1716  /* find last field name, if any, ignoring "*" */
1717  foreach(l, ((ColumnRef *) node)->fields)
1718  {
1719  Node *i = lfirst(l);
1720 
1721  if (IsA(i, String))
1722  fname = strVal(i);
1723  }
1724  if (fname)
1725  {
1726  *name = fname;
1727  return 2;
1728  }
1729  }
1730  break;
1731  case T_A_Indirection:
1732  {
1733  A_Indirection *ind = (A_Indirection *) node;
1734  char *fname = NULL;
1735  ListCell *l;
1736 
1737  /* find last field name, if any, ignoring "*" and subscripts */
1738  foreach(l, ind->indirection)
1739  {
1740  Node *i = lfirst(l);
1741 
1742  if (IsA(i, String))
1743  fname = strVal(i);
1744  }
1745  if (fname)
1746  {
1747  *name = fname;
1748  return 2;
1749  }
1750  return FigureColnameInternal(ind->arg, name);
1751  }
1752  break;
1753  case T_FuncCall:
1754  *name = strVal(llast(((FuncCall *) node)->funcname));
1755  return 2;
1756  case T_A_Expr:
1757  if (((A_Expr *) node)->kind == AEXPR_NULLIF)
1758  {
1759  /* make nullif() act like a regular function */
1760  *name = "nullif";
1761  return 2;
1762  }
1763  if (((A_Expr *) node)->kind == AEXPR_PAREN)
1764  {
1765  /* look through dummy parenthesis node */
1766  return FigureColnameInternal(((A_Expr *) node)->lexpr, name);
1767  }
1768  break;
1769  case T_TypeCast:
1770  strength = FigureColnameInternal(((TypeCast *) node)->arg,
1771  name);
1772  if (strength <= 1)
1773  {
1774  if (((TypeCast *) node)->typeName != NULL)
1775  {
1776  *name = strVal(llast(((TypeCast *) node)->typeName->names));
1777  return 1;
1778  }
1779  }
1780  break;
1781  case T_CollateClause:
1782  return FigureColnameInternal(((CollateClause *) node)->arg, name);
1783  case T_GroupingFunc:
1784  /* make GROUPING() act like a regular function */
1785  *name = "grouping";
1786  return 2;
1787  case T_SubLink:
1788  switch (((SubLink *) node)->subLinkType)
1789  {
1790  case EXISTS_SUBLINK:
1791  *name = "exists";
1792  return 2;
1793  case ARRAY_SUBLINK:
1794  *name = "array";
1795  return 2;
1796  case EXPR_SUBLINK:
1797  {
1798  /* Get column name of the subquery's single target */
1799  SubLink *sublink = (SubLink *) node;
1800  Query *query = (Query *) sublink->subselect;
1801 
1802  /*
1803  * The subquery has probably already been transformed,
1804  * but let's be careful and check that. (The reason
1805  * we can see a transformed subquery here is that
1806  * transformSubLink is lazy and modifies the SubLink
1807  * node in-place.)
1808  */
1809  if (IsA(query, Query))
1810  {
1811  TargetEntry *te = (TargetEntry *) linitial(query->targetList);
1812 
1813  if (te->resname)
1814  {
1815  *name = te->resname;
1816  return 2;
1817  }
1818  }
1819  }
1820  break;
1821  /* As with other operator-like nodes, these have no names */
1822  case MULTIEXPR_SUBLINK:
1823  case ALL_SUBLINK:
1824  case ANY_SUBLINK:
1825  case ROWCOMPARE_SUBLINK:
1826  case CTE_SUBLINK:
1827  break;
1828  }
1829  break;
1830  case T_CaseExpr:
1831  strength = FigureColnameInternal((Node *) ((CaseExpr *) node)->defresult,
1832  name);
1833  if (strength <= 1)
1834  {
1835  *name = "case";
1836  return 1;
1837  }
1838  break;
1839  case T_A_ArrayExpr:
1840  /* make ARRAY[] act like a function */
1841  *name = "array";
1842  return 2;
1843  case T_RowExpr:
1844  /* make ROW() act like a function */
1845  *name = "row";
1846  return 2;
1847  case T_CoalesceExpr:
1848  /* make coalesce() act like a regular function */
1849  *name = "coalesce";
1850  return 2;
1851  case T_MinMaxExpr:
1852  /* make greatest/least act like a regular function */
1853  switch (((MinMaxExpr *) node)->op)
1854  {
1855  case IS_GREATEST:
1856  *name = "greatest";
1857  return 2;
1858  case IS_LEAST:
1859  *name = "least";
1860  return 2;
1861  }
1862  break;
1863  case T_SQLValueFunction:
1864  /* make these act like a function or variable */
1865  switch (((SQLValueFunction *) node)->op)
1866  {
1867  case SVFOP_CURRENT_DATE:
1868  *name = "current_date";
1869  return 2;
1870  case SVFOP_CURRENT_TIME:
1871  case SVFOP_CURRENT_TIME_N:
1872  *name = "current_time";
1873  return 2;
1876  *name = "current_timestamp";
1877  return 2;
1878  case SVFOP_LOCALTIME:
1879  case SVFOP_LOCALTIME_N:
1880  *name = "localtime";
1881  return 2;
1882  case SVFOP_LOCALTIMESTAMP:
1884  *name = "localtimestamp";
1885  return 2;
1886  case SVFOP_CURRENT_ROLE:
1887  *name = "current_role";
1888  return 2;
1889  case SVFOP_CURRENT_USER:
1890  *name = "current_user";
1891  return 2;
1892  case SVFOP_USER:
1893  *name = "user";
1894  return 2;
1895  case SVFOP_SESSION_USER:
1896  *name = "session_user";
1897  return 2;
1898  case SVFOP_CURRENT_CATALOG:
1899  *name = "current_catalog";
1900  return 2;
1901  case SVFOP_CURRENT_SCHEMA:
1902  *name = "current_schema";
1903  return 2;
1904  }
1905  break;
1906  case T_XmlExpr:
1907  /* make SQL/XML functions act like a regular function */
1908  switch (((XmlExpr *) node)->op)
1909  {
1910  case IS_XMLCONCAT:
1911  *name = "xmlconcat";
1912  return 2;
1913  case IS_XMLELEMENT:
1914  *name = "xmlelement";
1915  return 2;
1916  case IS_XMLFOREST:
1917  *name = "xmlforest";
1918  return 2;
1919  case IS_XMLPARSE:
1920  *name = "xmlparse";
1921  return 2;
1922  case IS_XMLPI:
1923  *name = "xmlpi";
1924  return 2;
1925  case IS_XMLROOT:
1926  *name = "xmlroot";
1927  return 2;
1928  case IS_XMLSERIALIZE:
1929  *name = "xmlserialize";
1930  return 2;
1931  case IS_DOCUMENT:
1932  /* nothing */
1933  break;
1934  }
1935  break;
1936  case T_XmlSerialize:
1937  *name = "xmlserialize";
1938  return 2;
1939  default:
1940  break;
1941  }
1942 
1943  return strength;
1944 }
List * indirection
Definition: parsenodes.h:441
#define NIL
Definition: pg_list.h:65
Oid getBaseTypeAndTypmod(Oid typid, int32 *typmod)
Definition: lsyscache.c:2316
#define IsA(nodeptr, _type_)
Definition: nodes.h:575
Expr * arg
Definition: primnodes.h:777
List * joinaliasvars
Definition: parsenodes.h:1030
Node * val
Definition: parsenodes.h:442
Index varlevelsup
Definition: primnodes.h:177
int errhint(const char *fmt,...)
Definition: elog.c:974
#define forboth(cell1, list1, cell2, list2)
Definition: pg_list.h:419
int exprLocation(const Node *expr)
Definition: nodeFuncs.c:1192
Expr * transformAssignedExpr(ParseState *pstate, Expr *expr, ParseExprKind exprKind, const char *colname, int attrno, List *indirection, int location)
Definition: parse_target.c:458
static ListCell * lnext(const List *l, const ListCell *c)
Definition: pg_list.h:321
TupleDesc CreateTemplateTupleDesc(int natts)
Definition: tupdesc.c:44
char * name
Definition: parsenodes.h:440
void markVarForSelectPriv(ParseState *pstate, Var *var, RangeTblEntry *rte)
Oid resulttype
Definition: primnodes.h:750
#define RelationGetNumberOfAttributes(relation)
Definition: rel.h:422
int32 exprTypmod(const Node *expr)
Definition: nodeFuncs.c:276
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
#define for_each_cell(cell, lst, initcell)
Definition: pg_list.h:390
char * pstrdup(const char *in)
Definition: mcxt.c:1161
static Node * transformAssignmentIndirection(ParseState *pstate, Node *basenode, const char *targetName, bool targetIsSubscripting, Oid targetTypeId, int32 targetTypMod, Oid targetCollation, List *indirection, ListCell *indirection_cell, Node *rhs, int location)
Definition: parse_target.c:681
Node * transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind)
Definition: parse_expr.c:145
#define llast(l)
Definition: pg_list.h:215
List * list_truncate(List *list, int new_size)
Definition: list.c:585
CommonTableExpr * GetCTEForRTE(ParseState *pstate, RangeTblEntry *rte, int rtelevelsup)
Node * coerce_type(ParseState *pstate, Node *node, Oid inputTypeId, Oid targetTypeId, int32 targetTypeMod, CoercionContext ccontext, CoercionForm cformat, int location)
Definition: parse_coerce.c:156
Definition: nodes.h:524
#define strVal(v)
Definition: value.h:54
static List * ExpandSingleTable(ParseState *pstate, RangeTblEntry *rte, int location, bool make_target_entry)
List * list_concat(List *list1, const List *list2)
Definition: list.c:515
int errcode(int sqlerrcode)
Definition: elog.c:570
char * FigureIndexColname(Node *node)
List * p_multiassign_exprs
Definition: parse_node.h:193
Oid resorigtbl
Definition: primnodes.h:1398
#define MemSet(start, val, len)
Definition: c.h:955
AttrNumber varattno
Definition: primnodes.h:172
char * format_type_be(Oid type_oid)
Definition: format_type.c:326
Expr * arg
Definition: primnodes.h:748
Oid typeidTypeRelid(Oid type_id)
Definition: parse_type.c:667
AclMode requiredPerms
Definition: parsenodes.h:1096
NameData relname
Definition: pg_class.h:35
unsigned int Oid
Definition: postgres_ext.h:31
char * resname
Definition: primnodes.h:1395
Definition: primnodes.h:167
ParseExprKind
Definition: parse_node.h:33
RangeTblEntry * refnameRangeTblEntry(ParseState *pstate, const char *schemaname, const char *refname, int location, int *sublevels_up)
#define lsecond(l)
Definition: pg_list.h:200
int32 typeMod
Definition: primnodes.h:959
PostParseColumnRefHook p_post_columnref_hook
Definition: parse_node.h:216
signed int int32
Definition: c.h:346
List * targetList
Definition: parsenodes.h:140
Const * makeNullConst(Oid consttype, int32 consttypmod, Oid constcollid)
Definition: makefuncs.c:335
int location
Definition: parsenodes.h:236
int location
Definition: parsenodes.h:443
static List * ExpandRowReference(ParseState *pstate, Node *expr, bool make_target_entry)
#define list_make1(x1)
Definition: pg_list.h:227
List * transformTargetList(ParseState *pstate, List *targetlist, ParseExprKind exprKind)
Definition: parse_target.c:133
RangeTblEntry * p_rte
Definition: parse_node.h:251
static List * ExpandColumnRefStar(ParseState *pstate, ColumnRef *cref, bool make_target_entry)
bool resjunk
Definition: primnodes.h:1400
#define linitial(l)
Definition: pg_list.h:195
List * rtable
Definition: parsenodes.h:137
#define ERROR
Definition: elog.h:43
TupleDesc get_expr_result_tupdesc(Node *expr, bool noError)
Definition: funcapi.c:397
static void * list_nth(const List *list, int n)
Definition: pg_list.h:277
Oid vartype
Definition: primnodes.h:174
char * FigureColname(Node *node)
Node * coerce_to_target_type(ParseState *pstate, Node *expr, Oid exprtype, Oid targettype, int32 targettypmod, CoercionContext ccontext, CoercionForm cformat, int location)
Definition: parse_coerce.c:78
struct A_Star A_Star
void TupleDescInitEntryCollation(TupleDesc desc, AttrNumber attributeNumber, Oid collationid)
Definition: tupdesc.c:769
Node * coerce_to_domain(Node *arg, Oid baseTypeId, int32 baseTypeMod, Oid typeId, CoercionContext ccontext, CoercionForm cformat, int location, bool hideInputCoercion)
Definition: parse_coerce.c:663
Oid resultcollid
Definition: primnodes.h:753
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2099
int location
Definition: primnodes.h:182
List * p_namespace
Definition: parse_node.h:181
int32 typeMod
Definition: primnodes.h:1282
AttrNumber get_attnum(Oid relid, const char *attname)
Definition: lsyscache.c:806
AttrNumber resno
Definition: primnodes.h:1394
Oid attnumTypeId(Relation rd, int attid)
void errorMissingRTE(ParseState *pstate, RangeVar *relation)
int p_next_resno
Definition: parse_node.h:192
#define RelationGetRelationName(relation)
Definition: rel.h:450
static ListCell * list_head(const List *l)
Definition: pg_list.h:125
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:200
Oid resulttype
Definition: primnodes.h:780
TupleDesc expandRecordVariable(ParseState *pstate, Var *var, int levelsup)
List * expandRelAttrs(ParseState *pstate, RangeTblEntry *rte, int rtindex, int sublevels_up, int location)
#define list_make1_int(x1)
Definition: pg_list.h:238
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition: tupdesc.c:603
static List * ExpandIndirectionStar(ParseState *pstate, A_Indirection *ind, bool make_target_entry, ParseExprKind exprKind)
#define ereport(elevel, rest)
Definition: elog.h:141
TargetEntry * makeTargetEntry(Expr *expr, AttrNumber resno, char *resname, bool resjunk)
Definition: makefuncs.c:236
List * lappend_int(List *list, int datum)
Definition: list.c:339
List * newvals
Definition: primnodes.h:778
List * lappend(List *list, void *datum)
Definition: list.c:321
Index varno
Definition: primnodes.h:170
void expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up, int location, bool include_dropped, List **colnames, List **colvars)
char * NameListToString(List *names)
Definition: namespace.c:3094
struct ParseState * parentParseState
Definition: parse_node.h:175
SubscriptingRef * transformContainerSubscripts(ParseState *pstate, Node *containerBase, Oid containerType, Oid elementType, int32 containerTypMod, List *indirection, Node *assignFrom)
Definition: parse_node.c:298
List * transformExpressionList(ParseState *pstate, List *exprlist, ParseExprKind exprKind, bool allowDefault)
Definition: parse_target.c:230
void resolveTargetListUnknowns(ParseState *pstate, List *targetlist)
Definition: parse_target.c:301
#define ACL_SELECT
Definition: parsenodes.h:75
bool self_reference
Definition: parsenodes.h:1058
static char * label
Definition: pg_basebackup.c:90
Oid MyDatabaseId
Definition: globals.c:85
RangeTblEntry * GetRTEByRangeTablePosn(ParseState *pstate, int varno, int sublevels_up)
RangeTblEntry * p_target_rangetblentry
Definition: parse_node.h:188
unsigned int Index
Definition: c.h:475
ParseExprKind p_expr_kind
Definition: parse_node.h:191
TupleDesc rd_att
Definition: rel.h:84
int16 attnum
Definition: pg_attribute.h:79
Oid get_typcollation(Oid typid)
Definition: lsyscache.c:2823
Var * make_var(ParseState *pstate, RangeTblEntry *rte, int attrno, int location)
Definition: parse_node.c:189
#define makeNode(_type_)
Definition: nodes.h:572
int attnameAttNum(Relation rd, const char *attname, bool sysColOK)
static Node * transformAssignmentSubscripts(ParseState *pstate, Node *basenode, const char *targetName, Oid targetTypeId, int32 targetTypMod, Oid targetCollation, List *subscripts, bool isSlice, List *indirection, ListCell *next_indirection, Node *rhs, int location)
Definition: parse_target.c:895
#define Assert(condition)
Definition: c.h:732
#define lfirst(lc)
Definition: pg_list.h:190
char * aliasname
Definition: primnodes.h:42
List * indirection
Definition: parsenodes.h:406
void markTargetListOrigins(ParseState *pstate, List *targetlist)
Definition: parse_target.c:331
Expr * expr
Definition: primnodes.h:1393
List * checkInsertTargets(ParseState *pstate, List *cols, List **attrnos)
Definition: parse_target.c:989
void get_atttypetypmodcoll(Oid relid, AttrNumber attnum, Oid *typid, int32 *typmod, Oid *collid)
Definition: lsyscache.c:891
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
static int list_length(const List *l)
Definition: pg_list.h:169
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:111
Oid exprCollation(const Node *expr)
Definition: nodeFuncs.c:720
Index ctelevelsup
Definition: parsenodes.h:1057
static int FigureColnameInternal(Node *node, char **name)
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:736
const char * name
Definition: encode.c:521
#define InvalidAttrNumber
Definition: attnum.h:23
#define nodeTag(nodeptr)
Definition: nodes.h:529
int RTERangeTablePosn(ParseState *pstate, RangeTblEntry *rte, int *sublevels_up)
RTEKind rtekind
Definition: parsenodes.h:974
static void markTargetListOrigin(ParseState *pstate, TargetEntry *tle, Var *var, int levelsup)
Definition: parse_target.c:353
e
Definition: preproc-init.c:82
AttrNumber resorigcol
Definition: primnodes.h:1399
Query * subquery
Definition: parsenodes.h:1009
int errmsg(const char *fmt,...)
Definition: elog.c:784
static List * ExpandAllTables(ParseState *pstate, int location)
Relation p_target_relation
Definition: parse_node.h:187
List * fieldnums
Definition: primnodes.h:779
#define elog(elevel,...)
Definition: elog.h:226
bool p_is_insert
Definition: parse_node.h:189
int i
TargetEntry * get_tle_by_resno(List *tlist, AttrNumber resno)
#define NameStr(name)
Definition: c.h:609
void * arg
#define lthird(l)
Definition: pg_list.h:205
PreParseColumnRefHook p_pre_columnref_hook
Definition: parse_node.h:215
Alias * eref
Definition: parsenodes.h:1092
#define copyObject(obj)
Definition: nodes.h:640
TargetEntry * transformTargetEntry(ParseState *pstate, Node *node, Node *expr, ParseExprKind exprKind, char *colname, bool resjunk)
Definition: parse_target.c:87
Definition: regcomp.c:224
Definition: pg_list.h:50
bool bms_is_member(int x, const Bitmapset *a)
Definition: bitmapset.c:427
#define GetCTETargetList(cte)
Definition: parsenodes.h:1444
void updateTargetListEntry(ParseState *pstate, TargetEntry *tle, char *colname, int attrno, List *indirection, int location)
Definition: parse_target.c:621
int16 AttrNumber
Definition: attnum.h:21
Oid transformContainerType(Oid *containerType, int32 *containerTypmod)
Definition: parse_node.c:217
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
Definition: makefuncs.c:420
List * fields
Definition: parsenodes.h:235
int32 resulttypmod
Definition: primnodes.h:752
AttrNumber fieldnum
Definition: primnodes.h:749
List * p_rtable
Definition: parse_node.h:177