mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	REALLOCATE_BITMAPSETS manual compile-time option
This option forces each bitmapset modification to reallocate bitmapset. This is useful for debugging hangling pointers to bitmapset's. Discussion: https://postgr.es/m/CAMbWs4_wJthNtYBL%2BSsebpgF-5L2r5zFFk6xYbS0A78GKOTFHw%40mail.gmail.com Reviewed-by: Richard Guo, Andres Freund, Ashutosh Bapat, Andrei Lepikhov
This commit is contained in:
		@@ -263,6 +263,7 @@ bms_intersect(const Bitmapset *a, const Bitmapset *b)
 | 
			
		||||
	/* Handle cases where either input is NULL */
 | 
			
		||||
	if (a == NULL || b == NULL)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	/* Identify shorter and longer input; copy the shorter one */
 | 
			
		||||
	if (a->nwords <= b->nwords)
 | 
			
		||||
	{
 | 
			
		||||
@@ -798,8 +799,15 @@ bms_add_member(Bitmapset *a, int x)
 | 
			
		||||
	{
 | 
			
		||||
		int			oldnwords = a->nwords;
 | 
			
		||||
		int			i;
 | 
			
		||||
#ifdef REALLOCATE_BITMAPSETS
 | 
			
		||||
		Bitmapset  *tmp = a;
 | 
			
		||||
 | 
			
		||||
		a = (Bitmapset *) palloc(BITMAPSET_SIZE(wordnum + 1));
 | 
			
		||||
		memcpy(a, tmp, BITMAPSET_SIZE(tmp->nwords));
 | 
			
		||||
		pfree(tmp);
 | 
			
		||||
#else
 | 
			
		||||
		a = (Bitmapset *) repalloc(a, BITMAPSET_SIZE(wordnum + 1));
 | 
			
		||||
#endif
 | 
			
		||||
		a->nwords = wordnum + 1;
 | 
			
		||||
		/* zero out the enlarged portion */
 | 
			
		||||
		i = oldnwords;
 | 
			
		||||
@@ -808,6 +816,16 @@ bms_add_member(Bitmapset *a, int x)
 | 
			
		||||
			a->words[i] = 0;
 | 
			
		||||
		} while (++i < a->nwords);
 | 
			
		||||
	}
 | 
			
		||||
#ifdef REALLOCATE_BITMAPSETS
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		Bitmapset  *tmp = a;
 | 
			
		||||
 | 
			
		||||
		a = (Bitmapset *) palloc(BITMAPSET_SIZE(tmp->nwords));
 | 
			
		||||
		memcpy(a, tmp, BITMAPSET_SIZE(tmp->nwords));
 | 
			
		||||
		pfree(tmp);
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	a->words[wordnum] |= ((bitmapword) 1 << bitnum);
 | 
			
		||||
	return a;
 | 
			
		||||
@@ -825,6 +843,9 @@ bms_del_member(Bitmapset *a, int x)
 | 
			
		||||
{
 | 
			
		||||
	int			wordnum,
 | 
			
		||||
				bitnum;
 | 
			
		||||
#ifdef REALLOCATE_BITMAPSETS
 | 
			
		||||
	Bitmapset  *tmp = a;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	if (x < 0)
 | 
			
		||||
		elog(ERROR, "negative bitmapset member not allowed");
 | 
			
		||||
@@ -836,6 +857,12 @@ bms_del_member(Bitmapset *a, int x)
 | 
			
		||||
	wordnum = WORDNUM(x);
 | 
			
		||||
	bitnum = BITNUM(x);
 | 
			
		||||
 | 
			
		||||
#ifdef REALLOCATE_BITMAPSETS
 | 
			
		||||
	a = (Bitmapset *) palloc(BITMAPSET_SIZE(tmp->nwords));
 | 
			
		||||
	memcpy(a, tmp, BITMAPSET_SIZE(tmp->nwords));
 | 
			
		||||
	pfree(tmp);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/* member can't exist.  Return 'a' unmodified */
 | 
			
		||||
	if (unlikely(wordnum >= a->nwords))
 | 
			
		||||
		return a;
 | 
			
		||||
@@ -889,6 +916,13 @@ bms_add_members(Bitmapset *a, const Bitmapset *b)
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
#ifdef REALLOCATE_BITMAPSETS
 | 
			
		||||
		Bitmapset  *tmp = a;
 | 
			
		||||
 | 
			
		||||
		a = (Bitmapset *) palloc(BITMAPSET_SIZE(tmp->nwords));
 | 
			
		||||
		memcpy(a, tmp, BITMAPSET_SIZE(tmp->nwords));
 | 
			
		||||
		pfree(tmp);
 | 
			
		||||
#endif
 | 
			
		||||
		result = a;
 | 
			
		||||
		other = b;
 | 
			
		||||
	}
 | 
			
		||||
