On 07/21/2015 03:44 PM, Alexander Korotkov wrote:
While Uriy is on vacation, I've revised this patch a bit.

I whacked this around quite a bit, and I think it's in a committable state now. But if you could run whatever tests you were using before on this, to make sure it still produces the same estimates, that would be great. I didn't change the estimates it should produce, only the code structure.

One thing that bothers me slightly with this patch is the way it peeks into the Most-Common-Elements arrays, which is produced by the built-in type analyze function. If we ever change what statistics are collected for arrays, or the way they are stored, this might break. In matchsel, why don't we just call the built-in estimator function for each element that we need to probe, and not look into the statistics ourselves at all? I actually experimented with that, and it did slash much of the code, and it would be more future-proof. However, it was also a lot slower for queries that contain multiple values. That's understandable: the built-in estimator will fetch the statistics tuple, parse the arrays, etc. separately for each value in the query_int, while this patch will do it only once for the whole query, and perform a simple binary search for each value. So overall, I think this is OK as it is. But if we find that we need to use the MCE list in this fashion in more places in the future, it might be worthwhile to add some support code for this in the backend to allow extracting the stats once, and doing multiple "lightweight estimations" using the extracted stats.

Some things I fixed/changed:

* I didn't like that transformOperator() function, which looked up the function's name. I replaced it with separate wrapper functions for each operator, so that the built-in operator's OID can be hardcoded into each.

* I refactored the matchsel function heavily. I think it's more readable now.

* I got rid of the Int4Freq array. It didn't seem significantly easier to work with than the separate values/numbers arrays, so I just used those directly.

* Also use the matchsel estimator for ~~ (the commutator of @@)

* Also use the estimators for the obsolete @ and ~ operators. Not that I care much about those as they are obsolete, but seems strange not to, as it's a trivial matter of setting the right estimator function.

* I added an ANALYZE in the regression test. It still won't systematically test all the cost estimation code, and there's nothing to check that the estimates make sense, but at least more of the code will now run.

- Heikki

diff --git a/contrib/intarray/Makefile b/contrib/intarray/Makefile
index 920c5b1..5ea7f2a 100644
--- a/contrib/intarray/Makefile
+++ b/contrib/intarray/Makefile
@@ -2,10 +2,10 @@
 
 MODULE_big = _int
 OBJS = _int_bool.o _int_gist.o _int_op.o _int_tool.o \
-	_intbig_gist.o _int_gin.o $(WIN32RES)
+	_intbig_gist.o _int_gin.o _int_selfuncs.o $(WIN32RES)
 
 EXTENSION = intarray
-DATA = intarray--1.0.sql intarray--unpackaged--1.0.sql
+DATA = intarray--1.1.sql intarray--1.0--1.1.sql intarray--unpackaged--1.0.sql
 PGFILEDESC = "intarray - functions and operators for arrays of integers"
 
 REGRESS = _int
