Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit d21de3b

Browse files
committed
> =================================================================
> User interface proposal for multi-row function targetlist entries > ================================================================= > 1. Only one targetlist entry may return a set. > 2. Each targetlist item (other than the set returning one) is > repeated for each item in the returned set. > Having gotten no objections (actually, no response at all), I can only assume no one had heartburn with this change. The attached patch covers the first of the two proposals, i.e. restricting the target list to only one set returning function. It compiles cleanly, and passes all regression tests. If there are no objections, please apply. Any suggestions on where this should be documented (other than maybe sql-select)? Thanks, Joe p.s. Here's what the previous example now looks like: CREATE TABLE bar(f1 int, f2 text, f3 int); INSERT INTO bar VALUES(1, 'Hello', 42); INSERT INTO bar VALUES(2, 'Happy', 45); CREATE TABLE foo(a int, b text); INSERT INTO foo VALUES(42, 'World'); INSERT INTO foo VALUES(42, 'Everyone'); INSERT INTO foo VALUES(45, 'Birthday'); INSERT INTO foo VALUES(45, 'New Year'); CREATE TABLE foo2(a int, b text); INSERT INTO foo2 VALUES(42, '!!!!'); INSERT INTO foo2 VALUES(42, '????'); INSERT INTO foo2 VALUES(42, '####'); INSERT INTO foo2 VALUES(45, '$$$$'); CREATE OR REPLACE FUNCTION getfoo(int) RETURNS SETOF text AS ' SELECT b FROM foo WHERE a = $1 ' language 'sql'; CREATE OR REPLACE FUNCTION getfoo2(int) RETURNS SETOF text AS ' SELECT b FROM foo2 WHERE a = $1 ' language 'sql'; regression=# SELECT f1, f2, getfoo(f3) AS f4 FROM bar; f1 | f2 | f4 ----+-------+---------- 1 | Hello | World 1 | Hello | Everyone 2 | Happy | Birthday 2 | Happy | New Year (4 rows) regression=# SELECT f1, f2, getfoo(f3) AS f4, getfoo2(f3) AS f5 FROM bar; ERROR: Only one target list entry may return a set result Joe Conway
1 parent 2bd6311 commit d21de3b

File tree

3 files changed

+24
-8
lines changed

3 files changed

+24
-8
lines changed

src/backend/parser/parse_clause.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.106 2003/02/10 04:44:46 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.107 2003/02/13 05:06:34 momjian Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1118,7 +1118,7 @@ findTargetlistEntry(ParseState *pstate, Node *node, List *tlist, int clause)
11181118
* the end of the target list. This target is given resjunk = TRUE so
11191119
* that it will not be projected into the final tuple.
11201120
*/
1121-
target_result = transformTargetEntry(pstate, node, expr, NULL, true);
1121+
target_result = transformTargetEntry(pstate, node, expr, NULL, true, NULL);
11221122
lappend(tlist, target_result);
11231123

11241124
return target_result;

src/backend/parser/parse_target.c

+20-4
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.95 2003/02/09 06:56:28 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.96 2003/02/13 05:06:35 momjian Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -42,13 +42,16 @@ static int FigureColnameInternal(Node *node, char **name);
4242
* colname the column name to be assigned, or NULL if none yet set.
4343
* resjunk true if the target should be marked resjunk, ie, it is not
4444
* wanted in the final projected tuple.
45+
* retset if non-NULL, and the entry is a function expression, pass back
46+
* expr->funcretset
4547
*/
4648
TargetEntry *
4749
transformTargetEntry(ParseState *pstate,
4850
Node *node,
4951
Node *expr,
5052
char *colname,
51-
bool resjunk)
53+
bool resjunk,
54+
bool *retset)
5255
{
5356
Oid type_id;
5457
int32 type_mod;
@@ -61,6 +64,9 @@ transformTargetEntry(ParseState *pstate,
6164
if (IsA(expr, RangeVar))
6265
elog(ERROR, "You can't use relation names alone in the target list, try relation.*.");
6366

67+
if (retset && IsA(expr, FuncExpr))
68+
*retset = ((FuncExpr *) expr)->funcretset;
69+
6470
type_id = exprType(expr);
6571
type_mod = exprTypmod(expr);
6672

@@ -93,10 +99,12 @@ transformTargetEntry(ParseState *pstate,
9399
List *
94100
transformTargetList(ParseState *pstate, List *targetlist)
95101
{
102+
bool retset = false;
96103
List *p_target = NIL;
97104

98105
while (targetlist != NIL)
99106
{
107+
bool entry_retset = false;
100108
ResTarget *res = (ResTarget *) lfirst(targetlist);
101109

102110
if (IsA(res->val, ColumnRef))
@@ -173,7 +181,8 @@ transformTargetList(ParseState *pstate, List *targetlist)
173181
res->val,
174182
NULL,
175183
res->name,
176-
false));
184+
false,
185+
&entry_retset));
177186
}
178187
}
179188
else if (IsA(res->val, InsertDefault))
@@ -194,9 +203,16 @@ transformTargetList(ParseState *pstate, List *targetlist)
194203
res->val,
195204
NULL,
196205
res->name,
197-
false));
206+
false,
207+
&entry_retset));
198208
}
199209

210+
if (retset && entry_retset)
211+
elog(ERROR, "Only one target list entry may return a set result");
212+
213+
if (entry_retset)
214+
retset = true;
215+
200216
targetlist = lnext(targetlist);
201217
}
202218

src/include/parser/parse_target.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Id: parse_target.h,v 1.27 2002/09/18 21:35:24 tgl Exp $
10+
* $Id: parse_target.h,v 1.28 2003/02/13 05:06:35 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -20,7 +20,7 @@
2020
extern List *transformTargetList(ParseState *pstate, List *targetlist);
2121
extern TargetEntry *transformTargetEntry(ParseState *pstate,
2222
Node *node, Node *expr,
23-
char *colname, bool resjunk);
23+
char *colname, bool resjunk, bool *retset);
2424
extern void updateTargetListEntry(ParseState *pstate, TargetEntry *tle,
2525
char *colname, int attrno,
2626
List *indirection);

0 commit comments

Comments
 (0)