From 7025d85048468134823cfeec1c84559bb2607634 Mon Sep 17 00:00:00 2001 From: Yuya Watari Date: Mon, 12 Jun 2023 07:33:04 +0900 Subject: [PATCH v2 4/4] Fix a bug where the necessary truncation was missing --- src/backend/nodes/bitmapset.c | 53 +++++++++++++++-------------------- 1 file changed, 22 insertions(+), 31 deletions(-) diff --git a/src/backend/nodes/bitmapset.c b/src/backend/nodes/bitmapset.c index 1839292d4b..fd59826c00 100644 --- a/src/backend/nodes/bitmapset.c +++ b/src/backend/nodes/bitmapset.c @@ -72,8 +72,6 @@ #error "invalid BITS_PER_BITMAPWORD" #endif -static bool bms_is_empty_internal(const Bitmapset *a); - /* * bms_copy - make a palloc'd copy of a bitmapset @@ -689,30 +687,6 @@ bms_membership(const Bitmapset *a) return result; } -/* - * bms_is_empty_internal - is a set empty? - * - * This is now used only locally, to detect cases where a function has - * computed an empty set that we must now get rid of. Hence, we can - * assume the input isn't NULL. - */ -static bool -bms_is_empty_internal(const Bitmapset *a) -{ - int nwords; - int wordnum; - - nwords = a->nwords; - wordnum = 0; - do { - bitmapword w = a->words[wordnum]; - - if (w != 0) - return false; - } while (++wordnum < nwords); - return true; -} - /* * These operations all "recycle" their non-const inputs, ie, either @@ -781,12 +755,29 @@ bms_del_member(Bitmapset *a, int x) wordnum = WORDNUM(x); bitnum = BITNUM(x); if (wordnum < a->nwords) - a->words[wordnum] &= ~((bitmapword) 1 << bitnum); - /* If we computed an empty result, we must return NULL */ - if (bms_is_empty_internal(a)) { - pfree(a); - return NULL; + a->words[wordnum] &= ~((bitmapword) 1 << bitnum); + + if (a->words[wordnum] == 0) + { + int lastnonzero; + + /* If this word became zero, we may have to truncate the result */ + lastnonzero = a->nwords - 1; + do + { + if (a->words[lastnonzero] != 0) + break; + } while (--lastnonzero >= 0); + /* If we computed an empty result, we must return NULL */ + if (lastnonzero == -1) + { + pfree(a); + return NULL; + } + /* get rid of trailing zero words */ + a->nwords = lastnonzero + 1; + } } return a; } -- 2.41.0.windows.1