*** a/contrib/intarray/Makefile
--- b/contrib/intarray/Makefile
***************
*** 1,7 ****
  # $PostgreSQL$
  
  MODULE_big = _int
! OBJS = _int_bool.o _int_gist.o _int_op.o _int_tool.o _intbig_gist.o _int_gin.o 
  DATA_built = _int.sql
  DATA = uninstall__int.sql
  REGRESS = _int
--- 1,7 ----
  # $PostgreSQL$
  
  MODULE_big = _int
! OBJS = _int_bool.o _int_gist.o _int_op.o _int_tool.o _intbig_gist.o _int_gin.o intset_op.o
  DATA_built = _int.sql
  DATA = uninstall__int.sql
  REGRESS = _int
*** a/contrib/intarray/_int.sql.in
--- b/contrib/intarray/_int.sql.in
***************
*** 3,8 ****
--- 3,64 ----
  -- Adjust this setting to control where the objects get created.
  SET search_path = public;
  
+ CREATE TYPE intset;
+ 
+ 
+ CREATE OR REPLACE FUNCTION intset_in(cstring)
+ RETURNS intset
+ AS 'array_in'
+ LANGUAGE internal IMMUTABLE STRICT;
+ 
+ CREATE OR REPLACE FUNCTION intset_out(intset)
+ RETURNS cstring
+ AS 'array_out'
+ LANGUAGE internal IMMUTABLE STRICT;
+ 
+ CREATE OR REPLACE FUNCTION intset_recv(internal)
+ RETURNS intset
+ AS 'array_recv'
+ LANGUAGE internal STABLE STRICT;
+ 
+ CREATE OR REPLACE FUNCTION intset_send(intset)
+ RETURNS bytea
+ AS 'array_send'
+ LANGUAGE internal STABLE STRICT;
+ 
+ CREATE TYPE intset (
+     INPUT          = intset_in,
+     OUTPUT         = intset_out,
+     RECEIVE        = intset_recv,
+     SEND           = intset_send,
+ 	--ELEMENT        = int4,
+     INTERNALLENGTH = VARIABLE,
+     STORAGE        = extended,
+     -- make it a non-preferred member of string type category
+     CATEGORY       = 'I',
+     PREFERRED      = false
+ );
+ 
+ 
+ CREATE OR REPLACE FUNCTION intset_to_array(intset)
+ RETURNS _int4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE OR REPLACE FUNCTION array_to_intset(_int4)
+ RETURNS intset
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ CREATE OR REPLACE FUNCTION intset_idx(intset, int4)
+ RETURNS int4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+ 
+ 
+ CREATE CAST (intset AS _int4) WITH FUNCTION intset_to_array(intset) AS IMPLICIT;
+ CREATE CAST (_int4 AS intset) WITH FUNCTION array_to_intset(_int4) AS IMPLICIT;
+ 
  --
  -- Create the user-defined type for the 1-D integer arrays (_int4)
  --
*** a/contrib/intarray/uninstall__int.sql
--- b/contrib/intarray/uninstall__int.sql
***************
*** 126,128 **** DROP FUNCTION boolop(_int4, query_int);
--- 126,130 ----
  DROP FUNCTION querytree(query_int);
  
  DROP TYPE query_int CASCADE;
