PostgreSQL supports Set Returning Function (second name is tabular function). Functions from this class returns a table instead scalar value. There are a lot of use cases - one use case is a function "unnest"
CREATE OR REPLACE FUNCTION simple_srf(int)
RETURNS SETOF int AS $$
BEGIN
FOR i IN 1..$1
LOOP
RETURN NEXT i; -- push value to result
END LOOP;
RETURN; -- finish execution
END;
$$ LANGUAGE plpgsql IMMUTABLE STRICT;
postgres=# SELECT * FROM simple_srf(3);
simple_srf
------------
1
2
3
(3 rows)
Function "string_to_array" parse string using separator to array.
postgres=# select string_to_array('aaa*bbb*ccc','*');
string_to_array
-----------------
{aaa,bbb,ccc}
(1 row)
Unnest is simple function, that transforms a array to table. A source code of this function in plpgsql can be:
-- use PostgreSQL 8.4 syntax for simplicity
CREATE OR REPLACE FUNCTION unnest(anyarray)
RETURNS SETOF anyelement AS $$
BEGIN
FOR i IN array_lower($1,1) .. array_upper($1,1)
LOOP
RETURN NEXT $1[i];
END LOOP;
RETURN;
END;
$$ LANGUAGE plpgsql STRICT IMMUTABLE;
"Unnest" is a polymorphic set returned function. PostgreSQL supports more builtin srf (tabular) function - e.g. generic_series or generate_subscripts
A older implementation of "unnest" function was:
CREATE OR REPLACE FUNCTION unnest(anyarray)
RETURNS anyelement AS $$
SELECT $1[i] FROM generate_series(array_lower($1,1),array_upper($1,1)) g(i)
$$ LANGUAGE sql;
-- or with generate_subscripts
CREATE OR REPLACE FUNCTION unnest(anyarray)
RETURNS anyelement AS $$
/*
* g is a table alias
* i is a column alias
*/
SELECT $1[i] FROM generate_subscripts($1,1) g(i)
$$ LANGUAGE sql;