From ecfe770d4ef8139d6f852dde5037a7eb51715e89 Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Wed, 8 Oct 2025 14:27:30 -0400 Subject: [PATCH v1] Correct flaws in randomized Bitmapset tests There were two oversights in the function designated to perform randomized tests against Bitmapset. First, the test validating bms_union() was not checking the return from bms_is_member() and so wasn't testing much at all. Second, in the second half of this function performing randomized operations there was no tracking of what members should exist after some number of random add/del operations. This patch addresses both of those issues. Reported-by: Ranier Vilela Discussion: https://postgr.es/m/CAApHDvqghMnm_zgSNefto9oaEJ0S-3Cgb3gdsV7XvLC-hMS02Q@mail.gmail.com --- .../modules/test_bitmapset/test_bitmapset.c | 31 ++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/test/modules/test_bitmapset/test_bitmapset.c b/src/test/modules/test_bitmapset/test_bitmapset.c index 8bc9b1f48e9..00651cb8df1 100644 --- a/src/test/modules/test_bitmapset/test_bitmapset.c +++ b/src/test/modules/test_bitmapset/test_bitmapset.c @@ -624,10 +624,8 @@ test_random_operations(PG_FUNCTION_ARGS) member = pg_prng_uint32(&state) % max_range + min_value; if (!bms_is_member(member, bms1)) - { members[num_members++] = member; - bms1 = bms_add_member(bms1, member); - } + bms1 = bms_add_member(bms1, member); } /* Phase 2: Random set operations */ @@ -635,6 +633,8 @@ test_random_operations(PG_FUNCTION_ARGS) { member = pg_prng_uint32(&state) % max_range + min_value; + if (!bms_is_member(member, bms1) && !bms_is_member(member, bms2)) + members[num_members++] = member; bms2 = bms_add_member(bms2, member); } @@ -683,24 +683,39 @@ test_random_operations(PG_FUNCTION_ARGS) bms_free(bms1); bms_free(bms2); - for (int i = 0; i < num_ops; i++) + num_members = 0; + members = palloc(sizeof(int) * num_ops); + + for (int op = 0; op < num_ops; op++) { - member = pg_prng_uint32(&state) % max_range + min_value; switch (pg_prng_uint32(&state) % 3) { case 0: /* add */ + member = pg_prng_uint32(&state) % max_range + min_value; + if (!bms_is_member(member, bms)) + members[num_members++] = member; bms = bms_add_member(bms, member); break; case 1: /* delete */ - if (bms != NULL) + if (num_members > 0) { + int pos = pg_prng_uint32(&state) % num_members; + + member = members[pos]; + if (!bms_is_member(member, bms)) + elog(ERROR, "expected %d to be a valid member", member); bms = bms_del_member(bms, member); + num_members--; + memmove(members + pos, members + pos + 1, + (num_members - pos) * sizeof(int)); } break; case 2: /* test membership */ - if (bms != NULL) + /* Verify bitmap contains all members */ + for (int i = 0; i < num_members; i++) { - bms_is_member(member, bms); + if (!bms_is_member(members[i], bms)) + elog(ERROR, "missing member %d", members[i]); } break; } -- 2.49.0