Como evitar várias funções evals com a sintaxe (func ()). * Em uma consulta SQL?

Contexto

Quando uma função retorna umTABLE ou umSETOF composite-type, como esta função de amostra:

CREATE FUNCTION func(n int) returns table(i int, j bigint) as $
BEGIN
  RETURN QUERY select 1,n::bigint 
      union all select 2,n*n::bigint
      union all select 3,n*n*n::bigint;
END
$ language plpgsql;

os resultados podem ser acessados ​​por vários métodos:

1)select * from func(3) irá produzir estas colunas de saída:

 i | j 
---+---
 1 |  3
 2 |  9
 3 | 27

2)select func(3) produzirá apenas uma coluna de saída do tipo ROW.

 func  
-------
 (1,3)
 (2,9)
 (3,27)

3)select (func(3)).* irá produzir como # 1:

 i | j 
---+---
 1 |  3
 2 |  9
 3 | 27

Quando o argumento da função vem de uma tabela ou de uma subconsulta, a sintaxe # 3 é a única possível, como em:

select N, (func(N)).* from (select 2 as N union select 3 as N) s;

ou como neste relacionadoresponda. Se tivéssemosLATERAL JOIN nós poderíamos usar isso, mas até que o PostgreSQL 9.3 esteja fora, não é suportado, e as versões anteriores ainda serão usadas por anos de qualquer maneira.

Problema

Agora o problema com a sintaxe # 3 é que a função é chamada quantas vezes houver colunas no resultado. Não há razão aparente para isso, mas acontece. Podemos ver isso na versão 9.2, adicionando umRAISE NOTICE 'called for %', n na função. Com a consulta acima, ele gera:

NOTICE:  called for 2
NOTICE:  called for 2
NOTICE:  called for 3
NOTICE:  called for 3

Agora, se a função for alterada para retornar 4 colunas, assim:

CREATE FUNCTION func(n int) returns table(i int, j bigint,k int, l int) as $
BEGIN
  raise notice 'called for %', n;
  RETURN QUERY select 1,n::bigint,1,1 
      union all select 2,n*n::bigint,1,1
      union all select 3,n*n*n::bigint,1,1;
END                                        
$ language plpgsql stable;

então a mesma saída de consulta:

NOTICE:  called for 2
NOTICE:  called for 2
NOTICE:  called for 2
NOTICE:  called for 2
NOTICE:  called for 3
NOTICE:  called for 3
NOTICE:  called for 3
NOTICE:  called for 3

2 chamadas de função foram necessárias, 8 foram realmente feitas. A proporção é o número de colunas de saída.

Com a sintaxe # 2 que produz o mesmo resultado, exceto pelo layout das colunas de saída, essas várias chamadas não acontecem:

select N,func(N) from (select 2 as N union select 3 as N) s;

dá:

NOTICE:  called for 2
NOTICE:  called for 3

seguido pelas 6 linhas resultantes:

 n |    func    
---+------------
 2 | (1,2,1,1)
 2 | (2,4,1,1)
 2 | (3,8,1,1)
 3 | (1,3,1,1)
 3 | (2,9,1,1)
 3 | (3,27,1,1)
Questões

Existe uma sintaxe ou uma construção com 9.2 que alcançaria o resultado esperado fazendo apenas as chamadas de função mínimas necessárias?

Pergunta bônus: por que as avaliações múltiplas acontecem?

questionAnswers(1)

yourAnswerToTheQuestion