Podany przykład można w całości zastąpić przez RETURN QUERY :
BEGIN
RETURN QUERY SELECT y_.y, 'hi' FROM generate_series(1,10,1) AS y_(y)
END;
co będzie dużo szybciej.
Ogólnie rzecz biorąc, powinieneś unikać iteracji, gdy tylko jest to możliwe, i zamiast tego preferować operacje zorientowane na zbiór.
Gdzie return next nad pętlą jest nieuniknione (co jest bardzo rzadkie i najczęściej ogranicza się do sytuacji, gdy potrzebujesz obsługi wyjątków) musisz ustawić OUT wartości parametrów lub parametry tabeli, a następnie return next bez argumentów.
W tym przypadku Twoim problemem jest linia SELECT yr.y, 'hi'; który nic nie robi. Zakładasz, że niejawne miejsce docelowe SELECT to parametry wyjściowe, ale tak nie jest. Musiałbyś użyć parametrów out jako zmiennych pętli, tak jak zrobił to @peterm, użyć przypisań lub użyć 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;