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