Re: Re: functions returning records - Mailing list pgsql-hackers

From Alex Pilosov
Subject Re: Re: functions returning records
Date
Msg-id Pine.BSO.4.10.10106270843510.20546-100000@spider.pilosoft.com
Whole thread Raw
In response to Re: functions returning records  (mlw <markw@mohawksoft.com>)
List 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
> 
> 



pgsql-hackers by date:

Previous
From: Hannu Krosing
Date:
Subject: Re: Re: 7.2 items
Next
From: Karel Zak
Date:
Subject: Re: AW: functions returning records