Re: Making empty Bitmapsets always be NULL

Nathan Bossart <nathandbossart@gmail.com>

From: Nathan Bossart <nathandbossart@gmail.com>
To: Tom Lane <tgl@sss.pgh.pa.us>
Cc: pgsql-hackers@lists.postgresql.org
Date: 2023-03-01T20:19:51Z
Lists: pgsql-hackers
On Tue, Feb 28, 2023 at 04:59:48PM -0500, Tom Lane wrote:
> When I designed the Bitmapset module, I set things up so that an empty
> Bitmapset could be represented either by a NULL pointer, or by an
> allocated object all of whose bits are zero.  I've recently come to
> the conclusion that that was a bad idea and we should instead have
> a convention like the longstanding invariant for Lists: an empty
> list is represented by NIL and nothing else.

+1

> I found just a few places that have issues with this idea.  One thing
> that is problematic is bms_first_member(): assuming you allow it to
> loop to completion, it ends with the passed Bitmapset being empty,
> which is now an invariant violation.  I made it pfree the argument
> at that point, and fixed a couple of callers that would be broken
> thereby; but I wonder if it wouldn't be better to get rid of that
> function entirely and convert all its callers to use bms_next_member.
> There are only about half a dozen.

Unless there is a way to avoid the invariant violation that doesn't involve
scanning the rest of the words before bms_first_member returns, +1 to
removing it.  Perhaps we could add a num_members variable to the struct so
that we know right away when the set becomes empty.  But maintaining that
might be more trouble than it's worth.

> I also discovered that nodeAppend.c is relying on bms_del_members
> not reducing a non-empty set to NULL, because it uses the nullness
> of appendstate->as_valid_subplans as a state boolean.  That was
> probably acceptable when it was written, but whoever added
> classify_matching_subplans made a hash of the state invariants here,
> because that can set as_valid_subplans to empty.  I added a separate
> boolean as an easy way out, but maybe that code could do with a more
> thorough revisit.

The separate boolean certainly seems less fragile.  That might even be
worthwhile independent of the rest of the patch.

-- 
Nathan Bossart
Amazon Web Services: https://aws.amazon.com



Commits

  1. Remove trailing zero words from Bitmapsets

  2. Remove local optimizations of empty Bitmapsets into null pointers.

  3. Require empty Bitmapsets to be represented as NULL.

  4. Mop up some undue familiarity with the innards of Bitmapsets.

  5. Remove bms_first_member().