diff --git a/contrib/intarray/_int_selfuncs.c b/contrib/intarray/_int_selfuncs.c
new file mode 100644
index 0000000..4896461
--- /dev/null
+++ b/contrib/intarray/_int_selfuncs.c
@@ -0,0 +1,334 @@
+/*-------------------------------------------------------------------------
+ *
+ * _int_selfuncs.c
+ *	  Functions for selectivity estimation of intarray operators
+ *
+ * Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ *	  contrib/intarray/_int_selfuncs.c
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres.h"
+#include "_int.h"
+
+#include "access/htup_details.h"
+#include "catalog/pg_operator.h"
+#include "catalog/pg_statistic.h"
+#include "catalog/pg_type.h"
+#include "utils/selfuncs.h"
+#include "utils/syscache.h"
+#include "utils/lsyscache.h"
+#include "miscadmin.h"
+
+PG_FUNCTION_INFO_V1(_int_overlap_sel);
+PG_FUNCTION_INFO_V1(_int_contains_sel);
+PG_FUNCTION_INFO_V1(_int_contained_sel);
+PG_FUNCTION_INFO_V1(_int_overlap_joinsel);
+PG_FUNCTION_INFO_V1(_int_contains_joinsel);
+PG_FUNCTION_INFO_V1(_int_contained_joinsel);
+PG_FUNCTION_INFO_V1(_int_matchsel);
+
+Datum		_int_overlap_sel(PG_FUNCTION_ARGS);
+Datum		_int_contains_sel(PG_FUNCTION_ARGS);
+Datum		_int_contained_sel(PG_FUNCTION_ARGS);
+Datum		_int_overlap_joinsel(PG_FUNCTION_ARGS);
+Datum		_int_contains_joinsel(PG_FUNCTION_ARGS);
+Datum		_int_contained_joinsel(PG_FUNCTION_ARGS);
+Datum		_int_matchsel(PG_FUNCTION_ARGS);
+
+
+static Selectivity int_query_opr_selec(ITEM *item, Datum *values, float4 *freqs,
+					int nmncelems, float4 minfreq);
+static int	compare_val_int4(const void *a, const void *b);
+
+/*
+ * Wrappers around the default array selectivity estimation functions.
+ *
+ * The default array selectivity operators for the @>, && and @< operators
+ * work fine for integer arrays. However, if we tried to just use arraycontsel
+ * and arracontjoinsel directly as the cost estimator functions for our
+ * operators, they would not work as intended, because they look at the
+ * operator's OID. Our operators behave exactly like the built-in anyarray
+ * versions, but we must tell the cost estimator functions which built-in
+ * operators they correspond to. These wrappers just replace the operator
+ * OID with the corresponding built-in operator's OID, and call the built-in
+ * function.
+ */
+
+Datum
+_int_overlap_sel(PG_FUNCTION_ARGS)
+{
+	PG_RETURN_DATUM(DirectFunctionCall4(arraycontsel,
+										PG_GETARG_DATUM(0),
+										ObjectIdGetDatum(OID_ARRAY_OVERLAP_OP),
+										PG_GETARG_DATUM(2),
+										PG_GETARG_DATUM(3)));
+}
+
+Datum
+_int_contains_sel(PG_FUNCTION_ARGS)
+{
+	PG_RETURN_DATUM(DirectFunctionCall4(arraycontsel,
+										PG_GETARG_DATUM(0),
+										ObjectIdGetDatum(OID_ARRAY_CONTAINS_OP),
+										PG_GETARG_DATUM(2),
+										PG_GETARG_DATUM(3)));
+}
+
+Datum
+_int_contained_sel(PG_FUNCTION_ARGS)
+{
+	PG_RETURN_DATUM(DirectFunctionCall4(arraycontsel,
+										PG_GETARG_DATUM(0),
+										ObjectIdGetDatum(OID_ARRAY_CONTAINED_OP),
+										PG_GETARG_DATUM(2),
+										PG_GETARG_DATUM(3)));
+}
+
+Datum
+_int_overlap_joinsel(PG_FUNCTION_ARGS)
+{
+	PG_RETURN_DATUM(DirectFunctionCall5(arraycontjoinsel,
+										PG_GETARG_DATUM(0),
+										ObjectIdGetDatum(OID_ARRAY_OVERLAP_OP),
+										PG_GETARG_DATUM(2),
+										PG_GETARG_DATUM(3),
+										PG_GETARG_DATUM(4)));
+}
+
+Datum
+_int_contains_joinsel(PG_FUNCTION_ARGS)
+{
+	PG_RETURN_DATUM(DirectFunctionCall5(arraycontjoinsel,
+										PG_GETARG_DATUM(0),
+										ObjectIdGetDatum(OID_ARRAY_CONTAINS_OP),
+										PG_GETARG_DATUM(2),
+										PG_GETARG_DATUM(3),
+										PG_GETARG_DATUM(4)));
+}
+
+Datum
+_int_contained_joinsel(PG_FUNCTION_ARGS)
+{
+	PG_RETURN_DATUM(DirectFunctionCall5(arraycontjoinsel,
+										PG_GETARG_DATUM(0),
+										ObjectIdGetDatum(OID_ARRAY_CONTAINED_OP),
+										PG_GETARG_DATUM(2),
+										PG_GETARG_DATUM(3),
+										PG_GETARG_DATUM(4)));
+}
+
+
+/*
+ * _int_matchsel -- restriction selectivity function for intarray @@ query_int
+ */
+Datum
+_int_matchsel(PG_FUNCTION_ARGS)
+{
+	PlannerInfo *root = (PlannerInfo *) PG_GETARG_POINTER(0);
+
+	List	   *args = (List *) PG_GETARG_POINTER(2);
+	int			varRelid = PG_GETARG_INT32(3);
+	VariableStatData vardata;
+	Node	   *other;
+	bool		varonleft;
+	Selectivity selec;
+	QUERYTYPE  *query;
+	Datum	   *mcelems = NULL;
+	float4	   *mcefreqs = NULL;
+	int			nmcelems = 0;
+	float4		minfreq = 0.0;
+	float4		nullfrac = 0.0;
+	Form_pg_statistic stats;
+	Datum	   *values = NULL;
+	int			nvalues = 0;
+	float4	   *numbers = NULL;
+	int			nnumbers = 0;
+
+	/*
+	 * If expression is not "variable @@ something" or "something @@ variable"
+	 * then punt and return a default estimate.
+	 */
+	if (!get_restriction_variable(root, args, varRelid,
+								  &vardata, &other, &varonleft))
+		PG_RETURN_FLOAT8(DEFAULT_EQ_SEL);
+
+	/*
+	 * Can't do anything useful if the something is not a constant, either.
+	 */
+	if (!IsA(other, Const))
+	{
+		ReleaseVariableStats(vardata);
+		PG_RETURN_FLOAT8(DEFAULT_EQ_SEL);
+	}
+
+	/*
+	 * The "@@" operator is strict, so we can cope with NULL right away.
+	 */
+	if (((Const *) other)->constisnull)
+	{
+		ReleaseVariableStats(vardata);
+		PG_RETURN_FLOAT8(0.0);
+	}
+
+	/* The caller made sure the const is a query, so get it now */
+	query = DatumGetQueryTypeP(((Const *) other)->constvalue);
+
+	/* Empty query matches nothing */
+	if (query->size == 0)
+	{
+		ReleaseVariableStats(vardata);
+		return (Selectivity) 0.0;
+	}
+
+	/*
+	 * Get the statistics for the intarray column.
+	 *
+	 * We're interested in the Most-Common-Elements list, and the NULL
+	 * fraction.
+	 */
+	if (HeapTupleIsValid(vardata.statsTuple))
+	{
+		stats = (Form_pg_statistic) GETSTRUCT(vardata.statsTuple);
+		nullfrac = stats->stanullfrac;
+
+		/*
+		 * For an int4 array, the default array type analyze function will
+		 * collect a Most Common Elements list, which is an array of int4s.
+		 */
+		if (get_attstatsslot(vardata.statsTuple,
+							 INT4OID, -1,
+							 STATISTIC_KIND_MCELEM, InvalidOid,
+							 NULL,
+							 &values, &nvalues,
+							 &numbers, &nnumbers))
+		{
+			/*
+			 * There should be three more Numbers than Values, because the last
+			 * three (for intarray) cells are taken for minimal, maximal and nulls
+			 * frequency. Punt if not.
+			 */
+			if (nnumbers == nvalues + 3)
+			{
+				/* Grab the lowest frequency. */
+				minfreq = numbers[nnumbers - (nnumbers - nvalues)];
+
+				mcelems = values;
+				mcefreqs = numbers;
+				nmcelems = nvalues;
+			}
+		}
+	}
+
+	/* Process the logical expression in the query, using the stats */
+	selec = int_query_opr_selec(GETQUERY(query) + query->size - 1,
+								mcelems, mcefreqs, nmcelems, minfreq);
+
+	/* MCE stats count only non-null rows, so adjust for null rows. */
+	selec *= (1.0 - nullfrac);
+
+	free_attstatsslot(INT4OID, values, nvalues, numbers, nnumbers);
+	ReleaseVariableStats(vardata);
+
+	CLAMP_PROBABILITY(selec);
+
+	PG_RETURN_FLOAT8((float8) selec);
+}
+
+/*
+ * Estimate selectivity of single intquery operator
+ */
+static Selectivity
+int_query_opr_selec(ITEM *item, Datum *mcelems, float4 *mcefreqs,
+					int nmcelems, float4 minfreq)
+{
+	Selectivity selec;
+
+	/* since this function recurses, it could be driven to stack overflow */
+	check_stack_depth();
+
+	if (item->type == VAL)
+	{
+		Datum	   *searchres;
+
+		if (mcelems == NULL)
+			return (Selectivity) DEFAULT_EQ_SEL;
+
+		searchres = (Datum *) bsearch(&item->val, mcelems, nmcelems,
+									  sizeof(Datum), compare_val_int4);
+		if (searchres)
+		{
+			/*
+			 * The element is in MCELEM.  Return precise selectivity (or at
+			 * least as precise as ANALYZE could find out).
+			 */
+			selec = mcefreqs[searchres - mcelems];
+		}
+		else
+		{
+			/*
+			 * The element is not in MCELEM.  Punt, but assume that the
+			 * selectivity cannot be more than minfreq / 2.
+			 */
+			selec = Min(DEFAULT_EQ_SEL, minfreq / 2);
+		}
+	}
+	else if (item->type == OPR)
+	{
+		/* Current query node is an operator */
+		Selectivity s1,
+					s2;
+
+		s1 = int_query_opr_selec(item - 1, mcelems, mcefreqs, nmcelems,
+								 minfreq);
+		switch (item->val)
+		{
+			case (int32) '!':
+				selec = 1.0 - s1;
+				break;
+
+			case (int32) '&':
+				s2 = int_query_opr_selec(item + item->left, mcelems, mcefreqs,
+										 nmcelems, minfreq);
+				selec = s1 * s2;
+				break;
+
+			case (int32) '|':
+				s2 = int_query_opr_selec(item + item->left, mcelems, mcefreqs,
+										 nmcelems, minfreq);
+				selec = s1 + s2 - s1 * s2;
+				break;
+
+			default:
+				elog(ERROR, "unrecognized operator: %d", item->val);
+				selec = 0;		/* keep compiler quiet */
+				break;
+		}
+	}
+	else
+	{
+		elog(ERROR, "unrecognized int query item type: %u", item->type);
+		selec = 0;				/* keep compiler quiet */
+	}
+
+	/* Clamp intermediate results to stay sane despite roundoff error */
+	CLAMP_PROBABILITY(selec);
+
+	return selec;
+}
+
+/*
+ * Comparison function for binary search in mcelem array.
+ */
+static int
+compare_val_int4(const void *a, const void *b)
+{
+	int32		key = *(int32 *) a;
+	const Datum *t = (const Datum *) b;
+
+	return key - DatumGetInt32(*t);
+}
diff --git a/contrib/intarray/expected/_int.out b/contrib/intarray/expected/_int.out
index 4080b96..962e5c6 100644
--- a/contrib/intarray/expected/_int.out
+++ b/contrib/intarray/expected/_int.out
@@ -368,6 +368,7 @@ SELECT '1&(2&(4&(5|!6)))'::query_int;
 
 CREATE TABLE test__int( a int[] );
 \copy test__int from 'data/test__int.data'
