aboutsummaryrefslogtreecommitdiff
path: root/src/include/nodes/bitmapset.h
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2023-03-02 11:47:26 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2023-03-02 11:47:26 -0500
commit00b41463c21615f9bf3927f207e37f9e215d32e6 (patch)
tree355258ff476ae3209f6ee14f4c75d4e59ddbdd35 /src/include/nodes/bitmapset.h
parent141225b2518f20ca7bd68d4458953c3404d2e364 (diff)
downloadpostgresql-00b41463c21615f9bf3927f207e37f9e215d32e6.tar.gz
postgresql-00b41463c21615f9bf3927f207e37f9e215d32e6.zip
Require empty Bitmapsets to be represented as NULL.
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, whereby an empty list is represented by NIL and nothing else. To do this, we need to fix bms_intersect, bms_difference, and a couple of other functions to check for having produced an empty result; but then we can replace bms_is_empty(a) by a simple "a == NULL" test. This is very likely a (marginal) win performance-wise, because we call bms_is_empty many more times than those other functions put together. However, the real reason to do it is that we have various places that have hand-implemented a rule about "this Bitmapset variable must be exactly NULL if empty", so that they can use checks-for-null in place of bms_is_empty calls in particularly hot code paths. That is a really fragile, mistake-prone way to do things, and I'm surprised that we've seldom been bitten by it. It's not well documented at all which variables have this property, so you can't readily tell which code might be violating those conventions. By making the convention universal, we can eliminate a subtle source of bugs. Patch by me; thanks to Nathan Bossart and Richard Guo for review. Discussion: https://postgr.es/m/1159933.1677621588@sss.pgh.pa.us
Diffstat (limited to 'src/include/nodes/bitmapset.h')
-rw-r--r--src/include/nodes/bitmapset.h10
1 files changed, 5 insertions, 5 deletions
diff --git a/src/include/nodes/bitmapset.h b/src/include/nodes/bitmapset.h
index c344ac04bec..14de6a9ff1e 100644
--- a/src/include/nodes/bitmapset.h
+++ b/src/include/nodes/bitmapset.h
@@ -5,10 +5,8 @@
*
* A bitmap set can represent any set of nonnegative integers, although
* it is mainly intended for sets where the maximum value is not large,
- * say at most a few hundred. By convention, a NULL pointer is always
- * accepted by all operations to represent the empty set. (But beware
- * that this is not the only representation of the empty set. Use
- * bms_is_empty() in preference to testing for NULL.)
+ * say at most a few hundred. By convention, we always represent the
+ * empty set by a NULL pointer.
*
*
* Copyright (c) 2003-2023, PostgreSQL Global Development Group
@@ -102,7 +100,9 @@ extern int bms_num_members(const Bitmapset *a);
/* optimized tests when we don't need to know exact membership count: */
extern BMS_Membership bms_membership(const Bitmapset *a);
-extern bool bms_is_empty(const Bitmapset *a);
+
+/* NULL is now the only allowed representation of an empty bitmapset */
+#define bms_is_empty(a) ((a) == NULL)
/* these routines recycle (modify or free) their non-const inputs: */