@@ -941,9 +975,16 @@ bms_add_range(Bitmapset *a, int lower, int upper)
 | 
			
		||||
	{
 | 
			
		||||
		int			oldnwords = a->nwords;
 | 
			
		||||
		int			i;
 | 
			
		||||
#ifdef REALLOCATE_BITMAPSETS
 | 
			
		||||
		Bitmapset  *tmp = a;
 | 
			
		||||
 | 
			
		||||
		a = (Bitmapset *) palloc(BITMAPSET_SIZE(uwordnum + 1));
 | 
			
		||||
		memcpy(a, tmp, BITMAPSET_SIZE(tmp->nwords));
 | 
			
		||||
		pfree(tmp);
 | 
			
		||||
#else
 | 
			
		||||
		/* ensure we have enough words to store the upper bit */
 | 
			
		||||
		a = (Bitmapset *) repalloc(a, BITMAPSET_SIZE(uwordnum + 1));
 | 
			
		||||
#endif
 | 
			
		||||
		a->nwords = uwordnum + 1;
 | 
			
		||||
		/* zero out the enlarged portion */
 | 
			
		||||
		i = oldnwords;
 | 
			
		||||
@@ -992,6 +1033,12 @@ bms_int_members(Bitmapset *a, const Bitmapset *b)
 | 
			
		||||
	int			lastnonzero;
 | 
			
		||||
	int			shortlen;
 | 
			
		||||
	int			i;
 | 
			
		||||
#ifdef REALLOCATE_BITMAPSETS
 | 
			
		||||
	Bitmapset  *tmp = a;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	Assert(a == NULL || IsA(a, Bitmapset));
 | 
			
		||||
	Assert(b == NULL || IsA(b, Bitmapset));
 | 
			
		||||
 | 
			
		||||
	Assert(a == NULL || IsA(a, Bitmapset));
 | 
			
		||||
	Assert(b == NULL || IsA(b, Bitmapset));
 | 
			
		||||
@@ -1004,6 +1051,13 @@ bms_int_members(Bitmapset *a, const Bitmapset *b)
 | 
			
		||||
		pfree(a);
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#ifdef REALLOCATE_BITMAPSETS
 | 
			
		||||
	a = (Bitmapset *) palloc(BITMAPSET_SIZE(tmp->nwords));
 | 
			
		||||
	memcpy(a, tmp, BITMAPSET_SIZE(tmp->nwords));
 | 
			
		||||
	pfree(tmp);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/* Intersect b into a; we need never copy */
 | 
			
		||||
	shortlen = Min(a->nwords, b->nwords);
 | 
			
		||||
	lastnonzero = -1;
 | 
			
		||||
@@ -1035,6 +1089,9 @@ Bitmapset *
 | 
			
		||||
bms_del_members(Bitmapset *a, const Bitmapset *b)
 | 
			
		||||
{
 | 
			
		||||
	int			i;
 | 
			
		||||
#ifdef REALLOCATE_BITMAPSETS
 | 
			
		||||
	Bitmapset  *tmp = a;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	Assert(a == NULL || (IsA(a, Bitmapset) && a->words[a->nwords - 1] != 0));
 | 
			
		||||
	Assert(b == NULL || (IsA(b, Bitmapset) && b->words[b->nwords - 1] != 0));
 | 
			
		||||
@@ -1044,6 +1101,13 @@ bms_del_members(Bitmapset *a, const Bitmapset *b)
 | 
			
		||||
		return NULL;
 | 
			
		||||
	if (b == NULL)
 | 
			
		||||
		return a;
 | 
			
		||||
 | 
			
		||||
#ifdef REALLOCATE_BITMAPSETS
 | 
			
		||||
	a = (Bitmapset *) palloc(BITMAPSET_SIZE(tmp->nwords));
 | 
			
		||||
	memcpy(a, tmp, BITMAPSET_SIZE(tmp->nwords));
 | 
			
		||||
	pfree(tmp);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/* Remove b's bits from a; we need never copy */
 | 
			
		||||
	if (a->nwords > b->nwords)
 | 
			
		||||
	{
 | 
			
		||||
@@ -1096,6 +1160,12 @@ bms_join(Bitmapset *a, Bitmapset *b)
 | 
			
		||||
	Bitmapset  *other;
 | 
			
		||||
	int			otherlen;
 | 
			
		||||
	int			i;
 | 
			
		||||
#ifdef REALLOCATE_BITMAPSETS
 | 
			
		||||
	Bitmapset  *tmp = a;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	Assert(a == NULL || IsA(a, Bitmapset));
 | 
			
		||||
	Assert(b == NULL || IsA(b, Bitmapset));
 | 
			
		||||
 | 
			
		||||
	Assert(a == NULL || IsA(a, Bitmapset));
 | 
			
		||||
	Assert(b == NULL || IsA(b, Bitmapset));
 | 
			
		||||
@@ -1105,6 +1175,13 @@ bms_join(Bitmapset *a, Bitmapset *b)
 | 
			
		||||
		return b;
 | 
			
		||||
	if (b == NULL)
 | 
			
		||||
		return a;
 | 
			
		||||
 | 
			
		||||
#ifdef REALLOCATE_BITMAPSETS
 | 
			
		||||
	a = (Bitmapset *) palloc(BITMAPSET_SIZE(tmp->nwords));
 | 
			
		||||
	memcpy(a, tmp, BITMAPSET_SIZE(tmp->nwords));
 | 
			
		||||
	pfree(tmp);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/* Identify shorter and longer input; use longer one as result */
 | 
			
		||||
	if (a->nwords < b->nwords)
 | 
			
		||||
	{
 | 
			
		||||
 
 | 
			
		||||
@@ -335,6 +335,12 @@
 | 
			
		||||
 */
 | 
			
		||||
/* #define COPY_PARSE_PLAN_TREES */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Define this to force Bitmapset reallocation on each modification.  Helps
 | 
			
		||||
 * to find hangling pointers to Bitmapset's.
 | 
			
		||||
 */
 | 
			
		||||
/* #define REALLOCATE_BITMAPSETS */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Define this to force all parse and plan trees to be passed through
 | 
			
		||||
 * outfuncs.c/readfuncs.c, to facilitate catching errors and omissions in
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user