1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-13 07:41:39 +03:00

Fix EXPLAIN's column alias output for mismatched child tables.

If an inheritance/partitioning parent table is assigned some column
alias names in the query, EXPLAIN mapped those aliases onto the
child tables' columns by physical position, resulting in bogus output
if a child table's columns aren't one-for-one with the parent's.

To fix, make expand_single_inheritance_child() generate a correctly
re-mapped column alias list, rather than just copying the parent
RTE's alias node.  (We have to fill the alias field, not just
adjust the eref field, because ruleutils.c will ignore eref in
favor of looking at the real column names.)

This means that child tables will now always have alias fields in
plan rtables, where before they might not have.  That results in
a rather substantial set of regression test output changes:
EXPLAIN will now always show child tables with aliases that match
the parent table (usually with "_N" appended for uniqueness).
But that seems like a net positive for understandability, since
the parent alias corresponds to something that actually appeared
in the original query, while the child table names didn't.
(Note that this does not change anything for cases where an explicit
table alias was written in the query for the parent table; it
just makes cases without such aliases behave similarly to that.)
Hence, while we could avoid these subsidiary changes if we made
inherit.c more complicated, we choose not to.

Discussion: https://postgr.es/m/12424.1575168015@sss.pgh.pa.us
This commit is contained in:
Tom Lane
2019-12-02 19:08:10 -05:00
parent ce76c0ba53
commit 55a1954da1
16 changed files with 2072 additions and 1982 deletions

View File

