Se por "baseado em uma tabela conhecida" você quer dizer "exatamente como uma tabela conhecida", então sim .
SQL é uma linguagem estritamente tipada e as funções devem ser criadas com um tipo de retorno bem definido. Você pode recorrer a registros anônimos como você obviamente fez (com o registro
RETURNS SETOF record
), mas você precisará adicionar uma lista de definição de coluna para cada chamada, como a mensagem de erro informa. Algo como:SELECT *
FROM my_function('foo') AS foo (
colum_name1 integer -- name and data type for every column
, colum_name2 text
, colum_name3 real);
E isso dificilmente é dinâmico.
Sua pergunta deixa espaço para interpretação, mas "com base em uma tabela conhecida" indicaria que uma função polimórfica pode fazer o truque. O tipo de retorno pode ser baseado em qualquer tipo de linha registrado dinamicamente, e há um para cada tabela no sistema automaticamente. Exemplo de código Barebone:
CREATE OR REPLACE FUNCTION my_function(_rowtype anyelement)
RETURNS SETOF anyelement AS
$func$
BEGIN
RETURN QUERY EXECUTE format(
'SELECT * FROM %s LIMIT 10'
, pg_typeof(_rowtype) -- pg_typeof() returns regtype, quoted where necessary
);
END
$func$ LANGUAGE plpgsql;
Ligar:
SELECT * FROM my_function(NULL::my_table);
Instruções detalhadas nesta resposta relacionada (veja o último capítulo "Vários tipos de tabelas completas" ):