How to use RETURNS TABLE with an existing table in PostgreSQL?
PS: sorry for my comments, I was developing a complex code and I have a small error that seems a stupid PostgreSQL restriction on a &quot;returing table&quot; part... I was stupid, instead of concentrating and solving it, I used the internet (search engine put me here). Now, this wiki-answer is to help other readers, called by  search engine and attracted by the title of the question.
Thanks to @dezso (was a correct answer) and, please all readers, you can edit this question to be more didactic, it is a Wiki.

Since PostgreSQL-v8 we can do it! We can RETURNS EXISTING_TABLE_NAME
In its Guide, in all PostgreSQL versions, from since pg v8 to current version, all have a section named  &quot;SQL Functions as Table Sources&quot;. Let's reproduce the Guide's example with some simplifications:
CREATE TABLE foo (fooid int, foosubid int, fooname text);
INSERT INTO foo VALUES (1, 1, 'Joe'), (1, 2, 'Ed'), (2, 1, 'Mary');

CREATE FUNCTION getfoo(int) RETURNS SETOF foo AS $$
    SELECT * FROM foo WHERE fooid = $1;
$$ LANGUAGE SQL;

SELECT * FROM getfoo(1);

It is running as expected, it is perfect!
 fooid | foosubid | fooname
-------+----------+---------
     1 |        1 | Joe
     1 |        2 | Ed

The question &quot;How to use RETURNS TABLE with an existing table in PostgreSQL?&quot; have a good answer since pg v8... This is the way we do it in the last 15 years, the syntax is:  RETURNS SETOF &lt;EXISTING_TABLE_NAME&gt;.
Use clause TABLE as instantaneous CREATE TABLE for returning
The @tinlyx's confusion, explainded on his question, is about the use of the clause TABLE instead of SETOF... To think using the &quot;PostgreSQL syntax logic&quot;, we must  first remember that RETURN &lt;EXISTING_TABLE_NAME&gt; is also valid, and it has the same behavior   that RETURN &lt;EXISTING_TYPE_NAME&gt;. Is natural to return only one row.
Next step, remember that we declare a tuple with the CREATE TABLE clause (&lt;tuple_description&gt;), therefore, a good syntax to express an &quot;instant-define-tuple table&quot; is RETURN TABLE (&lt;tuple_description&gt;), and it makes sense to return TABLE -type, which is like an array type, will return several instances (TABLE is a set of tuples).
Next step, remember that we declare a tuple with the CREATE TABLE (&lt;tuple_description&gt;) clause, therefore, a good syntax to express an &quot;instantaneous table-definition&quot; is RETURN TABLE (&lt;tuple_description&gt;); and it makes sense to return Table-type, that is like Array-type, they return multiple instances (TABLE is a set of tuples).
The &quot;modern thing&quot; in PostgreSQL (!) is what @ZiggyCrueltyfreeZeitgeister showed, the RETURNS TABLE (LIKE &lt;table_name&gt;) syntax.
CREATE FUNCTION getfoo2(int) RETURNS TABLE (LIKE foo) AS $$ -- working fine!
    SELECT * FROM foo WHERE fooid = $1;
$$ LANGUAGE SQL;
SELECT * FROM getfoo2(1); -- same result as getfoo(1)


Many ways to do the same, a summary:
Expliciting the table name (two ways) or type name:

RETURNS TABLE (LIKE &lt;table_name&gt;) (modern and good)
RETURNS SETOF &lt;table_name&gt; (old but good)
RETURNS SETOF &lt;type_name&gt; (after  CREATE TYPE &lt;type_name&gt; (&lt;tuple_description&gt;))

Implicit/generic ways, by anonymous types:

RETURNS SETOF  RECORD (generic but somethimes a problem)
(exist something as?) RETURNS SETOF  ROW?

Instantaneous table-definition:

RETURNS TABLE (&lt;tuple_description&gt;)
(no RETURNS) using OUT in the parameter list.

For the last case, using our example to illustrate: CREATE FUNCTION getfoo(int, OUT fooid int, OUT foosubid int, OUT fooname text)
For dynamic and/or polymophic input you must check this explanation.
Best practice?
There are many ways to do the same, so, there are a &quot;best one&quot;?
As syntax I prefer the use of RETURNS TABLE (LIKE &lt;table_name&gt;), that is explicit: no confusion with &quot;implicit RECORD&quot;, no fear of incompatibilities...
Important for library management, DROP TABLE foo CASCADE will drop also the function: in any syntax (returns table or returns setof) PostgreSQL will do a good job.
drop table foo cascade;
NOTICE:  drop cascades to 2 other objects
DETAIL:  drop cascades to function getfoo(integer)
drop cascades to function getfoo2(integer)