*** 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