From: | Shlok Kyal <shlok(dot)kyal(dot)oss(at)gmail(dot)com> |
---|---|
To: | vignesh C <vignesh21(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 10:20:38 |
Message-ID: | CANhcyEVbFMWnEkShq37SSgW7+X+xOxx9bvc4Jtj6BgAy9jGnqA@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
On Thu, 13 Feb 2025 at 11:25, vignesh C <vignesh21(at)gmail(dot)com> wrote:
>
> 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);
>
Hi Vignesh,
I have fixed the issue. Attached the updated v6 patch.
Thanks and Regards,
Shlok Kyal
Attachment | Content-Type | Size |
---|---|---|
v6-0001-Restrict-publishing-of-partitioned-table-with-for.patch | application/octet-stream | 25.9 KB |
From | Date | Subject | |
---|---|---|---|
Next Message | vignesh C | 2025-02-13 10:23:59 | Re: Restrict copying of invalidated replication slots |
Previous Message | Alexander Korotkov | 2025-02-13 10:08:13 | Re: Get rid of WALBufMappingLock |