Commit adf328c0 authored by Tom Lane's avatar Tom Lane

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.
parent 4d1b76e4
...@@ -2998,7 +2998,7 @@ deconstruct_array(ArrayType *array, ...@@ -2998,7 +2998,7 @@ deconstruct_array(ArrayType *array,
nelems = ArrayGetNItems(ARR_NDIM(array), ARR_DIMS(array)); nelems = ArrayGetNItems(ARR_NDIM(array), ARR_DIMS(array));
*elemsp = elems = (Datum *) palloc(nelems * sizeof(Datum)); *elemsp = elems = (Datum *) palloc(nelems * sizeof(Datum));
if (nullsp) if (nullsp)
*nullsp = nulls = (bool *) palloc(nelems * sizeof(bool)); *nullsp = nulls = (bool *) palloc0(nelems * sizeof(bool));
else else
nulls = NULL; nulls = NULL;
*nelemsp = nelems; *nelemsp = nelems;
...@@ -3023,8 +3023,6 @@ deconstruct_array(ArrayType *array, ...@@ -3023,8 +3023,6 @@ deconstruct_array(ArrayType *array,
else else
{ {
elems[i] = fetch_att(p, elmbyval, elmlen); elems[i] = fetch_att(p, elmbyval, elmlen);
if (nulls)
nulls[i] = false;
p = att_addlength_pointer(p, elmlen, p); p = att_addlength_pointer(p, elmlen, p);
p = (char *) att_align_nominal(p, elmalign); p = (char *) att_align_nominal(p, elmalign);
} }
...@@ -3042,6 +3040,49 @@ deconstruct_array(ArrayType *array, ...@@ -3042,6 +3040,49 @@ deconstruct_array(ArrayType *array,
} }
} }
/*
* array_contains_nulls --- detect whether an array has any null elements
*
* This gives an accurate answer, whereas testing ARR_HASNULL only tells
* if the array *might* contain a null.
*/
bool
array_contains_nulls(ArrayType *array)
{
int nelems;
bits8 *bitmap;
int bitmask;
/* Easy answer if there's no null bitmap */
if (!ARR_HASNULL(array))
return false;
nelems = ArrayGetNItems(ARR_NDIM(array), ARR_DIMS(array));
bitmap = ARR_NULLBITMAP(array);
/* check whole bytes of the bitmap byte-at-a-time */
while (nelems >= 8)
{
if (*bitmap != 0xFF)
return true;
bitmap++;
nelems -= 8;
}
/* check last partial byte */
bitmask = 1;
while (nelems > 0)
{
if ((*bitmap & bitmask) == 0)
return true;
bitmask <<= 1;
nelems--;
}
return false;
}
/* /*
* array_eq : * array_eq :
......
...@@ -244,6 +244,7 @@ extern void deconstruct_array(ArrayType *array, ...@@ -244,6 +244,7 @@ extern void deconstruct_array(ArrayType *array,
Oid elmtype, Oid elmtype,
int elmlen, bool elmbyval, char elmalign, int elmlen, bool elmbyval, char elmalign,
Datum **elemsp, bool **nullsp, int *nelemsp); Datum **elemsp, bool **nullsp, int *nelemsp);
extern bool array_contains_nulls(ArrayType *array);
extern ArrayBuildState *accumArrayResult(ArrayBuildState *astate, extern ArrayBuildState *accumArrayResult(ArrayBuildState *astate,
Datum dvalue, bool disnull, Datum dvalue, bool disnull,
Oid element_type, Oid element_type,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment