The handling of anyelement
as a return type is described in Polymorphic Types:
When the return value of a function is declared as a polymorphic type, there must be at least one argument position that is also polymorphic, and the actual data type supplied as the argument determines the actual result type for that call.
This argument in your case is relation_name
typed as anyelement
, and by passing NULL::table1
, this indeed tells the planner that this particular call of function1
should return SETOF table1
. So far so good.
Now the problem is that once executing, the function does not return SETOF table1
but something else. This is not what the executor was expecting, hence the error.
Despite the title of the question being How to return dynamic rows..., what you seem to want is dynamic columns or polymorphic result sets.
And this is an uphill battle with SQL, because in order to build the execution plan of a query, the planner has to know each column with its type for each intermediate result. If you design your query with a function that has to be executed in order to find the structure of its output, that creates a chicken and egg problem: planning must precede execution, it cannot depend on it.
With its dynamic type-infering technique applied to anyelement
, PostgreSQL is already pushing the envelope to implement as much polymorphism as possible given this constraint.