Re: Add bms_offset_members() function for bitshifting Bitmapsets

From: "Greg Burd" <greg(at)burd(dot)me>
To: "David Rowley" <dgrowleyml(at)gmail(dot)com>, "Tom Lane" <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: "Chao Li" <li(dot)evan(dot)chao(at)gmail(dot)com>, "PostgreSQL Hackers" <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: Re: Add bms_offset_members() function for bitshifting Bitmapsets
Date: 2026-04-19 19:21:41
Message-ID: 77f5109f-6d39-4cf1-8d0d-f826435d6cb6@app.fastmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers


On Sat, Apr 18, 2026, at 3:49 AM, David Rowley wrote:
> On Wed, 15 Apr 2026 at 14:33, David Rowley <dgrowleyml(at)gmail(dot)com> wrote:
>>
>> On Wed, 15 Apr 2026 at 14:30, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:
>> >
>> > David Rowley <dgrowleyml(at)gmail(dot)com> writes:
>> > > I'd not considered surprise-prone as an aspect. I understand we have
>> > > bms_join and bms_union, which do the same thing if you only care about
>> > > the value of the result and not what happens to the inputs.
>> >
>> > Sure, but bms_join is an optional optimization of the far safer
>> > bms_union operation. It bothers me to create the optimized case
>> > but not the base case.
>>
>> Hmm, yeah. That seems like a good argument for making a new set. I'll
>> go make it so.
>
> Patch attached for the version that creates a new set rather than
> modifying the input set in-place.
>
> David

Hey David,

> Attachments:
> * v2-0001-Introduce-bms_offset_members-function.patch

I applied, tested, and reviewed these changes. Thanks for doing this, only a few small things jumped out.

nit: in bitmapset.c there is a new line added above bms_add_range()

+ * Arguments:
+ * arg1: optional random seed, or < 0 to use a random seed.
+ * arg2: the number of operations to perform.
+ * arg3: the maximum bitmapset member number to use in the random set.
+ * arg4: the minimum bitmapset member number to use in the random set.

nit: whitespace ahead of arg1, also should be "NULL" not "< 0"

in test_bitmapset.sql

+-- perform some random test on bms_offset_members()

nit: "tests"

Also, I think the random testing will likely cover these, but here are a few more explicit tests for odd corner cases.

-- shift that shrinks nwords
SELECT test_bms_offset_members('(b 64 65 66)', -64); -- drops into word 0

-- shift that drops some low members and keeps others
SELECT test_bms_offset_members('(b 0 1 2 10)', -2); -- expect (b 0 8)

-- entire set shifts below zero -> empty
SELECT test_bms_offset_members('(b 1 2 3)', -10); -- expect empty

-- word-aligned positive and negative shifts
SELECT test_bms_offset_members('(b 1 2 3)', 64);
SELECT test_bms_offset_members('(b 65 66 67)', -64);

-- INT_MIN boundary
SELECT test_bms_offset_members('(b 1)', -2147483648);

I like the functionality and the reduction of repeated code that you've identified and fixed.

best.

-greg

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Andres Freund 2026-04-19 19:25:42 Re: First draft of PG 19 release notes
Previous Message Alexander Lakhin 2026-04-19 19:00:00 Re: Typos in the code and README