Fix PL/Python for recursion and interleaved set-returning functions.
[pgsql.git] / src / pl / plpython / expected / plpython_setof.out
blob308d2abb7f36c7be8a101dcabd56e68477857d10
1 --
2 -- Test returning SETOF
3 --
4 CREATE FUNCTION test_setof_error() RETURNS SETOF text AS $$
5 return 37
6 $$ LANGUAGE plpythonu;
7 SELECT test_setof_error();
8 ERROR:  returned object cannot be iterated
9 DETAIL:  PL/Python set-returning functions must return an iterable object.
10 CONTEXT:  PL/Python function "test_setof_error"
11 CREATE FUNCTION test_setof_as_list(count integer, content text) RETURNS SETOF text AS $$
12 return [ content ]*count
13 $$ LANGUAGE plpythonu;
14 CREATE FUNCTION test_setof_as_tuple(count integer, content text) RETURNS SETOF text AS $$
15 t = ()
16 for i in range(count):
17         t += ( content, )
18 return t
19 $$ LANGUAGE plpythonu;
20 CREATE FUNCTION test_setof_as_iterator(count integer, content text) RETURNS SETOF text AS $$
21 class producer:
22         def __init__ (self, icount, icontent):
23                 self.icontent = icontent
24                 self.icount = icount
25         def __iter__ (self):
26                 return self
27         def next (self):
28                 if self.icount == 0:
29                         raise StopIteration
30                 self.icount -= 1
31                 return self.icontent
32 return producer(count, content)
33 $$ LANGUAGE plpythonu;
34 CREATE FUNCTION test_setof_spi_in_iterator() RETURNS SETOF text AS
36     for s in ('Hello', 'Brave', 'New', 'World'):
37         plpy.execute('select 1')
38         yield s
39         plpy.execute('select 2')
41 LANGUAGE plpythonu;
42 -- Test set returning functions
43 SELECT test_setof_as_list(0, 'list');
44  test_setof_as_list 
45 --------------------
46 (0 rows)
48 SELECT test_setof_as_list(1, 'list');
49  test_setof_as_list 
50 --------------------
51  list
52 (1 row)
54 SELECT test_setof_as_list(2, 'list');
55  test_setof_as_list 
56 --------------------
57  list
58  list
59 (2 rows)
61 SELECT test_setof_as_list(2, null);
62  test_setof_as_list 
63 --------------------
66 (2 rows)
68 SELECT test_setof_as_tuple(0, 'tuple');
69  test_setof_as_tuple 
70 ---------------------
71 (0 rows)
73 SELECT test_setof_as_tuple(1, 'tuple');
74  test_setof_as_tuple 
75 ---------------------
76  tuple
77 (1 row)
79 SELECT test_setof_as_tuple(2, 'tuple');
80  test_setof_as_tuple 
81 ---------------------
82  tuple
83  tuple
84 (2 rows)
86 SELECT test_setof_as_tuple(2, null);
87  test_setof_as_tuple 
88 ---------------------
91 (2 rows)
93 SELECT test_setof_as_iterator(0, 'list');
94  test_setof_as_iterator 
95 ------------------------
96 (0 rows)
98 SELECT test_setof_as_iterator(1, 'list');
99  test_setof_as_iterator 
100 ------------------------
101  list
102 (1 row)
104 SELECT test_setof_as_iterator(2, 'list');
105  test_setof_as_iterator 
106 ------------------------
107  list
108  list
109 (2 rows)
111 SELECT test_setof_as_iterator(2, null);
112  test_setof_as_iterator 
113 ------------------------
116 (2 rows)
118 SELECT test_setof_spi_in_iterator();
119  test_setof_spi_in_iterator 
120 ----------------------------
121  Hello
122  Brave
123  New
124  World
125 (4 rows)
127 -- set-returning function that modifies its parameters
128 CREATE OR REPLACE FUNCTION ugly(x int, lim int) RETURNS SETOF int AS $$
129 global x
130 while x <= lim:
131     yield x
132     x = x + 1
133 $$ LANGUAGE plpythonu;
134 SELECT ugly(1, 5);
135  ugly 
136 ------
137     1
138     2
139     3
140     4
141     5
142 (5 rows)
144 -- interleaved execution of such a function
145 SELECT ugly(1,3), ugly(7,8);
146  ugly | ugly 
147 ------+------
148     1 |    7
149     2 |    8
150     3 |    7
151     1 |    8
152     2 |    7
153     3 |    8
154 (6 rows)
156 -- returns set of named-composite-type tuples
157 CREATE OR REPLACE FUNCTION get_user_records()
158 RETURNS SETOF users
159 AS $$
160     return plpy.execute("SELECT * FROM users ORDER BY username")
161 $$ LANGUAGE plpythonu;
162 SELECT get_user_records();
163    get_user_records   
164 ----------------------
165  (jane,doe,j_doe,1)
166  (john,doe,johnd,2)
167  (rick,smith,slash,4)
168  (willem,doe,w_doe,3)
169 (4 rows)
171 SELECT * FROM get_user_records();
172  fname  | lname | username | userid 
173 --------+-------+----------+--------
174  jane   | doe   | j_doe    |      1
175  john   | doe   | johnd    |      2
176  rick   | smith | slash    |      4
177  willem | doe   | w_doe    |      3
178 (4 rows)
180 -- same, but returning set of RECORD
181 CREATE OR REPLACE FUNCTION get_user_records2()
182 RETURNS TABLE(fname text, lname text, username text, userid int)
183 AS $$
184     return plpy.execute("SELECT * FROM users ORDER BY username")
185 $$ LANGUAGE plpythonu;
186 SELECT get_user_records2();
187   get_user_records2   
188 ----------------------
189  (jane,doe,j_doe,1)
190  (john,doe,johnd,2)
191  (rick,smith,slash,4)
192  (willem,doe,w_doe,3)
193 (4 rows)
195 SELECT * FROM get_user_records2();
196  fname  | lname | username | userid 
197 --------+-------+----------+--------
198  jane   | doe   | j_doe    |      1
199  john   | doe   | johnd    |      2
200  rick   | smith | slash    |      4
201  willem | doe   | w_doe    |      3
202 (4 rows)