Isso funciona:
CREATE OR REPLACE FUNCTION sql_fun()
RETURNS TABLE (id UUID) AS $$
INSERT INTO foo DEFAULT VALUES
RETURNING id
$$ LANGUAGE SQL;
SELECT *
FROM sql_fun();
Isso não:
CREATE OR REPLACE FUNCTION plpgsql_fun()
RETURNS TABLE (id UUID) AS $$
BEGIN
RETURN QUERY
INSERT INTO foo DEFAULT VALUES
RETURNING id;
END
$$ LANGUAGE PLpgSQL;
SELECT *
FROM plpgsql_fun();
Isso é um bug no PL/pgSQL? Como posso corrigir isso mantendo o tipo de retorno como está?
A solução é qualificar todas as colunas das
RETURNING
quais têm o mesmo nome das colunasRETURNS TABLE
com o nome da tabela que eraINSERTED INTO
:Se o nome da tabela for longo e houver várias colunas, o nome poderá ser alias:
Você pode até corrigi-lo mantendo toda a função como está, adicionando o parâmetro de configuração especial
#variable_conflict
:Mas é uma boa forma de fazê-lo por nomes de colunas de qualificação de tabela, como você se encontrou - se possível. Existem casos de canto, onde não é facilmente possível:
Relacionado:
Nas primeiras versões, o Postgres não gerava uma exceção, mas preferia silenciosamente valores de parâmetro em vez de colunas:
E evite colocar CaMeL no nome do idioma
plpgsql
. Isso para de funcionar quando citado, o que (infelizmente) é uma negligência generalizada.