diff --git a/contrib/intarray/_int.h b/contrib/intarray/_int.h
index 702dfaade538cbd9578a3f27134f74f33a14e094..ec09b149733a877fa48bc4f0d5074f64153f0723 100644
--- a/contrib/intarray/_int.h
+++ b/contrib/intarray/_int.h
@@ -19,13 +19,24 @@
 
 /* useful macros for accessing int4 arrays */
 #define ARRPTR(x)  ( (int4 *) ARR_DATA_PTR(x) )
-#define ARRNELEMS(x)  ArrayGetNItems( ARR_NDIM(x), ARR_DIMS(x))
+#define ARRNELEMS(x)  ArrayGetNItems(ARR_NDIM(x), ARR_DIMS(x))
 
-#define ARRISVOID(x) ( (x) ? ( ( ARR_NDIM(x) == NDIM ) ? ( ( ARRNELEMS( x ) ) ? 0 : 1 ) : ( ( ARR_NDIM(x) ) ? ( \
-	ereport(ERROR, \
-			(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR), \
-			 errmsg("array must be one-dimensional, not %d dimensions", ARRNELEMS( x )))) \
-	,1) : 0 )  ) : 0 )
+/* reject arrays we can't handle; but allow a NULL or empty array */
+#define CHECKARRVALID(x) \
+	do { \
+		if (x) { \
+			if (ARR_NDIM(x) != NDIM && ARR_NDIM(x) != 0) \
+				ereport(ERROR, \
+						(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR), \
+						 errmsg("array must be one-dimensional"))); \
+			if (ARR_HASNULL(x)) \
+				ereport(ERROR, \
+						(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), \
+						 errmsg("array must not contain nulls"))); \
+		} \
+	} while(0)
+
+#define ARRISVOID(x)  ((x) == NULL || ARRNELEMS(x) == 0)
 
 #define SORT(x) \
 	do { \
@@ -52,9 +63,6 @@
 typedef char BITVEC[SIGLEN];
 typedef char *BITVECP;
 
-#define SIGPTR(x)  ( (BITVECP) ARR_DATA_PTR(x) )
-
-
 #define LOOPBYTE(a) \
 		for(i=0;i<SIGLEN;i++) {\
 				a;\
diff --git a/contrib/intarray/_int_bool.c b/contrib/intarray/_int_bool.c
index 824dc5b677569018d8a5f64465fb988b946df95e..8e0b913c0137e458fbd76fe6d13dfa237e08130d 100644
--- a/contrib/intarray/_int_bool.c
+++ b/contrib/intarray/_int_bool.c
@@ -309,6 +309,7 @@ execconsistent(QUERYTYPE * query, ArrayType *array, bool calcnot)
 {
 	CHKVAL		chkval;
 
+	CHECKARRVALID(array);
 	chkval.arrb = ARRPTR(array);
 	chkval.arre = chkval.arrb + ARRNELEMS(array);
 	return execute(
@@ -339,6 +340,7 @@ boolop(PG_FUNCTION_ARGS)
 	CHKVAL		chkval;
 	bool		result;
 
+	CHECKARRVALID(val);
 	if (ARRISVOID(val))
 	{
 		pfree(val);
diff --git a/contrib/intarray/_int_gist.c b/contrib/intarray/_int_gist.c
index c5f8818aa3d3eaf4574e7f49fde865e66ba521c3..1e26bcef284fc9a123297690ae7177e74e9ea66e 100644
--- a/contrib/intarray/_int_gist.c
+++ b/contrib/intarray/_int_gist.c
@@ -44,6 +44,7 @@ g_int_consistent(PG_FUNCTION_ARGS)
 	/* XXX are we sure it's safe to scribble on the query object here? */
 	/* XXX what about toasted input? */
 	/* sort query for fast search, key is already sorted */
+	CHECKARRVALID(query);
 	if (ARRISVOID(query))
 		PG_RETURN_BOOL(false);
 	PREPAREARR(query);
@@ -89,21 +90,30 @@ g_int_union(PG_FUNCTION_ARGS)
 {
 	GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
 	int		   *size = (int *) PG_GETARG_POINTER(1);
-	int4		i;
-	ArrayType  *res;
-	int			totlen = 0,
+	int4		i,
 			   *ptr;
+	ArrayType  *res;
+	int			totlen = 0;
 
 	for (i = 0; i < entryvec->n; i++)
-		totlen += ARRNELEMS(GETENTRY(entryvec, i));
+	{
+		ArrayType *ent = GETENTRY(entryvec, i);
+
+		CHECKARRVALID(ent);
+		totlen += ARRNELEMS(ent);
+	}
 
 	res = new_intArrayType(totlen);
 	ptr = ARRPTR(res);
 
 	for (i = 0; i < entryvec->n; i++)
 	{
-		memcpy(ptr, ARRPTR(GETENTRY(entryvec, i)), ARRNELEMS(GETENTRY(entryvec, i)) * sizeof(int4));
-		ptr += ARRNELEMS(GETENTRY(entryvec, i));
+		ArrayType *ent = GETENTRY(entryvec, i);
+		int nel;
+
+		nel = ARRNELEMS(ent);
+		memcpy(ptr, ARRPTR(ent), nel * sizeof(int4));
+		ptr += nel;
 	}
 
 	QSORT(res, 1);
@@ -130,6 +140,7 @@ g_int_compress(PG_FUNCTION_ARGS)
 	if (entry->leafkey)
 	{
 		r = (ArrayType *) PG_DETOAST_DATUM_COPY(entry->key);
+		CHECKARRVALID(r);
 		PREPAREARR(r);
 
 		if (ARRNELEMS(r)>= 2 * MAXNUMRANGE)
@@ -147,6 +158,7 @@ g_int_compress(PG_FUNCTION_ARGS)
            so now we work only with internal keys  */
 
 	r = (ArrayType *) PG_DETOAST_DATUM(entry->key);
+	CHECKARRVALID(r);
 	if (ARRISVOID(r)) 
 	{
 		if (r != (ArrayType *) DatumGetPointer(entry->key))
@@ -207,6 +219,7 @@ g_int_decompress(PG_FUNCTION_ARGS)
 
 	in = (ArrayType *) PG_DETOAST_DATUM(entry->key);
 
+	CHECKARRVALID(in);
 	if (ARRISVOID(in))
 		PG_RETURN_POINTER(entry);
 
@@ -280,6 +293,9 @@ g_int_same(PG_FUNCTION_ARGS)
 	int4	   *da,
 			   *db;
 
+	CHECKARRVALID(a);
+	CHECKARRVALID(b);
+
 	if (n != ARRNELEMS(b))
 	{
 		*result = false;
diff --git a/contrib/intarray/_int_op.c b/contrib/intarray/_int_op.c
index 70951bfd47a7506394270f8ae959ae3eb2b762a8..7a2065bc214e8ebcd7c2011cd70d712eba1db9d0 100644
--- a/contrib/intarray/_int_op.c
+++ b/contrib/intarray/_int_op.c
@@ -37,6 +37,8 @@ _int_contains(PG_FUNCTION_ARGS)
 	ArrayType  *b = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1)));
 	bool		res;
 
+	CHECKARRVALID(a);
+	CHECKARRVALID(b);
 	if (ARRISVOID(a) || ARRISVOID(b))
 		return FALSE;
 
@@ -71,9 +73,13 @@ _int_same(PG_FUNCTION_ARGS)
 	int		   *da,
 			   *db;
 	bool		result;
-	bool		avoid = ARRISVOID(a);
-	bool		bvoid = ARRISVOID(b);
+	bool		avoid;
+	bool		bvoid;
 
+	CHECKARRVALID(a);
+	CHECKARRVALID(b);
+	avoid = ARRISVOID(a);
+	bvoid = ARRISVOID(b);
 	if (avoid || bvoid)
 		return (avoid && bvoid) ? TRUE : FALSE;
 
@@ -112,6 +118,8 @@ _int_overlap(PG_FUNCTION_ARGS)
 	ArrayType  *b = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1)));
 	bool		result;
 
+	CHECKARRVALID(a);
+	CHECKARRVALID(b);
 	if (ARRISVOID(a) || ARRISVOID(b))
 		return FALSE;
 
@@ -133,6 +141,9 @@ _int_union(PG_FUNCTION_ARGS)
 	ArrayType  *b = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1)));
 	ArrayType  *result;
 
