From: | "Merlin Moncure" <mmoncure(at)gmail(dot)com> |
---|---|
To: | "Pavel Stehule" <pavel(dot)stehule(at)gmail(dot)com> |
Cc: | "Cultural Sublimation" <cultural_sublimation(at)yahoo(dot)com>, "Sam Mason" <sam(at)samason(dot)me(dot)uk>, pgsql-general(at)postgresql(dot)org |
Subject: | Re: PL/pgSQL and SETOF |
Date: | 2007-12-03 21:58:47 |
Message-ID: | b42b73150712031358v1cffdf02h50b4a7195351eff7@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-general |
On Dec 3, 2007 3:31 PM, Pavel Stehule <pavel(dot)stehule(at)gmail(dot)com> wrote:
> > > no. Your simplest version is historic relict and is available only in
> > > sql language. I am not sure, maybe in C language too.
> >
> > It is extremely useful to be able call functions in this way. I
> > really wish it were possible to do this with pl/sql functions as
> > well...
> >
>
> where is this form better, than standard form? It's similar to CALL
> statement, but I am sorry, it's inconsistent, and it do problems
> mainly for beginners.
as you noted, a principal draw of this syntax isf invoking functions
like procedures. if we had true stored procedures, this argument
would probably go away. However, it also allows expressing some
complex queries in a simpler, faster way. The payoff here is in some
really tricky cases. Here is an example (note the expansion of the
set via the SRF 'explode array'). This isn't the only way to do this,
but is the best in PostgreSQL terms (AFAICT).
select q.item_lookup, is_child, p.* from item p
join
(
select
item_id as item_lookup,
false as is_child,
explode_array(parents) as item_id
from item
union all
select
l.item_id as item_lookup,
true as is_child,
r.item_id
from item l
join item r on r.parents between (l.parents || 0) and (l.parents
|| 2147483647)
) q using (item_id);
for the full context where I used that query, go to
http://merlinmoncure.blogspot.com/2007/09/one-of-my-favorite-problems-in.html
The really odd thing to me is that multiple SRF as field functions
expand to LCM number of rows. OTOH, this gives us a brain busting
(seasonally themed) way to count up the 12 days of Christmas :D
create or replace function f(i int) returns setof int as
$$
select generate_series(1, $1);
$$ language sql;
select sum((v).f) from (select f(f(12))) v;
sum
-----
364
(1 row)
merlin
From | Date | Subject | |
---|---|---|---|
Next Message | Tom Lane | 2007-12-03 22:16:47 | Re: Moving pgstat.stat and pgstat.tmp |
Previous Message | Stefan Niantschur | 2007-12-03 21:54:04 | Re: pgcrypto functions fail for asymmetric encryption/decryption |