Subject: PublicationActions - use bit flags.

From: Peter Smith <[email-masked]>
Date: Mon, 20 Dec 2021 11:18:41 +1100

For some reason the current HEAD PublicationActions is a struct of
boolean representing combinations of the 4 different "publication
actions".

I felt it is more natural to implement boolean flag combinations using
a bitmask instead of a struct of bools. IMO using the bitmask also
simplifies assignment and checking of said flags.

PSA a small patch for this.

Thoughts?

------
Kind Regards,
Peter Smith.
Fujitsu Australia

---

From: Greg Nancarrow <[email-masked]>
Date: Mon, 20 Dec 2021 16:10:23 +1100

> PSA a small patch for this.

+1
I think the bit flags are a more natural fit, and also the patch
removes the unnecessary use of a palloc'd tiny struct to return the
PublicationActions (which also currently isn't explicitly pfree'd).

Regards,
Greg Nancarrow
Fujitsu Australia

---

From: Peter Eisentraut <[email-masked]>
Date: Mon, 20 Dec 2021 14:58:06 +0100

> simplifies assignment and checking of said flags.

I don't see why this is better.  It just makes the code longer and adds 
more punctuation and reduces type safety.

---

From: Tom Lane <[email-masked]>
Date: Mon, 20 Dec 2021 11:56:40 -0500

> more punctuation and reduces type safety.

It makes the code shorter in places where you need to process all the
flags at once, but I agree it's not really an improvement elsewhere.
Not sure if it's worth changing.

One thing I noted is that the duplicate PublicationActions typedefs
will certainly draw warnings, if not hard errors, from some compilers.
You could get around that by removing the typedefs altogether and just
using "int", which'd be more consistent with our usual practices anyway.
But it does play into Peter's objection about type safety.

			regards, tom lane

---

From: Alvaro Herrera <[email-masked]>
Date: Mon, 20 Dec 2021 14:14:01 -0300

On 2021-Dec-20, Peter Eisentraut wrote:

> I don't see why this is better.  It just makes the code longer and adds more
> punctuation and reduces type safety.

Removing one palloc is I think the most important consequence ...
probably not a big deal though.

I think we could change the memcpy calls to struct assignment, as that
would look a bit cleaner, and call it a day.

One thing I would not like would be to change the catalog representation
from bools into an integer.  We do that for pg_trigger.tgflags (IIRC)
and it is horrible.

-- 
Álvaro Herrera           39°49'30"S 73°17'W  —  https://www.EnterpriseDB.com/

---

From: Greg Nancarrow <[email-masked]>
Date: Tue, 21 Dec 2021 11:19:16 +1100

> would look a bit cleaner, and call it a day.

I think we can all agree that returning PublicationActions as a
palloc'd struct is unnecessary.
I've attached a patch which addresses that and replaces a couple of
memcpy()s with struct assignment, as suggested.

Regards,
Greg Nancarrow
Fujitsu Australia

---

From: Tom Lane <[email-masked]>
Date: Mon, 20 Dec 2021 19:56:26 -0500

> memcpy()s with struct assignment, as suggested.

Removing this is not good:

 	if (relation->rd_pubactions)
-	{
 		pfree(relation->rd_pubactions);
-		relation->rd_pubactions = NULL;
-	}
 
If the subsequent palloc fails, you've created a problem where
there was none before.

I do wonder why we have to palloc a constant-size substructure in
the first place, especially one that is likely smaller than the
pointer that points to it.  Maybe the struct definition should be
moved so that we can just declare it in-line in the relcache entry?

			regards, tom lane

---

From: Greg Nancarrow <[email-masked]>
Date: Tue, 21 Dec 2021 12:55:52 +1100

> If the subsequent palloc fails, you've created a problem where

Oops, yeah, I got carried away; if palloc() failed and called exit(),
then it would end up crashing when trying to use/pfree rd_pubactions
again.
Better leave that line in ...

> moved so that we can just declare it in-line in the relcache entry?

I think currently it's effectively using the rd_pubactions pointer as
a boolean flag to indicate whether the publication membership info has
been fetched (so the bool flags are valid).
I guess you'd need another bool flag if you wanted to make that struct
in-line in the relcache entry.

Regards,
Greg Nancarrow
Fujitsu Australia

---

From: Peter Smith <[email-masked]>
Date: Wed, 29 Dec 2021 15:21:36 +1100

> moved so that we can just declare it in-line in the relcache entry?

At the risk of flogging a dead horse, here is v2 of my original
bit-flag replacement for the PublicationActions struct.

This version introduces one more bit flag for the relcache status, and
by doing so means all that code for Relation cache PublicationActions
pointers and pallocs and context switches can just disappear...

------
Kind Regards,
Peter Smith.
Fujitsu Australia

---

From: Justin Pryzby <[email-masked]>
Date: Wed, 29 Dec 2021 10:30:15 -0600

> simplifies assignment and checking of said flags.

Peter E made a suggestion to use a similar struct with bools last year for
REINDEX.
https://www.postgresql.org/message-id/[email-masked]

Alvaro pointed out that the integer flags are better for ABI compatibility - it
would allow adding a new flag in backbranches, if that were needed for a
bugfix.

But that's not very compelling, since the bools have existed in v10...
Also, the booleans directly correspond with the catalog.

+       if (pubform->pubinsert) pub->pubactions |= PUBACTION_INSERT;

This is usually written like:

	pub->pubactions |= (pubform->pubinsert ? PUBACTION_INSERT : 0)

-- 
Justin

---

From: Peter Smith <[email-masked]>
Date: Thu, 30 Dec 2021 11:31:53 +1100

>         pub->pubactions |= (pubform->pubinsert ? PUBACTION_INSERT : 0)

Thanks for the info, I've modified those assignment styles as suggested.

------
Kind Regards,
Peter Smith.
Fujitsu Australia.

---

From: Tom Lane <[email-masked]>
Date: Wed, 29 Dec 2021 19:36:32 -0500

> Thanks for the info, I've modified those assignment styles as suggested.

FWIW, I think it's utter nonsense to claim that the second way is
preferred over the first.  There may be some people who think
the second way is more legible, but I don't; and I'm pretty sure
that the first way is significantly more common in the PG codebase.

			regards, tom lane