1 /*-------------------------------------------------------------------------
6 * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.81 2002/04/02 08:51:52 inoue Exp $
13 *-------------------------------------------------------------------------
17 #include "miscadmin.h"
18 #include "nodes/makefuncs.h"
19 #include "parser/parsetree.h"
20 #include "parser/parse_coerce.h"
21 #include "parser/parse_expr.h"
22 #include "parser/parse_func.h"
23 #include "parser/parse_relation.h"
24 #include "parser/parse_target.h"
25 #include "parser/parse_type.h"
26 #include "utils/builtins.h"
29 static List *ExpandAllTables(ParseState *pstate);
30 static char *FigureColname(Node *node);
31 static int FigureColnameInternal(Node *node, char **name);
35 * transformTargetEntry()
36 * Transform any ordinary "expression-type" node into a targetlist entry.
37 * This is exported so that parse_clause.c can generate targetlist entries
38 * for ORDER/GROUP BY items that are not already in the targetlist.
40 * node the (untransformed) parse tree for the value expression.
41 * expr the transformed expression, or NULL if caller didn't do it yet.
42 * colname the column name to be assigned, or NULL if none yet set.
43 * resjunk true if the target should be marked resjunk, ie, it is not
44 * wanted in the final projected tuple.
47 transformTargetEntry(ParseState *pstate,
57 /* Transform the node if caller didn't do it already */
59 expr = transformExpr(pstate, node);
61 if (IsA(expr, RangeVar))
62 elog(ERROR, "You can't use relation names alone in the target list, try relation.*.");
64 type_id = exprType(expr);
65 type_mod = exprTypmod(expr);
70 * Generate a suitable column name for a column without any
71 * explicit 'AS ColumnName' clause.
73 colname = FigureColname(node);
76 resnode = makeResdom((AttrNumber) pstate->p_last_resno++,
82 return makeTargetEntry(resnode, expr);
87 * transformTargetList()
88 * Turns a list of ResTarget's into a list of TargetEntry's.
90 * At this point, we don't care whether we are doing SELECT, INSERT,
91 * or UPDATE; we just transform the given expressions.
94 transformTargetList(ParseState *pstate, List *targetlist)
98 while (targetlist != NIL)
100 ResTarget *res = (ResTarget *) lfirst(targetlist);
102 if (IsA(res->val, ColumnRef))
104 ColumnRef *cref = (ColumnRef *) res->val;
105 List *fields = cref->fields;
106 int numnames = length(fields);
108 if (numnames == 1 && strcmp(strVal(lfirst(fields)), "*") == 0)
111 * Target item is a single '*', expand all tables (eg.
114 p_target = nconc(p_target,
115 ExpandAllTables(pstate));
117 else if (strcmp(strVal(nth(numnames-1, fields)), "*") == 0)
120 * Target item is relation.*, expand that table (eg.
121 * SELECT emp.*, dname FROM emp, dept)
132 relname = strVal(lfirst(fields));
135 schemaname = strVal(lfirst(fields));
136 relname = strVal(lsecond(fields));
140 char *name1 = strVal(lfirst(fields));
143 * We check the catalog name and then ignore it.
145 if (strcmp(name1, DatabaseName) != 0)
146 elog(ERROR, "Cross-database references are not implemented");
147 schemaname = strVal(lsecond(fields));
148 relname = strVal(lfirst(lnext(lnext(fields))));
152 elog(ERROR, "Invalid qualified name syntax (too many names)");
153 schemaname = NULL; /* keep compiler quiet */
158 /* XXX do something with schema name */
159 rte = refnameRangeTblEntry(pstate, relname,
162 rte = addImplicitRTE(pstate, makeRangeVar(NULL, relname));
164 p_target = nconc(p_target,
165 expandRelAttrs(pstate, rte));
169 /* Plain ColumnRef node, treat it as an expression */
170 p_target = lappend(p_target,
171 transformTargetEntry(pstate,
180 /* Everything else but ColumnRef */
181 p_target = lappend(p_target,
182 transformTargetEntry(pstate,
189 targetlist = lnext(targetlist);
197 * updateTargetListEntry()
198 * This is used in INSERT and UPDATE statements only. It prepares a
199 * TargetEntry for assignment to a column of the target table.
200 * This includes coercing the given value to the target column's type
201 * (if necessary), and dealing with any subscripts attached to the target
205 * tle target list entry to be modified
206 * colname target column name (ie, name of attribute to be assigned to)
207 * attrno target attribute number
208 * indirection subscripts for target column, if any
211 updateTargetListEntry(ParseState *pstate,
217 Oid type_id = exprType(tle->expr); /* type of value provided */
218 Oid attrtype; /* type of target column */
220 Resdom *resnode = tle->resdom;
221 Relation rd = pstate->p_target_relation;
225 elog(ERROR, "Cannot assign to system attribute '%s'", colname);
226 attrtype = attnumTypeId(rd, attrno);
227 attrtypmod = rd->rd_att->attrs[attrno - 1]->atttypmod;
230 * If there are subscripts on the target column, prepare an array
231 * assignment expression. This will generate an array value that the
232 * source value has been inserted into, which can then be placed in
233 * the new tuple constructed by INSERT or UPDATE. Note that
234 * transformArraySubscripts takes care of type coercion.
241 if (pstate->p_is_insert)
244 * The command is INSERT INTO table (arraycol[subscripts]) ...
245 * so there is not really a source array value to work with.
246 * Let the executor do something reasonable, if it can. Notice
247 * that we force transformArraySubscripts to treat the
248 * subscripting op as an array-slice op below, so the source
249 * data will have been coerced to the array type.
251 arrayBase = NULL; /* signal there is no source array */
256 * Build a Var for the array to be updated.
258 arrayBase = (Node *) make_var(pstate,
259 pstate->p_target_rangetblentry,
263 aref = transformArraySubscripts(pstate,
269 tle->expr = (Node *) aref;
274 * For normal non-subscripted target column, do type checking and
275 * coercion. But accept InvalidOid, which indicates the source is
278 if (type_id != InvalidOid)
280 if (type_id != attrtype)
282 tle->expr = CoerceTargetExpr(pstate, tle->expr, type_id,
283 attrtype, attrtypmod);
284 if (tle->expr == NULL)
285 elog(ERROR, "column \"%s\" is of type '%s'"
286 " but expression is of type '%s'"
287 "\n\tYou will need to rewrite or cast the expression",
289 format_type_be(attrtype),
290 format_type_be(type_id));
294 * If the target is a fixed-length type, it may need a length
295 * coercion as well as a type coercion.
297 tle->expr = coerce_type_typmod(pstate, tle->expr,
298 attrtype, attrtypmod);
303 * The result of the target expression should now match the
304 * destination column's type. Also, reset the resname and resno to
305 * identify the destination column --- rewriter and planner depend on
308 resnode->restype = attrtype;
309 resnode->restypmod = attrtypmod;
310 resnode->resname = colname;
311 resnode->resno = (AttrNumber) attrno;
316 CoerceTargetExpr(ParseState *pstate,
322 if (can_coerce_type(1, &type_id, &attrtype))
323 expr = coerce_type(pstate, expr, type_id, attrtype, attrtypmod);
325 #ifndef DISABLE_STRING_HACKS
328 * string hacks to get transparent conversions w/o explicit
331 else if ((attrtype == BPCHAROID) || (attrtype == VARCHAROID))
333 Oid text_id = TEXTOID;
335 if (type_id == TEXTOID)
338 else if (can_coerce_type(1, &type_id, &text_id))
339 expr = coerce_type(pstate, expr, type_id, text_id, attrtypmod);
353 * checkInsertTargets -
354 * generate a list of INSERT column targets if not supplied, or
355 * test supplied column names to make sure they are in target table.
356 * Also return an integer list of the columns' attribute numbers.
359 checkInsertTargets(ParseState *pstate, List *cols, List **attrnos)
366 * Generate default column list for INSERT.
368 Form_pg_attribute *attr = pstate->p_target_relation->rd_att->attrs;
369 int numcol = pstate->p_target_relation->rd_rel->relnatts;
372 for (i = 0; i < numcol; i++)
374 ResTarget *col = makeNode(ResTarget);
376 col->name = pstrdup(NameStr(attr[i]->attname));
377 col->indirection = NIL;
379 cols = lappend(cols, col);
380 *attrnos = lappendi(*attrnos, i + 1);
386 * Do initial validation of user-supplied INSERT column list.
392 char *name = ((ResTarget *) lfirst(tl))->name;
395 /* Lookup column name, elog on failure */
396 attrno = attnameAttNum(pstate->p_target_relation, name);
397 /* Check for duplicates */
398 if (intMember(attrno, *attrnos))
399 elog(ERROR, "Attribute '%s' specified more than once", name);
400 *attrnos = lappendi(*attrnos, attrno);
408 * Turns '*' (in the target list) into a list of targetlist entries.
410 * tlist entries are generated for each relation appearing at the top level
411 * of the query's namespace, except for RTEs marked not inFromCl. (These
412 * may include NEW/OLD pseudo-entries, implicit RTEs, etc.)
415 ExpandAllTables(ParseState *pstate)
420 foreach(ns, pstate->p_namespace)
422 Node *n = (Node *) lfirst(ns);
425 if (IsA(n, RangeTblRef))
426 rte = rt_fetch(((RangeTblRef *) n)->rtindex,
428 else if (IsA(n, JoinExpr))
429 rte = rt_fetch(((JoinExpr *) n)->rtindex,
433 elog(ERROR, "ExpandAllTables: unexpected node (internal error)"
434 "\n\t%s", nodeToString(n));
435 rte = NULL; /* keep compiler quiet */
439 * Ignore added-on relations that were not listed in the FROM
445 target = nconc(target, expandRelAttrs(pstate, rte));
448 /* Check for SELECT *; */
450 elog(ERROR, "Wildcard with no tables specified not allowed");
457 * if the name of the resulting column is not specified in the target
458 * list, we have to guess a suitable name. The SQL spec provides some
459 * guidance, but not much...
461 * Note that the argument is the *untransformed* parse tree for the target
462 * item. This is a shade easier to work with than the transformed tree.
465 FigureColname(Node *node)
469 FigureColnameInternal(node, &name);
472 /* default result if we can't guess anything */
477 FigureColnameInternal(Node *node, char **name)
484 switch (nodeTag(node))
487 *name = ((Ident *) node)->name;
491 List *fields = ((ColumnRef *) node)->fields;
493 while (lnext(fields) != NIL)
494 fields = lnext(fields);
495 if (strcmp(strVal(lfirst(fields)), "*") != 0)
497 *name = strVal(lfirst(fields));
502 case T_ExprFieldSelect:
504 List *fields = ((ExprFieldSelect *) node)->fields;
508 while (lnext(fields) != NIL)
509 fields = lnext(fields);
510 if (strcmp(strVal(lfirst(fields)), "*") != 0)
512 *name = strVal(lfirst(fields));
519 *name = ((FuncCall *) node)->funcname;
522 if (((A_Const *) node)->typename != NULL)
524 List *names = ((A_Const *) node)->typename->names;
528 while (lnext(names) != NIL)
529 names = lnext(names);
530 *name = strVal(lfirst(names));
536 strength = FigureColnameInternal(((TypeCast *) node)->arg,
540 if (((TypeCast *) node)->typename != NULL)
542 List *names = ((TypeCast *) node)->typename->names;
546 while (lnext(names) != NIL)
547 names = lnext(names);
548 *name = strVal(lfirst(names));
555 strength = FigureColnameInternal(((CaseExpr *) node)->defresult,