+ANALYZE test__int;
 SELECT count(*) from test__int WHERE a && '{23,50}';
  count 
 -------
diff --git a/contrib/intarray/intarray--1.0.sql b/contrib/intarray/intarray--1.0.sql
deleted file mode 100644
index 0b89e0f..0000000
--- a/contrib/intarray/intarray--1.0.sql
+++ /dev/null
@@ -1,485 +0,0 @@
-/* contrib/intarray/intarray--1.0.sql */
-
--- complain if script is sourced in psql, rather than via CREATE EXTENSION
-\echo Use "CREATE EXTENSION intarray" to load this file. \quit
-
---
--- Create the user-defined type for the 1-D integer arrays (_int4)
---
-
--- Query type
-CREATE FUNCTION bqarr_in(cstring)
-RETURNS query_int
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION bqarr_out(query_int)
-RETURNS cstring
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE TYPE query_int (
-	INTERNALLENGTH = -1,
-	INPUT = bqarr_in,
-	OUTPUT = bqarr_out
-);
-
---only for debug
-CREATE FUNCTION querytree(query_int)
-RETURNS text
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-
-CREATE FUNCTION boolop(_int4, query_int)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-COMMENT ON FUNCTION boolop(_int4, query_int) IS 'boolean operation with array';
-
-CREATE FUNCTION rboolop(query_int, _int4)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-COMMENT ON FUNCTION rboolop(query_int, _int4) IS 'boolean operation with array';
-
-CREATE OPERATOR @@ (
-	LEFTARG = _int4,
-	RIGHTARG = query_int,
-	PROCEDURE = boolop,
-	COMMUTATOR = '~~',
-	RESTRICT = contsel,
-	JOIN = contjoinsel
-);
-
-CREATE OPERATOR ~~ (
-	LEFTARG = query_int,
-	RIGHTARG = _int4,
-	PROCEDURE = rboolop,
-	COMMUTATOR = '@@',
-	RESTRICT = contsel,
-	JOIN = contjoinsel
-);
-
-
---
--- External C-functions for R-tree methods
---
-
--- Comparison methods
-
-CREATE FUNCTION _int_contains(_int4, _int4)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-COMMENT ON FUNCTION _int_contains(_int4, _int4) IS 'contains';
-
-CREATE FUNCTION _int_contained(_int4, _int4)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-COMMENT ON FUNCTION _int_contained(_int4, _int4) IS 'contained in';
-
-CREATE FUNCTION _int_overlap(_int4, _int4)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-COMMENT ON FUNCTION _int_overlap(_int4, _int4) IS 'overlaps';
-
-CREATE FUNCTION _int_same(_int4, _int4)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-COMMENT ON FUNCTION _int_same(_int4, _int4) IS 'same as';
-
-CREATE FUNCTION _int_different(_int4, _int4)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-COMMENT ON FUNCTION _int_different(_int4, _int4) IS 'different';
-
--- support routines for indexing
-
-CREATE FUNCTION _int_union(_int4, _int4)
-RETURNS _int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION _int_inter(_int4, _int4)
-RETURNS _int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
---
--- OPERATORS
---
-
-CREATE OPERATOR && (
-	LEFTARG = _int4,
-	RIGHTARG = _int4,
-	PROCEDURE = _int_overlap,
-	COMMUTATOR = '&&',
-	RESTRICT = contsel,
-	JOIN = contjoinsel
-);
-
---CREATE OPERATOR = (
---	LEFTARG = _int4,
---	RIGHTARG = _int4,
---	PROCEDURE = _int_same,
---	COMMUTATOR = '=',
---	NEGATOR = '<>',
---	RESTRICT = eqsel,
---	JOIN = eqjoinsel,
---	SORT1 = '<',
---	SORT2 = '<'
---);
-
---CREATE OPERATOR <> (
---	LEFTARG = _int4,
---	RIGHTARG = _int4,
---	PROCEDURE = _int_different,
---	COMMUTATOR = '<>',
---	NEGATOR = '=',
---	RESTRICT = neqsel,
---	JOIN = neqjoinsel
---);
-
-CREATE OPERATOR @> (
-	LEFTARG = _int4,
-	RIGHTARG = _int4,
-	PROCEDURE = _int_contains,
-	COMMUTATOR = '<@',
-	RESTRICT = contsel,
-	JOIN = contjoinsel
-);
-
-CREATE OPERATOR <@ (
-	LEFTARG = _int4,
-	RIGHTARG = _int4,
-	PROCEDURE = _int_contained,
-	COMMUTATOR = '@>',
-	RESTRICT = contsel,
-	JOIN = contjoinsel
-);
-
--- obsolete:
-CREATE OPERATOR @ (
-	LEFTARG = _int4,
-	RIGHTARG = _int4,
-	PROCEDURE = _int_contains,
-	COMMUTATOR = '~',
-	RESTRICT = contsel,
-	JOIN = contjoinsel
-);
-
-CREATE OPERATOR ~ (
-	LEFTARG = _int4,
-	RIGHTARG = _int4,
-	PROCEDURE = _int_contained,
-	COMMUTATOR = '@',
-	RESTRICT = contsel,
-	JOIN = contjoinsel
-);
-
---------------
-CREATE FUNCTION intset(int4)
-RETURNS _int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION icount(_int4)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR # (
-	RIGHTARG = _int4,
-	PROCEDURE = icount
-);
-
-CREATE FUNCTION sort(_int4, text)
-RETURNS _int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION sort(_int4)
-RETURNS _int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION sort_asc(_int4)
-RETURNS _int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION sort_desc(_int4)
-RETURNS _int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION uniq(_int4)
-RETURNS _int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION idx(_int4, int4)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR # (
-	LEFTARG = _int4,
-	RIGHTARG = int4,
-	PROCEDURE = idx
-);
-
-CREATE FUNCTION subarray(_int4, int4, int4)
-RETURNS _int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION subarray(_int4, int4)
-RETURNS _int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION intarray_push_elem(_int4, int4)
-RETURNS _int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR + (
-	LEFTARG = _int4,
-	RIGHTARG = int4,
-	PROCEDURE = intarray_push_elem
-);
-
-CREATE FUNCTION intarray_push_array(_int4, _int4)
-RETURNS _int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR + (
-	LEFTARG = _int4,
-	RIGHTARG = _int4,
-	COMMUTATOR = +,
-	PROCEDURE = intarray_push_array
-);
-
-CREATE FUNCTION intarray_del_elem(_int4, int4)
-RETURNS _int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR - (
-	LEFTARG = _int4,
-	RIGHTARG = int4,
-	PROCEDURE = intarray_del_elem
-);
-
-CREATE FUNCTION intset_union_elem(_int4, int4)
-RETURNS _int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR | (
-	LEFTARG = _int4,
-	RIGHTARG = int4,
-	PROCEDURE = intset_union_elem
-);
-
-CREATE OPERATOR | (
-	LEFTARG = _int4,
-	RIGHTARG = _int4,
-	COMMUTATOR = |,
-	PROCEDURE = _int_union
-);
-
-CREATE FUNCTION intset_subtract(_int4, _int4)
-RETURNS _int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR - (
-	LEFTARG = _int4,
-	RIGHTARG = _int4,
-	PROCEDURE = intset_subtract
-);
-
-CREATE OPERATOR & (
-	LEFTARG = _int4,
-	RIGHTARG = _int4,
-	COMMUTATOR = &,
-	PROCEDURE = _int_inter
-);
---------------
-
--- define the GiST support methods
-CREATE FUNCTION g_int_consistent(internal,_int4,int,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION g_int_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION g_int_decompress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION g_int_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION g_int_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION g_int_union(internal, internal)
-RETURNS _int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION g_int_same(_int4, _int4, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-
--- Create the operator class for indexing
-
-CREATE OPERATOR CLASS gist__int_ops
-DEFAULT FOR TYPE _int4 USING gist AS
-	OPERATOR	3	&&,
-	OPERATOR	6	= (anyarray, anyarray),
-	OPERATOR	7	@>,
-	OPERATOR	8	<@,
-	OPERATOR	13	@,
-	OPERATOR	14	~,
-	OPERATOR	20	@@ (_int4, query_int),
-	FUNCTION	1	g_int_consistent (internal, _int4, int, oid, internal),
-	FUNCTION	2	g_int_union (internal, internal),
-	FUNCTION	3	g_int_compress (internal),
-	FUNCTION	4	g_int_decompress (internal),
-	FUNCTION	5	g_int_penalty (internal, internal, internal),
-	FUNCTION	6	g_int_picksplit (internal, internal),
-	FUNCTION	7	g_int_same (_int4, _int4, internal);
-
-
----------------------------------------------
--- intbig
----------------------------------------------
--- define the GiST support methods
-
-CREATE FUNCTION _intbig_in(cstring)
-RETURNS intbig_gkey
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION _intbig_out(intbig_gkey)
-RETURNS cstring
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE TYPE intbig_gkey (
-        INTERNALLENGTH = -1,
-        INPUT = _intbig_in,
-        OUTPUT = _intbig_out
-);
-
-CREATE FUNCTION g_intbig_consistent(internal,internal,int,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION g_intbig_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION g_intbig_decompress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION g_intbig_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION g_intbig_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION g_intbig_union(internal, internal)
-RETURNS _int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION g_intbig_same(internal, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- register the opclass for indexing (not as default)
-
-CREATE OPERATOR CLASS gist__intbig_ops
-FOR TYPE _int4 USING gist
-AS
-	OPERATOR	3	&&,
-	OPERATOR	6	= (anyarray, anyarray),
-	OPERATOR	7	@>,
-	OPERATOR	8	<@,
-	OPERATOR	13	@,
-	OPERATOR	14	~,
-	OPERATOR	20	@@ (_int4, query_int),
-	FUNCTION	1	g_intbig_consistent (internal, internal, int, oid, internal),
-	FUNCTION	2	g_intbig_union (internal, internal),
-	FUNCTION	3	g_intbig_compress (internal),
-	FUNCTION	4	g_intbig_decompress (internal),
-	FUNCTION	5	g_intbig_penalty (internal, internal, internal),
-	FUNCTION	6	g_intbig_picksplit (internal, internal),
-	FUNCTION	7	g_intbig_same (internal, internal, internal),
-	STORAGE		intbig_gkey;
-
---GIN
-
-CREATE FUNCTION ginint4_queryextract(internal, internal, int2, internal, internal, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION ginint4_consistent(internal, int2, internal, int4, internal, internal, internal, internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE OPERATOR CLASS gin__int_ops
-FOR TYPE _int4 USING gin
-AS
-	OPERATOR	3	&&,
-	OPERATOR	6	= (anyarray, anyarray),
-	OPERATOR	7	@>,
-	OPERATOR	8	<@,
-	OPERATOR	13	@,
-	OPERATOR	14	~,
-	OPERATOR	20	@@ (_int4, query_int),
-	FUNCTION	1	btint4cmp (int4, int4),
-	FUNCTION	2	ginarrayextract (anyarray, internal, internal),
-	FUNCTION	3	ginint4_queryextract (internal, internal, int2, internal, internal, internal, internal),
-	FUNCTION	4	ginint4_consistent (internal, int2, internal, int4, internal, internal, internal, internal),
-	STORAGE		int4;
diff --git a/contrib/intarray/intarray--1.1.sql b/contrib/intarray/intarray--1.1.sql
new file mode 100644
index 0000000..817625e
--- /dev/null
+++ b/contrib/intarray/intarray--1.1.sql
@@ -0,0 +1,520 @@
+/* contrib/intarray/intarray--1.1.sql */
+
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "CREATE EXTENSION intarray" to load this file. \quit
+
+--
+-- Create the user-defined type for the 1-D integer arrays (_int4)
+--
+
+-- Query type
+CREATE FUNCTION bqarr_in(cstring)
+RETURNS query_int
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION bqarr_out(query_int)
+RETURNS cstring
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE TYPE query_int (
+	INTERNALLENGTH = -1,
+	INPUT = bqarr_in,
+	OUTPUT = bqarr_out
+);
+
+--only for debug
+CREATE FUNCTION querytree(query_int)
+RETURNS text
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+
+CREATE FUNCTION boolop(_int4, query_int)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+COMMENT ON FUNCTION boolop(_int4, query_int) IS 'boolean operation with array';
+
+CREATE FUNCTION rboolop(query_int, _int4)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+COMMENT ON FUNCTION rboolop(query_int, _int4) IS 'boolean operation with array';
+
+CREATE FUNCTION _int_matchsel(internal, oid, internal, integer)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT STABLE;
+
+CREATE OPERATOR @@ (
+	LEFTARG = _int4,
+	RIGHTARG = query_int,
+	PROCEDURE = boolop,
+	COMMUTATOR = '~~',
+	RESTRICT = _int_matchsel,
+	JOIN = contjoinsel
+);
+
+CREATE OPERATOR ~~ (
+	LEFTARG = query_int,
+	RIGHTARG = _int4,
+	PROCEDURE = rboolop,
+	COMMUTATOR = '@@',
+	RESTRICT = _int_matchsel,
+	JOIN = contjoinsel
+);
+
+
+--
+-- External C-functions for R-tree methods
+--
+
+-- Comparison methods
+
+CREATE FUNCTION _int_contains(_int4, _int4)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+COMMENT ON FUNCTION _int_contains(_int4, _int4) IS 'contains';
+
+CREATE FUNCTION _int_contained(_int4, _int4)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+COMMENT ON FUNCTION _int_contained(_int4, _int4) IS 'contained in';
+
+CREATE FUNCTION _int_overlap(_int4, _int4)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+COMMENT ON FUNCTION _int_overlap(_int4, _int4) IS 'overlaps';
+
+CREATE FUNCTION _int_same(_int4, _int4)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+COMMENT ON FUNCTION _int_same(_int4, _int4) IS 'same as';
+
+CREATE FUNCTION _int_different(_int4, _int4)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+COMMENT ON FUNCTION _int_different(_int4, _int4) IS 'different';
+
+-- support routines for indexing
+
+CREATE FUNCTION _int_union(_int4, _int4)
+RETURNS _int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION _int_inter(_int4, _int4)
+RETURNS _int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION _int_overlap_sel(internal, oid, internal, integer)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT STABLE;
+
+CREATE FUNCTION _int_contains_sel(internal, oid, internal, integer)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT STABLE;
+
+CREATE FUNCTION _int_contained_sel(internal, oid, internal, integer)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT STABLE;
+
+CREATE FUNCTION _int_overlap_joinsel(internal, oid, internal, smallint, internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT STABLE;
+
+CREATE FUNCTION _int_contains_joinsel(internal, oid, internal, smallint, internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT STABLE;
+
+CREATE FUNCTION _int_contained_joinsel(internal, oid, internal, smallint, internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT STABLE;
+
+--
+-- OPERATORS
+--
+
+CREATE OPERATOR && (
+	LEFTARG = _int4,
+	RIGHTARG = _int4,
+	PROCEDURE = _int_overlap,
+	COMMUTATOR = '&&',
+	RESTRICT = _int_overlap_sel,
+	JOIN = _int_overlap_joinsel
+);
+
+--CREATE OPERATOR = (
+--	LEFTARG = _int4,
+--	RIGHTARG = _int4,
+--	PROCEDURE = _int_same,
+--	COMMUTATOR = '=',
+--	NEGATOR = '<>',
+--	RESTRICT = eqsel,
+--	JOIN = eqjoinsel,
+--	SORT1 = '<',
+--	SORT2 = '<'
+--);
+
+--CREATE OPERATOR <> (
+--	LEFTARG = _int4,
+--	RIGHTARG = _int4,
+--	PROCEDURE = _int_different,
+--	COMMUTATOR = '<>',
+--	NEGATOR = '=',
+--	RESTRICT = neqsel,
+--	JOIN = neqjoinsel
+--);
+
+CREATE OPERATOR @> (
+	LEFTARG = _int4,
+	RIGHTARG = _int4,
+	PROCEDURE = _int_contains,
+	COMMUTATOR = '<@',
+	RESTRICT = _int_contains_sel,
+	JOIN = _int_contains_joinsel
+);
+
+CREATE OPERATOR <@ (
+	LEFTARG = _int4,
+	RIGHTARG = _int4,
+	PROCEDURE = _int_contained,
+	COMMUTATOR = '@>',
+	RESTRICT = _int_contained_sel,
+	JOIN = _int_contained_joinsel
+);
+
+-- obsolete:
+CREATE OPERATOR @ (
+	LEFTARG = _int4,
+	RIGHTARG = _int4,
+	PROCEDURE = _int_contains,
+	COMMUTATOR = '~',
+	RESTRICT = _int_contains_sel,
+	JOIN = _int_contains_joinsel
+);
+
+CREATE OPERATOR ~ (
+	LEFTARG = _int4,
+	RIGHTARG = _int4,
+	PROCEDURE = _int_contained,
+	COMMUTATOR = '@',
+	RESTRICT = _int_contained_sel,
+	JOIN = _int_contained_joinsel
+);
+
+--------------
+CREATE FUNCTION intset(int4)
+RETURNS _int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION icount(_int4)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR # (
+	RIGHTARG = _int4,
+	PROCEDURE = icount
+);
+
+CREATE FUNCTION sort(_int4, text)
+RETURNS _int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION sort(_int4)
+RETURNS _int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION sort_asc(_int4)
+RETURNS _int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION sort_desc(_int4)
+RETURNS _int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION uniq(_int4)
+RETURNS _int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION idx(_int4, int4)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR # (
+	LEFTARG = _int4,
+	RIGHTARG = int4,
+	PROCEDURE = idx
+);
+
+CREATE FUNCTION subarray(_int4, int4, int4)
+RETURNS _int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION subarray(_int4, int4)
+RETURNS _int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION intarray_push_elem(_int4, int4)
+RETURNS _int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR + (
+	LEFTARG = _int4,
+	RIGHTARG = int4,
+	PROCEDURE = intarray_push_elem
+);
+
+CREATE FUNCTION intarray_push_array(_int4, _int4)
+RETURNS _int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR + (
+	LEFTARG = _int4,
+	RIGHTARG = _int4,
+	COMMUTATOR = +,
+	PROCEDURE = intarray_push_array
+);
+
+CREATE FUNCTION intarray_del_elem(_int4, int4)
+RETURNS _int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR - (
+	LEFTARG = _int4,
+	RIGHTARG = int4,
+	PROCEDURE = intarray_del_elem
+);
+
+CREATE FUNCTION intset_union_elem(_int4, int4)
+RETURNS _int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR | (
+	LEFTARG = _int4,
+	RIGHTARG = int4,
+	PROCEDURE = intset_union_elem
+);
+
+CREATE OPERATOR | (
+	LEFTARG = _int4,
+	RIGHTARG = _int4,
+	COMMUTATOR = |,
+	PROCEDURE = _int_union
+);
+
+CREATE FUNCTION intset_subtract(_int4, _int4)
+RETURNS _int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR - (
+	LEFTARG = _int4,
+	RIGHTARG = _int4,
+	PROCEDURE = intset_subtract
+);
+
+CREATE OPERATOR & (
+	LEFTARG = _int4,
+	RIGHTARG = _int4,
+	COMMUTATOR = &,
+	PROCEDURE = _int_inter
+);
+--------------
+
+-- define the GiST support methods
+CREATE FUNCTION g_int_consistent(internal,_int4,int,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION g_int_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION g_int_decompress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION g_int_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION g_int_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION g_int_union(internal, internal)
+RETURNS _int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION g_int_same(_int4, _int4, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+
+-- Create the operator class for indexing
+
+CREATE OPERATOR CLASS gist__int_ops
+DEFAULT FOR TYPE _int4 USING gist AS
+	OPERATOR	3	&&,
+	OPERATOR	6	= (anyarray, anyarray),
+	OPERATOR	7	@>,
+	OPERATOR	8	<@,
+	OPERATOR	13	@,
+	OPERATOR	14	~,
+	OPERATOR	20	@@ (_int4, query_int),
+	FUNCTION	1	g_int_consistent (internal, _int4, int, oid, internal),
+	FUNCTION	2	g_int_union (internal, internal),
+	FUNCTION	3	g_int_compress (internal),
+	FUNCTION	4	g_int_decompress (internal),
+	FUNCTION	5	g_int_penalty (internal, internal, internal),
+	FUNCTION	6	g_int_picksplit (internal, internal),
+	FUNCTION	7	g_int_same (_int4, _int4, internal);
+
+
+---------------------------------------------
+-- intbig
+---------------------------------------------
+-- define the GiST support methods
+
+CREATE FUNCTION _intbig_in(cstring)
+RETURNS intbig_gkey
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION _intbig_out(intbig_gkey)
+RETURNS cstring
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE TYPE intbig_gkey (
+        INTERNALLENGTH = -1,
+        INPUT = _intbig_in,
+        OUTPUT = _intbig_out
+);
+
+CREATE FUNCTION g_intbig_consistent(internal,internal,int,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION g_intbig_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION g_intbig_decompress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION g_intbig_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION g_intbig_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION g_intbig_union(internal, internal)
+RETURNS _int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION g_intbig_same(internal, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- register the opclass for indexing (not as default)
+
+CREATE OPERATOR CLASS gist__intbig_ops
+FOR TYPE _int4 USING gist
+AS
+	OPERATOR	3	&&,
+	OPERATOR	6	= (anyarray, anyarray),
+	OPERATOR	7	@>,
+	OPERATOR	8	<@,
+	OPERATOR	13	@,
+	OPERATOR	14	~,
+	OPERATOR	20	@@ (_int4, query_int),
+	FUNCTION	1	g_intbig_consistent (internal, internal, int, oid, internal),
+	FUNCTION	2	g_intbig_union (internal, internal),
+	FUNCTION	3	g_intbig_compress (internal),
+	FUNCTION	4	g_intbig_decompress (internal),
+	FUNCTION	5	g_intbig_penalty (internal, internal, internal),
+	FUNCTION	6	g_intbig_picksplit (internal, internal),
+	FUNCTION	7	g_intbig_same (internal, internal, internal),
+	STORAGE		intbig_gkey;
+
+--GIN
+
+CREATE FUNCTION ginint4_queryextract(internal, internal, int2, internal, internal, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION ginint4_consistent(internal, int2, internal, int4, internal, internal, internal, internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR CLASS gin__int_ops
+FOR TYPE _int4 USING gin
+AS
+	OPERATOR	3	&&,
+	OPERATOR	6	= (anyarray, anyarray),
+	OPERATOR	7	@>,
+	OPERATOR	8	<@,
+	OPERATOR	13	@,
+	OPERATOR	14	~,
+	OPERATOR	20	@@ (_int4, query_int),
+	FUNCTION	1	btint4cmp (int4, int4),
+	FUNCTION	2	ginarrayextract (anyarray, internal, internal),
+	FUNCTION	3	ginint4_queryextract (internal, internal, int2, internal, internal, internal, internal),
+	FUNCTION	4	ginint4_consistent (internal, int2, internal, int4, internal, internal, internal, internal),
+	STORAGE		int4;
diff --git a/contrib/intarray/intarray.control b/contrib/intarray/intarray.control
index 7b3d4f7..8c23e8d 100644
--- a/contrib/intarray/intarray.control
+++ b/contrib/intarray/intarray.control
@@ -1,5 +1,5 @@
 # intarray extension
 comment = 'functions, operators, and index support for 1-D arrays of integers'
-default_version = '1.0'
+default_version = '1.1'
 module_pathname = '$libdir/_int'
 relocatable = true
diff --git a/contrib/intarray/sql/_int.sql b/contrib/intarray/sql/_int.sql
index 216c5c5..f6fe2de 100644
--- a/contrib/intarray/sql/_int.sql
+++ b/contrib/intarray/sql/_int.sql
@@ -68,8 +68,8 @@ SELECT '1&(2&(4&(5|!6)))'::query_int;
 
 
 CREATE TABLE test__int( a int[] );
-
 \copy test__int from 'data/test__int.data'
+ANALYZE test__int;
 
 SELECT count(*) from test__int WHERE a && '{23,50}';
 SELECT count(*) from test__int WHERE a @@ '23|50';
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to