| From: | Peter Smith <smithpb2250(at)gmail(dot)com> |
|---|---|
| To: | Nisha Moond <nisha(dot)moond412(at)gmail(dot)com> |
| Cc: | shveta malik <shveta(dot)malik(at)gmail(dot)com>, Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Zsolt Parragi <zsolt(dot)parragi(at)percona(dot)com>, pgsql-hackers(at)lists(dot)postgresql(dot)org |
| Subject: | Re: Support EXCEPT for TABLES IN SCHEMA publications |
| Date: | 2026-07-16 08:34:13 |
| Message-ID: | CAHut+PsQaOjTKN46qZ-SsAc4uYBEV9PW7Ff6aKcLrqOb4JBzRA@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Hi Nisha.
Some review comments for v21-0001.
======
src/backend/catalog/pg_publication.c
1.
+bool
+get_publication_rel_entry(Oid pubid, Oid relid, bool *is_except)
This is a bit like the 'is_table_publication' function and others.
Perhaps it should be moved nearer that one?
~~~
check_publication_add_relation:
2.
+ Oid relid = RelationGetRelid(targetrel);
+ Oid root;
+ bool root_except;
Those declarations can all be moved closer to where they are used.
~~~
3.
+ * A partition cannot be included when its partition root is in the
+ * same publication's EXCEPT list. Doing so would leave the catalog
+ * inconsistent (root excluded, partition included) and the
+ * ancestor-cascade rule would silently override the include at
+ * replication time.
Hmm. A single publication may have multiple EXCEPT clauses, but that
first sentence wording seems to be suggesting there is only one.
Perhaps better to say:
SUGGESTION
A partition cannot be included when its partition root is excluded by
the same publication.
~~~
4.
+ errdetail("Ancestor \"%s\" of partition \"%s\" is currently listed
in the EXCEPT clause of the publication.",
For the same reason (a publication may have multiple EXCEPT clauses, I
think this errdetail should change:
/the EXCEPT clause/an EXCEPT clause/
~~~
GetTopMostAncestorInPublication:
5.
+ * If the partition root (the last element of ancestors) is excluded from
+ * this publication via its EXCEPT clause, the partition is not published
+ * through this publication at all, so we short-circuit and return
+ * InvalidOid without walking the ancestor list. Only the root of a
Similar to above. Should not be singular "its EXCEPT clause".
/via its EXCEPT clause/via an EXCEPT clause/
~~~
6.
{
- table_close(rel, RowExclusiveLock);
+ bool is_except;
- if (if_not_exists)
- return InvalidObjectAddress;
-
- ereport(ERROR,
- (errcode(ERRCODE_DUPLICATE_OBJECT),
- errmsg("relation \"%s\" is already member of publication \"%s\"",
- RelationGetRelationName(targetrel), pub->name)));
+ if (get_publication_rel_entry(pubid, relid, &is_except))
+ {
...
+ }
}
I think having a code block like this just for the variable
declaration is unconventional for PG source code; it's not necessary
here, so maybe don't do it.
~~~
7.
+ errdetail("Ancestor \"%s\" of partition \"%s\" is currently listed
in the EXCEPT clause of the publication.",
+ quote_qualified_identifier(get_namespace_name(get_rel_namespace(root)),
Similar (singular) comment to before.
/in the EXCEPT clause/in an EXCEPT clause/
~~~
GetAllSchemaPublicationRelations:
8.
/*
* Gets the list of all relations published by FOR TABLES IN SCHEMA
- * publication.
+ * publication, excluding any tables listed in the EXCEPT clause.
*/
/EXCEPT clause./EXCEPT clauses./
~~~
9.
+ /* filter out any tables that appear in the EXCEPT list */
+ ListCell *rlc;
+
+ foreach(rlc, schemaRels)
+ {
+ Oid relid = lfirst_oid(rlc);
Isn't this loop something that can be simplified using foreach_oid macro?
~~~
10.
+ * A partition whose root is in the publication's EXCEPT list
+ * is also excluded, even if the partition itself lives in a
+ * different (included) schema. Only the topmost root of a
SUGGESTION #1
A partition whose root is in an EXCEPT list of the publication is also
excluded, even if...
SUGGESTION #2
A partition whose root is excluded from the publication is also
excluded, even if...
~~~
is_table_publishable_in_publication:
11.
+ {
+ bool is_except;
+
+ if (get_publication_rel_entry(pub->oid, relid, &is_except))
+ return !is_except;
+ }
Here is another code block which AFAIK is uncommon in PG source code.
IMO would be better to remove this and have a new function variable
`is_except`. You can also remove the other existing `root_except`
declaration because they can bother share this same var. So, the
result will be fewer vars, less unusual code blocks, less code.
======
src/backend/commands/tablecmds.c
12.
+ errhint("%s", has_alltables_pub ?
+ _("Change the publication's EXCEPT clause using ALTER PUBLICATION
... SET ALL TABLES ... EXCEPT.") :
+ _("Change the publication's EXCEPT clause using ALTER PUBLICATION
... SET TABLES IN SCHEMA ... EXCEPT.")));
12a.
The message wording is slightly broken now because there is potential
for even a single publication to have multiple EXCEPT clauses.
Here it might be OK to reword it like:
BEFORE
Change the publication's EXCEPT clause...
SUGGESTION
Change the EXCEPT clause...
~
12b.
Also, IMO the errmsg_plural might be better if reworded:
BEFORE
"cannot attach table \"%s\" as partition because it is referenced in
publication %s EXCEPT clause",
"cannot attach table \"%s\" as partition because it is referenced in
publications %s EXCEPT clause",
SUGGESTION
"cannot attach table \"%s\" as partition because it is referenced in
EXCEPT clause of publication %s",
"cannot attach table \"%s\" as partition because it is referenced in
EXCEPT clause of publications %s",
======
src/include/catalog/pg_publication.h
13.
+extern bool get_publication_rel_entry(Oid pubid, Oid relid, bool *is_except);
Do you think this function name should be CamelCase (more common for
non-static functions), instead of snake_case?
======
Kind Regards,
Peter Smith.
Fujitsu Australia
| From | Date | Subject | |
|---|---|---|---|
| Next Message | vignesh C | 2026-07-16 08:52:27 | Re: Fix publisher-side sequence permission reporting |
| Previous Message | Guoqing Yang | 2026-07-16 07:54:57 | Re: Follow-up fixes for online wal_level change |