| -- |
| -- Test returning SETOF |
| -- |
| CREATE FUNCTION test_setof_error() RETURNS SETOF text AS $$ |
| return 37 |
| $$ LANGUAGE plpythonu; |
| SELECT test_setof_error(); |
| ERROR: returned object cannot be iterated |
| DETAIL: PL/Python set-returning functions must return an iterable object. |
| CONTEXT: PL/Python function "test_setof_error" |
| CREATE FUNCTION test_setof_as_list(count integer, content text) RETURNS SETOF text AS $$ |
| return [ content ]*count |
| $$ LANGUAGE plpythonu; |
| CREATE FUNCTION test_setof_as_tuple(count integer, content text) RETURNS SETOF text AS $$ |
| t = () |
| for i in range(count): |
| t += ( content, ) |
| return t |
| $$ LANGUAGE plpythonu; |
| CREATE FUNCTION test_setof_as_iterator(count integer, content text) RETURNS SETOF text AS $$ |
| class producer: |
| def __init__ (self, icount, icontent): |
| self.icontent = icontent |
| self.icount = icount |
| def __iter__ (self): |
| return self |
| def next (self): |
| if self.icount == 0: |
| raise StopIteration |
| self.icount -= 1 |
| return self.icontent |
| return producer(count, content) |
| $$ LANGUAGE plpythonu; |
| CREATE FUNCTION test_setof_spi_in_iterator() RETURNS SETOF text AS |
| $$ |
| for s in ('Hello', 'Brave', 'New', 'World'): |
| plpy.execute('select 1') |
| yield s |
| plpy.execute('select 2') |
| $$ |
| LANGUAGE plpythonu; |
| -- Test set returning functions |
| SELECT test_setof_as_list(0, 'list'); |
| test_setof_as_list |
| -------------------- |
| (0 rows) |
| |
| SELECT test_setof_as_list(1, 'list'); |
| test_setof_as_list |
| -------------------- |
| list |
| (1 row) |
| |
| SELECT test_setof_as_list(2, 'list'); |
| test_setof_as_list |
| -------------------- |
| list |
| list |
| (2 rows) |
| |
| SELECT test_setof_as_list(2, null); |
| test_setof_as_list |
| -------------------- |
| |
| |
| (2 rows) |
| |
| SELECT test_setof_as_tuple(0, 'tuple'); |
| test_setof_as_tuple |
| --------------------- |
| (0 rows) |
| |
| SELECT test_setof_as_tuple(1, 'tuple'); |
| test_setof_as_tuple |
| --------------------- |
| tuple |
| (1 row) |
| |
| SELECT test_setof_as_tuple(2, 'tuple'); |
| test_setof_as_tuple |
| --------------------- |
| tuple |
| tuple |
| (2 rows) |
| |
| SELECT test_setof_as_tuple(2, null); |
| test_setof_as_tuple |
| --------------------- |
| |
| |
| (2 rows) |
| |
| SELECT test_setof_as_iterator(0, 'list'); |
| test_setof_as_iterator |
| ------------------------ |
| (0 rows) |
| |
| SELECT test_setof_as_iterator(1, 'list'); |
| test_setof_as_iterator |
| ------------------------ |
| list |
| (1 row) |
| |
| SELECT test_setof_as_iterator(2, 'list'); |
| test_setof_as_iterator |
| ------------------------ |
| list |
| list |
| (2 rows) |
| |
| SELECT test_setof_as_iterator(2, null); |
| test_setof_as_iterator |
| ------------------------ |
| |
| |
| (2 rows) |
| |
| SELECT test_setof_spi_in_iterator(); |
| test_setof_spi_in_iterator |
| ---------------------------- |
| Hello |
| Brave |
| New |
| World |
| (4 rows) |
| |
| -- set-returning function that modifies its parameters |
| CREATE OR REPLACE FUNCTION ugly(x int, lim int) RETURNS SETOF int AS $$ |
| global x |
| while x <= lim: |
| yield x |
| x = x + 1 |
| $$ LANGUAGE plpythonu; |
| SELECT ugly(1, 5); |
| ugly |
| ------ |
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| (5 rows) |
| |
| -- interleaved execution of such a function |
| SELECT ugly(1,3), ugly(7,8); |
| ugly | ugly |
| ------+------ |
| 1 | 7 |
| 2 | 8 |
| 3 | |
| (3 rows) |
| |
| -- returns set of named-composite-type tuples |
| CREATE OR REPLACE FUNCTION get_user_records() |
| RETURNS SETOF users |
| AS $$ |
| return plpy.execute("SELECT * FROM users ORDER BY username") |
| $$ LANGUAGE plpythonu; |
| SELECT get_user_records(); |
| get_user_records |
| ---------------------- |
| (jane,doe,j_doe,1) |
| (john,doe,johnd,2) |
| (rick,smith,slash,4) |
| (willem,doe,w_doe,3) |
| (4 rows) |
| |
| SELECT * FROM get_user_records(); |
| fname | lname | username | userid |
| --------+-------+----------+-------- |
| jane | doe | j_doe | 1 |
| john | doe | johnd | 2 |
| rick | smith | slash | 4 |
| willem | doe | w_doe | 3 |
| (4 rows) |
| |
| -- same, but returning set of RECORD |
| CREATE OR REPLACE FUNCTION get_user_records2() |
| RETURNS TABLE(fname text, lname text, username text, userid int) |
| AS $$ |
| return plpy.execute("SELECT * FROM users ORDER BY username") |
| $$ LANGUAGE plpythonu; |
| SELECT get_user_records2(); |
| get_user_records2 |
| ---------------------- |
| (jane,doe,j_doe,1) |
| (john,doe,johnd,2) |
| (rick,smith,slash,4) |
| (willem,doe,w_doe,3) |
| (4 rows) |
| |
| SELECT * FROM get_user_records2(); |
| fname | lname | username | userid |
| --------+-------+----------+-------- |
| jane | doe | j_doe | 1 |
| john | doe | johnd | 2 |
| rick | smith | slash | 4 |
| willem | doe | w_doe | 3 |
| (4 rows) |
| |