-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmaterialize_cursor.sql
More file actions
88 lines (68 loc) · 2.58 KB
/
Copy pathmaterialize_cursor.sql
File metadata and controls
88 lines (68 loc) · 2.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
-- Test srf_materialize_cursor
CREATE OR REPLACE FUNCTION single_column(text) RETURNS SETOF text LANGUAGE python AS
$python$
def main(txt):
return prepare(txt)
$python$;
SELECT * FROM single_column('SELECT ''foo''::text AS bleh');
SELECT * FROM single_column('SELECT ''foo''::text AS meh UNION ALL SELECT ''bar'' ORDER BY meh;');
CREATE OR REPLACE FUNCTION multi_column(OUT i int, OUT n numeric) RETURNS SETOF RECORD LANGUAGE python AS
$python$
def main():
return prepare('SELECT 123::int AS i, 4321.234423::numeric AS n')
$python$;
SELECT * FROM multi_column();
-- Getting a bit side-tracked with this next test as it's not materialization.
--
-- The tuple descriptor must be *exactly* the same for the following to work.
-- That is, the iterator produces anonymous records targeting an anonymous
-- record type. In general, when creating a datum from a Postgres.Object, it's
-- preferred to cast, but in this particular case casting is not possible.
SELECT multi_column();
DROP TABLE IF EXISTS no_columns CASCADE;
CREATE TABLE no_columns ();
INSERT INTO no_columns DEFAULT VALUES;
INSERT INTO no_columns DEFAULT VALUES;
INSERT INTO no_columns DEFAULT VALUES;
INSERT INTO no_columns DEFAULT VALUES;
CREATE OR REPLACE FUNCTION no_columns_func() RETURNS SETOF no_columns LANGUAGE python AS
$python$
def main():
return prepare('SELECT * FROM no_columns')
$python$;
SELECT count(*) FROM no_columns_func();
DROP TABLE IF EXISTS a_single_column CASCADE;
CREATE TABLE a_single_column (i int);
INSERT INTO a_single_column SELECT i FROM generate_series(1, 200) AS g(i);
CREATE OR REPLACE FUNCTION a_single_column_func() RETURNS SETOF a_single_column LANGUAGE python AS
$python$
def main():
r = prepare('SELECT * FROM a_single_column').rows()
next(r)
next(r)
return r
$python$;
-- 200 - 2
SELECT count(*) FROM a_single_column_func();
DROP TABLE IF EXISTS column_pair CASCADE;
CREATE TABLE column_pair (k int, v text);
INSERT INTO column_pair SELECT i as k, i::text as v FROM generate_series(1, 235) AS g(i);
CREATE OR REPLACE FUNCTION column_pair_func() RETURNS SETOF column_pair LANGUAGE python AS
$python$
def main():
return prepare('SELECT * FROM column_pair').chunks()
$python$;
SELECT count(*) FROM column_pair_func();
-- and finally, a scroll
CREATE OR REPLACE FUNCTION scrolled_cursor() RETURNS SETOF int LANGUAGE python AS
$python$
def main():
cur = prepare('SELECT i::int FROM generate_series(1, 223) AS g(i)').declare()
cur.direction = False
# go to the end (beginning, with backward direction)
cur.seek(0, 2)
# and scroll back 13 rows
cur.seek(-13, 1)
return cur
$python$;
SELECT * FROM scrolled_cursor();