While Craig is correct that return types cannot be dynamic in function declarations, there is a way around this with polymorphic types. This is surprisingly simple and would actually work flawlessly:
CREATE OR REPLACE FUNCTION data_of(_tbl_type anyelement)
RETURNS SETOF anyelement AS
$func$
BEGIN
RETURN QUERY EXECUTE 'SELECT * FROM '|| pg_typeof(_tbl_type);
END
$func$ LANGUAGE plpgsql;
Call (important!):
SELECT rollno,fname FROM data_of(NULL::testing);
SELECT * FROM data_of(NULL::my_schema.my_table);
SELECT * FROM data_of(NULL::my_custom_type);
What you need is a well-known type. For every table there is a well-known type automatically. But you can create any type, cast NULL
to it and pass it to the function. This way you can build exactly what you have in your question ...
Related answer with a lot more details:
Refactor a PL/pgSQL function to return the output of various SELECT queries