3 -- Test partitionwise aggregation on partitioned tables
5 -- Note: to ensure plan stability, it's a good idea to make the partitions of
6 -- any one partitioned table in this test all have different numbers of rows.
8 -- Enable partitionwise aggregate, which by default is disabled.
9 SET enable_partitionwise_aggregate TO true;
10 -- Enable partitionwise join, which by default is disabled.
11 SET enable_partitionwise_join TO true;
12 -- Disable parallel plans.
13 SET max_parallel_workers_per_gather TO 0;
14 -- Disable incremental sort, which can influence selected plans due to fuzz factor.
15 SET enable_incremental_sort TO off;
17 -- Tests for list partitioned tables.
19 CREATE TABLE pagg_tab (a int, b int, c text, d int) PARTITION BY LIST(c);
20 CREATE TABLE pagg_tab_p1 PARTITION OF pagg_tab FOR VALUES IN ('0000', '0001', '0002', '0003', '0004');
21 CREATE TABLE pagg_tab_p2 PARTITION OF pagg_tab FOR VALUES IN ('0005', '0006', '0007', '0008');
22 CREATE TABLE pagg_tab_p3 PARTITION OF pagg_tab FOR VALUES IN ('0009', '0010', '0011');
23 INSERT INTO pagg_tab SELECT i % 20, i % 30, to_char(i % 12, 'FM0000'), i % 30 FROM generate_series(0, 2999) i;
25 -- When GROUP BY clause matches; full aggregation is performed for each partition.
27 SELECT c, sum(a), avg(b), count(*), min(a), max(b) FROM pagg_tab GROUP BY c HAVING avg(d) < 15 ORDER BY 1, 2, 3;
29 --------------------------------------------------------------
31 Sort Key: pagg_tab.c, (sum(pagg_tab.a)), (avg(pagg_tab.b))
35 Filter: (avg(pagg_tab.d) < '15'::numeric)
36 -> Seq Scan on pagg_tab_p1 pagg_tab
38 Group Key: pagg_tab_1.c
39 Filter: (avg(pagg_tab_1.d) < '15'::numeric)
40 -> Seq Scan on pagg_tab_p2 pagg_tab_1
42 Group Key: pagg_tab_2.c
43 Filter: (avg(pagg_tab_2.d) < '15'::numeric)
44 -> Seq Scan on pagg_tab_p3 pagg_tab_2
47 SELECT c, sum(a), avg(b), count(*), min(a), max(b) FROM pagg_tab GROUP BY c HAVING avg(d) < 15 ORDER BY 1, 2, 3;
48 c | sum | avg | count | min | max
49 ------+------+---------------------+-------+-----+-----
50 0000 | 2000 | 12.0000000000000000 | 250 | 0 | 24
51 0001 | 2250 | 13.0000000000000000 | 250 | 1 | 25
52 0002 | 2500 | 14.0000000000000000 | 250 | 2 | 26
53 0006 | 2500 | 12.0000000000000000 | 250 | 2 | 24
54 0007 | 2750 | 13.0000000000000000 | 250 | 3 | 25
55 0008 | 2000 | 14.0000000000000000 | 250 | 0 | 26
58 -- When GROUP BY clause does not match; partial aggregation is performed for each partition.
60 SELECT a, sum(b), avg(b), count(*), min(a), max(b) FROM pagg_tab GROUP BY a HAVING avg(d) < 15 ORDER BY 1, 2, 3;
62 --------------------------------------------------------------
64 Sort Key: pagg_tab.a, (sum(pagg_tab.b)), (avg(pagg_tab.b))
65 -> Finalize HashAggregate
67 Filter: (avg(pagg_tab.d) < '15'::numeric)
69 -> Partial HashAggregate
71 -> Seq Scan on pagg_tab_p1 pagg_tab
72 -> Partial HashAggregate
73 Group Key: pagg_tab_1.a
74 -> Seq Scan on pagg_tab_p2 pagg_tab_1
75 -> Partial HashAggregate
76 Group Key: pagg_tab_2.a
77 -> Seq Scan on pagg_tab_p3 pagg_tab_2
80 SELECT a, sum(b), avg(b), count(*), min(a), max(b) FROM pagg_tab GROUP BY a HAVING avg(d) < 15 ORDER BY 1, 2, 3;
81 a | sum | avg | count | min | max
82 ----+------+---------------------+-------+-----+-----
83 0 | 1500 | 10.0000000000000000 | 150 | 0 | 20
84 1 | 1650 | 11.0000000000000000 | 150 | 1 | 21
85 2 | 1800 | 12.0000000000000000 | 150 | 2 | 22
86 3 | 1950 | 13.0000000000000000 | 150 | 3 | 23
87 4 | 2100 | 14.0000000000000000 | 150 | 4 | 24
88 10 | 1500 | 10.0000000000000000 | 150 | 10 | 20
89 11 | 1650 | 11.0000000000000000 | 150 | 11 | 21
90 12 | 1800 | 12.0000000000000000 | 150 | 12 | 22
91 13 | 1950 | 13.0000000000000000 | 150 | 13 | 23
92 14 | 2100 | 14.0000000000000000 | 150 | 14 | 24
95 -- Check with multiple columns in GROUP BY
97 SELECT a, c, count(*) FROM pagg_tab GROUP BY a, c;
99 ------------------------------------------------
102 Group Key: pagg_tab.a, pagg_tab.c
103 -> Seq Scan on pagg_tab_p1 pagg_tab
105 Group Key: pagg_tab_1.a, pagg_tab_1.c
106 -> Seq Scan on pagg_tab_p2 pagg_tab_1
108 Group Key: pagg_tab_2.a, pagg_tab_2.c
109 -> Seq Scan on pagg_tab_p3 pagg_tab_2
112 -- Check with multiple columns in GROUP BY, order in GROUP BY is reversed
114 SELECT a, c, count(*) FROM pagg_tab GROUP BY c, a;
116 ------------------------------------------------
119 Group Key: pagg_tab.c, pagg_tab.a
120 -> Seq Scan on pagg_tab_p1 pagg_tab
122 Group Key: pagg_tab_1.c, pagg_tab_1.a
123 -> Seq Scan on pagg_tab_p2 pagg_tab_1
125 Group Key: pagg_tab_2.c, pagg_tab_2.a
126 -> Seq Scan on pagg_tab_p3 pagg_tab_2
129 -- Check with multiple columns in GROUP BY, order in target-list is reversed
131 SELECT c, a, count(*) FROM pagg_tab GROUP BY a, c;
133 ------------------------------------------------
136 Group Key: pagg_tab.a, pagg_tab.c
137 -> Seq Scan on pagg_tab_p1 pagg_tab
139 Group Key: pagg_tab_1.a, pagg_tab_1.c
140 -> Seq Scan on pagg_tab_p2 pagg_tab_1
142 Group Key: pagg_tab_2.a, pagg_tab_2.c
143 -> Seq Scan on pagg_tab_p3 pagg_tab_2
146 -- Test when input relation for grouping is dummy
148 SELECT c, sum(a) FROM pagg_tab WHERE 1 = 2 GROUP BY c;
150 --------------------------------
154 One-Time Filter: false
157 SELECT c, sum(a) FROM pagg_tab WHERE 1 = 2 GROUP BY c;
163 SELECT c, sum(a) FROM pagg_tab WHERE c = 'x' GROUP BY c;
165 --------------------------------
169 One-Time Filter: false
172 SELECT c, sum(a) FROM pagg_tab WHERE c = 'x' GROUP BY c;
177 -- Test GroupAggregate paths by disabling hash aggregates.
178 SET enable_hashagg TO false;
179 -- When GROUP BY clause matches full aggregation is performed for each partition.
181 SELECT c, sum(a), avg(b), count(*) FROM pagg_tab GROUP BY 1 HAVING avg(d) < 15 ORDER BY 1, 2, 3;
183 --------------------------------------------------------------
185 Sort Key: pagg_tab.c, (sum(pagg_tab.a)), (avg(pagg_tab.b))
188 Group Key: pagg_tab.c
189 Filter: (avg(pagg_tab.d) < '15'::numeric)
192 -> Seq Scan on pagg_tab_p1 pagg_tab
194 Group Key: pagg_tab_1.c
195 Filter: (avg(pagg_tab_1.d) < '15'::numeric)
197 Sort Key: pagg_tab_1.c
198 -> Seq Scan on pagg_tab_p2 pagg_tab_1
200 Group Key: pagg_tab_2.c
201 Filter: (avg(pagg_tab_2.d) < '15'::numeric)
203 Sort Key: pagg_tab_2.c
204 -> Seq Scan on pagg_tab_p3 pagg_tab_2
207 SELECT c, sum(a), avg(b), count(*) FROM pagg_tab GROUP BY 1 HAVING avg(d) < 15 ORDER BY 1, 2, 3;
208 c | sum | avg | count
209 ------+------+---------------------+-------
210 0000 | 2000 | 12.0000000000000000 | 250
211 0001 | 2250 | 13.0000000000000000 | 250
212 0002 | 2500 | 14.0000000000000000 | 250
213 0006 | 2500 | 12.0000000000000000 | 250
214 0007 | 2750 | 13.0000000000000000 | 250
215 0008 | 2000 | 14.0000000000000000 | 250
218 -- When GROUP BY clause does not match; partial aggregation is performed for each partition.
220 SELECT a, sum(b), avg(b), count(*) FROM pagg_tab GROUP BY 1 HAVING avg(d) < 15 ORDER BY 1, 2, 3;
222 ------------------------------------------------------------------
224 Sort Key: pagg_tab.a, (sum(pagg_tab.b)), (avg(pagg_tab.b))
225 -> Finalize GroupAggregate
226 Group Key: pagg_tab.a
227 Filter: (avg(pagg_tab.d) < '15'::numeric)
230 -> Partial GroupAggregate
231 Group Key: pagg_tab.a
234 -> Seq Scan on pagg_tab_p1 pagg_tab
235 -> Partial GroupAggregate
236 Group Key: pagg_tab_1.a
238 Sort Key: pagg_tab_1.a
239 -> Seq Scan on pagg_tab_p2 pagg_tab_1
240 -> Partial GroupAggregate
241 Group Key: pagg_tab_2.a
243 Sort Key: pagg_tab_2.a
244 -> Seq Scan on pagg_tab_p3 pagg_tab_2
247 SELECT a, sum(b), avg(b), count(*) FROM pagg_tab GROUP BY 1 HAVING avg(d) < 15 ORDER BY 1, 2, 3;
248 a | sum | avg | count
249 ----+------+---------------------+-------
250 0 | 1500 | 10.0000000000000000 | 150
251 1 | 1650 | 11.0000000000000000 | 150
252 2 | 1800 | 12.0000000000000000 | 150
253 3 | 1950 | 13.0000000000000000 | 150
254 4 | 2100 | 14.0000000000000000 | 150
255 10 | 1500 | 10.0000000000000000 | 150
256 11 | 1650 | 11.0000000000000000 | 150
257 12 | 1800 | 12.0000000000000000 | 150
258 13 | 1950 | 13.0000000000000000 | 150
259 14 | 2100 | 14.0000000000000000 | 150
262 -- Test partitionwise grouping without any aggregates
264 SELECT c FROM pagg_tab GROUP BY c ORDER BY 1;
266 ------------------------------------------------------
270 Group Key: pagg_tab.c
273 -> Seq Scan on pagg_tab_p1 pagg_tab
275 Group Key: pagg_tab_1.c
277 Sort Key: pagg_tab_1.c
278 -> Seq Scan on pagg_tab_p2 pagg_tab_1
280 Group Key: pagg_tab_2.c
282 Sort Key: pagg_tab_2.c
283 -> Seq Scan on pagg_tab_p3 pagg_tab_2
286 SELECT c FROM pagg_tab GROUP BY c ORDER BY 1;
304 SELECT a FROM pagg_tab WHERE a < 3 GROUP BY a ORDER BY 1;
306 ------------------------------------------------------------
308 Group Key: pagg_tab.a
312 Group Key: pagg_tab.a
315 -> Seq Scan on pagg_tab_p1 pagg_tab
318 Group Key: pagg_tab_1.a
320 Sort Key: pagg_tab_1.a
321 -> Seq Scan on pagg_tab_p2 pagg_tab_1
324 Group Key: pagg_tab_2.a
326 Sort Key: pagg_tab_2.a
327 -> Seq Scan on pagg_tab_p3 pagg_tab_2
331 SELECT a FROM pagg_tab WHERE a < 3 GROUP BY a ORDER BY 1;
339 RESET enable_hashagg;
340 -- ROLLUP, partitionwise aggregation does not apply
342 SELECT c, sum(a) FROM pagg_tab GROUP BY rollup(c) ORDER BY 1, 2;
344 ------------------------------------------------------
346 Sort Key: pagg_tab.c, (sum(pagg_tab.a))
351 -> Seq Scan on pagg_tab_p1 pagg_tab_1
352 -> Seq Scan on pagg_tab_p2 pagg_tab_2
353 -> Seq Scan on pagg_tab_p3 pagg_tab_3
356 -- ORDERED SET within the aggregate.
357 -- Full aggregation; since all the rows that belong to the same group come
358 -- from the same partition, having an ORDER BY within the aggregate doesn't
359 -- make any difference.
361 SELECT c, sum(b order by a) FROM pagg_tab GROUP BY c ORDER BY 1, 2;
363 ---------------------------------------------------------------
365 Sort Key: pagg_tab.c, (sum(pagg_tab.b ORDER BY pagg_tab.a))
368 Group Key: pagg_tab.c
371 -> Seq Scan on pagg_tab_p1 pagg_tab
373 Group Key: pagg_tab_1.c
375 Sort Key: pagg_tab_1.c
376 -> Seq Scan on pagg_tab_p2 pagg_tab_1
378 Group Key: pagg_tab_2.c
380 Sort Key: pagg_tab_2.c
381 -> Seq Scan on pagg_tab_p3 pagg_tab_2
384 -- Since GROUP BY clause does not match with PARTITION KEY; we need to do
385 -- partial aggregation. However, ORDERED SET are not partial safe and thus
386 -- partitionwise aggregation plan is not generated.
388 SELECT a, sum(b order by a) FROM pagg_tab GROUP BY a ORDER BY 1, 2;
390 ---------------------------------------------------------------
392 Sort Key: pagg_tab.a, (sum(pagg_tab.b ORDER BY pagg_tab.a))
394 Group Key: pagg_tab.a
398 -> Seq Scan on pagg_tab_p1 pagg_tab_1
399 -> Seq Scan on pagg_tab_p2 pagg_tab_2
400 -> Seq Scan on pagg_tab_p3 pagg_tab_3
404 CREATE TABLE pagg_tab1(x int, y int) PARTITION BY RANGE(x);
405 CREATE TABLE pagg_tab1_p1 PARTITION OF pagg_tab1 FOR VALUES FROM (0) TO (10);
406 CREATE TABLE pagg_tab1_p2 PARTITION OF pagg_tab1 FOR VALUES FROM (10) TO (20);
407 CREATE TABLE pagg_tab1_p3 PARTITION OF pagg_tab1 FOR VALUES FROM (20) TO (30);
408 CREATE TABLE pagg_tab2(x int, y int) PARTITION BY RANGE(y);
409 CREATE TABLE pagg_tab2_p1 PARTITION OF pagg_tab2 FOR VALUES FROM (0) TO (10);
410 CREATE TABLE pagg_tab2_p2 PARTITION OF pagg_tab2 FOR VALUES FROM (10) TO (20);
411 CREATE TABLE pagg_tab2_p3 PARTITION OF pagg_tab2 FOR VALUES FROM (20) TO (30);
412 INSERT INTO pagg_tab1 SELECT i % 30, i % 20 FROM generate_series(0, 299, 2) i;
413 INSERT INTO pagg_tab2 SELECT i % 20, i % 30 FROM generate_series(0, 299, 3) i;
416 -- When GROUP BY clause matches; full aggregation is performed for each partition.
418 SELECT t1.x, sum(t1.y), count(*) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t1.x ORDER BY 1, 2, 3;
420 -------------------------------------------------------------
422 Sort Key: t1.x, (sum(t1.y)), (count(*))
427 Hash Cond: (t1.x = t2.y)
428 -> Seq Scan on pagg_tab1_p1 t1
430 -> Seq Scan on pagg_tab2_p1 t2
434 Hash Cond: (t1_1.x = t2_1.y)
435 -> Seq Scan on pagg_tab1_p2 t1_1
437 -> Seq Scan on pagg_tab2_p2 t2_1
441 Hash Cond: (t2_2.y = t1_2.x)
442 -> Seq Scan on pagg_tab2_p3 t2_2
444 -> Seq Scan on pagg_tab1_p3 t1_2
447 SELECT t1.x, sum(t1.y), count(*) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t1.x ORDER BY 1, 2, 3;
457 -- Check with whole-row reference; partitionwise aggregation does not apply
459 SELECT t1.x, sum(t1.y), count(t1) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t1.x ORDER BY 1, 2, 3;
461 -------------------------------------------------------------
463 Sort Key: t1.x, (sum(t1.y)), (count(((t1.*)::pagg_tab1)))
467 Hash Cond: (t1.x = t2.y)
469 -> Seq Scan on pagg_tab1_p1 t1_1
470 -> Seq Scan on pagg_tab1_p2 t1_2
471 -> Seq Scan on pagg_tab1_p3 t1_3
474 -> Seq Scan on pagg_tab2_p1 t2_1
475 -> Seq Scan on pagg_tab2_p2 t2_2
476 -> Seq Scan on pagg_tab2_p3 t2_3
479 SELECT t1.x, sum(t1.y), count(t1) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t1.x ORDER BY 1, 2, 3;
489 -- GROUP BY having other matching key
491 SELECT t2.y, sum(t1.y), count(*) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t2.y ORDER BY 1, 2, 3;
493 -------------------------------------------------------------
495 Sort Key: t2.y, (sum(t1.y)), (count(*))
500 Hash Cond: (t1.x = t2.y)
501 -> Seq Scan on pagg_tab1_p1 t1
503 -> Seq Scan on pagg_tab2_p1 t2
507 Hash Cond: (t1_1.x = t2_1.y)
508 -> Seq Scan on pagg_tab1_p2 t1_1
510 -> Seq Scan on pagg_tab2_p2 t2_1
514 Hash Cond: (t2_2.y = t1_2.x)
515 -> Seq Scan on pagg_tab2_p3 t2_2
517 -> Seq Scan on pagg_tab1_p3 t1_2
520 -- When GROUP BY clause does not match; partial aggregation is performed for each partition.
521 -- Also test GroupAggregate paths by disabling hash aggregates.
522 SET enable_hashagg TO false;
524 SELECT t1.y, sum(t1.x), count(*) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t1.y HAVING avg(t1.x) > 10 ORDER BY 1, 2, 3;
526 -------------------------------------------------------------------------
528 Sort Key: t1.y, (sum(t1.x)), (count(*))
529 -> Finalize GroupAggregate
531 Filter: (avg(t1.x) > '10'::numeric)
534 -> Partial GroupAggregate
539 Hash Cond: (t1.x = t2.y)
540 -> Seq Scan on pagg_tab1_p1 t1
542 -> Seq Scan on pagg_tab2_p1 t2
543 -> Partial GroupAggregate
548 Hash Cond: (t1_1.x = t2_1.y)
549 -> Seq Scan on pagg_tab1_p2 t1_1
551 -> Seq Scan on pagg_tab2_p2 t2_1
552 -> Partial GroupAggregate
557 Hash Cond: (t2_2.y = t1_2.x)
558 -> Seq Scan on pagg_tab2_p3 t2_2
560 -> Seq Scan on pagg_tab1_p3 t1_2
563 SELECT t1.y, sum(t1.x), count(*) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t1.y HAVING avg(t1.x) > 10 ORDER BY 1, 2, 3;
574 RESET enable_hashagg;
575 -- Check with LEFT/RIGHT/FULL OUTER JOINs which produces NULL values for
577 -- LEFT JOIN, should produce partial partitionwise aggregation plan as
578 -- GROUP BY is on nullable column
580 SELECT b.y, sum(a.y) FROM pagg_tab1 a LEFT JOIN pagg_tab2 b ON a.x = b.y GROUP BY b.y ORDER BY 1 NULLS LAST;
582 ------------------------------------------------------------------
583 Finalize GroupAggregate
588 -> Partial HashAggregate
591 Hash Cond: (a.x = b.y)
592 -> Seq Scan on pagg_tab1_p1 a
594 -> Seq Scan on pagg_tab2_p1 b
595 -> Partial HashAggregate
598 Hash Cond: (a_1.x = b_1.y)
599 -> Seq Scan on pagg_tab1_p2 a_1
601 -> Seq Scan on pagg_tab2_p2 b_1
602 -> Partial HashAggregate
605 Hash Cond: (b_2.y = a_2.x)
606 -> Seq Scan on pagg_tab2_p3 b_2
608 -> Seq Scan on pagg_tab1_p3 a_2
611 SELECT b.y, sum(a.y) FROM pagg_tab1 a LEFT JOIN pagg_tab2 b ON a.x = b.y GROUP BY b.y ORDER BY 1 NULLS LAST;
622 -- RIGHT JOIN, should produce full partitionwise aggregation plan as
623 -- GROUP BY is on non-nullable column
625 SELECT b.y, sum(a.y) FROM pagg_tab1 a RIGHT JOIN pagg_tab2 b ON a.x = b.y GROUP BY b.y ORDER BY 1 NULLS LAST;
627 ------------------------------------------------------------
634 Hash Cond: (a.x = b.y)
635 -> Seq Scan on pagg_tab1_p1 a
637 -> Seq Scan on pagg_tab2_p1 b
641 Hash Cond: (a_1.x = b_1.y)
642 -> Seq Scan on pagg_tab1_p2 a_1
644 -> Seq Scan on pagg_tab2_p2 b_1
648 Hash Cond: (b_2.y = a_2.x)
649 -> Seq Scan on pagg_tab2_p3 b_2
651 -> Seq Scan on pagg_tab1_p3 a_2
654 SELECT b.y, sum(a.y) FROM pagg_tab1 a RIGHT JOIN pagg_tab2 b ON a.x = b.y GROUP BY b.y ORDER BY 1 NULLS LAST;
669 -- FULL JOIN, should produce partial partitionwise aggregation plan as
670 -- GROUP BY is on nullable column
672 SELECT a.x, sum(b.x) FROM pagg_tab1 a FULL OUTER JOIN pagg_tab2 b ON a.x = b.y GROUP BY a.x ORDER BY 1 NULLS LAST;
674 ------------------------------------------------------------------
675 Finalize GroupAggregate
680 -> Partial HashAggregate
683 Hash Cond: (a.x = b.y)
684 -> Seq Scan on pagg_tab1_p1 a
686 -> Seq Scan on pagg_tab2_p1 b
687 -> Partial HashAggregate
690 Hash Cond: (a_1.x = b_1.y)
691 -> Seq Scan on pagg_tab1_p2 a_1
693 -> Seq Scan on pagg_tab2_p2 b_1
694 -> Partial HashAggregate
697 Hash Cond: (b_2.y = a_2.x)
698 -> Seq Scan on pagg_tab2_p3 b_2
700 -> Seq Scan on pagg_tab1_p3 a_2
703 SELECT a.x, sum(b.x) FROM pagg_tab1 a FULL OUTER JOIN pagg_tab2 b ON a.x = b.y GROUP BY a.x ORDER BY 1 NULLS LAST;
724 -- LEFT JOIN, with dummy relation on right side, ideally
725 -- should produce full partitionwise aggregation plan as GROUP BY is on
726 -- non-nullable columns.
727 -- But right now we are unable to do partitionwise join in this case.
729 SELECT a.x, b.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x < 20) a LEFT JOIN (SELECT * FROM pagg_tab2 WHERE y > 10) b ON a.x = b.y WHERE a.x > 5 or b.y < 20 GROUP BY a.x, b.y ORDER BY 1, 2;
731 --------------------------------------------------------------------
733 Sort Key: pagg_tab1.x, pagg_tab2.y
735 Group Key: pagg_tab1.x, pagg_tab2.y
737 Hash Cond: (pagg_tab1.x = pagg_tab2.y)
738 Filter: ((pagg_tab1.x > 5) OR (pagg_tab2.y < 20))
740 -> Seq Scan on pagg_tab1_p1 pagg_tab1_1
742 -> Seq Scan on pagg_tab1_p2 pagg_tab1_2
746 -> Seq Scan on pagg_tab2_p2 pagg_tab2_1
748 -> Seq Scan on pagg_tab2_p3 pagg_tab2_2
752 SELECT a.x, b.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x < 20) a LEFT JOIN (SELECT * FROM pagg_tab2 WHERE y > 10) b ON a.x = b.y WHERE a.x > 5 or b.y < 20 GROUP BY a.x, b.y ORDER BY 1, 2;
764 -- FULL JOIN, with dummy relations on both sides, ideally
765 -- should produce partial partitionwise aggregation plan as GROUP BY is on
767 -- But right now we are unable to do partitionwise join in this case.
769 SELECT a.x, b.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x < 20) a FULL JOIN (SELECT * FROM pagg_tab2 WHERE y > 10) b ON a.x = b.y WHERE a.x > 5 or b.y < 20 GROUP BY a.x, b.y ORDER BY 1, 2;
771 --------------------------------------------------------------------
773 Sort Key: pagg_tab1.x, pagg_tab2.y
775 Group Key: pagg_tab1.x, pagg_tab2.y
777 Hash Cond: (pagg_tab1.x = pagg_tab2.y)
778 Filter: ((pagg_tab1.x > 5) OR (pagg_tab2.y < 20))
780 -> Seq Scan on pagg_tab1_p1 pagg_tab1_1
782 -> Seq Scan on pagg_tab1_p2 pagg_tab1_2
786 -> Seq Scan on pagg_tab2_p2 pagg_tab2_1
788 -> Seq Scan on pagg_tab2_p3 pagg_tab2_2
792 SELECT a.x, b.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x < 20) a FULL JOIN (SELECT * FROM pagg_tab2 WHERE y > 10) b ON a.x = b.y WHERE a.x > 5 or b.y < 20 GROUP BY a.x, b.y ORDER BY 1, 2;
805 -- Empty join relation because of empty outer side, no partitionwise agg plan
807 SELECT a.x, a.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x = 1 AND x = 2) a LEFT JOIN pagg_tab2 b ON a.x = b.y GROUP BY a.x, a.y ORDER BY 1, 2;
809 ---------------------------------------
811 Group Key: pagg_tab1.x, pagg_tab1.y
813 Sort Key: pagg_tab1.y
815 One-Time Filter: false
818 SELECT a.x, a.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x = 1 AND x = 2) a LEFT JOIN pagg_tab2 b ON a.x = b.y GROUP BY a.x, a.y ORDER BY 1, 2;
823 -- Partition by multiple columns
824 CREATE TABLE pagg_tab_m (a int, b int, c int) PARTITION BY RANGE(a, ((a+b)/2));
825 CREATE TABLE pagg_tab_m_p1 PARTITION OF pagg_tab_m FOR VALUES FROM (0, 0) TO (12, 12);
826 CREATE TABLE pagg_tab_m_p2 PARTITION OF pagg_tab_m FOR VALUES FROM (12, 12) TO (22, 22);
827 CREATE TABLE pagg_tab_m_p3 PARTITION OF pagg_tab_m FOR VALUES FROM (22, 22) TO (30, 30);
828 INSERT INTO pagg_tab_m SELECT i % 30, i % 40, i % 50 FROM generate_series(0, 2999) i;
830 -- Partial aggregation as GROUP BY clause does not match with PARTITION KEY
832 SELECT a, sum(b), avg(c), count(*) FROM pagg_tab_m GROUP BY a HAVING avg(c) < 22 ORDER BY 1, 2, 3;
834 --------------------------------------------------------------------
836 Sort Key: pagg_tab_m.a, (sum(pagg_tab_m.b)), (avg(pagg_tab_m.c))
837 -> Finalize HashAggregate
838 Group Key: pagg_tab_m.a
839 Filter: (avg(pagg_tab_m.c) < '22'::numeric)
841 -> Partial HashAggregate
842 Group Key: pagg_tab_m.a
843 -> Seq Scan on pagg_tab_m_p1 pagg_tab_m
844 -> Partial HashAggregate
845 Group Key: pagg_tab_m_1.a
846 -> Seq Scan on pagg_tab_m_p2 pagg_tab_m_1
847 -> Partial HashAggregate
848 Group Key: pagg_tab_m_2.a
849 -> Seq Scan on pagg_tab_m_p3 pagg_tab_m_2
852 SELECT a, sum(b), avg(c), count(*) FROM pagg_tab_m GROUP BY a HAVING avg(c) < 22 ORDER BY 1, 2, 3;
853 a | sum | avg | count
854 ----+------+---------------------+-------
855 0 | 1500 | 20.0000000000000000 | 100
856 1 | 1600 | 21.0000000000000000 | 100
857 10 | 1500 | 20.0000000000000000 | 100
858 11 | 1600 | 21.0000000000000000 | 100
859 20 | 1500 | 20.0000000000000000 | 100
860 21 | 1600 | 21.0000000000000000 | 100
863 -- Full aggregation as GROUP BY clause matches with PARTITION KEY
865 SELECT a, sum(b), avg(c), count(*) FROM pagg_tab_m GROUP BY a, (a+b)/2 HAVING sum(b) < 50 ORDER BY 1, 2, 3;
867 ----------------------------------------------------------------------------------
869 Sort Key: pagg_tab_m.a, (sum(pagg_tab_m.b)), (avg(pagg_tab_m.c))
872 Group Key: pagg_tab_m.a, ((pagg_tab_m.a + pagg_tab_m.b) / 2)
873 Filter: (sum(pagg_tab_m.b) < 50)
874 -> Seq Scan on pagg_tab_m_p1 pagg_tab_m
876 Group Key: pagg_tab_m_1.a, ((pagg_tab_m_1.a + pagg_tab_m_1.b) / 2)
877 Filter: (sum(pagg_tab_m_1.b) < 50)
878 -> Seq Scan on pagg_tab_m_p2 pagg_tab_m_1
880 Group Key: pagg_tab_m_2.a, ((pagg_tab_m_2.a + pagg_tab_m_2.b) / 2)
881 Filter: (sum(pagg_tab_m_2.b) < 50)
882 -> Seq Scan on pagg_tab_m_p3 pagg_tab_m_2
885 SELECT a, sum(b), avg(c), count(*) FROM pagg_tab_m GROUP BY a, (a+b)/2 HAVING sum(b) < 50 ORDER BY 1, 2, 3;
886 a | sum | avg | count
887 ----+-----+---------------------+-------
888 0 | 0 | 20.0000000000000000 | 25
889 1 | 25 | 21.0000000000000000 | 25
890 10 | 0 | 20.0000000000000000 | 25
891 11 | 25 | 21.0000000000000000 | 25
892 20 | 0 | 20.0000000000000000 | 25
893 21 | 25 | 21.0000000000000000 | 25
896 -- Full aggregation as PARTITION KEY is part of GROUP BY clause
898 SELECT a, c, sum(b), avg(c), count(*) FROM pagg_tab_m GROUP BY (a+b)/2, 2, 1 HAVING sum(b) = 50 AND avg(c) > 25 ORDER BY 1, 2, 3;
900 --------------------------------------------------------------------------------------------------
902 Sort Key: pagg_tab_m.a, pagg_tab_m.c, (sum(pagg_tab_m.b))
905 Group Key: ((pagg_tab_m.a + pagg_tab_m.b) / 2), pagg_tab_m.c, pagg_tab_m.a
906 Filter: ((sum(pagg_tab_m.b) = 50) AND (avg(pagg_tab_m.c) > '25'::numeric))
907 -> Seq Scan on pagg_tab_m_p1 pagg_tab_m
909 Group Key: ((pagg_tab_m_1.a + pagg_tab_m_1.b) / 2), pagg_tab_m_1.c, pagg_tab_m_1.a
910 Filter: ((sum(pagg_tab_m_1.b) = 50) AND (avg(pagg_tab_m_1.c) > '25'::numeric))
911 -> Seq Scan on pagg_tab_m_p2 pagg_tab_m_1
913 Group Key: ((pagg_tab_m_2.a + pagg_tab_m_2.b) / 2), pagg_tab_m_2.c, pagg_tab_m_2.a
914 Filter: ((sum(pagg_tab_m_2.b) = 50) AND (avg(pagg_tab_m_2.c) > '25'::numeric))
915 -> Seq Scan on pagg_tab_m_p3 pagg_tab_m_2
918 SELECT a, c, sum(b), avg(c), count(*) FROM pagg_tab_m GROUP BY (a+b)/2, 2, 1 HAVING sum(b) = 50 AND avg(c) > 25 ORDER BY 1, 2, 3;
919 a | c | sum | avg | count
920 ----+----+-----+---------------------+-------
921 0 | 30 | 50 | 30.0000000000000000 | 5
922 0 | 40 | 50 | 40.0000000000000000 | 5
923 10 | 30 | 50 | 30.0000000000000000 | 5
924 10 | 40 | 50 | 40.0000000000000000 | 5
925 20 | 30 | 50 | 30.0000000000000000 | 5
926 20 | 40 | 50 | 40.0000000000000000 | 5
929 -- Test with multi-level partitioning scheme
930 CREATE TABLE pagg_tab_ml (a int, b int, c text) PARTITION BY RANGE(a);
931 CREATE TABLE pagg_tab_ml_p1 PARTITION OF pagg_tab_ml FOR VALUES FROM (0) TO (12);
932 CREATE TABLE pagg_tab_ml_p2 PARTITION OF pagg_tab_ml FOR VALUES FROM (12) TO (20) PARTITION BY LIST (c);
933 CREATE TABLE pagg_tab_ml_p2_s1 PARTITION OF pagg_tab_ml_p2 FOR VALUES IN ('0000', '0001', '0002');
934 CREATE TABLE pagg_tab_ml_p2_s2 PARTITION OF pagg_tab_ml_p2 FOR VALUES IN ('0003');
935 -- This level of partitioning has different column positions than the parent
936 CREATE TABLE pagg_tab_ml_p3(b int, c text, a int) PARTITION BY RANGE (b);
937 CREATE TABLE pagg_tab_ml_p3_s1(c text, a int, b int);
938 CREATE TABLE pagg_tab_ml_p3_s2 PARTITION OF pagg_tab_ml_p3 FOR VALUES FROM (7) TO (10);
939 ALTER TABLE pagg_tab_ml_p3 ATTACH PARTITION pagg_tab_ml_p3_s1 FOR VALUES FROM (0) TO (7);
940 ALTER TABLE pagg_tab_ml ATTACH PARTITION pagg_tab_ml_p3 FOR VALUES FROM (20) TO (30);
941 INSERT INTO pagg_tab_ml SELECT i % 30, i % 10, to_char(i % 4, 'FM0000') FROM generate_series(0, 29999) i;
943 -- For Parallel Append
944 SET max_parallel_workers_per_gather TO 2;
945 -- Full aggregation at level 1 as GROUP BY clause matches with PARTITION KEY
946 -- for level 1 only. For subpartitions, GROUP BY clause does not match with
947 -- PARTITION KEY, but still we do not see a partial aggregation as array_agg()
948 -- is not partial agg safe.
950 SELECT a, sum(b), array_agg(distinct c), count(*) FROM pagg_tab_ml GROUP BY a HAVING avg(b) < 3 ORDER BY 1, 2, 3;
952 --------------------------------------------------------------------------------------
954 Sort Key: pagg_tab_ml.a, (sum(pagg_tab_ml.b)), (array_agg(DISTINCT pagg_tab_ml.c))
959 Group Key: pagg_tab_ml.a
960 Filter: (avg(pagg_tab_ml.b) < '3'::numeric)
962 Sort Key: pagg_tab_ml.a
963 -> Seq Scan on pagg_tab_ml_p1 pagg_tab_ml
965 Group Key: pagg_tab_ml_5.a
966 Filter: (avg(pagg_tab_ml_5.b) < '3'::numeric)
968 Sort Key: pagg_tab_ml_5.a
970 -> Seq Scan on pagg_tab_ml_p3_s1 pagg_tab_ml_5
971 -> Seq Scan on pagg_tab_ml_p3_s2 pagg_tab_ml_6
973 Group Key: pagg_tab_ml_2.a
974 Filter: (avg(pagg_tab_ml_2.b) < '3'::numeric)
976 Sort Key: pagg_tab_ml_2.a
978 -> Seq Scan on pagg_tab_ml_p2_s1 pagg_tab_ml_2
979 -> Seq Scan on pagg_tab_ml_p2_s2 pagg_tab_ml_3
982 SELECT a, sum(b), array_agg(distinct c), count(*) FROM pagg_tab_ml GROUP BY a HAVING avg(b) < 3 ORDER BY 1, 2, 3;
983 a | sum | array_agg | count
984 ----+------+-------------+-------
985 0 | 0 | {0000,0002} | 1000
986 1 | 1000 | {0001,0003} | 1000
987 2 | 2000 | {0000,0002} | 1000
988 10 | 0 | {0000,0002} | 1000
989 11 | 1000 | {0001,0003} | 1000
990 12 | 2000 | {0000,0002} | 1000
991 20 | 0 | {0000,0002} | 1000
992 21 | 1000 | {0001,0003} | 1000
993 22 | 2000 | {0000,0002} | 1000
996 -- Without ORDER BY clause, to test Gather at top-most path
998 SELECT a, sum(b), array_agg(distinct c), count(*) FROM pagg_tab_ml GROUP BY a HAVING avg(b) < 3;
1000 ---------------------------------------------------------------------------
1005 Group Key: pagg_tab_ml.a
1006 Filter: (avg(pagg_tab_ml.b) < '3'::numeric)
1008 Sort Key: pagg_tab_ml.a
1009 -> Seq Scan on pagg_tab_ml_p1 pagg_tab_ml
1011 Group Key: pagg_tab_ml_5.a
1012 Filter: (avg(pagg_tab_ml_5.b) < '3'::numeric)
1014 Sort Key: pagg_tab_ml_5.a
1016 -> Seq Scan on pagg_tab_ml_p3_s1 pagg_tab_ml_5
1017 -> Seq Scan on pagg_tab_ml_p3_s2 pagg_tab_ml_6
1019 Group Key: pagg_tab_ml_2.a
1020 Filter: (avg(pagg_tab_ml_2.b) < '3'::numeric)
1022 Sort Key: pagg_tab_ml_2.a
1024 -> Seq Scan on pagg_tab_ml_p2_s1 pagg_tab_ml_2
1025 -> Seq Scan on pagg_tab_ml_p2_s2 pagg_tab_ml_3
1028 -- Full aggregation at level 1 as GROUP BY clause matches with PARTITION KEY
1029 -- for level 1 only. For subpartitions, GROUP BY clause does not match with
1030 -- PARTITION KEY, thus we will have a partial aggregation for them.
1032 SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a HAVING avg(b) < 3 ORDER BY 1, 2, 3;
1034 ---------------------------------------------------------------------------------
1036 Sort Key: pagg_tab_ml.a, (sum(pagg_tab_ml.b)), (count(*))
1039 Group Key: pagg_tab_ml.a
1040 Filter: (avg(pagg_tab_ml.b) < '3'::numeric)
1041 -> Seq Scan on pagg_tab_ml_p1 pagg_tab_ml
1042 -> Finalize GroupAggregate
1043 Group Key: pagg_tab_ml_2.a
1044 Filter: (avg(pagg_tab_ml_2.b) < '3'::numeric)
1046 Sort Key: pagg_tab_ml_2.a
1048 -> Partial HashAggregate
1049 Group Key: pagg_tab_ml_2.a
1050 -> Seq Scan on pagg_tab_ml_p2_s1 pagg_tab_ml_2
1051 -> Partial HashAggregate
1052 Group Key: pagg_tab_ml_3.a
1053 -> Seq Scan on pagg_tab_ml_p2_s2 pagg_tab_ml_3
1054 -> Finalize GroupAggregate
1055 Group Key: pagg_tab_ml_5.a
1056 Filter: (avg(pagg_tab_ml_5.b) < '3'::numeric)
1058 Sort Key: pagg_tab_ml_5.a
1060 -> Partial HashAggregate
1061 Group Key: pagg_tab_ml_5.a
1062 -> Seq Scan on pagg_tab_ml_p3_s1 pagg_tab_ml_5
1063 -> Partial HashAggregate
1064 Group Key: pagg_tab_ml_6.a
1065 -> Seq Scan on pagg_tab_ml_p3_s2 pagg_tab_ml_6
1068 SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a HAVING avg(b) < 3 ORDER BY 1, 2, 3;
1082 -- Partial aggregation at all levels as GROUP BY clause does not match with
1085 SELECT b, sum(a), count(*) FROM pagg_tab_ml GROUP BY b ORDER BY 1, 2, 3;
1087 ---------------------------------------------------------------------------
1089 Sort Key: pagg_tab_ml.b, (sum(pagg_tab_ml.a)), (count(*))
1090 -> Finalize GroupAggregate
1091 Group Key: pagg_tab_ml.b
1093 Sort Key: pagg_tab_ml.b
1095 -> Partial HashAggregate
1096 Group Key: pagg_tab_ml.b
1097 -> Seq Scan on pagg_tab_ml_p1 pagg_tab_ml
1098 -> Partial HashAggregate
1099 Group Key: pagg_tab_ml_1.b
1100 -> Seq Scan on pagg_tab_ml_p2_s1 pagg_tab_ml_1
1101 -> Partial HashAggregate
1102 Group Key: pagg_tab_ml_2.b
1103 -> Seq Scan on pagg_tab_ml_p2_s2 pagg_tab_ml_2
1104 -> Partial HashAggregate
1105 Group Key: pagg_tab_ml_3.b
1106 -> Seq Scan on pagg_tab_ml_p3_s1 pagg_tab_ml_3
1107 -> Partial HashAggregate
1108 Group Key: pagg_tab_ml_4.b
1109 -> Seq Scan on pagg_tab_ml_p3_s2 pagg_tab_ml_4
1112 SELECT b, sum(a), count(*) FROM pagg_tab_ml GROUP BY b HAVING avg(a) < 15 ORDER BY 1, 2, 3;
1122 -- Full aggregation at all levels as GROUP BY clause matches with PARTITION KEY
1124 SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a, b, c HAVING avg(b) > 7 ORDER BY 1, 2, 3;
1126 ----------------------------------------------------------------------------
1128 Sort Key: pagg_tab_ml.a, (sum(pagg_tab_ml.b)), (count(*))
1131 Group Key: pagg_tab_ml.a, pagg_tab_ml.b, pagg_tab_ml.c
1132 Filter: (avg(pagg_tab_ml.b) > '7'::numeric)
1133 -> Seq Scan on pagg_tab_ml_p1 pagg_tab_ml
1135 Group Key: pagg_tab_ml_1.a, pagg_tab_ml_1.b, pagg_tab_ml_1.c
1136 Filter: (avg(pagg_tab_ml_1.b) > '7'::numeric)
1137 -> Seq Scan on pagg_tab_ml_p2_s1 pagg_tab_ml_1
1139 Group Key: pagg_tab_ml_2.a, pagg_tab_ml_2.b, pagg_tab_ml_2.c
1140 Filter: (avg(pagg_tab_ml_2.b) > '7'::numeric)
1141 -> Seq Scan on pagg_tab_ml_p2_s2 pagg_tab_ml_2
1143 Group Key: pagg_tab_ml_3.a, pagg_tab_ml_3.b, pagg_tab_ml_3.c
1144 Filter: (avg(pagg_tab_ml_3.b) > '7'::numeric)
1145 -> Seq Scan on pagg_tab_ml_p3_s1 pagg_tab_ml_3
1147 Group Key: pagg_tab_ml_4.a, pagg_tab_ml_4.b, pagg_tab_ml_4.c
1148 Filter: (avg(pagg_tab_ml_4.b) > '7'::numeric)
1149 -> Seq Scan on pagg_tab_ml_p3_s2 pagg_tab_ml_4
1152 SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a, b, c HAVING avg(b) > 7 ORDER BY 1, 2, 3;
1169 -- Parallelism within partitionwise aggregates
1170 SET min_parallel_table_scan_size TO '8kB';
1171 SET parallel_setup_cost TO 0;
1172 -- Full aggregation at level 1 as GROUP BY clause matches with PARTITION KEY
1173 -- for level 1 only. For subpartitions, GROUP BY clause does not match with
1174 -- PARTITION KEY, thus we will have a partial aggregation for them.
1176 SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a HAVING avg(b) < 3 ORDER BY 1, 2, 3;
1178 ------------------------------------------------------------------------------------------------
1180 Sort Key: pagg_tab_ml.a, (sum(pagg_tab_ml.b)), (count(*))
1182 -> Finalize GroupAggregate
1183 Group Key: pagg_tab_ml.a
1184 Filter: (avg(pagg_tab_ml.b) < '3'::numeric)
1188 Sort Key: pagg_tab_ml.a
1189 -> Partial HashAggregate
1190 Group Key: pagg_tab_ml.a
1191 -> Parallel Seq Scan on pagg_tab_ml_p1 pagg_tab_ml
1192 -> Finalize GroupAggregate
1193 Group Key: pagg_tab_ml_2.a
1194 Filter: (avg(pagg_tab_ml_2.b) < '3'::numeric)
1198 Sort Key: pagg_tab_ml_2.a
1200 -> Partial HashAggregate
1201 Group Key: pagg_tab_ml_2.a
1202 -> Parallel Seq Scan on pagg_tab_ml_p2_s1 pagg_tab_ml_2
1203 -> Partial HashAggregate
1204 Group Key: pagg_tab_ml_3.a
1205 -> Parallel Seq Scan on pagg_tab_ml_p2_s2 pagg_tab_ml_3
1206 -> Finalize GroupAggregate
1207 Group Key: pagg_tab_ml_5.a
1208 Filter: (avg(pagg_tab_ml_5.b) < '3'::numeric)
1212 Sort Key: pagg_tab_ml_5.a
1214 -> Partial HashAggregate
1215 Group Key: pagg_tab_ml_5.a
1216 -> Parallel Seq Scan on pagg_tab_ml_p3_s1 pagg_tab_ml_5
1217 -> Partial HashAggregate
1218 Group Key: pagg_tab_ml_6.a
1219 -> Parallel Seq Scan on pagg_tab_ml_p3_s2 pagg_tab_ml_6
1222 SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a HAVING avg(b) < 3 ORDER BY 1, 2, 3;
1236 -- Partial aggregation at all levels as GROUP BY clause does not match with
1239 SELECT b, sum(a), count(*) FROM pagg_tab_ml GROUP BY b ORDER BY 1, 2, 3;
1241 ------------------------------------------------------------------------------------------
1243 Sort Key: pagg_tab_ml.b, (sum(pagg_tab_ml.a)), (count(*))
1244 -> Finalize GroupAggregate
1245 Group Key: pagg_tab_ml.b
1249 Sort Key: pagg_tab_ml.b
1251 -> Partial HashAggregate
1252 Group Key: pagg_tab_ml.b
1253 -> Parallel Seq Scan on pagg_tab_ml_p1 pagg_tab_ml
1254 -> Partial HashAggregate
1255 Group Key: pagg_tab_ml_3.b
1256 -> Parallel Seq Scan on pagg_tab_ml_p3_s1 pagg_tab_ml_3
1257 -> Partial HashAggregate
1258 Group Key: pagg_tab_ml_1.b
1259 -> Parallel Seq Scan on pagg_tab_ml_p2_s1 pagg_tab_ml_1
1260 -> Partial HashAggregate
1261 Group Key: pagg_tab_ml_4.b
1262 -> Parallel Seq Scan on pagg_tab_ml_p3_s2 pagg_tab_ml_4
1263 -> Partial HashAggregate
1264 Group Key: pagg_tab_ml_2.b
1265 -> Parallel Seq Scan on pagg_tab_ml_p2_s2 pagg_tab_ml_2
1268 SELECT b, sum(a), count(*) FROM pagg_tab_ml GROUP BY b HAVING avg(a) < 15 ORDER BY 1, 2, 3;
1278 -- Full aggregation at all levels as GROUP BY clause matches with PARTITION KEY
1280 SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a, b, c HAVING avg(b) > 7 ORDER BY 1, 2, 3;
1282 ----------------------------------------------------------------------------------
1286 Sort Key: pagg_tab_ml.a, (sum(pagg_tab_ml.b)), (count(*))
1289 Group Key: pagg_tab_ml.a, pagg_tab_ml.b, pagg_tab_ml.c
1290 Filter: (avg(pagg_tab_ml.b) > '7'::numeric)
1291 -> Seq Scan on pagg_tab_ml_p1 pagg_tab_ml
1293 Group Key: pagg_tab_ml_3.a, pagg_tab_ml_3.b, pagg_tab_ml_3.c
1294 Filter: (avg(pagg_tab_ml_3.b) > '7'::numeric)
1295 -> Seq Scan on pagg_tab_ml_p3_s1 pagg_tab_ml_3
1297 Group Key: pagg_tab_ml_1.a, pagg_tab_ml_1.b, pagg_tab_ml_1.c
1298 Filter: (avg(pagg_tab_ml_1.b) > '7'::numeric)
1299 -> Seq Scan on pagg_tab_ml_p2_s1 pagg_tab_ml_1
1301 Group Key: pagg_tab_ml_4.a, pagg_tab_ml_4.b, pagg_tab_ml_4.c
1302 Filter: (avg(pagg_tab_ml_4.b) > '7'::numeric)
1303 -> Seq Scan on pagg_tab_ml_p3_s2 pagg_tab_ml_4
1305 Group Key: pagg_tab_ml_2.a, pagg_tab_ml_2.b, pagg_tab_ml_2.c
1306 Filter: (avg(pagg_tab_ml_2.b) > '7'::numeric)
1307 -> Seq Scan on pagg_tab_ml_p2_s2 pagg_tab_ml_2
1310 SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a, b, c HAVING avg(b) > 7 ORDER BY 1, 2, 3;
1327 -- Parallelism within partitionwise aggregates (single level)
1328 -- Add few parallel setup cost, so that we will see a plan which gathers
1329 -- partially created paths even for full aggregation and sticks a single Gather
1330 -- followed by finalization step.
1331 -- Without this, the cost of doing partial aggregation + Gather + finalization
1332 -- for each partition and then Append over it turns out to be same and this
1333 -- wins as we add it first. This parallel_setup_cost plays a vital role in
1334 -- costing such plans.
1335 SET parallel_setup_cost TO 10;
1336 CREATE TABLE pagg_tab_para(x int, y int) PARTITION BY RANGE(x);
1337 CREATE TABLE pagg_tab_para_p1 PARTITION OF pagg_tab_para FOR VALUES FROM (0) TO (12);
1338 CREATE TABLE pagg_tab_para_p2 PARTITION OF pagg_tab_para FOR VALUES FROM (12) TO (22);
1339 CREATE TABLE pagg_tab_para_p3 PARTITION OF pagg_tab_para FOR VALUES FROM (22) TO (30);
1340 INSERT INTO pagg_tab_para SELECT i % 30, i % 20 FROM generate_series(0, 29999) i;
1341 ANALYZE pagg_tab_para;
1342 -- When GROUP BY clause matches; full aggregation is performed for each partition.
1344 SELECT x, sum(y), avg(y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3;
1346 -------------------------------------------------------------------------------------------
1348 Sort Key: pagg_tab_para.x, (sum(pagg_tab_para.y)), (avg(pagg_tab_para.y))
1349 -> Finalize GroupAggregate
1350 Group Key: pagg_tab_para.x
1351 Filter: (avg(pagg_tab_para.y) < '7'::numeric)
1355 Sort Key: pagg_tab_para.x
1357 -> Partial HashAggregate
1358 Group Key: pagg_tab_para.x
1359 -> Parallel Seq Scan on pagg_tab_para_p1 pagg_tab_para
1360 -> Partial HashAggregate
1361 Group Key: pagg_tab_para_1.x
1362 -> Parallel Seq Scan on pagg_tab_para_p2 pagg_tab_para_1
1363 -> Partial HashAggregate
1364 Group Key: pagg_tab_para_2.x
1365 -> Parallel Seq Scan on pagg_tab_para_p3 pagg_tab_para_2
1368 SELECT x, sum(y), avg(y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3;
1369 x | sum | avg | count
1370 ----+------+--------------------+-------
1371 0 | 5000 | 5.0000000000000000 | 1000
1372 1 | 6000 | 6.0000000000000000 | 1000
1373 10 | 5000 | 5.0000000000000000 | 1000
1374 11 | 6000 | 6.0000000000000000 | 1000
1375 20 | 5000 | 5.0000000000000000 | 1000
1376 21 | 6000 | 6.0000000000000000 | 1000
1379 -- When GROUP BY clause does not match; partial aggregation is performed for each partition.
1381 SELECT y, sum(x), avg(x), count(*) FROM pagg_tab_para GROUP BY y HAVING avg(x) < 12 ORDER BY 1, 2, 3;
1383 -------------------------------------------------------------------------------------------
1385 Sort Key: pagg_tab_para.y, (sum(pagg_tab_para.x)), (avg(pagg_tab_para.x))
1386 -> Finalize GroupAggregate
1387 Group Key: pagg_tab_para.y
1388 Filter: (avg(pagg_tab_para.x) < '12'::numeric)
1392 Sort Key: pagg_tab_para.y
1394 -> Partial HashAggregate
1395 Group Key: pagg_tab_para.y
1396 -> Parallel Seq Scan on pagg_tab_para_p1 pagg_tab_para
1397 -> Partial HashAggregate
1398 Group Key: pagg_tab_para_1.y
1399 -> Parallel Seq Scan on pagg_tab_para_p2 pagg_tab_para_1
1400 -> Partial HashAggregate
1401 Group Key: pagg_tab_para_2.y
1402 -> Parallel Seq Scan on pagg_tab_para_p3 pagg_tab_para_2
1405 SELECT y, sum(x), avg(x), count(*) FROM pagg_tab_para GROUP BY y HAVING avg(x) < 12 ORDER BY 1, 2, 3;
1406 y | sum | avg | count
1407 ----+-------+---------------------+-------
1408 0 | 15000 | 10.0000000000000000 | 1500
1409 1 | 16500 | 11.0000000000000000 | 1500
1410 10 | 15000 | 10.0000000000000000 | 1500
1411 11 | 16500 | 11.0000000000000000 | 1500
1414 -- Test when parent can produce parallel paths but not any (or some) of its children
1415 -- (Use one more aggregate to tilt the cost estimates for the plan we want)
1416 ALTER TABLE pagg_tab_para_p1 SET (parallel_workers = 0);
1417 ALTER TABLE pagg_tab_para_p3 SET (parallel_workers = 0);
1418 ANALYZE pagg_tab_para;
1420 SELECT x, sum(y), avg(y), sum(x+y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3;
1422 -------------------------------------------------------------------------------------------
1424 Sort Key: pagg_tab_para.x, (sum(pagg_tab_para.y)), (avg(pagg_tab_para.y))
1425 -> Finalize GroupAggregate
1426 Group Key: pagg_tab_para.x
1427 Filter: (avg(pagg_tab_para.y) < '7'::numeric)
1431 Sort Key: pagg_tab_para.x
1432 -> Partial HashAggregate
1433 Group Key: pagg_tab_para.x
1435 -> Seq Scan on pagg_tab_para_p1 pagg_tab_para_1
1436 -> Seq Scan on pagg_tab_para_p3 pagg_tab_para_3
1437 -> Parallel Seq Scan on pagg_tab_para_p2 pagg_tab_para_2
1440 SELECT x, sum(y), avg(y), sum(x+y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3;
1441 x | sum | avg | sum | count
1442 ----+------+--------------------+-------+-------
1443 0 | 5000 | 5.0000000000000000 | 5000 | 1000
1444 1 | 6000 | 6.0000000000000000 | 7000 | 1000
1445 10 | 5000 | 5.0000000000000000 | 15000 | 1000
1446 11 | 6000 | 6.0000000000000000 | 17000 | 1000
1447 20 | 5000 | 5.0000000000000000 | 25000 | 1000
1448 21 | 6000 | 6.0000000000000000 | 27000 | 1000
1451 ALTER TABLE pagg_tab_para_p2 SET (parallel_workers = 0);
1452 ANALYZE pagg_tab_para;
1454 SELECT x, sum(y), avg(y), sum(x+y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3;
1456 ----------------------------------------------------------------------------------
1458 Sort Key: pagg_tab_para.x, (sum(pagg_tab_para.y)), (avg(pagg_tab_para.y))
1459 -> Finalize GroupAggregate
1460 Group Key: pagg_tab_para.x
1461 Filter: (avg(pagg_tab_para.y) < '7'::numeric)
1465 Sort Key: pagg_tab_para.x
1466 -> Partial HashAggregate
1467 Group Key: pagg_tab_para.x
1469 -> Seq Scan on pagg_tab_para_p1 pagg_tab_para_1
1470 -> Seq Scan on pagg_tab_para_p2 pagg_tab_para_2
1471 -> Seq Scan on pagg_tab_para_p3 pagg_tab_para_3
1474 SELECT x, sum(y), avg(y), sum(x+y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3;
1475 x | sum | avg | sum | count
1476 ----+------+--------------------+-------+-------
1477 0 | 5000 | 5.0000000000000000 | 5000 | 1000
1478 1 | 6000 | 6.0000000000000000 | 7000 | 1000
1479 10 | 5000 | 5.0000000000000000 | 15000 | 1000
1480 11 | 6000 | 6.0000000000000000 | 17000 | 1000
1481 20 | 5000 | 5.0000000000000000 | 25000 | 1000
1482 21 | 6000 | 6.0000000000000000 | 27000 | 1000
1485 -- Reset parallelism parameters to get partitionwise aggregation plan.
1486 RESET min_parallel_table_scan_size;
1487 RESET parallel_setup_cost;
1489 SELECT x, sum(y), avg(y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3;
1491 -----------------------------------------------------------------------------
1493 Sort Key: pagg_tab_para.x, (sum(pagg_tab_para.y)), (avg(pagg_tab_para.y))
1496 Group Key: pagg_tab_para.x
1497 Filter: (avg(pagg_tab_para.y) < '7'::numeric)
1498 -> Seq Scan on pagg_tab_para_p1 pagg_tab_para
1500 Group Key: pagg_tab_para_1.x
1501 Filter: (avg(pagg_tab_para_1.y) < '7'::numeric)
1502 -> Seq Scan on pagg_tab_para_p2 pagg_tab_para_1
1504 Group Key: pagg_tab_para_2.x
1505 Filter: (avg(pagg_tab_para_2.y) < '7'::numeric)
1506 -> Seq Scan on pagg_tab_para_p3 pagg_tab_para_2
1509 SELECT x, sum(y), avg(y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3;
1510 x | sum | avg | count
1511 ----+------+--------------------+-------
1512 0 | 5000 | 5.0000000000000000 | 1000
1513 1 | 6000 | 6.0000000000000000 | 1000
1514 10 | 5000 | 5.0000000000000000 | 1000
1515 11 | 6000 | 6.0000000000000000 | 1000
1516 20 | 5000 | 5.0000000000000000 | 1000
1517 21 | 6000 | 6.0000000000000000 | 1000