No Postgres 9.3 ou mais tarde, use um
LATERAL
Junte-se:SELECT v.col_a, v.col_b, f.* -- no parentheses here, f is a table alias
FROM v_citizenversions v
LEFT JOIN LATERAL f_citizen_rec_modified(v.col1, v.col2) f ON true
WHERE f.col_c = _col_c;
Por que
LEFT JOIN LATERAL ... ON true
? - O registro retornado da função tem colunas concatenadas
Para versões mais antigas , há uma maneira muito simples de realizar o que eu acho você está tentando com uma função de retorno de conjunto (
RETURNS TABLE
ou RETURNS SETOF record
OU RETURNS record
):SELECT *, (f_citizen_rec_modified(col1, col2)).*
FROM v_citizenversions v
A função calcula valores uma vez para cada linha da consulta externa. Se a função retornar várias linhas, as linhas resultantes serão multiplicadas de acordo. Todos os parênteses são sintaticamente obrigatórios para decompor um tipo de linha. A função da tabela pode ser algo assim:
CREATE OR REPLACE FUNCTION f_citizen_rec_modified(_col1 int, _col2 text)
RETURNS TABLE(col_c integer, col_d text) AS
$func$
SELECT s.col_c, s.col_d
FROM some_tbl s
WHERE s.col_a = $1
AND s.col_b = $2
$func$ LANGUAGE sql;
Você precisa envolver isso em uma subconsulta ou CTE se quiser aplicar um
WHERE
cláusula porque as colunas não são visíveis no mesmo nível. (E é melhor para o desempenho de qualquer maneira, porque você evita avaliações repetidas para cada coluna de saída da função):SELECT col_a, col_b, (f_row).*
FROM (
SELECT col_a, col_b, f_citizen_rec_modified(col1, col2) AS f_row
FROM v_citizenversions v
) x
WHERE (f_row).col_c = _col_c;
Existem várias outras maneiras de fazer isso ou algo semelhante. Tudo depende do que você quer exatamente.