From: | Merlin Moncure <mmoncure(at)gmail(dot)com> |
---|---|
To: | Pavel Stehule <pavel(dot)stehule(at)gmail(dot)com> |
Cc: | screamge <screamge(at)gmail(dot)com>, pgsql-general(at)postgresql(dot)org |
Subject: | Re: RETURN QUERY SELECT & TYPE |
Date: | 2010-08-10 16:28:35 |
Message-ID: | AANLkTikW7QdCpMPvX6XFAUjuOaHkoX9aFxMFb3TgLYF2@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-general |
On Tue, Aug 10, 2010 at 2:27 AM, Pavel Stehule <pavel(dot)stehule(at)gmail(dot)com> wrote:
> Hello
>
> 2010/8/10 screamge <screamge(at)gmail(dot)com>:
>> Here is code of first procedure:
>> CREATE TYPE some_item AS
>> (id integer,
>> title character varying,
>> ...
>> );
>>
>>
>> CREATE OR REPLACE FUNCTION some_func (integer) RETURNS some_item AS
>> ...
>> itemid ALIAS for $1;
>> resulter some_item%rowtype;
>>
>> ...
>> SELECT INTO resulter
>> n_id, t_title FROM some_table WHERE n_id = itemid;
>> RETURN resulter;
>>
>>
>> I want to call some_func from another procedure and get result set of
>> some_items type. Something like this:
>>
>> CREATE OR REPLACE FUNCTION other_func (integer) RETURNS SETOF some_item AS
>> ...
>> RETURN QUERY SELECT some_func(id) FROM another_table;
>> ;
>
> hmm .. the I see it. PostgreSQL expect list of scalar values, but you
> are return a composite value. Pg does packing to composite type
> automatically. What you can do. Unpack a composite before (with
> subselect as protection to duplicate func call):
>
> RETURN QUERY SELECT (some_func).* FROM (SELECT some_func(id) FROM
> another_table) xx;
right -- when you have only a single composite type going out of the
function, postgres assumes you are returning its fields, not the type
itself. This also affects how you will access the results of the
function in the calling query. In non 'set returning' functions it's
not as noticeable if you are using variable assignment to set
composite memebers.
If you wanted to force a composite type return from a function (note:
I use composite types and have never had a reason to do this) you
could wrap the type to do it:
create table foo(foo_id) int;
create type foowrap(foo foo);
create function get_foo() returns setof foowrap as
$$
begin
return query select row(1)::foo;
end;
$$ language plpgsql;
postgres=# select * from get_foo();
foo
-----
(1)
(1 row)
A more direct way to do this is to declare the function without the
wrap and simply don't use 'select *':
create function get_foo() returns setof foo as
$$
begin
return query select 1;
end;
$$ language plpgsql;
postgres=# select get_foo();
get_foo
---------
(1)
(1 row)
postgres=# select * from get_foo();
foo_id
--------
1
(1 row)
merlin
From | Date | Subject | |
---|---|---|---|
Next Message | Tom Lane | 2010-08-10 17:32:55 | Re: Finding last checkpoint time |
Previous Message | Bruce Momjian | 2010-08-10 15:20:53 | Re: Finding last checkpoint time |