+	CHECKARRVALID(a);
+	CHECKARRVALID(b);
+
 	if (!ARRISVOID(a))
 		SORT(a);
 	if (!ARRISVOID(b))
@@ -155,6 +166,8 @@ _int_inter(PG_FUNCTION_ARGS)
 	ArrayType  *b = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1)));
 	ArrayType  *result;
 
+	CHECKARRVALID(a);
+	CHECKARRVALID(b);
 	if (ARRISVOID(a) || ARRISVOID(b))
 		PG_RETURN_POINTER(new_intArrayType(0));
 
@@ -197,12 +210,6 @@ Datum		intarray_del_elem(PG_FUNCTION_ARGS);
 Datum		intset_union_elem(PG_FUNCTION_ARGS);
 Datum		intset_subtract(PG_FUNCTION_ARGS);
 
-#define QSORT(a, direction)						\
-if (ARRNELEMS(a) > 1)						\
-	qsort((void*)ARRPTR(a), ARRNELEMS(a),sizeof(int4),	\
-		(direction) ? compASC : compDESC )
-
-
 Datum
 intset(PG_FUNCTION_ARGS)
 {
@@ -213,7 +220,7 @@ Datum
 icount(PG_FUNCTION_ARGS)
 {
 	ArrayType  *a = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0)));
-	int32		count = (ARRISVOID(a)) ? 0 : ARRNELEMS(a);
+	int32		count = ARRNELEMS(a);
 
 	PG_FREE_IF_COPY(a, 0);
 	PG_RETURN_INT32(count);
@@ -228,6 +235,7 @@ sort(PG_FUNCTION_ARGS)
 	char	   *d = (dirstr) ? VARDATA(dirstr) : NULL;
 	int			dir = -1;
 
+	CHECKARRVALID(a);
 	if (ARRISVOID(a) || ARRNELEMS(a) < 2)
 		PG_RETURN_POINTER(a);
 
@@ -255,6 +263,7 @@ sort_asc(PG_FUNCTION_ARGS)
 {
 	ArrayType  *a = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
 
+	CHECKARRVALID(a);
 	if (ARRISVOID(a))
 		PG_RETURN_POINTER(a);
 	QSORT(a, 1);
@@ -266,6 +275,7 @@ sort_desc(PG_FUNCTION_ARGS)
 {
 	ArrayType  *a = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
 
+	CHECKARRVALID(a);
 	if (ARRISVOID(a))
 		PG_RETURN_POINTER(a);
 	QSORT(a, 0);
@@ -277,6 +287,7 @@ uniq(PG_FUNCTION_ARGS)
 {
 	ArrayType  *a = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
 
+	CHECKARRVALID(a);
 	if (ARRISVOID(a) || ARRNELEMS(a) < 2)
 		PG_RETURN_POINTER(a);
 	a = _int_unique(a);
@@ -287,8 +298,10 @@ Datum
 idx(PG_FUNCTION_ARGS)
 {
 	ArrayType  *a = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0)));
-	int32		result = (ARRISVOID(a)) ? 0 : ARRNELEMS(a);
+	int32		result;
 
+	CHECKARRVALID(a);
+	result = (ARRISVOID(a)) ? 0 : ARRNELEMS(a);
 	if (result)
 		result = intarray_match_first(a, PG_GETARG_INT32(1));
 	PG_FREE_IF_COPY(a, 0);
@@ -305,6 +318,7 @@ subarray(PG_FUNCTION_ARGS)
 	int32		end = 0;
 	int32		c;
 
+	CHECKARRVALID(a);
 	if (ARRISVOID(a))
 	{
 		PG_FREE_IF_COPY(a, 0);
@@ -371,22 +385,29 @@ Datum
 intarray_del_elem(PG_FUNCTION_ARGS)
 {
 	ArrayType  *a = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
-	int32		c = (ARRISVOID(a)) ? 0 : ARRNELEMS(a);
-	int32	   *aa = ARRPTR(a);
+	int32		elem = PG_GETARG_INT32(1);
+	int32		c;
+	int32	   *aa;
 	int32		n = 0,
 				i;
-	int32		elem = PG_GETARG_INT32(1);
 
-	for (i = 0; i < c; i++)
-		if (aa[i] != elem)
+	CHECKARRVALID(a);
+	if (!ARRISVOID(a))
+	{
+		c = ARRNELEMS(a);
+		aa = ARRPTR(a);
+		for (i = 0; i < c; i++)
 		{
-			if (i > n)
-				aa[n++] = aa[i];
-			else
-				n++;
+			if (aa[i] != elem)
+			{
+				if (i > n)
+					aa[n++] = aa[i];
+				else
+					n++;
+			}
 		}
-	if (c > 0)
 		a = resize_intArrayType(a, n);
+	}
 	PG_RETURN_POINTER(a);
 }
 
@@ -408,8 +429,8 @@ intset_subtract(PG_FUNCTION_ARGS)
 	ArrayType  *a = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
 	ArrayType  *b = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1)));
 	ArrayType  *result;
-	int32		ca = ARRISVOID(a);
-	int32		cb = ARRISVOID(b);
+	int32		ca;
+	int32		cb;
 	int32	   *aa,
 			   *bb,
 			   *r;
@@ -417,6 +438,9 @@ intset_subtract(PG_FUNCTION_ARGS)
 				i = 0,
 				k = 0;
 
+	CHECKARRVALID(a);
+	CHECKARRVALID(b);
+
 	QSORT(a, 1);
 	a = _int_unique(a);
 	ca = ARRNELEMS(a);
diff --git a/contrib/intarray/_int_tool.c b/contrib/intarray/_int_tool.c
index 13c5d1e9e243950c12baa88a5f75b2ca49f9a8bb..480e16ed9fe57eebe1a08cb372ea5db64f9a8ca9 100644
--- a/contrib/intarray/_int_tool.c
+++ b/contrib/intarray/_int_tool.c
@@ -12,6 +12,9 @@ inner_int_contains(ArrayType *a, ArrayType *b)
 	int		   *da,
 			   *db;
 
+	CHECKARRVALID(a);
+	CHECKARRVALID(b);
+
 	if (ARRISVOID(a) || ARRISVOID(b))
 		return FALSE;
 
@@ -46,6 +49,9 @@ inner_int_overlap(ArrayType *a, ArrayType *b)
 	int		   *da,
 			   *db;
 
+	CHECKARRVALID(a);
+	CHECKARRVALID(b);
+
 	if (ARRISVOID(a) || ARRISVOID(b))
 		return FALSE;
 
@@ -78,6 +84,9 @@ inner_int_union(ArrayType *a, ArrayType *b)
 	int			i,
 				j;
 
+	CHECKARRVALID(a);
+	CHECKARRVALID(b);
+
 	if (ARRISVOID(a) && ARRISVOID(b))
 		return new_intArrayType(0);
 	if (ARRISVOID(a))
@@ -130,6 +139,9 @@ inner_int_inter(ArrayType *a, ArrayType *b)
 	int			i,
 				j;
 
+	CHECKARRVALID(a);
+	CHECKARRVALID(b);
+
 	if (ARRISVOID(a) || ARRISVOID(b))
 		return new_intArrayType(0);
 
@@ -243,7 +255,7 @@ copy_intArrayType(ArrayType *a)
 	ArrayType  *r;
 
 	r = new_intArrayType(ARRNELEMS(a));
-	memmove(r, a, VARSIZE(a));
+	memmove(r, a, VARSIZE(r));
 	return r;
 }
 
@@ -270,6 +282,8 @@ _int_unique(ArrayType *r)
 			   *data;
 	int			num = ARRNELEMS(r);
 
+	CHECKARRVALID(r);
+
 	if (num < 2)
 		return r;
 
