mirror of
https://github.com/postgres/postgres.git
synced 2025-07-02 09:02:37 +03:00
Generate EquivalenceClass members for partitionwise child join rels.
Commitd25ea0127
got rid of what I thought were entirely unnecessary derived child expressions in EquivalenceClasses for EC members that mention multiple baserels. But it turns out that some of the child expressions that code created are necessary for partitionwise joins, else we fail to find matching pathkeys for Sort nodes. (This happens only for certain shapes of the resulting plan; it may be that partitionwise aggregation is also necessary to show the failure, though I'm not sure of that.) Reverting that commit entirely would be quite painful performance-wise for large partition sets. So instead, add code that explicitly generates child expressions that match only partitionwise child join rels we have actually generated. Per report from Justin Pryzby. (Amit Langote noticed the problem earlier, though it's not clear if he recognized then that it could result in a planner error, not merely failure to exploit partitionwise join, in the code as-committed.) Back-patch to v12 where commitd25ea0127
came in. Amit Langote, with lots of kibitzing from me Discussion: https://postgr.es/m/CA+HiwqG2WVUGmLJqtR0tPFhniO=H=9qQ+Z3L_ZC+Y3-EVQHFGg@mail.gmail.com Discussion: https://postgr.es/m/20191011143703.GN10470@telsasoft.com
This commit is contained in:
@ -459,6 +459,83 @@ SELECT t1.a, ss.t2a, ss.t2c FROM prt1 t1 LEFT JOIN LATERAL
|
||||
550 | |
|
||||
(12 rows)
|
||||
|
||||
-- bug with inadequate sort key representation
|
||||
SET enable_partitionwise_aggregate TO true;
|
||||
SET enable_hashjoin TO false;
|
||||
EXPLAIN (COSTS OFF)
|
||||
SELECT a, b FROM prt1 FULL JOIN prt2 p2(b,a,c) USING(a,b)
|
||||
WHERE a BETWEEN 490 AND 510
|
||||
GROUP BY 1, 2 ORDER BY 1, 2;
|
||||
QUERY PLAN
|
||||
-------------------------------------------------------------------------------------------------------------------
|
||||
Group
|
||||
Group Key: (COALESCE(prt1_p1.a, p2.a)), (COALESCE(prt1_p1.b, p2.b))
|
||||
-> Merge Append
|
||||
Sort Key: (COALESCE(prt1_p1.a, p2.a)), (COALESCE(prt1_p1.b, p2.b))
|
||||
-> Group
|
||||
Group Key: (COALESCE(prt1_p1.a, p2.a)), (COALESCE(prt1_p1.b, p2.b))
|
||||
-> Sort
|
||||
Sort Key: (COALESCE(prt1_p1.a, p2.a)), (COALESCE(prt1_p1.b, p2.b))
|
||||
-> Merge Full Join
|
||||
Merge Cond: ((prt1_p1.a = p2.a) AND (prt1_p1.b = p2.b))
|
||||
Filter: ((COALESCE(prt1_p1.a, p2.a) >= 490) AND (COALESCE(prt1_p1.a, p2.a) <= 510))
|
||||
-> Sort
|
||||
Sort Key: prt1_p1.a, prt1_p1.b
|
||||
-> Seq Scan on prt1_p1
|
||||
-> Sort
|
||||
Sort Key: p2.a, p2.b
|
||||
-> Seq Scan on prt2_p1 p2
|
||||
-> Group
|
||||
Group Key: (COALESCE(prt1_p2.a, p2_1.a)), (COALESCE(prt1_p2.b, p2_1.b))
|
||||
-> Sort
|
||||
Sort Key: (COALESCE(prt1_p2.a, p2_1.a)), (COALESCE(prt1_p2.b, p2_1.b))
|
||||
-> Merge Full Join
|
||||
Merge Cond: ((prt1_p2.a = p2_1.a) AND (prt1_p2.b = p2_1.b))
|
||||
Filter: ((COALESCE(prt1_p2.a, p2_1.a) >= 490) AND (COALESCE(prt1_p2.a, p2_1.a) <= 510))
|
||||
-> Sort
|
||||
Sort Key: prt1_p2.a, prt1_p2.b
|
||||
-> Seq Scan on prt1_p2
|
||||
-> Sort
|
||||
Sort Key: p2_1.a, p2_1.b
|
||||
-> Seq Scan on prt2_p2 p2_1
|
||||
-> Group
|
||||
Group Key: (COALESCE(prt1_p3.a, p2_2.a)), (COALESCE(prt1_p3.b, p2_2.b))
|
||||
-> Sort
|
||||
Sort Key: (COALESCE(prt1_p3.a, p2_2.a)), (COALESCE(prt1_p3.b, p2_2.b))
|
||||
-> Merge Full Join
|
||||
Merge Cond: ((prt1_p3.a = p2_2.a) AND (prt1_p3.b = p2_2.b))
|
||||
Filter: ((COALESCE(prt1_p3.a, p2_2.a) >= 490) AND (COALESCE(prt1_p3.a, p2_2.a) <= 510))
|
||||
-> Sort
|
||||
Sort Key: prt1_p3.a, prt1_p3.b
|
||||
-> Seq Scan on prt1_p3
|
||||
-> Sort
|
||||
Sort Key: p2_2.a, p2_2.b
|
||||
-> Seq Scan on prt2_p3 p2_2
|
||||
(43 rows)
|
||||
|
||||
SELECT a, b FROM prt1 FULL JOIN prt2 p2(b,a,c) USING(a,b)
|
||||
WHERE a BETWEEN 490 AND 510
|
||||
GROUP BY 1, 2 ORDER BY 1, 2;
|
||||
a | b
|
||||
-----+----
|
||||
490 | 15
|
||||
492 | 17
|
||||
494 | 19
|
||||
495 | 20
|
||||
496 | 21
|
||||
498 | 23
|
||||
500 | 0
|
||||
501 | 1
|
||||
502 | 2
|
||||
504 | 4
|
||||
506 | 6
|
||||
507 | 7
|
||||
508 | 8
|
||||
510 | 10
|
||||
(14 rows)
|
||||
|
||||
RESET enable_partitionwise_aggregate;
|
||||
RESET enable_hashjoin;
|
||||
--
|
||||
-- partitioned by expression
|
||||
--
|
||||
|
@ -91,6 +91,21 @@ SELECT t1.a, ss.t2a, ss.t2c FROM prt1 t1 LEFT JOIN LATERAL
|
||||
(SELECT t2.a AS t2a, t3.a AS t3a, t2.b t2b, t2.c t2c, least(t1.a,t2.a,t3.a) FROM prt1 t2 JOIN prt2 t3 ON (t2.a = t3.b)) ss
|
||||
ON t1.c = ss.t2c WHERE (t1.b + coalesce(ss.t2b, 0)) = 0 ORDER BY t1.a;
|
||||
|
||||
-- bug with inadequate sort key representation
|
||||
SET enable_partitionwise_aggregate TO true;
|
||||
SET enable_hashjoin TO false;
|
||||
|
||||
EXPLAIN (COSTS OFF)
|
||||
SELECT a, b FROM prt1 FULL JOIN prt2 p2(b,a,c) USING(a,b)
|
||||
WHERE a BETWEEN 490 AND 510
|
||||
GROUP BY 1, 2 ORDER BY 1, 2;
|
||||
SELECT a, b FROM prt1 FULL JOIN prt2 p2(b,a,c) USING(a,b)
|
||||
WHERE a BETWEEN 490 AND 510
|
||||
GROUP BY 1, 2 ORDER BY 1, 2;
|
||||
|
||||
RESET enable_partitionwise_aggregate;
|
||||
RESET enable_hashjoin;
|
||||
|
||||
--
|
||||
-- partitioned by expression
|
||||
--
|
||||
|
Reference in New Issue
Block a user