aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/arrayfuncs.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2011-01-08 20:24:08 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2011-01-08 20:26:14 -0500
commitadf328c0e1bfde90b944d53f7197fc436bc0c707 (patch)
tree49b7c22708ff743dd85af5aa0ca82338f1f2b390 /src/backend/utils/adt/arrayfuncs.c
parent4d1b76e49eb848b046ddb1beb0f4589816ec8261 (diff)
downloadpostgresql-adf328c0e1bfde90b944d53f7197fc436bc0c707.tar.gz
postgresql-adf328c0e1bfde90b944d53f7197fc436bc0c707.zip
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.
Diffstat (limited to 'src/backend/utils/adt/arrayfuncs.c')
-rw-r--r--src/backend/utils/adt/arrayfuncs.c47
1 files changed, 44 insertions, 3 deletions
diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index fb4cbce23cc..a1bcbe687fd 100644
--- a/src/backend/utils/adt/arrayfuncs.c
+++ b/src/backend/utils/adt/arrayfuncs.c
@@ -2998,7 +2998,7 @@ deconstruct_array(ArrayType *array,
nelems = ArrayGetNItems(ARR_NDIM(array), ARR_DIMS(array));
*elemsp = elems = (Datum *) palloc(nelems * sizeof(Datum));
if (nullsp)
- *nullsp = nulls = (bool *) palloc(nelems * sizeof(bool));
+ *nullsp = nulls = (bool *) palloc0(nelems * sizeof(bool));
else
nulls = NULL;
*nelemsp = nelems;
@@ -3023,8 +3023,6 @@ deconstruct_array(ArrayType *array,
else
{
elems[i] = fetch_att(p, elmbyval, elmlen);
- if (nulls)
- nulls[i] = false;
p = att_addlength_pointer(p, elmlen, p);
p = (char *) att_align_nominal(p, elmalign);
}
@@ -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 :