@@ -302,7 +316,10 @@ intarray_match_first(ArrayType *a, int32 elem)
 				c,
 				i;
 
-	c = (ARRISVOID(a)) ? 0 : ARRNELEMS(a);
+	CHECKARRVALID(a);
+	if (ARRISVOID(a))
+		return 0;
+	c = ARRNELEMS(a);
 	aa = ARRPTR(a);
 	for (i = 0; i < c; i++)
 		if (aa[i] == elem)
@@ -315,8 +332,10 @@ intarray_add_elem(ArrayType *a, int32 elem)
 {
 	ArrayType  *result;
 	int32	   *r;
-	int32		c = (ARRISVOID(a)) ? 0 : ARRNELEMS(a);
+	int32		c;
 
+	CHECKARRVALID(a);
+	c = (ARRISVOID(a)) ? 0 : ARRNELEMS(a);
 	result = new_intArrayType(c + 1);
 	r = ARRPTR(result);
 	if (c > 0)
@@ -332,6 +351,8 @@ intarray_concat_arrays(ArrayType *a, ArrayType *b)
 	int32		ac = (ARRISVOID(a)) ? 0 : ARRNELEMS(a);
 	int32		bc = (ARRISVOID(b)) ? 0 : ARRNELEMS(b);
 
+	CHECKARRVALID(a);
+	CHECKARRVALID(b);
 	result = new_intArrayType(ac + bc);
 	if (ac)
 		memcpy(ARRPTR(result), ARRPTR(a), ac * sizeof(int32));
diff --git a/contrib/intarray/_intbig_gist.c b/contrib/intarray/_intbig_gist.c
index 237281aec5b61dba3aa2b4db555c9ed893265916..0064e450ddb9145241cb46d2284656cfe92d9d15 100644
--- a/contrib/intarray/_intbig_gist.c
+++ b/contrib/intarray/_intbig_gist.c
@@ -66,6 +66,8 @@ _intbig_overlap(GISTTYPE * a, ArrayType *b)
 	int			num = ARRNELEMS(b);
 	int4	   *ptr = ARRPTR(b);
 
+	CHECKARRVALID(b);
+
 	while (num--)
 	{
 		if (GETBIT(GETSIGN(a), HASHVAL(*ptr)))
@@ -82,6 +84,8 @@ _intbig_contains(GISTTYPE * a, ArrayType *b)
 	int			num = ARRNELEMS(b);
 	int4	   *ptr = ARRPTR(b);
 
+	CHECKARRVALID(b);
+
 	while (num--)
 	{
 		if (!GETBIT(GETSIGN(a), HASHVAL(*ptr)))
@@ -136,10 +140,17 @@ g_intbig_compress(PG_FUNCTION_ARGS)
 		int			num;
 		GISTTYPE   *res = (GISTTYPE *) palloc(CALCGTSIZE(0));
 
-		ARRISVOID(in);
-
-		ptr = ARRPTR(in);
-		num = ARRNELEMS(in);
+		CHECKARRVALID(in);
+		if (ARRISVOID(in))
+		{
+			ptr = NULL;
+			num = 0;
+		}
+		else
+		{
+			ptr = ARRPTR(in);
+			num = ARRNELEMS(in);
+		}
 		memset(res, 0, CALCGTSIZE(0));
 		res->len = CALCGTSIZE(0);
 
@@ -492,6 +503,7 @@ g_intbig_consistent(PG_FUNCTION_ARGS)
 	}
 
 	/* XXX what about toasted input? */
+	CHECKARRVALID(query);
 	if (ARRISVOID(query))
 		return FALSE;
 
@@ -510,6 +522,8 @@ g_intbig_consistent(PG_FUNCTION_ARGS)
 				BITVECP		dq,
 							de;
 
+				CHECKARRVALID(query);
+
 				memset(qp, 0, sizeof(BITVEC));
 
 				while (num--)
@@ -546,6 +560,8 @@ g_intbig_consistent(PG_FUNCTION_ARGS)
 				BITVECP		dq,
 							de;
 
+				CHECKARRVALID(query);
+
 				memset(qp, 0, sizeof(BITVEC));
 
 				while (num--)