diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c index ec468516ccadba53c232cf7c509d3e22a8809c62..85af5359eaf3648fbd5edc0b7701acc7260fb315 100644 --- a/src/backend/parser/parse_clause.c +++ b/src/backend/parser/parse_clause.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.106 2003/02/10 04:44:46 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.107 2003/02/13 05:06:34 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -1118,7 +1118,7 @@ findTargetlistEntry(ParseState *pstate, Node *node, List *tlist, int clause) * the end of the target list. This target is given resjunk = TRUE so * that it will not be projected into the final tuple. */ - target_result = transformTargetEntry(pstate, node, expr, NULL, true); + target_result = transformTargetEntry(pstate, node, expr, NULL, true, NULL); lappend(tlist, target_result); return target_result; diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c index 534b2e40978a240f43d1d261b5da1700c7c4ca97..0bc5e665d6fb49a65dff7404326628bc34aaf9c5 100644 --- a/src/backend/parser/parse_target.c +++ b/src/backend/parser/parse_target.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.95 2003/02/09 06:56:28 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.96 2003/02/13 05:06:35 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -42,13 +42,16 @@ static int FigureColnameInternal(Node *node, char **name); * colname the column name to be assigned, or NULL if none yet set. * resjunk true if the target should be marked resjunk, ie, it is not * wanted in the final projected tuple. + * retset if non-NULL, and the entry is a function expression, pass back + * expr->funcretset */ TargetEntry * transformTargetEntry(ParseState *pstate, Node *node, Node *expr, char *colname, - bool resjunk) + bool resjunk, + bool *retset) { Oid type_id; int32 type_mod; @@ -61,6 +64,9 @@ transformTargetEntry(ParseState *pstate, if (IsA(expr, RangeVar)) elog(ERROR, "You can't use relation names alone in the target list, try relation.*."); + if (retset && IsA(expr, FuncExpr)) + *retset = ((FuncExpr *) expr)->funcretset; + type_id = exprType(expr); type_mod = exprTypmod(expr); @@ -93,10 +99,12 @@ transformTargetEntry(ParseState *pstate, List * transformTargetList(ParseState *pstate, List *targetlist) { + bool retset = false; List *p_target = NIL; while (targetlist != NIL) { + bool entry_retset = false; ResTarget *res = (ResTarget *) lfirst(targetlist); if (IsA(res->val, ColumnRef)) @@ -173,7 +181,8 @@ transformTargetList(ParseState *pstate, List *targetlist) res->val, NULL, res->name, - false)); + false, + &entry_retset)); } } else if (IsA(res->val, InsertDefault)) @@ -194,9 +203,16 @@ transformTargetList(ParseState *pstate, List *targetlist) res->val, NULL, res->name, - false)); + false, + &entry_retset)); } + if (retset && entry_retset) + elog(ERROR, "Only one target list entry may return a set result"); + + if (entry_retset) + retset = true; + targetlist = lnext(targetlist); } diff --git a/src/include/parser/parse_target.h b/src/include/parser/parse_target.h index b8c495484bfd1ac13f184905b8f6073291d2e985..3fa67cbf41fc384c9ead58c759370700cf2e6d68 100644 --- a/src/include/parser/parse_target.h +++ b/src/include/parser/parse_target.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: parse_target.h,v 1.27 2002/09/18 21:35:24 tgl Exp $ + * $Id: parse_target.h,v 1.28 2003/02/13 05:06:35 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -20,7 +20,7 @@ extern List *transformTargetList(ParseState *pstate, List *targetlist); extern TargetEntry *transformTargetEntry(ParseState *pstate, Node *node, Node *expr, - char *colname, bool resjunk); + char *colname, bool resjunk, bool *retset); extern void updateTargetListEntry(ParseState *pstate, TargetEntry *tle, char *colname, int attrno, List *indirection);