return query with set-returning functions
we might have found a bug in postgres... first draft of bug report looks like
so
using 8.3.3, i have the following 2 plpgsql functions
reconnoiter=# \df stratcon.fetch_dataset
List of
functions
Schema | Name | Result data type |
Argument data types
----------+---------------+-----------------------------------------+-------------------------------------------------------------------------------------
stratcon | fetch_dataset | setof stratcon.rollup_matrix_numeric_5m | integer,
text, timestamp with time zone, timestamp with time zone, integer, boolean
stratcon | fetch_dataset | setof stratcon.rollup_matrix_numeric_5m | uuid,
text, timestamp with time zone, timestamp with time zone, integer, boolean
the second function takes a uuid, looks up an integer representation, and then
calls the first function. whenever I run it, I get the following error:
reconnoiter=# select * from
stratcon.fetch_dataset('cfe2aad7-71e5-400b-8418-a6d5834a0386'::uuid,'inoctets','2008-08-04
15:01:13-04','2008-08-11 15:01:13-04',500,'t');
ERROR: structure of query does not match function result type
CONTEXT: PL/pgSQL function "fetch_dataset" line 9 at RETURN QUERY
if i run the first function manually though, that function runs fine. looking
at pg_proc, the return types seem like they should be fine (same type, is a
set)
reconnoiter=# select proname, proargtypes, proretset, prorettype from pg_proc
where proname = 'fetch_dataset';
proname | proargtypes | proretset | prorettype
---------------+-------------------------+-----------+------------
fetch_dataset | 23 25 1184 1184 23 16 | t | 16905
fetch_dataset | 2950 25 1184 1184 23 16 | t | 16905
i even made a modified version to make sure the return type would match up
with the datatype:
CREATE or replace FUNCTION stratcon.fetch_dataset(in_uuid uuid, in_name text,
in_start_time timestamp with time zone, in_end_time timestamp with time zone,
in_hopeful_nperiods integer, derive boolean) RETURNS SETOF
stratcon.rollup_matrix_numeric_5m
AS $$
declare
v_sid int;
v_record stratcon.rollup_matrix_numeric_5m%rowtype;
begin
select sid into v_sid from stratcon.map_uuid_to_sid where id = in_uuid;
if not found then
return;
end if;
for v_record in select sid, name, rollup_time, count_rows, avg_value from
stratcon.fetch_dataset(v_sid::integer, in_name, in_start_time, in_end_time,
in_hopeful_nperiods, derive) loop
return next v_record;
end loop;
--- return query select sid, name, rollup_time, count_rows, avg_value from
stratcon.fetch_dataset(v_sid::integer, in_name, in_start_time, in_end_time,
in_hopeful_nperiods, derive);
return;
end
$$
LANGUAGE plpgsql;
in this case, the loop version works fine, even though I get an error with
return query. is there some limitation with return query and set returning
functions, or is this just a bug?
btw, table looks like this:
reconnoiter=# \d stratcon.rollup_matrix_numeric_5m
Table "stratcon.rollup_matrix_numeric_5m"
Column | Type | Modifiers
-------------+--------------------------+-----------
sid | integer | not null
name | text | not null
rollup_time | timestamp with time zone | not null
count_rows | integer |
avg_value | numeric |
Indexes:
"rollup_matrix_numeric_5m_pkey" PRIMARY KEY, btree (rollup_time, sid,
name) CLUSTER
the full code for the int version of the function can be found at
https://labs.omniti.com/trac/reconnoiter/browser/trunk/sql/reconnoiter_ddl_dump.sql#L402
--
Robert Treat
Build A Brighter LAMP :: Linux Apache {middleware} PostgreSQL
Robert Treat <xzilla@users.sourceforge.net> writes:
the second function takes a uuid, looks up an integer representation, and then
calls the first function. whenever I run it, I get the following error:
reconnoiter=# select * from
stratcon.fetch_dataset('cfe2aad7-71e5-400b-8418-a6d5834a0386'::uuid,'inoctets','2008-08-04
15:01:13-04','2008-08-11 15:01:13-04',500,'t');
ERROR: structure of query does not match function result type
CONTEXT: PL/pgSQL function "fetch_dataset" line 9 at RETURN QUERY
Works here after loading your schema dump, or at least it doesn't
complain:
treat-# stratcon.fetch_dataset('cfe2aad7-71e5-400b-8418-a6d5834a0386'::uuid,'inoctets','2008-08-04
treat'# 15:01:13-04','2008-08-11 15:01:13-04',500,'t');
sid | name | rollup_time | count_rows | avg_value
-----+------+-------------+------------+-----------
(0 rows)
It's possible that I'm missing the failure for lack of suitable test
data, but right offhand I'd bet that the problem is that there are
dropped columns in your copy of stratcon.rollup_matrix_numeric_5m.
plpgsql has some shortcomings in dealing with rowtypes that contain
dropped columns ...
regards, tom lane
On Monday 11 August 2008 21:38:38 Tom Lane wrote:
Robert Treat <xzilla@users.sourceforge.net> writes:
the second function takes a uuid, looks up an integer representation, and
then calls the first function. whenever I run it, I get the following
error:reconnoiter=# select * from
stratcon.fetch_dataset('cfe2aad7-71e5-400b-8418-a6d5834a0386'::uuid,'inoc
tets','2008-08-04 15:01:13-04','2008-08-11 15:01:13-04',500,'t');
ERROR: structure of query does not match function result type
CONTEXT: PL/pgSQL function "fetch_dataset" line 9 at RETURN QUERYWorks here after loading your schema dump, or at least it doesn't
complain:treat-#
stratcon.fetch_dataset('cfe2aad7-71e5-400b-8418-a6d5834a0386'::uuid,'inocte
ts','2008-08-04 treat'# 15:01:13-04','2008-08-11 15:01:13-04',500,'t');
sid | name | rollup_time | count_rows | avg_value
-----+------+-------------+------------+-----------
(0 rows)It's possible that I'm missing the failure for lack of suitable test
data, but right offhand I'd bet that the problem is that there are
dropped columns in your copy of stratcon.rollup_matrix_numeric_5m.
plpgsql has some shortcomings in dealing with rowtypes that contain
dropped columns ...
Ah, right, should have mentioned that.... I had suspected that too, and
reloaded the functions after finding a couple, thinking that would have been
enough, but I guess something more brute force is needed... do I have to
drop/recreate the table, or is there something a bit more friendly that can
be done.
--
Robert Treat
Build A Brighter LAMP :: Linux Apache {middleware} PostgreSQL