@ -6260,10 +6260,10 @@ UPDATE rw_view SET b = b + 5;
QUERY PLAN
----------------------------------------------------------------------------------------
Update on public.parent_tbl
Foreign Update on public.foreign_tbl
Foreign Update on public.foreign_tbl parent_tbl_1
Remote SQL: UPDATE public.child_tbl SET b = $2 WHERE ctid = $1 RETURNING a, b
-> Foreign Scan on public.foreign_tbl
Output: foreign_tbl.a, (foreign_tbl.b + 5), foreign_tbl.ctid
-> Foreign Scan on public.foreign_tbl parent_tbl_1
Output: parent_tbl_1.a, (parent_tbl_1.b + 5), parent_tbl_1.ctid
Remote SQL: SELECT a, b, ctid FROM public.child_tbl WHERE ((a < b)) FOR UPDATE
(6 rows)
@ -6275,10 +6275,10 @@ UPDATE rw_view SET b = b + 15;
QUERY PLAN
----------------------------------------------------------------------------------------
Update on public.parent_tbl
Foreign Update on public.foreign_tbl
Foreign Update on public.foreign_tbl parent_tbl_1
Remote SQL: UPDATE public.child_tbl SET b = $2 WHERE ctid = $1 RETURNING a, b
-> Foreign Scan on public.foreign_tbl
Output: foreign_tbl.a, (foreign_tbl.b + 15), foreign_tbl.ctid
-> Foreign Scan on public.foreign_tbl parent_tbl_1
Output: parent_tbl_1.a, (parent_tbl_1.b + 15), parent_tbl_1.ctid
Remote SQL: SELECT a, b, ctid FROM public.child_tbl WHERE ((a < b)) FOR UPDATE
(6 rows)
@ -7066,8 +7066,8 @@ select * from bar where f1 in (select f1 from foo) for update;
-> Append
-> Seq Scan on public.bar
Output: bar.f1, bar.f2, bar.ctid, bar.*, bar.tableoid
-> Foreign Scan on public.bar2
Output: bar2.f1, bar2.f2, bar2.ctid, bar2.*, bar2.tableoid
-> Foreign Scan on public.bar2 bar_1
Output: bar_1.f1, bar_1.f2, bar_1.ctid, bar_1.*, bar_1.tableoid
Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct2 FOR UPDATE
-> Hash
Output: foo.ctid, foo.f1, foo.*, foo.tableoid
@ -7077,8 +7077,8 @@ select * from bar where f1 in (select f1 from foo) for update;
-> Append
-> Seq Scan on public.foo
Output: foo.ctid, foo.f1, foo.*, foo.tableoid
-> Foreign Scan on public.foo2
Output: foo2.ctid, foo2.f1, foo2.*, foo2.tableoid
-> Foreign Scan on public.foo2 foo_1
Output: foo_1.ctid, foo_1.f1, foo_1.*, foo_1.tableoid
Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct1
(23 rows)
@ -7104,8 +7104,8 @@ select * from bar where f1 in (select f1 from foo) for share;
-> Append
-> Seq Scan on public.bar
Output: bar.f1, bar.f2, bar.ctid, bar.*, bar.tableoid
-> Foreign Scan on public.bar2
Output: bar2.f1, bar2.f2, bar2.ctid, bar2.*, bar2.tableoid
-> Foreign Scan on public.bar2 bar_1
Output: bar_1.f1, bar_1.f2, bar_1.ctid, bar_1.*, bar_1.tableoid
Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct2 FOR SHARE
-> Hash
Output: foo.ctid, foo.f1, foo.*, foo.tableoid
@ -7115,8 +7115,8 @@ select * from bar where f1 in (select f1 from foo) for share;
-> Append
-> Seq Scan on public.foo
Output: foo.ctid, foo.f1, foo.*, foo.tableoid
-> Foreign Scan on public.foo2
Output: foo2.ctid, foo2.f1, foo2.*, foo2.tableoid
-> Foreign Scan on public.foo2 foo_1
Output: foo_1.ctid, foo_1.f1, foo_1.*, foo_1.tableoid
Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct1
(23 rows)
@ -7132,11 +7132,11 @@ select * from bar where f1 in (select f1 from foo) for share;
-- Check UPDATE with inherited target and an inherited source table
explain (verbose, costs off)
update bar set f2 = f2 + 100 where f1 in (select f1 from foo);
QUERY PLAN
---------------------------------------------------------------------------------------------
QUERY PLAN
-------------------------------------------------------------------------------------------------
Update on public.bar
Update on public.bar
Foreign Update on public.bar2
Foreign Update on public.bar2 bar_1
Remote SQL: UPDATE public.loct2 SET f2 = $2 WHERE ctid = $1
-> Hash Join
Output: bar.f1, (bar.f2 + 100), bar.ctid, foo.ctid, foo.*, foo.tableoid
@ -7152,15 +7152,15 @@ update bar set f2 = f2 + 100 where f1 in (select f1 from foo);
-> Append
-> Seq Scan on public.foo
Output: foo.ctid, foo.f1, foo.*, foo.tableoid
-> Foreign Scan on public.foo2
Output: foo2.ctid, foo2.f1, foo2.*, foo2.tableoid
-> Foreign Scan on public.foo2 foo_1
Output: foo_1.ctid, foo_1.f1, foo_1.*, foo_1.tableoid
Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct1
-> Hash Join
Output: bar2.f1, (bar2.f2 + 100), bar2.f3, bar2.ctid, foo.ctid, foo.*, foo.tableoid
Output: bar_1.f1, (bar_1.f2 + 100), bar_1.f3, bar_1.ctid, foo.ctid, foo.*, foo.tableoid
Inner Unique: true
Hash Cond: (bar2.f1 = foo.f1)
-> Foreign Scan on public.bar2
Output: bar2.f1, bar2.f2, bar2.f3, bar2.ctid
Hash Cond: (bar_1.f1 = foo.f1)
-> Foreign Scan on public.bar2 bar_1
Output: bar_1.f1, bar_1.f2, bar_1.f3, bar_1.ctid
Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct2 FOR UPDATE
-> Hash
Output: foo.ctid, foo.f1, foo.*, foo.tableoid
@ -7170,8 +7170,8 @@ update bar set f2 = f2 + 100 where f1 in (select f1 from foo);
-> Append
-> Seq Scan on public.foo
Output: foo.ctid, foo.f1, foo.*, foo.tableoid
-> Foreign Scan on public.foo2
Output: foo2.ctid, foo2.f1, foo2.*, foo2.tableoid
-> Foreign Scan on public.foo2 foo_1
Output: foo_1.ctid, foo_1.f1, foo_1.*, foo_1.tableoid
Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct1
(39 rows)
@ -7197,7 +7197,7 @@ where bar.f1 = ss.f1;
--------------------------------------------------------------------------------------
Update on public.bar
Update on public.bar
Foreign Update on public.bar2
Foreign Update on public.bar2 bar_1
Remote SQL: UPDATE public.loct2 SET f2 = $2 WHERE ctid = $1
-> Hash Join
Output: bar.f1, (bar.f2 + 100), bar.ctid, (ROW(foo.f1))
@ -7205,26 +7205,26 @@ where bar.f1 = ss.f1;
-> Append
-> Seq Scan on public.foo
Output: ROW(foo.f1), foo.f1
-> Foreign Scan on public.foo2
Output: ROW(foo2.f1), foo2.f1
-> Foreign Scan on public.foo2 foo_1
Output: ROW(foo_1.f1), foo_1.f1
Remote SQL: SELECT f1 FROM public.loct1
-> Seq Scan on public.foo foo_1
Output: ROW((foo_1.f1 + 3)), (foo_1.f1 + 3)
-> Foreign Scan on public.foo2 foo2_1
Output: ROW((foo2_1.f1 + 3)), (foo2_1.f1 + 3)
-> Seq Scan on public.foo foo_2
Output: ROW((foo_2.f1 + 3)), (foo_2.f1 + 3)
-> Foreign Scan on public.foo2 foo_3
Output: ROW((foo_3.f1 + 3)), (foo_3.f1 + 3)
Remote SQL: SELECT f1 FROM public.loct1
-> Hash
Output: bar.f1, bar.f2, bar.ctid
-> Seq Scan on public.bar
Output: bar.f1, bar.f2, bar.ctid
-> Merge Join
Output: bar2.f1, (bar2.f2 + 100), bar2.f3, bar2.ctid, (ROW(foo.f1))
Merge Cond: (bar2.f1 = foo.f1)
Output: bar_1.f1, (bar_1.f2 + 100), bar_1.f3, bar_1.ctid, (ROW(foo.f1))
Merge Cond: (bar_1.f1 = foo.f1)
-> Sort
Output: bar2.f1, bar2.f2, bar2.f3, bar2.ctid
Sort Key: bar2.f1
-> Foreign Scan on public.bar2
Output: bar2.f1, bar2.f2, bar2.f3, bar2.ctid
Output: bar_1.f1, bar_1.f2, bar_1.f3, bar_1.ctid
Sort Key: bar_1.f1
-> Foreign Scan on public.bar2 bar_1
Output: bar_1.f1, bar_1.f2, bar_1.f3, bar_1.ctid
Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct2 FOR UPDATE
-> Sort
Output: (ROW(foo.f1)), foo.f1
@ -7232,13 +7232,13 @@ where bar.f1 = ss.f1;
-> Append
-> Seq Scan on public.foo
Output: ROW(foo.f1), foo.f1
-> Foreign Scan on public.foo2
Output: ROW(foo2.f1), foo2.f1
-> Foreign Scan on public.foo2 foo_1
Output: ROW(foo_1.f1), foo_1.f1
Remote SQL: SELECT f1 FROM public.loct1
-> Seq Scan on public.foo foo_1
Output: ROW((foo_1.f1 + 3)), (foo_1.f1 + 3)
-> Foreign Scan on public.foo2 foo2_1
Output: ROW((foo2_1.f1 + 3)), (foo2_1.f1 + 3)
-> Seq Scan on public.foo foo_2
Output: ROW((foo_2.f1 + 3)), (foo_2.f1 + 3)
-> Foreign Scan on public.foo2 foo_3
Output: ROW((foo_3.f1 + 3)), (foo_3.f1 + 3)
Remote SQL: SELECT f1 FROM public.loct1
(45 rows)
@ -7288,8 +7288,8 @@ explain (verbose, costs off)
Sort Key: foo.f1
-> Index Scan using i_foo_f1 on public.foo
Output: foo.f1, foo.f2
-> Foreign Scan on public.foo2
Output: foo2.f1, foo2.f2
-> Foreign Scan on public.foo2 foo_1
Output: foo_1.f1, foo_1.f2
Remote SQL: SELECT f1, f2 FROM public.loct1 ORDER BY f1 ASC NULLS LAST
-> Index Only Scan using i_loct1_f1 on public.loct1
Output: loct1.f1
@ -7328,8 +7328,8 @@ explain (verbose, costs off)
Sort Key: foo.f1
-> Index Scan using i_foo_f1 on public.foo
Output: foo.f1, foo.f2
-> Foreign Scan on public.foo2
Output: foo2.f1, foo2.f2
-> Foreign Scan on public.foo2 foo_1
Output: foo_1.f1, foo_1.f2
Remote SQL: SELECT f1, f2 FROM public.loct1 ORDER BY f1 ASC NULLS LAST
-> Index Only Scan using i_loct1_f1 on public.loct1
Output: loct1.f1
@ -7371,11 +7371,11 @@ delete from foo where f1 < 5 returning *;
Delete on public.foo
Output: foo.f1, foo.f2
Delete on public.foo
Foreign Delete on public.foo2
Foreign Delete on public.foo2 foo_1
-> Index Scan using i_foo_f1 on public.foo
Output: foo.ctid
Index Cond: (foo.f1 < 5)
-> Foreign Delete on public.foo2
-> Foreign Delete on public.foo2 foo_1
Remote SQL: DELETE FROM public.loct1 WHERE ((f1 < 5)) RETURNING f1, f2
(9 rows)
@ -7396,10 +7396,10 @@ update bar set f2 = f2 + 100 returning *;
Update on public.bar
Output: bar.f1, bar.f2
Update on public.bar
Foreign Update on public.bar2
Foreign Update on public.bar2 bar_1
-> Seq Scan on public.bar
Output: bar.f1, (bar.f2 + 100), bar.ctid
-> Foreign Update on public.bar2
-> Foreign Update on public.bar2 bar_1
Remote SQL: UPDATE public.loct2 SET f2 = (f2 + 100) RETURNING f1, f2
(8 rows)
@ -7427,12 +7427,12 @@ update bar set f2 = f2 + 100;
--------------------------------------------------------------------------------------------------------
Update on public.bar
Update on public.bar
Foreign Update on public.bar2
Foreign Update on public.bar2 bar_1
Remote SQL: UPDATE public.loct2 SET f1 = $2, f2 = $3, f3 = $4 WHERE ctid = $1 RETURNING f1, f2, f3
-> Seq Scan on public.bar
Output: bar.f1, (bar.f2 + 100), bar.ctid
-> Foreign Scan on public.bar2
Output: bar2.f1, (bar2.f2 + 100), bar2.f3, bar2.ctid, bar2.*
-> Foreign Scan on public.bar2 bar_1
Output: bar_1.f1, (bar_1.f2 + 100), bar_1.f3, bar_1.ctid, bar_1.*
Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct2 FOR UPDATE
(9 rows)
@ -7455,13 +7455,13 @@ delete from bar where f2 < 400;
---------------------------------------------------------------------------------------------
Delete on public.bar
Delete on public.bar
Foreign Delete on public.bar2
Foreign Delete on public.bar2 bar_1
Remote SQL: DELETE FROM public.loct2 WHERE ctid = $1 RETURNING f1, f2, f3
-> Seq Scan on public.bar
Output: bar.ctid
Filter: (bar.f2 < 400)
-> Foreign Scan on public.bar2
Output: bar2.ctid, bar2.*
-> Foreign Scan on public.bar2 bar_1
Output: bar_1.ctid, bar_1.*
Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct2 WHERE ((f2 < 400)) FOR UPDATE
(10 rows)
@ -7499,7 +7499,7 @@ update parent set b = parent.b || remt2.b from remt2 where parent.a = remt2.a re
Update on public.parent
Output: parent.a, parent.b, remt2.a, remt2.b
Update on public.parent
Foreign Update on public.remt1
Foreign Update on public.remt1 parent_1
-> Nested Loop
Output: parent.a, (parent.b || remt2.b), parent.ctid, remt2.*, remt2.a, remt2.b
Join Filter: (parent.a = remt2.a)
@ -7526,7 +7526,7 @@ delete from parent using remt2 where parent.a = remt2.a returning parent;
Delete on public.parent
Output: parent.*
Delete on public.parent
Foreign Delete on public.remt1
Foreign Delete on public.remt1 parent_1
-> Nested Loop
Output: parent.ctid, remt2.*
Join Filter: (parent.a = remt2.a)
@ -7753,14 +7753,14 @@ update utrtest set a = 1 where a = 1 or a = 2 returning *;
QUERY PLAN
----------------------------------------------------------------------------------------------
Update on public.utrtest
Output: remp.a, remp.b
Foreign Update on public.remp
Update on public.locp
-> Foreign Update on public.remp
Output: utrtest_1.a, utrtest_1.b
Foreign Update on public.remp utrtest_1
Update on public.locp utrtest_2
-> Foreign Update on public.remp utrtest_1
Remote SQL: UPDATE public.loct SET a = 1 WHERE (((a = 1) OR (a = 2))) RETURNING a, b
-> Seq Scan on public.locp
Output: 1, locp.b, locp.ctid
Filter: ((locp.a = 1) OR (locp.a = 2))
-> Seq Scan on public.locp utrtest_2
Output: 1, utrtest_2.b, utrtest_2.ctid
Filter: ((utrtest_2.a = 1) OR (utrtest_2.a = 2))
(9 rows)
-- The new values are concatenated with ' triggered !'
@ -7775,14 +7775,14 @@ insert into utrtest values (2, 'qux');
-- Check case where the foreign partition isn't a subplan target rel
explain (verbose, costs off)
update utrtest set a = 1 where a = 2 returning *;
QUERY PLAN
--------------------------------------
QUERY PLAN
------------------------------------------------
Update on public.utrtest
Output: locp.a, locp.b
Update on public.locp
-> Seq Scan on public.locp
Output: 1, locp.b, locp.ctid
Filter: (locp.a = 2)
Output: utrtest_1.a, utrtest_1.b
Update on public.locp utrtest_1
-> Seq Scan on public.locp utrtest_1
Output: 1, utrtest_1.b, utrtest_1.ctid
Filter: (utrtest_1.a = 2)
(6 rows)
-- The new values are concatenated with ' triggered !'
@ -7805,13 +7805,13 @@ update utrtest set a = 1 returning *;
QUERY PLAN
-----------------------------------------------------------------
Update on public.utrtest
Output: remp.a, remp.b
Foreign Update on public.remp
Update on public.locp
-> Foreign Update on public.remp
Output: utrtest_1.a, utrtest_1.b
Foreign Update on public.remp utrtest_1
Update on public.locp utrtest_2
-> Foreign Update on public.remp utrtest_1
Remote SQL: UPDATE public.loct SET a = 1 RETURNING a, b
-> Seq Scan on public.locp
Output: 1, locp.b, locp.ctid
-> Seq Scan on public.locp utrtest_2
Output: 1, utrtest_2.b, utrtest_2.ctid
(8 rows)
update utrtest set a = 1 returning *;
@ -7827,28 +7827,28 @@ insert into utrtest values (2, 'qux');
-- with a non-direct modification plan
explain (verbose, costs off)
update utrtest set a = 1 from (values (1), (2)) s(x) where a = s.x returning *;
QUERY PLAN
------------------------------------------------------------------------------
QUERY PLAN
----------------------------------------------------------------------------------
Update on public.utrtest
Output: remp.a, remp.b, "*VALUES*".column1
Foreign Update on public.remp
Output: utrtest_1.a, utrtest_1.b, "*VALUES*".column1
Foreign Update on public.remp utrtest_1
Remote SQL: UPDATE public.loct SET a = $2 WHERE ctid = $1 RETURNING a, b
Update on public.locp
Update on public.locp utrtest_2
-> Hash Join
Output: 1, remp.b, remp.ctid, "*VALUES*".*, "*VALUES*".column1
Hash Cond: (remp.a = "*VALUES*".column1)
-> Foreign Scan on public.remp
Output: remp.b, remp.ctid, remp.a
Output: 1, utrtest_1.b, utrtest_1.ctid, "*VALUES*".*, "*VALUES*".column1
Hash Cond: (utrtest_1.a = "*VALUES*".column1)
-> Foreign Scan on public.remp utrtest_1
Output: utrtest_1.b, utrtest_1.ctid, utrtest_1.a
Remote SQL: SELECT a, b, ctid FROM public.loct FOR UPDATE
-> Hash
Output: "*VALUES*".*, "*VALUES*".column1
-> Values Scan on "*VALUES*"
Output: "*VALUES*".*, "*VALUES*".column1
-> Hash Join
Output: 1, locp.b, locp.ctid, "*VALUES*".*, "*VALUES*".column1
Hash Cond: (locp.a = "*VALUES*".column1)
-> Seq Scan on public.locp
Output: locp.b, locp.ctid, locp.a
Output: 1, utrtest_2.b, utrtest_2.ctid, "*VALUES*".*, "*VALUES*".column1
Hash Cond: (utrtest_2.a = "*VALUES*".column1)
-> Seq Scan on public.locp utrtest_2
Output: utrtest_2.b, utrtest_2.ctid, utrtest_2.a
-> Hash
Output: "*VALUES*".*, "*VALUES*".column1
-> Values Scan on "*VALUES*"
@ -7880,12 +7880,12 @@ update utrtest set a = 3 returning *;
QUERY PLAN
-----------------------------------------------------------------
Update on public.utrtest
Output: locp.a, locp.b
Update on public.locp
Foreign Update on public.remp
-> Seq Scan on public.locp
Output: 3, locp.b, locp.ctid
-> Foreign Update on public.remp
Output: utrtest_1.a, utrtest_1.b
Update on public.locp utrtest_1
Foreign Update on public.remp utrtest_2
-> Seq Scan on public.locp utrtest_1
Output: 3, utrtest_1.b, utrtest_1.ctid
-> Foreign Update on public.remp utrtest_2
Remote SQL: UPDATE public.loct SET a = 3 RETURNING a, b
(8 rows)
@ -7894,27 +7894,27 @@ ERROR: cannot route tuples into foreign table to be updated "remp"
-- with a non-direct modification plan
explain (verbose, costs off)
update utrtest set a = 3 from (values (2), (3)) s(x) where a = s.x returning *;
QUERY PLAN
------------------------------------------------------------------------------
QUERY PLAN
----------------------------------------------------------------------------------
Update on public.utrtest
Output: locp.a, locp.b, "*VALUES*".column1
Update on public.locp
Foreign Update on public.remp
Output: utrtest_1.a, utrtest_1.b, "*VALUES*".column1
Update on public.locp utrtest_1
Foreign Update on public.remp utrtest_2
Remote SQL: UPDATE public.loct SET a = $2 WHERE ctid = $1 RETURNING a, b
-> Hash Join
Output: 3, locp.b, locp.ctid, "*VALUES*".*, "*VALUES*".column1
Hash Cond: (locp.a = "*VALUES*".column1)
-> Seq Scan on public.locp
Output: locp.b, locp.ctid, locp.a
Output: 3, utrtest_1.b, utrtest_1.ctid, "*VALUES*".*, "*VALUES*".column1
Hash Cond: (utrtest_1.a = "*VALUES*".column1)
-> Seq Scan on public.locp utrtest_1
Output: utrtest_1.b, utrtest_1.ctid, utrtest_1.a
-> Hash
Output: "*VALUES*".*, "*VALUES*".column1
-> Values Scan on "*VALUES*"
Output: "*VALUES*".*, "*VALUES*".column1
-> Hash Join
Output: 3, remp.b, remp.ctid, "*VALUES*".*, "*VALUES*".column1
Hash Cond: (remp.a = "*VALUES*".column1)
-> Foreign Scan on public.remp
Output: remp.b, remp.ctid, remp.a
Output: 3, utrtest_2.b, utrtest_2.ctid, "*VALUES*".*, "*VALUES*".column1
Hash Cond: (utrtest_2.a = "*VALUES*".column1)
-> Foreign Scan on public.remp utrtest_2
Output: utrtest_2.b, utrtest_2.ctid, utrtest_2.a
Remote SQL: SELECT a, b, ctid FROM public.loct FOR UPDATE
-> Hash
Output: "*VALUES*".*, "*VALUES*".column1
@ -8506,8 +8506,8 @@ SELECT t1.a,t2.b,t2.c FROM fprt1 t1 LEFT JOIN (SELECT * FROM fprt2 WHERE a < 10)
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Foreign Scan
Output: t1.a, ftprt2_p1.b, ftprt2_p1.c
Relations: (public.ftprt1_p1 t1) LEFT JOIN (public.ftprt2_p1)
Output: t1.a, fprt2.b, fprt2.c
Relations: (public.ftprt1_p1 t1) LEFT JOIN (public.ftprt2_p1 fprt2)
Remote SQL: SELECT r5.a, r6.b, r6.c FROM (public.fprt1_p1 r5 LEFT JOIN public.fprt2_p1 r6 ON (((r5.a = r6.b)) AND ((r5.b = r6.a)) AND ((r6.a < 10)))) WHERE ((r5.a < 10)) ORDER BY r5.a ASC NULLS LAST, r6.b ASC NULLS LAST, r6.c ASC NULLS LAST
(4 rows)
@ -8584,21 +8584,21 @@ SELECT t1.a,t1.b FROM fprt1 t1, LATERAL (SELECT t2.a, t2.b FROM fprt2 t2 WHERE t
-- with PHVs, partitionwise join selected but no join pushdown
EXPLAIN (COSTS OFF)
SELECT t1.a, t1.phv, t2.b, t2.phv FROM (SELECT 't1_phv' phv, * FROM fprt1 WHERE a % 25 = 0) t1 FULL JOIN (SELECT 't2_phv' phv, * FROM fprt2 WHERE b % 25 = 0) t2 ON (t1.a = t2.b) ORDER BY t1.a, t2.b;
QUERY PLAN
------------------------------------------------------
QUERY PLAN
-----------------------------------------------------------
Sort
Sort Key: ftprt1_p1.a, ftprt2_p1.b
Sort Key: fprt1.a, fprt2.b
-> Append
-> Hash Full Join
Hash Cond: (ftprt1_p1.a = ftprt2_p1.b)
-> Foreign Scan on ftprt1_p1
Hash Cond: (fprt1.a = fprt2.b)
-> Foreign Scan on ftprt1_p1 fprt1
-> Hash
-> Foreign Scan on ftprt2_p1
-> Foreign Scan on ftprt2_p1 fprt2
-> Hash Full Join
Hash Cond: (ftprt1_p2.a = ftprt2_p2.b)
-> Foreign Scan on ftprt1_p2
Hash Cond: (fprt1_1.a = fprt2_1.b)
-> Foreign Scan on ftprt1_p2 fprt1_1
-> Hash
-> Foreign Scan on ftprt2_p2
-> Foreign Scan on ftprt2_p2 fprt2_1
(13 rows)
SELECT t1.a, t1.phv, t2.b, t2.phv FROM (SELECT 't1_phv' phv, * FROM fprt1 WHERE a % 25 = 0) t1 FULL JOIN (SELECT 't2_phv' phv, * FROM fprt2 WHERE b % 25 = 0) t2 ON (t1.a = t2.b) ORDER BY t1.a, t2.b;
@ -8672,34 +8672,34 @@ ANALYZE fpagg_tab_p3;
SET enable_partitionwise_aggregate TO false;
EXPLAIN (COSTS OFF)
SELECT a, sum(b), min(b), count(*) FROM pagg_tab GROUP BY a HAVING avg(b) < 22 ORDER BY 1;
QUERY PLAN
-------------------------------------------------------
QUERY PLAN
-----------------------------------------------------------
Sort
Sort Key: fpagg_tab_p1.a
Sort Key: pagg_tab.a
-> HashAggregate
Group Key: fpagg_tab_p1.a
Filter: (avg(fpagg_tab_p1.b) < '22'::numeric)
Group Key: pagg_tab.a
Filter: (avg(pagg_tab.b) < '22'::numeric)
-> Append
-> Foreign Scan on fpagg_tab_p1
-> Foreign Scan on fpagg_tab_p2
-> Foreign Scan on fpagg_tab_p3
-> Foreign Scan on fpagg_tab_p1 pagg_tab
-> Foreign Scan on fpagg_tab_p2 pagg_tab_1
-> Foreign Scan on fpagg_tab_p3 pagg_tab_2
(9 rows)
-- Plan with partitionwise aggregates is enabled
SET enable_partitionwise_aggregate TO true;
EXPLAIN (COSTS OFF)
SELECT a, sum(b), min(b), count(*) FROM pagg_tab GROUP BY a HAVING avg(b) < 22 ORDER BY 1;
QUERY PLAN
-------------------------------------------------------------
QUERY PLAN
------------------------------------------------------------------------
Sort
Sort Key: fpagg_tab_p1.a
Sort Key: pagg_tab.a
-> Append
-> Foreign Scan
Relations: Aggregate on (public.fpagg_tab_p1)
Relations: Aggregate on (public.fpagg_tab_p1 pagg_tab)
-> Foreign Scan
Relations: Aggregate on (public.fpagg_tab_p2)
Relations: Aggregate on (public.fpagg_tab_p2 pagg_tab_1)
-> Foreign Scan
Relations: Aggregate on (public.fpagg_tab_p3)
Relations: Aggregate on (public.fpagg_tab_p3 pagg_tab_2)
(9 rows)
SELECT a, sum(b), min(b), count(*) FROM pagg_tab GROUP BY a HAVING avg(b) < 22 ORDER BY 1;
@ -8760,23 +8760,23 @@ SELECT a, count(t1) FROM pagg_tab t1 GROUP BY a HAVING avg(b) < 22 ORDER BY 1;
-- When GROUP BY clause does not match with PARTITION KEY.
EXPLAIN (COSTS OFF)
SELECT b, avg(a), max(a), count(*) FROM pagg_tab GROUP BY b HAVING sum(a) < 700 ORDER BY 1;
QUERY PLAN
------------------------------------------------------
QUERY PLAN
-----------------------------------------------------------------
Sort
Sort Key: fpagg_tab_p1.b
Sort Key: pagg_tab.b
-> Finalize HashAggregate
Group Key: fpagg_tab_p1.b
Filter: (sum(fpagg_tab_p1.a) < 700)
Group Key: pagg_tab.b
Filter: (sum(pagg_tab.a) < 700)
-> Append
-> Partial HashAggregate
Group Key: fpagg_tab_p1.b
-> Foreign Scan on fpagg_tab_p1
Group Key: pagg_tab.b
-> Foreign Scan on fpagg_tab_p1 pagg_tab
-> Partial HashAggregate
Group Key: fpagg_tab_p2.b
-> Foreign Scan on fpagg_tab_p2
Group Key: pagg_tab_1.b
-> Foreign Scan on fpagg_tab_p2 pagg_tab_1
-> Partial HashAggregate
Group Key: fpagg_tab_p3.b
-> Foreign Scan on fpagg_tab_p3
Group Key: pagg_tab_2.b
-> Foreign Scan on fpagg_tab_p3 pagg_tab_2
(15 rows)
-- Clean-up