If you really can't fix your design (or don't want to use the very good suggestion from jmz), your only choice is probably a set returning function that builds the necessary UNION "on the fly" and then returns the results from that.
create or replace function my_union()
returns table(a integer, b integer, c integer)
as
$body$
declare
union_cursor refcursor;
table_cursor cursor for SELECT table_name FROM union_source;
union_query text := '';
begin
-- build the query string for the union
for table_list_record in table_cursor loop
if union_query '' then
union_query := union_query||' UNION ALL';
end if;
union_query := union_query||' SELECT a,b,c FROM '||table_list_record.table_name;
end loop;
-- run the union and return the result
for a,b,c IN EXECUTE union_query LOOP
return next;
end loop;
end;
$body$
language plpgsql;
The function builds the necessary UNION based on the table names in union_source and then executes the union and returns the result.
You could extend the union_source table to also store the column list for each table, if the columns do not always have the same names.
To use this function, simply select from it:
select *
from my_union()