Você poderia retorne uma linha inteira como tipo composto e adicione mais:
CREATE OR REPLACE FUNCTION f_rowplus()
RETURNS TABLE (rec demo, add_int int, add_txt text) AS
$func$
SELECT d, 5, 'baz'::text FROM demo d;
$func$ LANGUAGE sql;
Mas então, quando você usa a chamada simples:
SELECT * FROM f_rowplus();
Você obtém a linha da tabela
demo
como tipo composto separado. Você teria que ligar:SELECT (rec).*, add_int, add_txt FROM f_rowplus();
para obter todos os individuais colunas. Parênteses obrigatórios.
Postgres é um pouco inconsistente aqui. Se você criar uma função com:
CREATE OR REPLACE FUNCTION f_row2()
RETURNS TABLE (rec demo) AS
...
então o tipo composto
demo
é silenciosamente convertido em colunas individuais (decompostas). Nenhum link para o tipo composto original permanece. Você não pode fazer referência à coluna de saída declarada rec
nada, uma vez que foi substituído pelas colunas do tipo decomposto. Essa chamada resultaria em uma mensagem de erro:SELECT rec FROM f_row2();
Mesmo aqui:
CREATE OR REPLACE FUNCTION f_row3(OUT rec demo)
RETURNS SETOF demo AS
...
No entanto , assim que você adicionar qualquer mais
OUT
colunas, o tipo composto é preservado como declarado (não decomposto) e você pode:SELECT rec FROM f_rowplus();
com a primeira função.
Eu criei um SQL Fiddle demonstrando as variantes.
À parte
Ao usar uma função retornando várias colunas no
FROM
list (como função de tabela) e decompondo no SELECT
lista assim:SELECT (rec).* FROM f_rowplus();
... a função ainda é avaliada uma vez apenas - enquanto uma chamada e decompondo no
SELECT
list diretamente assim:SELECT (f_rowplus()).*; -- also: different result
... avaliaria uma vez para cada coluna no tipo de retorno. Detalhes: