1-- 2-- SUBSELECT 3-- 4SELECT 1 AS one WHERE 1 IN (SELECT 1); 5 one 6----- 7 1 8(1 row) 9 10SELECT 1 AS zero WHERE 1 NOT IN (SELECT 1); 11 zero 12------ 13(0 rows) 14 15SELECT 1 AS zero WHERE 1 IN (SELECT 2); 16 zero 17------ 18(0 rows) 19 20-- Check grammar's handling of extra parens in assorted contexts 21SELECT * FROM (SELECT 1 AS x) ss; 22 x 23--- 24 1 25(1 row) 26 27SELECT * FROM ((SELECT 1 AS x)) ss; 28 x 29--- 30 1 31(1 row) 32 33(SELECT 2) UNION SELECT 2; 34 ?column? 35---------- 36 2 37(1 row) 38 39((SELECT 2)) UNION SELECT 2; 40 ?column? 41---------- 42 2 43(1 row) 44 45SELECT ((SELECT 2) UNION SELECT 2); 46 ?column? 47---------- 48 2 49(1 row) 50 51SELECT (((SELECT 2)) UNION SELECT 2); 52 ?column? 53---------- 54 2 55(1 row) 56 57SELECT (SELECT ARRAY[1,2,3])[1]; 58 array 59------- 60 1 61(1 row) 62 63SELECT ((SELECT ARRAY[1,2,3]))[2]; 64 array 65------- 66 2 67(1 row) 68 69SELECT (((SELECT ARRAY[1,2,3])))[3]; 70 array 71------- 72 3 73(1 row) 74 75-- Set up some simple test tables 76CREATE TABLE SUBSELECT_TBL ( 77 f1 integer, 78 f2 integer, 79 f3 float 80); 81INSERT INTO SUBSELECT_TBL VALUES (1, 2, 3); 82INSERT INTO SUBSELECT_TBL VALUES (2, 3, 4); 83INSERT INTO SUBSELECT_TBL VALUES (3, 4, 5); 84INSERT INTO SUBSELECT_TBL VALUES (1, 1, 1); 85INSERT INTO SUBSELECT_TBL VALUES (2, 2, 2); 86INSERT INTO SUBSELECT_TBL VALUES (3, 3, 3); 87INSERT INTO SUBSELECT_TBL VALUES (6, 7, 8); 88INSERT INTO SUBSELECT_TBL VALUES (8, 9, NULL); 89SELECT '' AS eight, * FROM SUBSELECT_TBL; 90 eight | f1 | f2 | f3 91-------+----+----+---- 92 | 1 | 2 | 3 93 | 2 | 3 | 4 94 | 3 | 4 | 5 95 | 1 | 1 | 1 96 | 2 | 2 | 2 97 | 3 | 3 | 3 98 | 6 | 7 | 8 99 | 8 | 9 | 100(8 rows) 101 102-- Uncorrelated subselects 103SELECT '' AS two, f1 AS "Constant Select" FROM SUBSELECT_TBL 104 WHERE f1 IN (SELECT 1); 105 two | Constant Select 106-----+----------------- 107 | 1 108 | 1 109(2 rows) 110 111SELECT '' AS six, f1 AS "Uncorrelated Field" FROM SUBSELECT_TBL 112 WHERE f1 IN (SELECT f2 FROM SUBSELECT_TBL); 113 six | Uncorrelated Field 114-----+-------------------- 115 | 1 116 | 2 117 | 3 118 | 1 119 | 2 120 | 3 121(6 rows) 122 123SELECT '' AS six, f1 AS "Uncorrelated Field" FROM SUBSELECT_TBL 124 WHERE f1 IN (SELECT f2 FROM SUBSELECT_TBL WHERE 125 f2 IN (SELECT f1 FROM SUBSELECT_TBL)); 126 six | Uncorrelated Field 127-----+-------------------- 128 | 1 129 | 2 130 | 3 131 | 1 132 | 2 133 | 3 134(6 rows) 135 136SELECT '' AS three, f1, f2 137 FROM SUBSELECT_TBL 138 WHERE (f1, f2) NOT IN (SELECT f2, CAST(f3 AS int4) FROM SUBSELECT_TBL 139 WHERE f3 IS NOT NULL); 140 three | f1 | f2 141-------+----+---- 142 | 1 | 2 143 | 6 | 7 144 | 8 | 9 145(3 rows) 146 147-- Correlated subselects 148SELECT '' AS six, f1 AS "Correlated Field", f2 AS "Second Field" 149 FROM SUBSELECT_TBL upper 150 WHERE f1 IN (SELECT f2 FROM SUBSELECT_TBL WHERE f1 = upper.f1); 151 six | Correlated Field | Second Field 152-----+------------------+-------------- 153 | 1 | 2 154 | 2 | 3 155 | 3 | 4 156 | 1 | 1 157 | 2 | 2 158 | 3 | 3 159(6 rows) 160 161SELECT '' AS six, f1 AS "Correlated Field", f3 AS "Second Field" 162 FROM SUBSELECT_TBL upper 163 WHERE f1 IN 164 (SELECT f2 FROM SUBSELECT_TBL WHERE CAST(upper.f2 AS float) = f3); 165 six | Correlated Field | Second Field 166-----+------------------+-------------- 167 | 2 | 4 168 | 3 | 5 169 | 1 | 1 170 | 2 | 2 171 | 3 | 3 172(5 rows) 173 174SELECT '' AS six, f1 AS "Correlated Field", f3 AS "Second Field" 175 FROM SUBSELECT_TBL upper 176 WHERE f3 IN (SELECT upper.f1 + f2 FROM SUBSELECT_TBL 177 WHERE f2 = CAST(f3 AS integer)); 178 six | Correlated Field | Second Field 179-----+------------------+-------------- 180 | 1 | 3 181 | 2 | 4 182 | 3 | 5 183 | 6 | 8 184(4 rows) 185 186SELECT '' AS five, f1 AS "Correlated Field" 187 FROM SUBSELECT_TBL 188 WHERE (f1, f2) IN (SELECT f2, CAST(f3 AS int4) FROM SUBSELECT_TBL 189 WHERE f3 IS NOT NULL); 190 five | Correlated Field 191------+------------------ 192 | 2 193 | 3 194 | 1 195 | 2 196 | 3 197(5 rows) 198 199-- 200-- Use some existing tables in the regression test 201-- 202SELECT '' AS eight, ss.f1 AS "Correlated Field", ss.f3 AS "Second Field" 203 FROM SUBSELECT_TBL ss 204 WHERE f1 NOT IN (SELECT f1+1 FROM INT4_TBL 205 WHERE f1 != ss.f1 AND f1 < 2147483647); 206 eight | Correlated Field | Second Field 207-------+------------------+-------------- 208 | 2 | 4 209 | 3 | 5 210 | 2 | 2 211 | 3 | 3 212 | 6 | 8 213 | 8 | 214(6 rows) 215 216select q1, float8(count(*)) / (select count(*) from int8_tbl) 217from int8_tbl group by q1 order by q1; 218 q1 | ?column? 219------------------+---------- 220 123 | 0.4 221 4567890123456789 | 0.6 222(2 rows) 223 224-- Unspecified-type literals in output columns should resolve as text 225SELECT *, pg_typeof(f1) FROM 226 (SELECT 'foo' AS f1 FROM generate_series(1,3)) ss ORDER BY 1; 227 f1 | pg_typeof 228-----+----------- 229 foo | text 230 foo | text 231 foo | text 232(3 rows) 233 234-- ... unless there's context to suggest differently 235explain (verbose, costs off) select '42' union all select '43'; 236 QUERY PLAN 237---------------------------- 238 Append 239 -> Result 240 Output: '42'::text 241 -> Result 242 Output: '43'::text 243(5 rows) 244 245explain (verbose, costs off) select '42' union all select 43; 246 QUERY PLAN 247-------------------- 248 Append 249 -> Result 250 Output: 42 251 -> Result 252 Output: 43 253(5 rows) 254 255-- check materialization of an initplan reference (bug #14524) 256explain (verbose, costs off) 257select 1 = all (select (select 1)); 258 QUERY PLAN 259----------------------------------- 260 Result 261 Output: (SubPlan 2) 262 SubPlan 2 263 -> Materialize 264 Output: ($0) 265 InitPlan 1 (returns $0) 266 -> Result 267 Output: 1 268 -> Result 269 Output: $0 270(10 rows) 271 272select 1 = all (select (select 1)); 273 ?column? 274---------- 275 t 276(1 row) 277 278-- 279-- Check EXISTS simplification with LIMIT 280-- 281explain (costs off) 282select * from int4_tbl o where exists 283 (select 1 from int4_tbl i where i.f1=o.f1 limit null); 284 QUERY PLAN 285------------------------------------ 286 Hash Semi Join 287 Hash Cond: (o.f1 = i.f1) 288 -> Seq Scan on int4_tbl o 289 -> Hash 290 -> Seq Scan on int4_tbl i 291(5 rows) 292 293explain (costs off) 294select * from int4_tbl o where not exists 295 (select 1 from int4_tbl i where i.f1=o.f1 limit 1); 296 QUERY PLAN 297------------------------------------ 298 Hash Anti Join 299 Hash Cond: (o.f1 = i.f1) 300 -> Seq Scan on int4_tbl o 301 -> Hash 302 -> Seq Scan on int4_tbl i 303(5 rows) 304 305explain (costs off) 306select * from int4_tbl o where exists 307 (select 1 from int4_tbl i where i.f1=o.f1 limit 0); 308 QUERY PLAN 309-------------------------------------- 310 Seq Scan on int4_tbl o 311 Filter: (SubPlan 1) 312 SubPlan 1 313 -> Limit 314 -> Seq Scan on int4_tbl i 315 Filter: (f1 = o.f1) 316(6 rows) 317 318-- 319-- Test cases to catch unpleasant interactions between IN-join processing 320-- and subquery pullup. 321-- 322select count(*) from 323 (select 1 from tenk1 a 324 where unique1 IN (select hundred from tenk1 b)) ss; 325 count 326------- 327 100 328(1 row) 329 330select count(distinct ss.ten) from 331 (select ten from tenk1 a 332 where unique1 IN (select hundred from tenk1 b)) ss; 333 count 334------- 335 10 336(1 row) 337 338select count(*) from 339 (select 1 from tenk1 a 340 where unique1 IN (select distinct hundred from tenk1 b)) ss; 341 count 342------- 343 100 344(1 row) 345 346select count(distinct ss.ten) from 347 (select ten from tenk1 a 348 where unique1 IN (select distinct hundred from tenk1 b)) ss; 349 count 350------- 351 10 352(1 row) 353 354-- 355-- Test cases to check for overenthusiastic optimization of 356-- "IN (SELECT DISTINCT ...)" and related cases. Per example from 357-- Luca Pireddu and Michael Fuhr. 358-- 359CREATE TEMP TABLE foo (id integer); 360CREATE TEMP TABLE bar (id1 integer, id2 integer); 361INSERT INTO foo VALUES (1); 362INSERT INTO bar VALUES (1, 1); 363INSERT INTO bar VALUES (2, 2); 364INSERT INTO bar VALUES (3, 1); 365-- These cases require an extra level of distinct-ing above subquery s 366SELECT * FROM foo WHERE id IN 367 (SELECT id2 FROM (SELECT DISTINCT id1, id2 FROM bar) AS s); 368 id 369---- 370 1 371(1 row) 372 373SELECT * FROM foo WHERE id IN 374 (SELECT id2 FROM (SELECT id1,id2 FROM bar GROUP BY id1,id2) AS s); 375 id 376---- 377 1 378(1 row) 379 380SELECT * FROM foo WHERE id IN 381 (SELECT id2 FROM (SELECT id1, id2 FROM bar UNION 382 SELECT id1, id2 FROM bar) AS s); 383 id 384---- 385 1 386(1 row) 387 388-- These cases do not 389SELECT * FROM foo WHERE id IN 390 (SELECT id2 FROM (SELECT DISTINCT ON (id2) id1, id2 FROM bar) AS s); 391 id 392---- 393 1 394(1 row) 395 396SELECT * FROM foo WHERE id IN 397 (SELECT id2 FROM (SELECT id2 FROM bar GROUP BY id2) AS s); 398 id 399---- 400 1 401(1 row) 402 403SELECT * FROM foo WHERE id IN 404 (SELECT id2 FROM (SELECT id2 FROM bar UNION 405 SELECT id2 FROM bar) AS s); 406 id 407---- 408 1 409(1 row) 410 411-- 412-- Test case to catch problems with multiply nested sub-SELECTs not getting 413-- recalculated properly. Per bug report from Didier Moens. 414-- 415CREATE TABLE orderstest ( 416 approver_ref integer, 417 po_ref integer, 418 ordercanceled boolean 419); 420INSERT INTO orderstest VALUES (1, 1, false); 421INSERT INTO orderstest VALUES (66, 5, false); 422INSERT INTO orderstest VALUES (66, 6, false); 423INSERT INTO orderstest VALUES (66, 7, false); 424INSERT INTO orderstest VALUES (66, 1, true); 425INSERT INTO orderstest VALUES (66, 8, false); 426INSERT INTO orderstest VALUES (66, 1, false); 427INSERT INTO orderstest VALUES (77, 1, false); 428INSERT INTO orderstest VALUES (1, 1, false); 429INSERT INTO orderstest VALUES (66, 1, false); 430INSERT INTO orderstest VALUES (1, 1, false); 431CREATE VIEW orders_view AS 432SELECT *, 433(SELECT CASE 434 WHEN ord.approver_ref=1 THEN '---' ELSE 'Approved' 435 END) AS "Approved", 436(SELECT CASE 437 WHEN ord.ordercanceled 438 THEN 'Canceled' 439 ELSE 440 (SELECT CASE 441 WHEN ord.po_ref=1 442 THEN 443 (SELECT CASE 444 WHEN ord.approver_ref=1 445 THEN '---' 446 ELSE 'Approved' 447 END) 448 ELSE 'PO' 449 END) 450END) AS "Status", 451(CASE 452 WHEN ord.ordercanceled 453 THEN 'Canceled' 454 ELSE 455 (CASE 456 WHEN ord.po_ref=1 457 THEN 458 (CASE 459 WHEN ord.approver_ref=1 460 THEN '---' 461 ELSE 'Approved' 462 END) 463 ELSE 'PO' 464 END) 465END) AS "Status_OK" 466FROM orderstest ord; 467SELECT * FROM orders_view; 468 approver_ref | po_ref | ordercanceled | Approved | Status | Status_OK 469--------------+--------+---------------+----------+----------+----------- 470 1 | 1 | f | --- | --- | --- 471 66 | 5 | f | Approved | PO | PO 472 66 | 6 | f | Approved | PO | PO 473 66 | 7 | f | Approved | PO | PO 474 66 | 1 | t | Approved | Canceled | Canceled 475 66 | 8 | f | Approved | PO | PO 476 66 | 1 | f | Approved | Approved | Approved 477 77 | 1 | f | Approved | Approved | Approved 478 1 | 1 | f | --- | --- | --- 479 66 | 1 | f | Approved | Approved | Approved 480 1 | 1 | f | --- | --- | --- 481(11 rows) 482 483DROP TABLE orderstest cascade; 484NOTICE: drop cascades to view orders_view 485-- 486-- Test cases to catch situations where rule rewriter fails to propagate 487-- hasSubLinks flag correctly. Per example from Kyle Bateman. 488-- 489create temp table parts ( 490 partnum text, 491 cost float8 492); 493create temp table shipped ( 494 ttype char(2), 495 ordnum int4, 496 partnum text, 497 value float8 498); 499create temp view shipped_view as 500 select * from shipped where ttype = 'wt'; 501create rule shipped_view_insert as on insert to shipped_view do instead 502 insert into shipped values('wt', new.ordnum, new.partnum, new.value); 503insert into parts (partnum, cost) values (1, 1234.56); 504insert into shipped_view (ordnum, partnum, value) 505 values (0, 1, (select cost from parts where partnum = '1')); 506select * from shipped_view; 507 ttype | ordnum | partnum | value 508-------+--------+---------+--------- 509 wt | 0 | 1 | 1234.56 510(1 row) 511 512create rule shipped_view_update as on update to shipped_view do instead 513 update shipped set partnum = new.partnum, value = new.value 514 where ttype = new.ttype and ordnum = new.ordnum; 515update shipped_view set value = 11 516 from int4_tbl a join int4_tbl b 517 on (a.f1 = (select f1 from int4_tbl c where c.f1=b.f1)) 518 where ordnum = a.f1; 519select * from shipped_view; 520 ttype | ordnum | partnum | value 521-------+--------+---------+------- 522 wt | 0 | 1 | 11 523(1 row) 524 525select f1, ss1 as relabel from 526 (select *, (select sum(f1) from int4_tbl b where f1 >= a.f1) as ss1 527 from int4_tbl a) ss; 528 f1 | relabel 529-------------+------------ 530 0 | 2147607103 531 123456 | 2147607103 532 -123456 | 2147483647 533 2147483647 | 2147483647 534 -2147483647 | 0 535(5 rows) 536 537-- 538-- Test cases involving PARAM_EXEC parameters and min/max index optimizations. 539-- Per bug report from David Sanchez i Gregori. 540-- 541select * from ( 542 select max(unique1) from tenk1 as a 543 where exists (select 1 from tenk1 as b where b.thousand = a.unique2) 544) ss; 545 max 546------ 547 9997 548(1 row) 549 550select * from ( 551 select min(unique1) from tenk1 as a 552 where not exists (select 1 from tenk1 as b where b.unique2 = 10000) 553) ss; 554 min 555----- 556 0 557(1 row) 558 559-- 560-- Test that an IN implemented using a UniquePath does unique-ification 561-- with the right semantics, as per bug #4113. (Unfortunately we have 562-- no simple way to ensure that this test case actually chooses that type 563-- of plan, but it does in releases 7.4-8.3. Note that an ordering difference 564-- here might mean that some other plan type is being used, rendering the test 565-- pointless.) 566-- 567create temp table numeric_table (num_col numeric); 568insert into numeric_table values (1), (1.000000000000000000001), (2), (3); 569create temp table float_table (float_col float8); 570insert into float_table values (1), (2), (3); 571select * from float_table 572 where float_col in (select num_col from numeric_table); 573 float_col 574----------- 575 1 576 2 577 3 578(3 rows) 579 580select * from numeric_table 581 where num_col in (select float_col from float_table); 582 num_col 583------------------------- 584 1 585 1.000000000000000000001 586 2 587 3 588(4 rows) 589 590-- 591-- Test case for bug #4290: bogus calculation of subplan param sets 592-- 593create temp table ta (id int primary key, val int); 594insert into ta values(1,1); 595insert into ta values(2,2); 596create temp table tb (id int primary key, aval int); 597insert into tb values(1,1); 598insert into tb values(2,1); 599insert into tb values(3,2); 600insert into tb values(4,2); 601create temp table tc (id int primary key, aid int); 602insert into tc values(1,1); 603insert into tc values(2,2); 604select 605 ( select min(tb.id) from tb 606 where tb.aval = (select ta.val from ta where ta.id = tc.aid) ) as min_tb_id 607from tc; 608 min_tb_id 609----------- 610 1 611 3 612(2 rows) 613 614-- 615-- Test case for 8.3 "failed to locate grouping columns" bug 616-- 617create temp table t1 (f1 numeric(14,0), f2 varchar(30)); 618select * from 619 (select distinct f1, f2, (select f2 from t1 x where x.f1 = up.f1) as fs 620 from t1 up) ss 621group by f1,f2,fs; 622 f1 | f2 | fs 623----+----+---- 624(0 rows) 625 626-- 627-- Test case for bug #5514 (mishandling of whole-row Vars in subselects) 628-- 629create temp table table_a(id integer); 630insert into table_a values (42); 631create temp view view_a as select * from table_a; 632select view_a from view_a; 633 view_a 634-------- 635 (42) 636(1 row) 637 638select (select view_a) from view_a; 639 view_a 640-------- 641 (42) 642(1 row) 643 644select (select (select view_a)) from view_a; 645 view_a 646-------- 647 (42) 648(1 row) 649 650select (select (a.*)::text) from view_a a; 651 a 652------ 653 (42) 654(1 row) 655 656-- 657-- Check that whole-row Vars reading the result of a subselect don't include 658-- any junk columns therein 659-- 660select q from (select max(f1) from int4_tbl group by f1 order by f1) q; 661 q 662--------------- 663 (-2147483647) 664 (-123456) 665 (0) 666 (123456) 667 (2147483647) 668(5 rows) 669 670with q as (select max(f1) from int4_tbl group by f1 order by f1) 671 select q from q; 672 q 673--------------- 674 (-2147483647) 675 (-123456) 676 (0) 677 (123456) 678 (2147483647) 679(5 rows) 680 681-- 682-- Test case for sublinks pulled up into joinaliasvars lists in an 683-- inherited update/delete query 684-- 685begin; -- this shouldn't delete anything, but be safe 686delete from road 687where exists ( 688 select 1 689 from 690 int4_tbl cross join 691 ( select f1, array(select q1 from int8_tbl) as arr 692 from text_tbl ) ss 693 where road.name = ss.f1 ); 694rollback; 695-- 696-- Test case for sublinks pushed down into subselects via join alias expansion 697-- 698select 699 (select sq1) as qq1 700from 701 (select exists(select 1 from int4_tbl where f1 = q2) as sq1, 42 as dummy 702 from int8_tbl) sq0 703 join 704 int4_tbl i4 on dummy = i4.f1; 705 qq1 706----- 707(0 rows) 708 709-- 710-- Test case for subselect within UPDATE of INSERT...ON CONFLICT DO UPDATE 711-- 712create temp table upsert(key int4 primary key, val text); 713insert into upsert values(1, 'val') on conflict (key) do update set val = 'not seen'; 714insert into upsert values(1, 'val') on conflict (key) do update set val = 'seen with subselect ' || (select f1 from int4_tbl where f1 != 0 limit 1)::text; 715select * from upsert; 716 key | val 717-----+---------------------------- 718 1 | seen with subselect 123456 719(1 row) 720 721with aa as (select 'int4_tbl' u from int4_tbl limit 1) 722insert into upsert values (1, 'x'), (999, 'y') 723on conflict (key) do update set val = (select u from aa) 724returning *; 725 key | val 726-----+---------- 727 1 | int4_tbl 728 999 | y 729(2 rows) 730 731-- 732-- Test case for cross-type partial matching in hashed subplan (bug #7597) 733-- 734create temp table outer_7597 (f1 int4, f2 int4); 735insert into outer_7597 values (0, 0); 736insert into outer_7597 values (1, 0); 737insert into outer_7597 values (0, null); 738insert into outer_7597 values (1, null); 739create temp table inner_7597(c1 int8, c2 int8); 740insert into inner_7597 values(0, null); 741select * from outer_7597 where (f1, f2) not in (select * from inner_7597); 742 f1 | f2 743----+---- 744 1 | 0 745 1 | 746(2 rows) 747 748-- 749-- Another test case for cross-type hashed subplans: comparison of 750-- inner-side values must be done with appropriate operator 751-- 752explain (verbose, costs off) 753select 'foo'::text in (select 'bar'::name union all select 'bar'::name); 754 QUERY PLAN 755------------------------------------- 756 Result 757 Output: (hashed SubPlan 1) 758 SubPlan 1 759 -> Append 760 -> Result 761 Output: 'bar'::name 762 -> Result 763 Output: 'bar'::name 764(8 rows) 765 766select 'foo'::text in (select 'bar'::name union all select 'bar'::name); 767 ?column? 768---------- 769 f 770(1 row) 771 772-- 773-- Test case for premature memory release during hashing of subplan output 774-- 775select '1'::text in (select '1'::name union all select '1'::name); 776 ?column? 777---------- 778 t 779(1 row) 780 781-- 782-- Test that we don't try to use a hashed subplan if the simplified 783-- testexpr isn't of the right shape 784-- 785create temp table inner_text (c1 text, c2 text); 786insert into inner_text values ('a', null); 787insert into inner_text values ('123', '456'); 788-- this fails by default, of course 789select * from int8_tbl where q1 in (select c1 from inner_text); 790ERROR: operator does not exist: bigint = text 791LINE 1: select * from int8_tbl where q1 in (select c1 from inner_tex... 792 ^ 793HINT: No operator matches the given name and argument types. You might need to add explicit type casts. 794begin; 795-- make an operator to allow it to succeed 796create function bogus_int8_text_eq(int8, text) returns boolean 797language sql as 'select $1::text = $2'; 798create operator = (procedure=bogus_int8_text_eq, leftarg=int8, rightarg=text); 799explain (costs off) 800select * from int8_tbl where q1 in (select c1 from inner_text); 801 QUERY PLAN 802-------------------------------- 803 Seq Scan on int8_tbl 804 Filter: (hashed SubPlan 1) 805 SubPlan 1 806 -> Seq Scan on inner_text 807(4 rows) 808 809select * from int8_tbl where q1 in (select c1 from inner_text); 810 q1 | q2 811-----+------------------ 812 123 | 456 813 123 | 4567890123456789 814(2 rows) 815 816-- inlining of this function results in unusual number of hash clauses, 817-- which we can still cope with 818create or replace function bogus_int8_text_eq(int8, text) returns boolean 819language sql as 'select $1::text = $2 and $1::text = $2'; 820explain (costs off) 821select * from int8_tbl where q1 in (select c1 from inner_text); 822 QUERY PLAN 823-------------------------------- 824 Seq Scan on int8_tbl 825 Filter: (hashed SubPlan 1) 826 SubPlan 1 827 -> Seq Scan on inner_text 828(4 rows) 829 830select * from int8_tbl where q1 in (select c1 from inner_text); 831 q1 | q2 832-----+------------------ 833 123 | 456 834 123 | 4567890123456789 835(2 rows) 836 837-- inlining of this function causes LHS and RHS to be switched, 838-- which we can't cope with, so hashing should be abandoned 839create or replace function bogus_int8_text_eq(int8, text) returns boolean 840language sql as 'select $2 = $1::text'; 841explain (costs off) 842select * from int8_tbl where q1 in (select c1 from inner_text); 843 QUERY PLAN 844-------------------------------------- 845 Seq Scan on int8_tbl 846 Filter: (SubPlan 1) 847 SubPlan 1 848 -> Materialize 849 -> Seq Scan on inner_text 850(5 rows) 851 852select * from int8_tbl where q1 in (select c1 from inner_text); 853 q1 | q2 854-----+------------------ 855 123 | 456 856 123 | 4567890123456789 857(2 rows) 858 859rollback; -- to get rid of the bogus operator 860-- 861-- Test case for planner bug with nested EXISTS handling 862-- 863select a.thousand from tenk1 a, tenk1 b 864where a.thousand = b.thousand 865 and exists ( select 1 from tenk1 c where b.hundred = c.hundred 866 and not exists ( select 1 from tenk1 d 867 where a.thousand = d.thousand ) ); 868 thousand 869---------- 870(0 rows) 871 872-- 873-- Check that nested sub-selects are not pulled up if they contain volatiles 874-- 875explain (verbose, costs off) 876 select x, x from 877 (select (select now()) as x from (values(1),(2)) v(y)) ss; 878 QUERY PLAN 879--------------------------- 880 Values Scan on "*VALUES*" 881 Output: $0, $1 882 InitPlan 1 (returns $0) 883 -> Result 884 Output: now() 885 InitPlan 2 (returns $1) 886 -> Result 887 Output: now() 888(8 rows) 889 890explain (verbose, costs off) 891 select x, x from 892 (select (select random()) as x from (values(1),(2)) v(y)) ss; 893 QUERY PLAN 894---------------------------------- 895 Subquery Scan on ss 896 Output: ss.x, ss.x 897 -> Values Scan on "*VALUES*" 898 Output: $0 899 InitPlan 1 (returns $0) 900 -> Result 901 Output: random() 902(7 rows) 903 904explain (verbose, costs off) 905 select x, x from 906 (select (select now() where y=y) as x from (values(1),(2)) v(y)) ss; 907 QUERY PLAN 908---------------------------------------------------------------------- 909 Values Scan on "*VALUES*" 910 Output: (SubPlan 1), (SubPlan 2) 911 SubPlan 1 912 -> Result 913 Output: now() 914 One-Time Filter: ("*VALUES*".column1 = "*VALUES*".column1) 915 SubPlan 2 916 -> Result 917 Output: now() 918 One-Time Filter: ("*VALUES*".column1 = "*VALUES*".column1) 919(10 rows) 920 921explain (verbose, costs off) 922 select x, x from 923 (select (select random() where y=y) as x from (values(1),(2)) v(y)) ss; 924 QUERY PLAN 925---------------------------------------------------------------------------- 926 Subquery Scan on ss 927 Output: ss.x, ss.x 928 -> Values Scan on "*VALUES*" 929 Output: (SubPlan 1) 930 SubPlan 1 931 -> Result 932 Output: random() 933 One-Time Filter: ("*VALUES*".column1 = "*VALUES*".column1) 934(8 rows) 935 936-- 937-- Test rescan of a hashed subplan (the use of random() is to prevent the 938-- sub-select from being pulled up, which would result in not hashing) 939-- 940explain (verbose, costs off) 941select sum(ss.tst::int) from 942 onek o cross join lateral ( 943 select i.ten in (select f1 from int4_tbl where f1 <= o.hundred) as tst, 944 random() as r 945 from onek i where i.unique1 = o.unique1 ) ss 946where o.ten = 0; 947 QUERY PLAN 948--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 949 Aggregate 950 Output: sum((((hashed SubPlan 1)))::integer) 951 -> Nested Loop 952 Output: ((hashed SubPlan 1)) 953 -> Seq Scan on public.onek o 954 Output: o.unique1, o.unique2, o.two, o.four, o.ten, o.twenty, o.hundred, o.thousand, o.twothousand, o.fivethous, o.tenthous, o.odd, o.even, o.stringu1, o.stringu2, o.string4 955 Filter: (o.ten = 0) 956 -> Index Scan using onek_unique1 on public.onek i 957 Output: (hashed SubPlan 1), random() 958 Index Cond: (i.unique1 = o.unique1) 959 SubPlan 1 960 -> Seq Scan on public.int4_tbl 961 Output: int4_tbl.f1 962 Filter: (int4_tbl.f1 <= $0) 963(14 rows) 964 965select sum(ss.tst::int) from 966 onek o cross join lateral ( 967 select i.ten in (select f1 from int4_tbl where f1 <= o.hundred) as tst, 968 random() as r 969 from onek i where i.unique1 = o.unique1 ) ss 970where o.ten = 0; 971 sum 972----- 973 100 974(1 row) 975 976-- 977-- Test rescan of a SetOp node 978-- 979explain (costs off) 980select count(*) from 981 onek o cross join lateral ( 982 select * from onek i1 where i1.unique1 = o.unique1 983 except 984 select * from onek i2 where i2.unique1 = o.unique2 985 ) ss 986where o.ten = 1; 987 QUERY PLAN 988------------------------------------------------------------------------------ 989 Aggregate 990 -> Nested Loop 991 -> Seq Scan on onek o 992 Filter: (ten = 1) 993 -> Subquery Scan on ss 994 -> HashSetOp Except 995 -> Append 996 -> Subquery Scan on "*SELECT* 1" 997 -> Index Scan using onek_unique1 on onek i1 998 Index Cond: (unique1 = o.unique1) 999 -> Subquery Scan on "*SELECT* 2" 1000 -> Index Scan using onek_unique1 on onek i2 1001 Index Cond: (unique1 = o.unique2) 1002(13 rows) 1003 1004select count(*) from 1005 onek o cross join lateral ( 1006 select * from onek i1 where i1.unique1 = o.unique1 1007 except 1008 select * from onek i2 where i2.unique1 = o.unique2 1009 ) ss 1010where o.ten = 1; 1011 count 1012------- 1013 100 1014(1 row) 1015 1016-- 1017-- Test rescan of a RecursiveUnion node 1018-- 1019explain (costs off) 1020select sum(o.four), sum(ss.a) from 1021 onek o cross join lateral ( 1022 with recursive x(a) as 1023 (select o.four as a 1024 union 1025 select a + 1 from x 1026 where a < 10) 1027 select * from x 1028 ) ss 1029where o.ten = 1; 1030 QUERY PLAN 1031--------------------------------------------------- 1032 Aggregate 1033 -> Nested Loop 1034 -> Seq Scan on onek o 1035 Filter: (ten = 1) 1036 -> CTE Scan on x 1037 CTE x 1038 -> Recursive Union 1039 -> Result 1040 -> WorkTable Scan on x x_1 1041 Filter: (a < 10) 1042(10 rows) 1043 1044select sum(o.four), sum(ss.a) from 1045 onek o cross join lateral ( 1046 with recursive x(a) as 1047 (select o.four as a 1048 union 1049 select a + 1 from x 1050 where a < 10) 1051 select * from x 1052 ) ss 1053where o.ten = 1; 1054 sum | sum 1055------+------ 1056 1700 | 5350 1057(1 row) 1058 1059-- 1060-- Check we behave sanely in corner case of empty SELECT list (bug #8648) 1061-- 1062create temp table nocolumns(); 1063select exists(select * from nocolumns); 1064 exists 1065-------- 1066 f 1067(1 row) 1068 1069-- 1070-- Check behavior with a SubPlan in VALUES (bug #14924) 1071-- 1072select val.x 1073 from generate_series(1,10) as s(i), 1074 lateral ( 1075 values ((select s.i + 1)), (s.i + 101) 1076 ) as val(x) 1077where s.i < 10 and (select val.x) < 110; 1078 x 1079----- 1080 2 1081 102 1082 3 1083 103 1084 4 1085 104 1086 5 1087 105 1088 6 1089 106 1090 7 1091 107 1092 8 1093 108 1094 9 1095 109 1096 10 1097(17 rows) 1098 1099-- another variant of that (bug #16213) 1100explain (verbose, costs off) 1101select * from 1102(values 1103 (3 not in (select * from (values (1), (2)) ss1)), 1104 (false) 1105) ss; 1106 QUERY PLAN 1107---------------------------------------- 1108 Values Scan on "*VALUES*" 1109 Output: "*VALUES*".column1 1110 SubPlan 1 1111 -> Values Scan on "*VALUES*_1" 1112 Output: "*VALUES*_1".column1 1113(5 rows) 1114 1115select * from 1116(values 1117 (3 not in (select * from (values (1), (2)) ss1)), 1118 (false) 1119) ss; 1120 column1 1121--------- 1122 t 1123 f 1124(2 rows) 1125 1126-- 1127-- Check sane behavior with nested IN SubLinks 1128-- 1129explain (verbose, costs off) 1130select * from int4_tbl where 1131 (case when f1 in (select unique1 from tenk1 a) then f1 else null end) in 1132 (select ten from tenk1 b); 1133 QUERY PLAN 1134--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1135 Nested Loop Semi Join 1136 Output: int4_tbl.f1 1137 Join Filter: (CASE WHEN (hashed SubPlan 1) THEN int4_tbl.f1 ELSE NULL::integer END = b.ten) 1138 -> Seq Scan on public.int4_tbl 1139 Output: int4_tbl.f1 1140 -> Seq Scan on public.tenk1 b 1141 Output: b.unique1, b.unique2, b.two, b.four, b.ten, b.twenty, b.hundred, b.thousand, b.twothousand, b.fivethous, b.tenthous, b.odd, b.even, b.stringu1, b.stringu2, b.string4 1142 SubPlan 1 1143 -> Index Only Scan using tenk1_unique1 on public.tenk1 a 1144 Output: a.unique1 1145(10 rows) 1146 1147select * from int4_tbl where 1148 (case when f1 in (select unique1 from tenk1 a) then f1 else null end) in 1149 (select ten from tenk1 b); 1150 f1 1151---- 1152 0 1153(1 row) 1154 1155-- 1156-- Check for incorrect optimization when IN subquery contains a SRF 1157-- 1158explain (verbose, costs off) 1159select * from int4_tbl o where (f1, f1) in 1160 (select f1, generate_series(1,2) / 10 g from int4_tbl i group by f1); 1161 QUERY PLAN 1162------------------------------------------------------------------- 1163 Nested Loop Semi Join 1164 Output: o.f1 1165 Join Filter: (o.f1 = "ANY_subquery".f1) 1166 -> Seq Scan on public.int4_tbl o 1167 Output: o.f1 1168 -> Materialize 1169 Output: "ANY_subquery".f1, "ANY_subquery".g 1170 -> Subquery Scan on "ANY_subquery" 1171 Output: "ANY_subquery".f1, "ANY_subquery".g 1172 Filter: ("ANY_subquery".f1 = "ANY_subquery".g) 1173 -> Result 1174 Output: i.f1, ((generate_series(1, 2)) / 10) 1175 -> ProjectSet 1176 Output: generate_series(1, 2), i.f1 1177 -> HashAggregate 1178 Output: i.f1 1179 Group Key: i.f1 1180 -> Seq Scan on public.int4_tbl i 1181 Output: i.f1 1182(19 rows) 1183 1184select * from int4_tbl o where (f1, f1) in 1185 (select f1, generate_series(1,2) / 10 g from int4_tbl i group by f1); 1186 f1 1187---- 1188 0 1189(1 row) 1190 1191-- 1192-- check for over-optimization of whole-row Var referencing an Append plan 1193-- 1194select (select q from 1195 (select 1,2,3 where f1 > 0 1196 union all 1197 select 4,5,6.0 where f1 <= 0 1198 ) q ) 1199from int4_tbl; 1200 q 1201----------- 1202 (4,5,6.0) 1203 (1,2,3) 1204 (4,5,6.0) 1205 (1,2,3) 1206 (4,5,6.0) 1207(5 rows) 1208 1209-- 1210-- Check for sane handling of a lateral reference in a subquery's quals 1211-- (most of the complication here is to prevent the test case from being 1212-- flattened too much) 1213-- 1214explain (verbose, costs off) 1215select * from 1216 int4_tbl i4, 1217 lateral ( 1218 select i4.f1 > 1 as b, 1 as id 1219 from (select random() order by 1) as t1 1220 union all 1221 select true as b, 2 as id 1222 ) as t2 1223where b and f1 >= 0; 1224 QUERY PLAN 1225-------------------------------------------- 1226 Nested Loop 1227 Output: i4.f1, ((i4.f1 > 1)), (1) 1228 -> Seq Scan on public.int4_tbl i4 1229 Output: i4.f1 1230 Filter: (i4.f1 >= 0) 1231 -> Append 1232 -> Subquery Scan on t1 1233 Output: (i4.f1 > 1), 1 1234 Filter: (i4.f1 > 1) 1235 -> Sort 1236 Output: (random()) 1237 Sort Key: (random()) 1238 -> Result 1239 Output: random() 1240 -> Result 1241 Output: true, 2 1242(16 rows) 1243 1244select * from 1245 int4_tbl i4, 1246 lateral ( 1247 select i4.f1 > 1 as b, 1 as id 1248 from (select random() order by 1) as t1 1249 union all 1250 select true as b, 2 as id 1251 ) as t2 1252where b and f1 >= 0; 1253 f1 | b | id 1254------------+---+---- 1255 0 | t | 2 1256 123456 | t | 1 1257 123456 | t | 2 1258 2147483647 | t | 1 1259 2147483647 | t | 2 1260(5 rows) 1261 1262-- 1263-- Check that volatile quals aren't pushed down past a DISTINCT: 1264-- nextval() should not be called more than the nominal number of times 1265-- 1266create temp sequence ts1; 1267select * from 1268 (select distinct ten from tenk1) ss 1269 where ten < 10 + nextval('ts1') 1270 order by 1; 1271 ten 1272----- 1273 0 1274 1 1275 2 1276 3 1277 4 1278 5 1279 6 1280 7 1281 8 1282 9 1283(10 rows) 1284 1285select nextval('ts1'); 1286 nextval 1287--------- 1288 11 1289(1 row) 1290 1291-- 1292-- Check that volatile quals aren't pushed down past a set-returning function; 1293-- while a nonvolatile qual can be, if it doesn't reference the SRF. 1294-- 1295create function tattle(x int, y int) returns bool 1296volatile language plpgsql as $$ 1297begin 1298 raise notice 'x = %, y = %', x, y; 1299 return x > y; 1300end$$; 1301explain (verbose, costs off) 1302select * from 1303 (select 9 as x, unnest(array[1,2,3,11,12,13]) as u) ss 1304 where tattle(x, 8); 1305 QUERY PLAN 1306---------------------------------------------------------- 1307 Subquery Scan on ss 1308 Output: x, u 1309 Filter: tattle(ss.x, 8) 1310 -> ProjectSet 1311 Output: 9, unnest('{1,2,3,11,12,13}'::integer[]) 1312 -> Result 1313(6 rows) 1314 1315select * from 1316 (select 9 as x, unnest(array[1,2,3,11,12,13]) as u) ss 1317 where tattle(x, 8); 1318NOTICE: x = 9, y = 8 1319NOTICE: x = 9, y = 8 1320NOTICE: x = 9, y = 8 1321NOTICE: x = 9, y = 8 1322NOTICE: x = 9, y = 8 1323NOTICE: x = 9, y = 8 1324 x | u 1325---+---- 1326 9 | 1 1327 9 | 2 1328 9 | 3 1329 9 | 11 1330 9 | 12 1331 9 | 13 1332(6 rows) 1333 1334-- if we pretend it's stable, we get different results: 1335alter function tattle(x int, y int) stable; 1336explain (verbose, costs off) 1337select * from 1338 (select 9 as x, unnest(array[1,2,3,11,12,13]) as u) ss 1339 where tattle(x, 8); 1340 QUERY PLAN 1341---------------------------------------------------- 1342 ProjectSet 1343 Output: 9, unnest('{1,2,3,11,12,13}'::integer[]) 1344 -> Result 1345 One-Time Filter: tattle(9, 8) 1346(4 rows) 1347 1348select * from 1349 (select 9 as x, unnest(array[1,2,3,11,12,13]) as u) ss 1350 where tattle(x, 8); 1351NOTICE: x = 9, y = 8 1352 x | u 1353---+---- 1354 9 | 1 1355 9 | 2 1356 9 | 3 1357 9 | 11 1358 9 | 12 1359 9 | 13 1360(6 rows) 1361 1362-- although even a stable qual should not be pushed down if it references SRF 1363explain (verbose, costs off) 1364select * from 1365 (select 9 as x, unnest(array[1,2,3,11,12,13]) as u) ss 1366 where tattle(x, u); 1367 QUERY PLAN 1368---------------------------------------------------------- 1369 Subquery Scan on ss 1370 Output: x, u 1371 Filter: tattle(ss.x, ss.u) 1372 -> ProjectSet 1373 Output: 9, unnest('{1,2,3,11,12,13}'::integer[]) 1374 -> Result 1375(6 rows) 1376 1377select * from 1378 (select 9 as x, unnest(array[1,2,3,11,12,13]) as u) ss 1379 where tattle(x, u); 1380NOTICE: x = 9, y = 1 1381NOTICE: x = 9, y = 2 1382NOTICE: x = 9, y = 3 1383NOTICE: x = 9, y = 11 1384NOTICE: x = 9, y = 12 1385NOTICE: x = 9, y = 13 1386 x | u 1387---+--- 1388 9 | 1 1389 9 | 2 1390 9 | 3 1391(3 rows) 1392 1393drop function tattle(x int, y int); 1394-- 1395-- Test that LIMIT can be pushed to SORT through a subquery that just projects 1396-- columns. We check for that having happened by looking to see if EXPLAIN 1397-- ANALYZE shows that a top-N sort was used. We must suppress or filter away 1398-- all the non-invariant parts of the EXPLAIN ANALYZE output. 1399-- 1400create table sq_limit (pk int primary key, c1 int, c2 int); 1401insert into sq_limit values 1402 (1, 1, 1), 1403 (2, 2, 2), 1404 (3, 3, 3), 1405 (4, 4, 4), 1406 (5, 1, 1), 1407 (6, 2, 2), 1408 (7, 3, 3), 1409 (8, 4, 4); 1410create function explain_sq_limit() returns setof text language plpgsql as 1411$$ 1412declare ln text; 1413begin 1414 for ln in 1415 explain (analyze, summary off, timing off, costs off) 1416 select * from (select pk,c2 from sq_limit order by c1,pk) as x limit 3 1417 loop 1418 ln := regexp_replace(ln, 'Memory: \S*', 'Memory: xxx'); 1419 -- this case might occur if force_parallel_mode is on: 1420 ln := regexp_replace(ln, 'Worker 0: Sort Method', 'Sort Method'); 1421 return next ln; 1422 end loop; 1423end; 1424$$; 1425select * from explain_sq_limit(); 1426 explain_sq_limit 1427---------------------------------------------------------------- 1428 Limit (actual rows=3 loops=1) 1429 -> Subquery Scan on x (actual rows=3 loops=1) 1430 -> Sort (actual rows=3 loops=1) 1431 Sort Key: sq_limit.c1, sq_limit.pk 1432 Sort Method: top-N heapsort Memory: xxx 1433 -> Seq Scan on sq_limit (actual rows=8 loops=1) 1434(6 rows) 1435 1436select * from (select pk,c2 from sq_limit order by c1,pk) as x limit 3; 1437 pk | c2 1438----+---- 1439 1 | 1 1440 5 | 1 1441 2 | 2 1442(3 rows) 1443 1444drop function explain_sq_limit(); 1445drop table sq_limit; 1446-- 1447-- Ensure that backward scan direction isn't propagated into 1448-- expression subqueries (bug #15336) 1449-- 1450begin; 1451declare c1 scroll cursor for 1452 select * from generate_series(1,4) i 1453 where i <> all (values (2),(3)); 1454move forward all in c1; 1455fetch backward all in c1; 1456 i 1457--- 1458 4 1459 1 1460(2 rows) 1461 1462commit; 1463