DECLARE foo1 SCROLL CURSORFORSELECT * FROM tenk1 ORDERBY unique2;
DECLARE foo2 SCROLL CURSORFORSELECT * FROM tenk2;
DECLARE foo3 SCROLL CURSORFORSELECT * FROM tenk1 ORDERBY unique2;
DECLARE foo4 SCROLL CURSORFORSELECT * FROM tenk2;
DECLARE foo5 SCROLL CURSORFORSELECT * FROM tenk1 ORDERBY unique2;
DECLARE foo6 SCROLL CURSORFORSELECT * FROM tenk2;
DECLARE foo7 SCROLL CURSORFORSELECT * FROM tenk1 ORDERBY unique2;
DECLARE foo8 SCROLL CURSORFORSELECT * FROM tenk2;
DECLARE foo9 SCROLL CURSORFORSELECT * FROM tenk1 ORDERBY unique2;
DECLARE foo10 SCROLL CURSORFORSELECT * FROM tenk2;
DECLARE foo11 SCROLL CURSORFORSELECT * FROM tenk1 ORDERBY unique2;
DECLARE foo12 SCROLL CURSORFORSELECT * FROM tenk2;
DECLARE foo13 SCROLL CURSORFORSELECT * FROM tenk1 ORDERBY unique2;
DECLARE foo14 SCROLL CURSORFORSELECT * FROM tenk2;
DECLARE foo15 SCROLL CURSORFORSELECT * FROM tenk1 ORDERBY unique2;
DECLARE foo16 SCROLL CURSORFORSELECT * FROM tenk2;
DECLARE foo17 SCROLL CURSORFORSELECT * FROM tenk1 ORDERBY unique2;
DECLARE foo18 SCROLL CURSORFORSELECT * FROM tenk2;
DECLARE foo19 SCROLL CURSORFORSELECT * FROM tenk1 ORDERBY unique2;
DECLARE foo20 SCROLL CURSORFORSELECT * FROM tenk2;
DECLARE foo21 SCROLL CURSORFORSELECT * FROM tenk1 ORDERBY unique2;
DECLARE foo22 SCROLL CURSORFORSELECT * FROM tenk2;
DECLARE foo23 SCROLL CURSORFORSELECT * FROM tenk1 ORDERBY unique2;
FETCH1in foo1;
FETCH2in foo2;
FETCH3in foo3;
FETCH4in foo4;
FETCH5in foo5;
FETCH6in foo6;
FETCH7in foo7;
FETCH8in foo8;
FETCH9in foo9;
FETCH10in foo10;
FETCH11in foo11;
FETCH12in foo12;
FETCH13in foo13;
FETCH14in foo14;
FETCH15in foo15;
FETCH16in foo16;
FETCH17in foo17;
FETCH18in foo18;
FETCH19in foo19;
FETCH20in foo20;
FETCH21in foo21;
FETCH22in foo22;
FETCH23in foo23;
FETCH backward 1in foo23;
FETCH backward 2in foo22;
FETCH backward 3in foo21;
FETCH backward 4in foo20;
FETCH backward 5in foo19;
FETCH backward 6in foo18;
FETCH backward 7in foo17;
FETCH backward 8in foo16;
FETCH backward 9in foo15;
FETCH backward 10in foo14;
FETCH backward 11in foo13;
FETCH backward 12in foo12;
FETCH backward 13in foo11;
FETCH backward 14in foo10;
FETCH backward 15in foo9;
FETCH backward 16in foo8;
FETCH backward 17in foo7;
FETCH backward 18in foo6;
FETCH backward 19in foo5;
FETCH backward 20in foo4;
FETCH backward 21in foo3;
FETCH backward 22in foo2;
FETCH backward 23in foo1;
CLOSE foo1;
CLOSE foo2;
CLOSE foo3;
CLOSE foo4;
CLOSE foo5;
CLOSE foo6;
CLOSE foo7;
CLOSE foo8;
CLOSE foo9;
CLOSE foo10;
CLOSE foo11;
CLOSE foo12;
-- leave some cursors open, to test that auto-close works.
-- record this in the system view as well (don't query the time field there -- however) SELECT name, statement, is_holdable, is_binary, is_scrollable FROM pg_cursors ORDERBY1;
END;
SELECT name, statement, is_holdable, is_binary, is_scrollable FROM pg_cursors;
-- -- NO SCROLL disallows backward fetching --
BEGIN;
DECLARE foo24 NO SCROLL CURSORFORSELECT * FROM tenk1 ORDERBY unique2;
FETCH1FROM foo24;
FETCH BACKWARD 1FROM foo24; -- should fail
END;
BEGIN;
DECLARE foo24 NO SCROLL CURSORFORSELECT * FROM tenk1 ORDERBY unique2;
FETCH1FROM foo24;
FETCH ABSOLUTE 2FROM foo24; -- allowed
FETCH ABSOLUTE 1FROM foo24; -- should fail
END;
-- -- Cursors outside transaction blocks --
SELECT name, statement, is_holdable, is_binary, is_scrollable FROM pg_cursors;
BEGIN;
DECLARE foo25 SCROLL CURSORWITH HOLD FORSELECT * FROM tenk2;
FETCHFROM foo25;
FETCHFROM foo25;
COMMIT;
FETCHFROM foo25;
FETCH BACKWARD FROM foo25;
FETCH ABSOLUTE -1FROM foo25;
SELECT name, statement, is_holdable, is_binary, is_scrollable FROM pg_cursors;
CLOSE foo25;
BEGIN;
DECLARE foo25ns NO SCROLL CURSORWITH HOLD FORSELECT * FROM tenk2;
FETCHFROM foo25ns;
FETCHFROM foo25ns;
COMMIT;
FETCHFROM foo25ns;
FETCH ABSOLUTE 4FROM foo25ns;
FETCH ABSOLUTE 4FROM foo25ns; -- fail
SELECT name, statement, is_holdable, is_binary, is_scrollable FROM pg_cursors;
CLOSE foo25ns;
-- -- ROLLBACK should close holdable cursors --
BEGIN;
DECLARE foo26 CURSORWITH HOLD FORSELECT * FROM tenk1 ORDERBY unique2;
ROLLBACK;
-- should fail FETCHFROM foo26;
-- -- Parameterized DECLARE needs to insert param values into the cursor portal --
BEGIN;
CREATE FUNCTION declares_cursor(text)
RETURNS void AS'DECLARE c CURSOR FOR SELECT stringu1 FROM tenk1 WHERE stringu1 LIKE $1;'
LANGUAGE SQL;
SELECT declares_cursor('AB%');
FETCHALLFROM c;
ROLLBACK;
-- -- Test behavior of both volatile and stable functions inside a cursor; -- in particular we want to see what happens during commit of a holdable -- cursor --
create temp table tt1(f1 int);
create function count_tt1_v() returns int8as 'select count(*) from tt1' language sql volatile;
create function count_tt1_s() returns int8as 'select count(*) from tt1' language sql stable;
declare c2 cursorwith hold forselect count_tt1_v(), count_tt1_s();
insertinto tt1 values(2);
commit;
deletefrom tt1;
fetchallfrom c2;
drop function count_tt1_v(); drop function count_tt1_s();
-- Create a cursor with the BINARY option and check the pg_cursors view
BEGIN; SELECT name, statement, is_holdable, is_binary, is_scrollable FROM pg_cursors; DECLARE bc BINARYCURSORFORSELECT * FROM tenk1; SELECT name, statement, is_holdable, is_binary, is_scrollable FROM pg_cursors ORDERBY1;
ROLLBACK;
-- We should not see the portal that is created internally to -- implement EXECUTE in pg_cursors
PREPARE cprep AS SELECT name, statement, is_holdable, is_binary, is_scrollable FROM pg_cursors;
EXECUTE cprep;
-- test CLOSE ALL; SELECT name FROM pg_cursors ORDERBY1;
CLOSE ALL; SELECT name FROM pg_cursors ORDERBY1;
BEGIN; DECLARE foo1 CURSORWITH HOLD FORSELECT1; DECLARE foo2 CURSOR WITHOUT HOLD FORSELECT1; SELECT name FROM pg_cursors ORDERBY1;
CLOSE ALL; SELECT name FROM pg_cursors ORDERBY1; COMMIT;
-- Check DELETE WHERE CURRENT
BEGIN; DECLARE c1 CURSORFORSELECT * FROM uctest; FETCH2FROM c1; DELETEFROM uctest WHERE CURRENT OF c1; -- should show deletion SELECT * FROM uctest; -- cursor did not move FETCHALLFROM c1; -- cursor is insensitive
MOVE BACKWARD ALLIN c1; FETCHALLFROM c1; COMMIT; -- should still see deletion SELECT * FROM uctest;
-- Check UPDATE WHERE CURRENT; this time use FOR UPDATE
BEGIN; DECLARE c1 CURSORFORSELECT * FROM uctest FORUPDATE; FETCH c1; UPDATE uctest SET f1 = 8WHERE CURRENT OF c1; SELECT * FROM uctest; COMMIT; SELECT * FROM uctest;
-- Check repeated-update and update-then-delete cases
BEGIN; DECLARE c1 CURSORFORSELECT * FROM uctest; FETCH c1; UPDATE uctest SET f1 = f1 + 10WHERE CURRENT OF c1; SELECT * FROM uctest; UPDATE uctest SET f1 = f1 + 10WHERE CURRENT OF c1; SELECT * FROM uctest; -- insensitive cursor should not show effects of updates or deletes FETCH RELATIVE 0FROM c1; DELETEFROM uctest WHERE CURRENT OF c1; SELECT * FROM uctest; DELETEFROM uctest WHERE CURRENT OF c1; -- no-op SELECT * FROM uctest; UPDATE uctest SET f1 = f1 + 10WHERE CURRENT OF c1; -- no-op SELECT * FROM uctest; FETCH RELATIVE 0FROM c1;
ROLLBACK; SELECT * FROM uctest;
BEGIN; DECLARE c1 CURSORFORSELECT * FROM uctest FORUPDATE; FETCH c1; UPDATE uctest SET f1 = f1 + 10WHERE CURRENT OF c1; SELECT * FROM uctest; UPDATE uctest SET f1 = f1 + 10WHERE CURRENT OF c1; SELECT * FROM uctest; DELETEFROM uctest WHERE CURRENT OF c1; SELECT * FROM uctest; DELETEFROM uctest WHERE CURRENT OF c1; -- no-op SELECT * FROM uctest; UPDATE uctest SET f1 = f1 + 10WHERE CURRENT OF c1; -- no-op SELECT * FROM uctest; --- FOR UPDATE cursors can't currently scroll back, so this is an error: FETCH RELATIVE 0FROM c1;
ROLLBACK; SELECT * FROM uctest;
-- Check insensitive cursor with INSERT -- (The above tests don't test the SQL notion of an insensitive cursor -- correctly, because per SQL standard, changes from WHERE CURRENT OF -- commands should be visible in the cursor. So here we make the -- changes with a command that is independent of the cursor.)
BEGIN; DECLARE c1 INSENSITIVECURSORFORSELECT * FROM uctest; INSERTINTO uctest VALUES (10, 'ten'); FETCH NEXT FROM c1; FETCH NEXT FROM c1; FETCH NEXT FROM c1; -- insert not visible COMMIT; SELECT * FROM uctest; DELETEFROM uctest WHERE f1 = 10; -- restore test table state
BEGIN; DECLARE c1 CURSORFORSELECT * FROM uctest FORUPDATE; FETCH1FROM c1; UPDATE uctest SET f1 = f1 + 10WHERE CURRENT OF c1; FETCH1FROM c1; UPDATE uctest SET f1 = f1 + 10WHERE CURRENT OF c1; FETCH1FROM c1; UPDATE uctest SET f1 = f1 + 10WHERE CURRENT OF c1; FETCH1FROM c1; COMMIT; SELECT * FROM uctest;
-- Can update from a self-join, but only if FOR UPDATE says which to use
BEGIN; DECLARE c1 CURSORFORSELECT * FROM uctest a, uctest b WHERE a.f1 = b.f1 + 5; FETCH1FROM c1; UPDATE uctest SET f1 = f1 + 10WHERE CURRENT OF c1; -- fail
ROLLBACK;
BEGIN; DECLARE c1 CURSORFORSELECT * FROM uctest a, uctest b WHERE a.f1 = b.f1 + 5FORUPDATE; FETCH1FROM c1; UPDATE uctest SET f1 = f1 + 10WHERE CURRENT OF c1; -- fail
ROLLBACK;
BEGIN; DECLARE c1 CURSORFORSELECT * FROM uctest a, uctest b WHERE a.f1 = b.f1 + 5FOR SHARE OF a; FETCH1FROM c1; UPDATE uctest SET f1 = f1 + 10WHERE CURRENT OF c1; SELECT * FROM uctest;
ROLLBACK;
-- Check various error cases
DELETEFROM uctest WHERE CURRENT OF c1; -- fail, no such cursor DECLARE cx CURSORWITH HOLD FORSELECT * FROM uctest; DELETEFROM uctest WHERE CURRENT OF cx; -- fail, can't use held cursor
BEGIN; DECLARE c CURSORFORSELECT * FROM tenk2; DELETEFROM uctest WHERE CURRENT OF c; -- fail, cursor on wrong table
ROLLBACK;
BEGIN; DECLARE c CURSORFORSELECT * FROM tenk2 FOR SHARE; DELETEFROM uctest WHERE CURRENT OF c; -- fail, cursor on wrong table
ROLLBACK;
BEGIN; DECLARE c CURSORFORSELECT * FROM tenk1 JOIN tenk2 USING (unique1); DELETEFROM tenk1 WHERE CURRENT OF c; -- fail, cursor is on a join
ROLLBACK;
BEGIN; DECLARE c CURSORFORSELECT f1,count(*) FROM uctest GROUPBY f1; DELETEFROM uctest WHERE CURRENT OF c; -- fail, cursor is on aggregation
ROLLBACK;
BEGIN; DECLARE c1 CURSORFORSELECT * FROM uctest; DELETEFROM uctest WHERE CURRENT OF c1; -- fail, no current row
ROLLBACK;
BEGIN; DECLARE c1 CURSORFORSELECT MIN(f1) FROM uctest FORUPDATE;
ROLLBACK;
-- WHERE CURRENT OF may someday work with views, but today is not that day. -- For now, just make sure it errors out cleanly. CREATE TEMP VIEW ucview ASSELECT * FROM uctest; CREATE RULE ucrule ASONDELETETO ucview DO INSTEAD DELETEFROM uctest WHERE f1 = OLD.f1;
BEGIN; DECLARE c1 CURSORFORSELECT * FROM ucview; FETCHFROM c1; DELETEFROM ucview WHERE CURRENT OF c1; -- fail, views not supported
ROLLBACK;
BEGIN; DECLARE c1 CURSORFORSELECT * FROM ucview; FETCHFROM c1; UPDATE ucview SET f1 = f1 + 10WHERE CURRENT OF c1; -- fail, views not supported
ROLLBACK;
-- Check WHERE CURRENT OF with an index-only scan
BEGIN; EXPLAIN (costs off) DECLARE c1 CURSORFORSELECT stringu1 FROM onek WHERE stringu1 = 'DZAAAA'; DECLARE c1 CURSORFORSELECT stringu1 FROM onek WHERE stringu1 = 'DZAAAA'; FETCHFROM c1; DELETEFROM onek WHERE CURRENT OF c1; SELECT stringu1 FROM onek WHERE stringu1 = 'DZAAAA';
ROLLBACK;
-- Check behavior with rewinding to a previous child scan node, -- as per bug #15395
BEGIN; CREATETABLE current_check (currentid int, payload text); CREATETABLE current_check_1 () INHERITS (current_check); CREATETABLE current_check_2 () INHERITS (current_check); INSERTINTO current_check_1 SELECT i, 'p' || i FROM generate_series(1,9) i; INSERTINTO current_check_2 SELECT i, 'P' || i FROM generate_series(10,19) i;
DECLARE c1 SCROLL CURSORFORSELECT * FROM current_check;
-- This tests the fetch-backwards code path FETCH ABSOLUTE 12FROM c1; FETCH ABSOLUTE 8FROM c1; DELETEFROM current_check WHERE CURRENT OF c1 RETURNING *;
-- This tests the ExecutorRewind code path FETCH ABSOLUTE 13FROM c1; FETCH ABSOLUTE 1FROM c1; DELETEFROM current_check WHERE CURRENT OF c1 RETURNING *;
SELECT * FROM current_check;
ROLLBACK;
-- Make sure snapshot management works okay, per bug report in -- 235395b90909301035v7228ce63q392931f15aa74b31@mail.gmail.com
BEGIN; SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; CREATETABLEcursor (a int); INSERTINTOcursorVALUES (1); DECLARE c1 NO SCROLL CURSORFORSELECT * FROMcursorFORUPDATE; UPDATEcursorSET a = 2; FETCHALLFROM c1; COMMIT; DROPTABLEcursor;
-- Check rewinding a cursor containing a stable function in LIMIT, -- per bug report in 8336843.9833.1399385291498.JavaMail.root@quick
begin; create function nochange(int) returns int as'select $1 limit 1' language sql stable; declare c cursorforselect * from int8_tbl limit nochange(3); fetchallfrom c;
move backward allin c; fetchallfrom c;
rollback;
-- Check handling of non-backwards-scan-capable plans with scroll cursors
begin; explain (costs off) declare c1 cursorforselect (select42) as x; explain (costs off) declare c1 scroll cursorforselect (select42) as x; declare c1 scroll cursorforselect (select42) as x; fetchallin c1; fetch backward allin c1;
rollback;
begin; explain (costs off) declare c2 cursorforselect generate_series(1,3) as g; explain (costs off) declare c2 scroll cursorforselect generate_series(1,3) as g; declare c2 scroll cursorforselect generate_series(1,3) as g; fetchallin c2; fetch backward allin c2;
rollback;
-- Check fetching of toasted datums via cursors.
begin;
-- Other compression algorithms may cause the compressed data to be stored -- inline. Use pglz to ensure consistent results. set default_toast_compression = 'pglz';
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.