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