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