Skip to content

Commit adf328c

Browse files
committed
Add array_contains_nulls() function in arrayfuncs.c.
This will support fixing contrib/intarray (and probably other places) so that they don't have to fail on arrays that contain a null bitmap but no live null entries.
1 parent 4d1b76e commit adf328c

File tree

2 files changed

+45
-3
lines changed

2 files changed

+45
-3
lines changed

src/backend/utils/adt/arrayfuncs.c

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2998,7 +2998,7 @@ deconstruct_array(ArrayType *array,
29982998
nelems = ArrayGetNItems(ARR_NDIM(array), ARR_DIMS(array));
29992999
*elemsp = elems = (Datum *) palloc(nelems * sizeof(Datum));
30003000
if (nullsp)
3001-
*nullsp = nulls = (bool *) palloc(nelems * sizeof(bool));
3001+
*nullsp = nulls = (bool *) palloc0(nelems * sizeof(bool));
30023002
else
30033003
nulls = NULL;
30043004
*nelemsp = nelems;
@@ -3023,8 +3023,6 @@ deconstruct_array(ArrayType *array,
30233023
else
30243024
{
30253025
elems[i] = fetch_att(p, elmbyval, elmlen);
3026-
if (nulls)
3027-
nulls[i] = false;
30283026
p = att_addlength_pointer(p, elmlen, p);
30293027
p = (char *) att_align_nominal(p, elmalign);
30303028
}
@@ -3042,6 +3040,49 @@ deconstruct_array(ArrayType *array,
30423040
}
30433041
}
30443042

3043+
/*
3044+
* array_contains_nulls --- detect whether an array has any null elements
3045+
*
3046+
* This gives an accurate answer, whereas testing ARR_HASNULL only tells
3047+
* if the array *might* contain a null.
3048+
*/
3049+
bool
3050+
array_contains_nulls(ArrayType *array)
3051+
{
3052+
int nelems;
3053+
bits8 *bitmap;
3054+
int bitmask;
3055+
3056+
/* Easy answer if there's no null bitmap */
3057+
if (!ARR_HASNULL(array))
3058+
return false;
3059+
3060+
nelems = ArrayGetNItems(ARR_NDIM(array), ARR_DIMS(array));
3061+
3062+
bitmap = ARR_NULLBITMAP(array);
3063+
3064+
/* check whole bytes of the bitmap byte-at-a-time */
3065+
while (nelems >= 8)
3066+
{
3067+
if (*bitmap != 0xFF)
3068+
return true;
3069+
bitmap++;
3070+
nelems -= 8;
3071+
}
3072+
3073+
/* check last partial byte */
3074+
bitmask = 1;
3075+
while (nelems > 0)
3076+
{
3077+
if ((*bitmap & bitmask) == 0)
3078+
return true;
3079+
bitmask <<= 1;
3080+
nelems--;
3081+
}
3082+
3083+
return false;
3084+
}
3085+
30453086

30463087
/*
30473088
* array_eq :

src/include/utils/array.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ extern void deconstruct_array(ArrayType *array,
244244
Oid elmtype,
245245
int elmlen, bool elmbyval, char elmalign,
246246
Datum **elemsp, bool **nullsp, int *nelemsp);
247+
extern bool array_contains_nulls(ArrayType *array);
247248
extern ArrayBuildState *accumArrayResult(ArrayBuildState *astate,
248249
Datum dvalue, bool disnull,
249250
Oid element_type,

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy