Re: Re: functions returning records

From: Alex Pilosov <alex(at)pilosoft(dot)com>
To: mlw <markw(at)mohawksoft(dot)com>
Cc: pgsql-hackers(at)postgresql(dot)org
Subject: Re: Re: functions returning records
Date: 2001-06-27 12:46:36
Message-ID: Pine.BSO.4.10.10106270843510.20546-100000@spider.pilosoft.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Wed, 27 Jun 2001, mlw wrote:

> While functions returning rows would be cool, and something I'd like
> to see. I think the functionality, if not the syntax, you are looking
> for is already in postgres 7.1.x. Here is an example: (Actual code at
> bottom of message)
Yes, its already possible, but its extremely ugly and nontransparent. I
don't want to create 5 functions to return 5-row tuple, or have to deal
with C SPI to do that. It needs a minor cleanup which is all I'm trying to
do :)

> select n1, n2 from (select foo1(10) as n1, foo2() as n2) as fubar ;
>
> The trick seems to be, to have the first function return a 'setof' results.
> Have the foo2() function return the next column of foo1()'s current result.
>
> Here is the output:
>
> markw=# select foo1(10) as n1, foo2() as n2;
> n1 | n2
> ----+----
> 1 | 1
> 2 | 2
> 3 | 3
> 4 | 4
> 5 | 5
> 6 | 6
> 7 | 7
> 8 | 8
> 9 | 9
> 10 | 10
> (10 rows)
>
> Or you can create a synthetic table at query time, called fubar:
>
> markw=# select * from (select foo1(10) as n1, foo2() as n2) as fubar;
> n1 | n2
> ----+----
> 1 | 1
> 2 | 2
> 3 | 3
> 4 | 4
> 5 | 5
> 6 | 6
> 7 | 7
> 8 | 8
> 9 | 9
> 10 | 10
> (10 rows)
>
>
> Now, I'm not sure if it is documented that the first function gets called
> first, or that next functions get called after each result of a result "setof"
> but it seem logical that they should, and I would like to lobby that this
> becomes an "official" behavior of the function manager and the execution
> processing.
>
>
> <<<<<<<<<<<<< code >>>>>>>>>>>>>>
>
>
> static int count;
> static int curr;
>
> Datum foo1(PG_FUNCTION_ARGS);
> Datum foo2(PG_FUNCTION_ARGS);
>
> Datum foo1(PG_FUNCTION_ARGS)
> {
> if(!fcinfo->resultinfo)
> {
> elog(ERROR, "Not called with fcinfo");
> PG_RETURN_NULL();
> }
> if(!count)
> {
> count = PG_GETARG_INT32(0);
> curr = 1;
> }
> else
> curr++;
>
> if(curr <= count)
> {
> ReturnSetInfo *rsi = (ReturnSetInfo *)fcinfo->resultinfo;
> rsi->isDone = ExprMultipleResult;
> PG_RETURN_INT32(curr);
> }
> else
> {
> ReturnSetInfo *rsi ;
> curr=0;
> count=0;
> rsi = (ReturnSetInfo *)fcinfo->resultinfo;
> rsi->isDone = ExprEndResult ;
> }
> PG_RETURN_NULL();
> }
>
> Datum foo2(PG_FUNCTION_ARGS)
> {
> if(curr <= count)
> PG_RETURN_INT32(curr);
> else
> PG_RETURN_INT32(42);
> }
>
> SQL:
>
> create function foo1( int4)
> returns setof int4
> as '/usr/local/lib/templ.so', 'foo1'
> language 'c' ;
>
> create function foo2()
> returns int4
> as '/usr/local/lib/templ.so', 'foo2'
> language 'c' ;
>
> ---------------------------(end of broadcast)---------------------------
> TIP 6: Have you searched our list archives?
>
> http://www.postgresql.org/search.mpl
>
>

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Karel Zak 2001-06-27 13:06:27 Re: AW: functions returning records
Previous Message Hannu Krosing 2001-06-27 12:43:33 Re: Re: 7.2 items