Hasta antes de Postgres 8.3.3, la forma en que una función retornaba un select era así (prueba es una tabla de 3 columnas y 10 filas):
create or replace function f1(out col1 varchar,out col2 varchar,out col3 varchar) returns setof record as
$$
declare
l record;
q varchar;
begin
q := $S$ select * from prueba$S$;
for l in execute q loop;
col1 := l.col1;
col2 := l.col2;
col3 := l.col3;
return next;
end loop;
return;
end;
$$
language 'plpgsql';
Ahora, la cosa se hace simple gracias al return query:
create or replace function f1()
returns setof prueba as
$$
begin
return query select * from prueba;
end;
$$
language 'plpgsql';