Re: Restrict publishing of partitioned table with a foreign table as partition - Mailing list pgsql-hackers

From Álvaro Herrera
Subject Re: Restrict publishing of partitioned table with a foreign table as partition
Date
Msg-id 202504071005.ijn65vntn7g5@alvherre.pgsql
Whole thread Raw
In response to Re: Restrict publishing of partitioned table with a foreign table as partition  (Álvaro Herrera <alvherre@alvh.no-ip.org>)
List pgsql-hackers
As promised, here's a rundown of the changes I did, mostly in order the
patch shows them:

- I reworded the documentation changes to read more coherent with the
surrounding text.

- It seemed wrong to have check_publication_add_relation() have the
relation first as argument and publication later, so I turned them
around.

- I rewrote almost all of the error messages.  The errdetails failed
style (no initial capitals and no end period); one of the errmsg() was
completely wrong (it said "cannot set parameter" instead of "cannot add
table to publication").  I also moved the parameter name out of the
translatable part of the message.

- I removed the novel use of the term "foreign partition".  We don't
seem to use that anywhere that's user-visible, only in code comments.
Instead I used "a partition that's a foreign table".  I just did a new
grep and I think I missed a couple, which I'm going to fix momentarily.

- I renamed check_foreign_tables to publication_check_foreign_parts and
moved to a different place in the file.  The original name wasn't very
good for an extern function.

- I renamed check_partrel_has_foreign_table to RelationHasForeignPartition 
and moved it to partdesc.c.  There's nothing that ties this function to
pg_publication.c, so in my mind it made no sense for it to be there.
I'm not 100% certain that partdesc.c is the best place for it, but if
there's another, then I didn't see it.  Also, I made it Assert() that
it's not given a relation other than a partitioned table, which forces
all callers to check the relkind before calling it.  This is good
because we don't need to open tables before ensuring the relkind is one
that interests us.  Also, I made it use the PartitionDesc->is_leaf flag
array to determine whether to recurse or not; and use get_rel_relkind to
get the relkind for leaf partitions, which is much cheaper than doing
table_open.  The original coding was kind of wasteful for no reason.

- The check to prohibit CREATE FOREIGN TABLE as a partition in
CreateForeignTable, was entirely in the wrong place.  This is proven by
the fact that the original coding had to do table_openrv() in order to
know what the parent table was.  This is terrible coding, because it
means we resolve the table name to OID twice.  (This is probably not so
terrible because the first location that does it already acquires a good
enough lock that it'd stay put; still, it's a bad coding pattern).  I
moved it to DefineRelation, in the block were we learn that we're
creating a partition; it's easy to check there that the new relation is
a foreign table.  We don't even need to open the parent table at all,
since it's already open.

- In ATExecAttachPartition (and in the check that was in
CreateForeignTable), there were a bunch of list_concat_unique_oids().
It's unlikely that this would bother anyone unless there are large
numbers of publications, but the performance characteristics of doing
this uniquification were unclear, and list_concat_unique() comments warn
against it anyway.  It seemed safer to just do list_concat() and a
single sort/uniq step at the end, just before walking the list.

- There were a bunch of list_frees() in there.  I removed them all.
They are pointless, unnecessary, and give a wrong sense of cleanliness.
In reality, you will be leaking the second argument of each
list_concat() anyway; to make this watertight, you'd have to read each
of those lists into a variable, concat, then free the variable.  The
code would become much noisier coding.  However, DDL code is normally
leaky and that causes no major problems, because the memory context in
use is going to be released or deleted soon afterwards.  Freeing a few
bytes ahead of time would only require more memory context bookkeeping
to be executed, to very little gain.


I think that's all I had ...

-- 
Álvaro Herrera               48°01'N 7°57'E  —  https://www.EnterpriseDB.com/



pgsql-hackers by date:

Previous
From: Heikki Linnakangas
Date:
Subject: Re: AIX support
Next
From: Álvaro Herrera
Date:
Subject: Re: Unquoted file name in an error message