There **is** a solution with just PL/pgSQL. Simple and elegant, too. Pretty advanced stuff, though.  
Requires Postgres **9.0** or later (workaround for older versions possible).

```pgsql
CREATE OR REPLACE FUNCTION gesio(_tbl_in anyelement, _tbl_out regclass)
  RETURNS void
  LANGUAGE plpgsql AS
$func$
BEGIN
   FOR _tbl_in IN EXECUTE
      format('SELECT * FROM %s', pg_typeof(_tbl_in))
   LOOP
      -- do something with record

      EXECUTE format('INSERT INTO %s SELECT $1.*', _tbl_out)
      USING _tbl_in;
   END LOOP;
END
$func$;
```

Call (important!):

    SELECT gesio(NULL::t, 't1');

`t` and `t1` being tables with identical schema.

The polymorphic parameter (`anyelement`) is only needed if you need it's value or data type for the computation in the function body. Else you can simplify like demonstrated in this later answer:

- https://dba.stackexchange.com/questions/163962/insert-values-from-a-record-variable-into-a-subclass-table/164224#164224

### Major ingredients

- [Implicit cursor of a `FOR` loop][1] instead of explicit cursor. That's generally preferable.

- [Polymorphic types][2]

- [Object identifier types][3]

- [Dynamic SQL in plpgsql][4]

- [`VALUES` can take a row type directly.][5]

An obstacle to overcome is that variables inside the function cannot be defined as polymorphic type `anyelement` (yet). [This related answer on SO][6] explains the solution. Provides a **workaround for older versions**, too.

I am handing in a `NULL` value of type `t`, which serves three purposes:

- Provide table name.
- Provide table type.
- Serve as loop variable.

The *value* of the first parameter is discarded. Just use `NULL`.

Consider [this related answer on SO with more details][7]. The most interesting part being the last chapter *"Various complete table types"*.

*db<>fiddle [here](https://dbfiddle.uk/?rdbms=postgres_14&fiddle=337f53ceab6e655b370c6b0a5337d198)*  
<sub>Old [sqlfiddle][8]</sub>

If your computations are not too sophisticated, you may be able to replace the loop with a single dynamic SQL statement, which is typically faster.


  [1]: https://www.postgresql.org/docs/current/plpgsql-control-structures.html#PLPGSQL-RECORDS-ITERATING
  [2]: https://www.postgresql.org/docs/current/extend-type-system.html#EXTEND-TYPES-POLYMORPHIC
  [3]: https://www.postgresql.org/docs/current/datatype-oid.html
  [4]: https://www.postgresql.org/docs/current/plpgsql-statements.html#PLPGSQL-STATEMENTS-EXECUTING-DYN
  [5]: https://stackoverflow.com/a/23249595/939860
  [6]: https://stackoverflow.com/a/7635605/939860
  [7]: https://stackoverflow.com/a/11751557/939860
  [8]: http://www.sqlfiddle.com/#!17/4f363/1