From 23c1dcd13ebe94e048e9700564391be5963f408b Mon Sep 17 00:00:00 2001 From: amitlan Date: Fri, 23 Dec 2022 11:23:52 +0900 Subject: [PATCH v1] postgres_fdw: test update of multi-level partitioned table This especially tests that get_rel_all_updated_cols() correctly translates the attribute numbers of RTEPermissionInfo.updatedCols belonging the root target table into the rowtype of the foreign leaf partition when postgresPlanForeignModify() calls it to generate the latter's target attribute numbers. --- .../postgres_fdw/expected/postgres_fdw.out | 32 +++++++++++++++++++ contrib/postgres_fdw/sql/postgres_fdw.sql | 17 ++++++++++ 2 files changed, 49 insertions(+) diff --git a/contrib/postgres_fdw/expected/postgres_fdw.out b/contrib/postgres_fdw/expected/postgres_fdw.out index 2ab3f1efaa..8eabc93e63 100644 --- a/contrib/postgres_fdw/expected/postgres_fdw.out +++ b/contrib/postgres_fdw/expected/postgres_fdw.out @@ -11699,3 +11699,35 @@ SELECT * FROM prem2; ALTER SERVER loopback OPTIONS (DROP parallel_commit); ALTER SERVER loopback2 OPTIONS (DROP parallel_commit); +-- Test updates of partitioned tables containing a foreign partition multiple +-- levels removed from the root parent and where attribute numbers differ +-- between each relation on the way down. +CREATE TABLE rootp (a integer, b text, c numeric, d numeric generated always as (c + 0.1) stored) + PARTITION BY LIST (a); +CREATE TABLE locpart1 (b text, c numeric, a integer, d numeric generated always as (c + 0.1) stored) + PARTITION BY LIST (a); +CREATE TABLE rempart11base (c numeric, a integer, b text, d numeric); +CREATE FOREIGN TABLE rempart11 (c numeric, a integer, b text, d numeric generated always as (c + 0.1) stored) + SERVER loopback OPTIONS (table_name 'rempart11base'); +ALTER TABLE rootp ATTACH PARTITION locpart1 FOR VALUES IN (1); +ALTER TABLE locpart1 ATTACH PARTITION rempart11 FOR VALUES IN (1); +INSERT INTO rootp VALUES (1, 'foo', 1.1); +EXPLAIN (VERBOSE, COSTS OFF) + UPDATE rootp SET b = b || 'd' RETURNING a, b, c, d; + QUERY PLAN +--------------------------------------------------------------------------------------------- + Update on public.rootp + Output: rootp_1.a, rootp_1.b, rootp_1.c, rootp_1.d + Foreign Update on public.rempart11 rootp_1 + Remote SQL: UPDATE public.rempart11base SET b = $2 WHERE ctid = $1 RETURNING c, a, b, d + -> Foreign Scan on public.rempart11 rootp_1 + Output: (rootp_1.b || 'd'::text), rootp_1.tableoid, rootp_1.ctid, rootp_1.* + Remote SQL: SELECT c, a, b, d, ctid FROM public.rempart11base FOR UPDATE +(7 rows) + +UPDATE rootp SET b = b || 'd' RETURNING a, b, c, d; + a | b | c | d +---+------+-----+--- + 1 | food | 1.1 | +(1 row) + diff --git a/contrib/postgres_fdw/sql/postgres_fdw.sql b/contrib/postgres_fdw/sql/postgres_fdw.sql index 51560429e0..1495969fce 100644 --- a/contrib/postgres_fdw/sql/postgres_fdw.sql +++ b/contrib/postgres_fdw/sql/postgres_fdw.sql @@ -3874,3 +3874,20 @@ SELECT * FROM prem2; ALTER SERVER loopback OPTIONS (DROP parallel_commit); ALTER SERVER loopback2 OPTIONS (DROP parallel_commit); + +-- Test updates of partitioned tables containing a foreign partition multiple +-- levels removed from the root parent and where attribute numbers differ +-- between each relation on the way down. +CREATE TABLE rootp (a integer, b text, c numeric, d numeric generated always as (c + 0.1) stored) + PARTITION BY LIST (a); +CREATE TABLE locpart1 (b text, c numeric, a integer, d numeric generated always as (c + 0.1) stored) + PARTITION BY LIST (a); +CREATE TABLE rempart11base (c numeric, a integer, b text, d numeric); +CREATE FOREIGN TABLE rempart11 (c numeric, a integer, b text, d numeric generated always as (c + 0.1) stored) + SERVER loopback OPTIONS (table_name 'rempart11base'); +ALTER TABLE rootp ATTACH PARTITION locpart1 FOR VALUES IN (1); +ALTER TABLE locpart1 ATTACH PARTITION rempart11 FOR VALUES IN (1); +INSERT INTO rootp VALUES (1, 'foo', 1.1); +EXPLAIN (VERBOSE, COSTS OFF) + UPDATE rootp SET b = b || 'd' RETURNING a, b, c, d; +UPDATE rootp SET b = b || 'd' RETURNING a, b, c, d; -- 2.35.3