+ 
+ DROP TYPE intset CASCADE;
*** a/src/backend/utils/adt/arrayfuncs.c
--- b/src/backend/utils/adt/arrayfuncs.c
***************
*** 1551,1557 **** array_send(PG_FUNCTION_ARGS)
  Datum
  array_ndims(PG_FUNCTION_ARGS)
  {
! 	ArrayType  *v = PG_GETARG_ARRAYTYPE_P(0);
  
  	/* Sanity check: does it look like an array at all? */
  	if (ARR_NDIM(v) <= 0 || ARR_NDIM(v) > MAXDIM)
--- 1551,1557 ----
  Datum
  array_ndims(PG_FUNCTION_ARGS)
  {
! 	ArrayType  *v = PG_GETARG_ARRAYTYPE_HEADER_P(0);
  
  	/* Sanity check: does it look like an array at all? */
  	if (ARR_NDIM(v) <= 0 || ARR_NDIM(v) > MAXDIM)
***************
*** 1567,1573 **** array_ndims(PG_FUNCTION_ARGS)
  Datum
  array_dims(PG_FUNCTION_ARGS)
  {
! 	ArrayType  *v = PG_GETARG_ARRAYTYPE_P(0);
  	char	   *p;
  	int			i;
  	int		   *dimv,
--- 1567,1573 ----
  Datum
  array_dims(PG_FUNCTION_ARGS)
  {
! 	ArrayType  *v = PG_GETARG_ARRAYTYPE_HEADER_P(0);
  	char	   *p;
  	int			i;
  	int		   *dimv,
***************
*** 1605,1611 **** array_dims(PG_FUNCTION_ARGS)
  Datum
  array_lower(PG_FUNCTION_ARGS)
  {
! 	ArrayType  *v = PG_GETARG_ARRAYTYPE_P(0);
  	int			reqdim = PG_GETARG_INT32(1);
  	int		   *lb;
  	int			result;
--- 1605,1611 ----
  Datum
  array_lower(PG_FUNCTION_ARGS)
  {
! 	ArrayType  *v = PG_GETARG_ARRAYTYPE_HEADER_P(0);
  	int			reqdim = PG_GETARG_INT32(1);
  	int		   *lb;
  	int			result;
***************
*** 1632,1638 **** array_lower(PG_FUNCTION_ARGS)
  Datum
  array_upper(PG_FUNCTION_ARGS)
  {
! 	ArrayType  *v = PG_GETARG_ARRAYTYPE_P(0);
  	int			reqdim = PG_GETARG_INT32(1);
  	int		   *dimv,
  			   *lb;
--- 1632,1638 ----
  Datum
  array_upper(PG_FUNCTION_ARGS)
  {
! 	ArrayType  *v = PG_GETARG_ARRAYTYPE_HEADER_P(0);
  	int			reqdim = PG_GETARG_INT32(1);
  	int		   *dimv,
  			   *lb;
***************
*** 1662,1668 **** array_upper(PG_FUNCTION_ARGS)
  Datum
  array_length(PG_FUNCTION_ARGS)
  {
! 	ArrayType  *v = PG_GETARG_ARRAYTYPE_P(0);
  	int			reqdim = PG_GETARG_INT32(1);
  	int		   *dimv;
  	int			result;
--- 1662,1668 ----
  Datum
  array_length(PG_FUNCTION_ARGS)
  {
! 	ArrayType  *v = PG_GETARG_ARRAYTYPE_HEADER_P(0);
  	int			reqdim = PG_GETARG_INT32(1);
  	int		   *dimv;
  	int			result;
*** a/src/include/utils/array.h
--- b/src/include/utils/array.h
***************
*** 119,126 **** typedef struct ArrayMapState
--- 119,129 ----
   */
  #define DatumGetArrayTypeP(X)		  ((ArrayType *) PG_DETOAST_DATUM(X))
  #define DatumGetArrayTypePCopy(X)	  ((ArrayType *) PG_DETOAST_DATUM_COPY(X))
+ #define DatamGetArrayTypeHeaderP(X) \
+ 	((ArrayType *) PG_DETOAST_DATUM_SLICE(X, 0, ARR_MAX_HEADER_SIZE))
  #define PG_GETARG_ARRAYTYPE_P(n)	  DatumGetArrayTypeP(PG_GETARG_DATUM(n))
  #define PG_GETARG_ARRAYTYPE_P_COPY(n) DatumGetArrayTypePCopy(PG_GETARG_DATUM(n))
+ #define PG_GETARG_ARRAYTYPE_HEADER_P(n)	  DatamGetArrayTypeHeaderP(PG_GETARG_DATUM(n))
  #define PG_RETURN_ARRAYTYPE_P(x)	  PG_RETURN_POINTER(x)
  
  /*
***************
*** 172,177 **** typedef struct ArrayMapState
--- 175,185 ----
  #define ARR_DATA_PTR(a) \
  		(((char *) (a)) + ARR_DATA_OFFSET(a))
  
+ /*
+  * Calculate the maximum size a header of an array can be
+  */
+ #define ARR_MAX_HEADER_SIZE \
+ 		ARR_OVERHEAD_NONULLS(MAXDIM)
  
  /*
   * GUC parameter