1-- 2-- Cursor regression tests 3-- 4BEGIN; 5DECLARE foo1 SCROLL CURSOR FOR 6 SELECT 7 * 8 FROM 9 tenk1 10 ORDER BY 11 unique2; 12DECLARE foo2 SCROLL CURSOR FOR 13 SELECT 14 * 15 FROM 16 tenk2; 17DECLARE foo3 SCROLL CURSOR FOR 18 SELECT 19 * 20 FROM 21 tenk1 22 ORDER BY 23 unique2; 24DECLARE foo4 SCROLL CURSOR FOR 25 SELECT 26 * 27 FROM 28 tenk2; 29DECLARE foo5 SCROLL CURSOR FOR 30 SELECT 31 * 32 FROM 33 tenk1 34 ORDER BY 35 unique2; 36DECLARE foo6 SCROLL CURSOR FOR 37 SELECT 38 * 39 FROM 40 tenk2; 41DECLARE foo7 SCROLL CURSOR FOR 42 SELECT 43 * 44 FROM 45 tenk1 46 ORDER BY 47 unique2; 48DECLARE foo8 SCROLL CURSOR FOR 49 SELECT 50 * 51 FROM 52 tenk2; 53DECLARE foo9 SCROLL CURSOR FOR 54 SELECT 55 * 56 FROM 57 tenk1 58 ORDER BY 59 unique2; 60DECLARE foo10 SCROLL CURSOR FOR 61 SELECT 62 * 63 FROM 64 tenk2; 65DECLARE foo11 SCROLL CURSOR FOR 66 SELECT 67 * 68 FROM 69 tenk1 70 ORDER BY 71 unique2; 72DECLARE foo12 SCROLL CURSOR FOR 73 SELECT 74 * 75 FROM 76 tenk2; 77DECLARE foo13 SCROLL CURSOR FOR 78 SELECT 79 * 80 FROM 81 tenk1 82 ORDER BY 83 unique2; 84DECLARE foo14 SCROLL CURSOR FOR 85 SELECT 86 * 87 FROM 88 tenk2; 89DECLARE foo15 SCROLL CURSOR FOR 90 SELECT 91 * 92 FROM 93 tenk1 94 ORDER BY 95 unique2; 96DECLARE foo16 SCROLL CURSOR FOR 97 SELECT 98 * 99 FROM 100 tenk2; 101DECLARE foo17 SCROLL CURSOR FOR 102 SELECT 103 * 104 FROM 105 tenk1 106 ORDER BY 107 unique2; 108DECLARE foo18 SCROLL CURSOR FOR 109 SELECT 110 * 111 FROM 112 tenk2; 113DECLARE foo19 SCROLL CURSOR FOR 114 SELECT 115 * 116 FROM 117 tenk1 118 ORDER BY 119 unique2; 120DECLARE foo20 SCROLL CURSOR FOR 121 SELECT 122 * 123 FROM 124 tenk2; 125DECLARE foo21 SCROLL CURSOR FOR 126 SELECT 127 * 128 FROM 129 tenk1 130 ORDER BY 131 unique2; 132DECLARE foo22 SCROLL CURSOR FOR 133 SELECT 134 * 135 FROM 136 tenk2; 137DECLARE foo23 SCROLL CURSOR FOR 138 SELECT 139 * 140 FROM 141 tenk1 142 ORDER BY 143 unique2; 144FETCH 1 IN foo1; 145FETCH 2 IN foo2; 146FETCH 3 IN foo3; 147FETCH 4 IN foo4; 148FETCH 5 IN foo5; 149FETCH 6 IN foo6; 150FETCH 7 IN foo7; 151FETCH 8 IN foo8; 152FETCH 9 IN foo9; 153FETCH 10 IN foo10; 154FETCH 11 IN foo11; 155FETCH 12 IN foo12; 156FETCH 13 IN foo13; 157FETCH 14 IN foo14; 158FETCH 15 IN foo15; 159FETCH 16 IN foo16; 160FETCH 17 IN foo17; 161FETCH 18 IN foo18; 162FETCH 19 IN foo19; 163FETCH 20 IN foo20; 164FETCH 21 IN foo21; 165FETCH 22 IN foo22; 166FETCH 23 IN foo23; 167FETCH BACKWARD 1 IN foo23; 168FETCH BACKWARD 2 IN foo22; 169FETCH BACKWARD 3 IN foo21; 170FETCH BACKWARD 4 IN foo20; 171FETCH BACKWARD 5 IN foo19; 172FETCH BACKWARD 6 IN foo18; 173FETCH BACKWARD 7 IN foo17; 174FETCH BACKWARD 8 IN foo16; 175FETCH BACKWARD 9 IN foo15; 176FETCH BACKWARD 10 IN foo14; 177FETCH BACKWARD 11 IN foo13; 178FETCH BACKWARD 12 IN foo12; 179FETCH BACKWARD 13 IN foo11; 180FETCH BACKWARD 14 IN foo10; 181FETCH BACKWARD 15 IN foo9; 182FETCH BACKWARD 16 IN foo8; 183FETCH BACKWARD 17 IN foo7; 184FETCH BACKWARD 18 IN foo6; 185FETCH BACKWARD 19 IN foo5; 186FETCH BACKWARD 20 IN foo4; 187FETCH BACKWARD 21 IN foo3; 188FETCH BACKWARD 22 IN foo2; 189FETCH BACKWARD 23 IN foo1; 190CLOSE foo1; 191CLOSE foo2; 192CLOSE foo3; 193CLOSE foo4; 194CLOSE foo5; 195CLOSE foo6; 196CLOSE foo7; 197CLOSE foo8; 198CLOSE foo9; 199CLOSE foo10; 200CLOSE foo11; 201CLOSE foo12; 202-- leave some cursors open, to test that auto-close works. 203-- record this in the system view as well (don't query the time field there 204-- however) 205SELECT 206 name, 207 statement, 208 is_holdable, 209 is_binary, 210 is_scrollable 211FROM 212 pg_cursors 213ORDER BY 214 1; 215END; 216SELECT 217 name, 218 statement, 219 is_holdable, 220 is_binary, 221 is_scrollable 222FROM 223 pg_cursors; 224-- 225-- NO SCROLL disallows backward fetching 226-- 227BEGIN; 228DECLARE foo24 NO SCROLL CURSOR FOR 229 SELECT 230 * 231 FROM 232 tenk1 233 ORDER BY 234 unique2; 235FETCH 1 FROM foo24; 236FETCH BACKWARD 1 FROM foo24; 237-- should fail 238END; 239-- 240-- Cursors outside transaction blocks 241-- 242SELECT 243 name, 244 statement, 245 is_holdable, 246 is_binary, 247 is_scrollable 248FROM 249 pg_cursors; 250BEGIN; 251DECLARE foo25 SCROLL CURSOR WITH HOLD FOR 252 SELECT 253 * 254 FROM 255 tenk2; 256FETCH FROM foo25; 257FETCH FROM foo25; 258COMMIT; 259 260FETCH FROM foo25; 261 262FETCH BACKWARD FROM foo25; 263 264FETCH ABSOLUTE - 1 FROM foo25; 265 266SELECT 267 name, 268 statement, 269 is_holdable, 270 is_binary, 271 is_scrollable 272FROM 273 pg_cursors; 274 275CLOSE foo25; 276 277-- 278-- ROLLBACK should close holdable cursors 279-- 280BEGIN; 281DECLARE foo26 CURSOR WITH HOLD FOR 282 SELECT 283 * 284 FROM 285 tenk1 286 ORDER BY 287 unique2; 288ROLLBACK; 289 290-- should fail 291FETCH 292FROM 293 foo26; 294 295-- 296-- Parameterized DECLARE needs to insert param values into the cursor portal 297-- 298BEGIN; 299CREATE FUNCTION declares_cursor (text) 300 RETURNS void 301 AS 'DECLARE c CURSOR FOR SELECT stringu1 FROM tenk1 WHERE stringu1 LIKE $1;' 302 LANGUAGE SQL; 303SELECT 304 declares_cursor ('AB%'); 305FETCH ALL FROM c; 306ROLLBACK; 307 308-- 309-- Test behavior of both volatile and stable functions inside a cursor; 310-- in particular we want to see what happens during commit of a holdable 311-- cursor 312-- 313CREATE temp TABLE tt1 ( 314 f1 int 315); 316 317CREATE FUNCTION count_tt1_v () 318 RETURNS int8 319 AS 'select count(*) from tt1' 320 LANGUAGE sql 321 VOLATILE; 322 323CREATE FUNCTION count_tt1_s () 324 RETURNS int8 325 AS 'select count(*) from tt1' 326 LANGUAGE sql 327 STABLE; 328 329BEGIN; 330INSERT INTO tt1 331 VALUES (1); 332DECLARE c1 CURSOR FOR 333 SELECT 334 count_tt1_v (), 335 count_tt1_s (); 336INSERT INTO tt1 337 VALUES (2); 338FETCH ALL FROM c1; 339ROLLBACK; 340 341BEGIN; 342INSERT INTO tt1 343 VALUES (1); 344DECLARE c2 CURSOR WITH hold FOR 345 SELECT 346 count_tt1_v ( 347), 348 count_tt1_s (); 349INSERT INTO tt1 350 VALUES (2); 351COMMIT; 352 353DELETE FROM tt1; 354 355FETCH ALL FROM c2; 356 357DROP FUNCTION count_tt1_v (); 358 359DROP FUNCTION count_tt1_s (); 360 361-- Create a cursor with the BINARY option and check the pg_cursors view 362BEGIN; 363SELECT 364 name, 365 statement, 366 is_holdable, 367 is_binary, 368 is_scrollable 369FROM 370 pg_cursors; 371DECLARE bc BINARY CURSOR FOR 372 SELECT 373 * 374 FROM 375 tenk1; 376SELECT 377 name, 378 statement, 379 is_holdable, 380 is_binary, 381 is_scrollable 382FROM 383 pg_cursors 384ORDER BY 385 1; 386ROLLBACK; 387 388-- We should not see the portal that is created internally to 389-- implement EXECUTE in pg_cursors 390PREPARE cprep AS 391SELECT 392 name, 393 statement, 394 is_holdable, 395 is_binary, 396 is_scrollable 397FROM 398 pg_cursors; 399 400EXECUTE cprep; 401 402-- test CLOSE ALL; 403SELECT 404 name 405FROM 406 pg_cursors 407ORDER BY 408 1; 409 410CLOSE ALL; 411 412SELECT 413 name 414FROM 415 pg_cursors 416ORDER BY 417 1; 418 419BEGIN; 420DECLARE foo1 CURSOR WITH HOLD FOR 421 SELECT 422 1; 423DECLARE foo2 CURSOR WITHOUT HOLD FOR 424 SELECT 425 1; 426SELECT 427 name 428FROM 429 pg_cursors 430ORDER BY 431 1; 432CLOSE ALL; 433SELECT 434 name 435FROM 436 pg_cursors 437ORDER BY 438 1; 439COMMIT; 440 441-- 442-- Tests for updatable cursors 443-- 444CREATE TEMP TABLE uctest ( 445 f1 int, 446 f2 text 447); 448 449INSERT INTO uctest 450 VALUES (1, 'one'), (2, 'two'), (3, 'three'); 451 452SELECT 453 * 454FROM 455 uctest; 456 457-- Check DELETE WHERE CURRENT 458BEGIN; 459DECLARE c1 CURSOR FOR 460 SELECT 461 * 462 FROM 463 uctest; 464FETCH 2 FROM c1; 465DELETE FROM uctest 466WHERE CURRENT OF c1; 467-- should show deletion 468SELECT 469 * 470FROM 471 uctest; 472-- cursor did not move 473FETCH ALL 474FROM 475 c1; 476-- cursor is insensitive 477MOVE BACKWARD ALL IN c1; 478FETCH ALL FROM c1; 479COMMIT; 480 481-- should still see deletion 482SELECT 483 * 484FROM 485 uctest; 486 487-- Check UPDATE WHERE CURRENT; this time use FOR UPDATE 488BEGIN; 489DECLARE c1 CURSOR FOR 490 SELECT 491 * 492 FROM 493 uctest 494 FOR UPDATE; 495FETCH c1; 496UPDATE 497 uctest 498SET 499 f1 = 8 500WHERE 501 CURRENT OF c1; 502SELECT 503 * 504FROM 505 uctest; 506COMMIT; 507 508SELECT 509 * 510FROM 511 uctest; 512 513-- Check repeated-update and update-then-delete cases 514BEGIN; 515DECLARE c1 CURSOR FOR 516 SELECT 517 * 518 FROM 519 uctest; 520FETCH c1; 521UPDATE 522 uctest 523SET 524 f1 = f1 + 10 525WHERE 526 CURRENT OF c1; 527SELECT 528 * 529FROM 530 uctest; 531UPDATE 532 uctest 533SET 534 f1 = f1 + 10 535WHERE 536 CURRENT OF c1; 537SELECT 538 * 539FROM 540 uctest; 541-- insensitive cursor should not show effects of updates or deletes 542FETCH RELATIVE 0 543FROM 544 c1; 545DELETE FROM uctest 546WHERE CURRENT OF c1; 547SELECT 548 * 549FROM 550 uctest; 551DELETE FROM uctest 552WHERE CURRENT OF c1; 553-- no-op 554SELECT 555 * 556FROM 557 uctest; 558UPDATE 559 uctest 560SET 561 f1 = f1 + 10 562WHERE 563 CURRENT OF c1; 564-- no-op 565SELECT 566 * 567FROM 568 uctest; 569FETCH RELATIVE 0 FROM c1; 570ROLLBACK; 571 572SELECT 573 * 574FROM 575 uctest; 576 577BEGIN; 578DECLARE c1 CURSOR FOR 579 SELECT 580 * 581 FROM 582 uctest 583 FOR UPDATE; 584FETCH c1; 585UPDATE 586 uctest 587SET 588 f1 = f1 + 10 589WHERE 590 CURRENT OF c1; 591SELECT 592 * 593FROM 594 uctest; 595UPDATE 596 uctest 597SET 598 f1 = f1 + 10 599WHERE 600 CURRENT OF c1; 601SELECT 602 * 603FROM 604 uctest; 605DELETE FROM uctest 606WHERE CURRENT OF c1; 607SELECT 608 * 609FROM 610 uctest; 611DELETE FROM uctest 612WHERE CURRENT OF c1; 613-- no-op 614SELECT 615 * 616FROM 617 uctest; 618UPDATE 619 uctest 620SET 621 f1 = f1 + 10 622WHERE 623 CURRENT OF c1; 624-- no-op 625SELECT 626 * 627FROM 628 uctest; 629--- sensitive cursors can't currently scroll back, so this is an error: 630FETCH RELATIVE 0 631FROM 632 c1; 633ROLLBACK; 634 635SELECT 636 * 637FROM 638 uctest; 639 640-- Check inheritance cases 641CREATE TEMP TABLE ucchild () 642INHERITS ( 643 uctest 644); 645 646INSERT INTO ucchild 647 VALUES (100, 'hundred'); 648 649SELECT 650 * 651FROM 652 uctest; 653 654BEGIN; 655DECLARE c1 CURSOR FOR 656 SELECT 657 * 658 FROM 659 uctest 660 FOR UPDATE; 661FETCH 1 FROM c1; 662UPDATE 663 uctest 664SET 665 f1 = f1 + 10 666WHERE 667 CURRENT OF c1; 668FETCH 1 FROM c1; 669UPDATE 670 uctest 671SET 672 f1 = f1 + 10 673WHERE 674 CURRENT OF c1; 675FETCH 1 FROM c1; 676UPDATE 677 uctest 678SET 679 f1 = f1 + 10 680WHERE 681 CURRENT OF c1; 682FETCH 1 FROM c1; 683COMMIT; 684 685SELECT 686 * 687FROM 688 uctest; 689 690-- Can update from a self-join, but only if FOR UPDATE says which to use 691BEGIN; 692DECLARE c1 CURSOR FOR 693 SELECT 694 * 695 FROM 696 uctest a, 697 uctest b 698 WHERE 699 a.f1 = b.f1 + 5; 700FETCH 1 FROM c1; 701UPDATE 702 uctest 703SET 704 f1 = f1 + 10 705WHERE 706 CURRENT OF c1; 707-- fail 708ROLLBACK; 709 710BEGIN; 711DECLARE c1 CURSOR FOR 712 SELECT 713 * 714 FROM 715 uctest a, 716 uctest b 717 WHERE 718 a.f1 = b.f1 + 5 719 FOR UPDATE; 720FETCH 1 FROM c1; 721UPDATE 722 uctest 723SET 724 f1 = f1 + 10 725WHERE 726 CURRENT OF c1; 727-- fail 728ROLLBACK; 729 730BEGIN; 731DECLARE c1 CURSOR FOR 732 SELECT 733 * 734 FROM 735 uctest a, 736 uctest b 737 WHERE 738 a.f1 = b.f1 + 5 FOR SHARE OF a; 739FETCH 1 FROM c1; 740UPDATE 741 uctest 742SET 743 f1 = f1 + 10 744WHERE 745 CURRENT OF c1; 746SELECT 747 * 748FROM 749 uctest; 750ROLLBACK; 751 752-- Check various error cases 753DELETE FROM uctest 754WHERE CURRENT OF c1; 755 756-- fail, no such cursor 757DECLARE cx CURSOR WITH HOLD FOR 758 SELECT 759 * 760 FROM 761 uctest; 762 763DELETE FROM uctest 764WHERE CURRENT OF cx; 765 766-- fail, can't use held cursor 767BEGIN; 768DECLARE c CURSOR FOR 769 SELECT 770 * 771 FROM 772 tenk2; 773DELETE FROM uctest 774WHERE CURRENT OF c; 775-- fail, cursor on wrong table 776ROLLBACK; 777 778BEGIN; 779DECLARE c CURSOR FOR 780 SELECT 781 * 782 FROM 783 tenk2 FOR SHARE; 784DELETE FROM uctest 785WHERE CURRENT OF c; 786-- fail, cursor on wrong table 787ROLLBACK; 788 789BEGIN; 790DECLARE c CURSOR FOR 791 SELECT 792 * 793 FROM 794 tenk1 795 JOIN tenk2 USING (unique1); 796DELETE FROM tenk1 797WHERE CURRENT OF c; 798-- fail, cursor is on a join 799ROLLBACK; 800 801BEGIN; 802DECLARE c CURSOR FOR 803 SELECT 804 f1, 805 count(*) 806 FROM 807 uctest 808 GROUP BY 809 f1; 810DELETE FROM uctest 811WHERE CURRENT OF c; 812-- fail, cursor is on aggregation 813ROLLBACK; 814 815BEGIN; 816DECLARE c1 CURSOR FOR 817 SELECT 818 * 819 FROM 820 uctest; 821DELETE FROM uctest 822WHERE CURRENT OF c1; 823-- fail, no current row 824ROLLBACK; 825 826BEGIN; 827DECLARE c1 CURSOR FOR 828 SELECT 829 MIN(f1) 830 FROM 831 uctest 832 FOR UPDATE; 833ROLLBACK; 834 835-- WHERE CURRENT OF may someday work with views, but today is not that day. 836-- For now, just make sure it errors out cleanly. 837CREATE TEMP VIEW ucview AS 838SELECT 839 * 840FROM 841 uctest; 842 843CREATE RULE ucrule AS ON DELETE TO ucview 844 DO INSTEAD 845 DELETE FROM uctest 846 WHERE f1 = OLD.f1; 847 848BEGIN; 849DECLARE c1 CURSOR FOR 850 SELECT 851 * 852 FROM 853 ucview; 854FETCH FROM c1; 855DELETE FROM ucview 856WHERE CURRENT OF c1; 857-- fail, views not supported 858ROLLBACK; 859 860-- Check WHERE CURRENT OF with an index-only scan 861BEGIN; 862EXPLAIN ( 863 COSTS OFF 864) DECLARE c1 CURSOR FOR 865 SELECT 866 stringu1 867 FROM 868 onek 869 WHERE 870 stringu1 = 'DZAAAA'; 871DECLARE c1 CURSOR FOR 872 SELECT 873 stringu1 874 FROM 875 onek 876 WHERE 877 stringu1 = 'DZAAAA'; 878FETCH FROM c1; 879DELETE FROM onek 880WHERE CURRENT OF c1; 881SELECT 882 stringu1 883FROM 884 onek 885WHERE 886 stringu1 = 'DZAAAA'; 887ROLLBACK; 888 889-- Check behavior with rewinding to a previous child scan node, 890-- as per bug #15395 891BEGIN; 892CREATE TABLE current_check ( 893 currentid int, 894 payload text 895); 896CREATE TABLE current_check_1 () 897INHERITS ( 898 current_check 899); 900CREATE TABLE current_check_2 () 901INHERITS ( 902 current_check 903); 904INSERT INTO current_check_1 905SELECT 906 i, 907 'p' || i 908FROM 909 generate_series(1, 9) i; 910INSERT INTO current_check_2 911SELECT 912 i, 913 'P' || i 914FROM 915 generate_series(10, 19) i; 916DECLARE c1 SCROLL CURSOR FOR 917 SELECT 918 * 919 FROM 920 current_check; 921-- This tests the fetch-backwards code path 922FETCH ABSOLUTE 12 923FROM 924 c1; 925FETCH ABSOLUTE 8 FROM c1; 926DELETE FROM current_check 927WHERE CURRENT OF c1 928RETURNING 929 *; 930-- This tests the ExecutorRewind code path 931FETCH ABSOLUTE 13 932FROM 933 c1; 934FETCH ABSOLUTE 1 FROM c1; 935DELETE FROM current_check 936WHERE CURRENT OF c1 937RETURNING 938 *; 939SELECT 940 * 941FROM 942 current_check; 943ROLLBACK; 944 945-- Make sure snapshot management works okay, per bug report in 946-- 235395b90909301035v7228ce63q392931f15aa74b31@mail.gmail.com 947BEGIN; 948SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; 949CREATE TABLE CURSOR ( 950 a int 951); 952INSERT INTO CURSOR 953 VALUES (1); 954DECLARE c1 NO SCROLL CURSOR FOR 955 SELECT 956 * 957 FROM 958 CURSOR 959 FOR UPDATE; 960UPDATE 961 CURSOR 962SET 963 a = 2; 964FETCH ALL FROM c1; 965COMMIT; 966 967DROP TABLE CURSOR; 968 969-- Check rewinding a cursor containing a stable function in LIMIT, 970-- per bug report in 8336843.9833.1399385291498.JavaMail.root@quick 971BEGIN; 972CREATE FUNCTION nochange (int) 973 RETURNS int 974 AS 'select $1 limit 1' 975 LANGUAGE sql 976 STABLE; 977DECLARE c CURSOR FOR 978 SELECT 979 * 980 FROM 981 int8_tbl 982 LIMIT nochange (3); 983FETCH ALL FROM c; 984MOVE BACKWARD ALL IN c; 985FETCH ALL FROM c; 986ROLLBACK; 987 988-- Check handling of non-backwards-scan-capable plans with scroll cursors 989BEGIN; 990EXPLAIN ( 991 COSTS OFF 992) DECLARE c1 CURSOR FOR 993 SELECT 994 ( 995 SELECT 996 42) AS x; 997EXPLAIN ( 998 COSTS OFF 999) DECLARE c1 SCROLL CURSOR FOR 1000 SELECT 1001 ( 1002 SELECT 1003 42) AS x; 1004DECLARE c1 SCROLL CURSOR FOR 1005 SELECT 1006 ( 1007 SELECT 1008 42) AS x; 1009FETCH ALL IN c1; 1010FETCH BACKWARD ALL IN c1; 1011ROLLBACK; 1012 1013BEGIN; 1014EXPLAIN ( 1015 COSTS OFF 1016) DECLARE c2 CURSOR FOR 1017 SELECT 1018 generate_series(1, 3) AS g; 1019EXPLAIN ( 1020 COSTS OFF 1021) DECLARE c2 SCROLL CURSOR FOR 1022 SELECT 1023 generate_series(1, 3) AS g; 1024DECLARE c2 SCROLL CURSOR FOR 1025 SELECT 1026 generate_series(1, 3) AS g; 1027FETCH ALL IN c2; 1028FETCH BACKWARD ALL IN c2; 1029ROLLBACK; 1030 1031