INTO is ambiguous in this use case and then is prohibited there.
You can use a CREATE TABLE AS SELECT instead.
CREATE OR REPLACE FUNCTION public.f1(tablename character varying) RETURNS integer LANGUAGE plpgsql AS $function$ begin execute 'create temp table xx on commit drop as select * from ' || quote_ident(tablename); return (select count(*) from xx); end; $function$ postgres=# select f1('omega'); f1 ──── 2 (1 row)