From: | vignesh C <vignesh21(at)gmail(dot)com> |
---|---|
To: | Shlok Kyal <shlok(dot)kyal(dot)oss(at)gmail(dot)com> |
Cc: | Álvaro Herrera <alvherre(at)alvh(dot)no-ip(dot)org>, Sergey Tatarintsev <s(dot)tatarintsev(at)postgrespro(dot)ru>, pgsql-hackers(at)lists(dot)postgresql(dot)org |
Subject: | Re: Restrict publishing of partitioned table with a foreign table as partition |
Date: | 2025-02-13 05:54:51 |
Message-ID: | CALDaNm2Q1rNN-L8u95pjVRw-aBJkcGJh2bHeaPc2bO=mj_1QMA@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
On Tue, 11 Feb 2025 at 16:55, Shlok Kyal <shlok(dot)kyal(dot)oss(at)gmail(dot)com> wrote:
> I have handled the above cases and added tests for the same.
There is a concurrency issue with the patch:
+check_partrel_has_foreign_table(Form_pg_class relform)
+{
+ bool has_foreign_tbl = false;
+
+ if (relform->relkind == RELKIND_PARTITIONED_TABLE)
+ {
+ List *relids = NIL;
+
+ relids = find_all_inheritors(relform->oid, NoLock, NULL);
+
+ foreach_oid(relid, relids)
+ {
+ Relation rel = table_open(relid,
AccessShareLock);
+
+ if (RelationGetForm(rel)->relkind ==
RELKIND_FOREIGN_TABLE)
+ has_foreign_tbl = true;
+
+ table_close(rel, AccessShareLock);
+
+ if (has_foreign_tbl)
+ break;
+ }
+ }
+
+ return has_foreign_tbl;
+}
In an ideal scenario, the creation of a foreign table should fail if
there is an associated publication, as demonstrated below:
CREATE TABLE t(id int) PARTITION BY RANGE(id);
CREATE TABLE part1 PARTITION OF t FOR VALUES FROM (0) TO (5);
CREATE TABLE part2 PARTITION OF t FOR VALUES FROM (5) TO (15)
PARTITION BY RANGE(id);
CREATE PUBLICATION pub1 FOR TABLE t with (publish_via_partition_root = true);
postgres=# CREATE FOREIGN TABLE part22 PARTITION OF part2 FOR VALUES
FROM (10) TO (15) SERVER fdw;
ERROR: cannot create table foreign partition "part22"
DETAIL: partition table "part2" is published with option
publish_via_partition_root
Consider a scenario where the publication is being created and after
the check_partrel_has_foreign_table execution is done, concurrently
creation of foreign table is executed, then the creation will be
successful.
postgres=# CREATE FOREIGN TABLE part22 PARTITION OF part2 FOR VALUES
FROM (10) TO (15) SERVER fdw;
CREATE FOREIGN TABLE
I felt the problem here is that you have released the lock:
+ if (RelationGetForm(rel)->relkind ==
RELKIND_FOREIGN_TABLE)
+ has_foreign_tbl = true;
+
+ table_close(rel, AccessShareLock);
We should retain the lock to fix this issue:
+ if (RelationGetForm(rel)->relkind ==
RELKIND_FOREIGN_TABLE)
+ has_foreign_tbl = true;
+
+ table_close(rel, NoLock);
Regards,
Vignesh
From | Date | Subject | |
---|---|---|---|
Next Message | John Naylor | 2025-02-13 06:03:19 | Re: Change GUC hashtable to use simplehash? |
Previous Message | Ashutosh Bapat | 2025-02-13 05:48:28 | Re: Address the bug in 041_checkpoint_at_promote.pl |