O exemplo dado pode ser totalmente substituído por
RETURN QUERY
:BEGIN
RETURN QUERY SELECT y_.y, 'hi' FROM generate_series(1,10,1) AS y_(y)
END;
que será muito muito mais rápido.
Em geral, você deve evitar a iteração sempre que possível e, em vez disso, favorecer as operações orientadas a conjuntos.
Onde
return next
em um loop é inevitável (o que é muito raro e principalmente limitado a quando você precisa de tratamento de exceção) você deve definir OUT
valores de parâmetro ou parâmetros de tabela e, em seguida, return next
sem argumentos. Neste caso, seu problema é a linha
SELECT yr.y, 'hi';
que não faz nada. Você está assumindo que o destino implícito de um SELECT
são os parâmetros de saída, mas esse não é o caso. Você teria que usar os parâmetros out como variáveis de loop como @peterm fez, usar atribuições ou usar SELECT INTO
:FOR yr IN SELECT * FROM generate_series(1,10,1) AS y_(y)
LOOP
RAISE NOTICE 'Computing %', yr.y;
y := yr.y;
result := 'hi';
RETURN NEXT;
END LOOP;
RETURN;