Jay Taylor's notes

back to listing index

postgres/postgres

[web search]
Original source (github.com)
Tags: postgres postgresql c parsers clean-architecture clean-code github.com
Clipped on: 2019-07-30

Skip to content
Branch: master

postgres / src / backend / parser / parse_target.c

Find file Copy path
Image (Asset 3/14) alt= Open this file in GitHub Desktop
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);
38 static Node *transformAssignmentIndirection(ParseState *pstate,
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);
49 static Node *transformAssignmentSubscripts(ParseState *pstate,
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);
64 static List *ExpandIndirectionStar(ParseState *pstate, A_Indirection *ind,
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 */
86 TargetEntry *
87 transformTargetEntry(ParseState *pstate,
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 *
230 transformExpressionList(ParseState *pstate, List *exprlist,
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 {
260 A_Indirection *ind = (A_Indirection *) e;
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
301 resolveTargetListUnknowns(ParseState *pstate, List *targetlist)
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,
314 COERCION_IMPLICIT,
315 COERCE_IMPLICIT_CAST,
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
353 markTargetListOrigin(ParseState *pstate, TargetEntry *tle,
354 Var *var, int levelsup)
355 {
356 int netlevelsup;
357 RangeTblEntry *rte;
358 AttrNumber attnum;
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 {
377 TargetEntry *ste = get_tle_by_resno(rte->subquery->targetList,
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 *
458 transformAssignedExpr(ParseState *pstate,
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 *)
559 transformAssignmentIndirection(pstate,
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,
583 COERCION_ASSIGNMENT,
584 COERCE_IMPLICIT_CAST,
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
621 updateTargetListEntry(ParseState *pstate,
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,
631 EXPR_KIND_UPDATE_TARGET,
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 *
681 transformAssignmentIndirection(ParseState *pstate,
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 */
707 CaseTestExpr *ctest = makeNode(CaseTestExpr);
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;
743 AttrNumber attnum;
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,
829 COERCION_IMPLICIT,
830 COERCE_IMPLICIT_CAST,
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,
861 COERCION_ASSIGNMENT,
862 COERCE_IMPLICIT_CAST,
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 *
895 transformAssignmentSubscripts(ParseState *pstate,
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,
965 COERCION_ASSIGNMENT,
966 COERCE_IMPLICIT_CAST,
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,
1043 RelationGetRelationName(pstate->p_target_relation)),
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 *
1094 ExpandColumnRefStar(ParseState *pstate, ColumnRef *cref,
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 *
1318 ExpandIndirectionStar(ParseState *pstate, A_Indirection *ind,
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);
1325 ind->indirection = list_truncate(ind->indirection,
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 *
1345 ExpandSingleTable(ParseState *pstate, RangeTblEntry *rte,
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 *
1394 ExpandRowReference(ParseState *pstate, Node *expr,
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;
1494 AttrNumber attnum;
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 */
1556 TargetEntry *ste = get_tle_by_resno(rte->subquery->targetList,
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 *
1663 FigureColname(Node *node)
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 *
1682 FigureIndexColname(Node *node)
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
1702 FigureColnameInternal(Node *node, char **name)
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;
1874 case SVFOP_CURRENT_TIMESTAMP:
1875 case SVFOP_CURRENT_TIMESTAMP_N:
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:
1883 case SVFOP_LOCALTIMESTAMP_N:
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 }