diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2011-01-08 20:24:08 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2011-01-08 20:26:14 -0500 |
commit | adf328c0e1bfde90b944d53f7197fc436bc0c707 (patch) | |
tree | 49b7c22708ff743dd85af5aa0ca82338f1f2b390 /src/backend/utils/adt/arrayfuncs.c | |
parent | 4d1b76e49eb848b046ddb1beb0f4589816ec8261 (diff) | |
download | postgresql-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.c | 47 |
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 : |