When returning SETOF record
the output columns are not typed and not named. Thus this form can't be used directly in a FROM clause as if it was a subquery or a table.
That is, when issuing:
SELECT * from events_by_type_2('social');
we get this error:
ERROR: a column definition list is required for functions returning "record"
It can be "casted" into the correct column types by the SQL caller though. This form does work:
SELECT * from events_by_type_2('social') as (id bigint, name text);
and results in:
id | name ----+---------------- 1 | Dance Party 2 | Happy Hour ...
For this reason SETOF record
is considered less practical. It should be used only when the column types of the results are not known in advance.