Hello.
Attached patch based on:
http://www.postgresql.org/message-id/capphfdssy+qepdcovxx-b4lp3ybr+qs04m6-arggknfk3fr...@mail.gmail.com
and adds selectivity estimation functions to @@ (port from tsquery). Now we
support &&, @>, <@ and @@.
In addition it was written migration to version 1.1 intarray. Because of what
this patch requires my other patch:
http://www.postgresql.org/message-id/14346041.DNcb5Y1inS@dinodell
Alexander Korotkov know about this patch.
Thanks.
--
Uriy Zhuravlev
Postgres Professional: http://www.postgrespro.com
The Russian Postgres Company
diff --git a/contrib/intarray/Makefile b/contrib/intarray/Makefile
index 920c5b1..16c829c 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.0.sql 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.h b/contrib/intarray/_int.h
index d524f0f..739c3c0 100644
--- a/contrib/intarray/_int.h
+++ b/contrib/intarray/_int.h
@@ -140,6 +140,7 @@ typedef struct QUERYTYPE
#define COMPUTESIZE(size) ( HDRSIZEQT + (size) * sizeof(ITEM) )
#define QUERYTYPEMAXITEMS ((MaxAllocSize - HDRSIZEQT) / sizeof(ITEM))
#define GETQUERY(x) ( (x)->items )
+#define GETRQUERY(x) ( (x)->items + ((x)->size - 1) )
/* "type" codes for ITEM */
#define END 0
diff --git a/contrib/intarray/_int_selfuncs.c b/contrib/intarray/_int_selfuncs.c
new file mode 100644
index 0000000..fd80668
--- /dev/null
+++ b/contrib/intarray/_int_selfuncs.c
@@ -0,0 +1,346 @@
+/*-------------------------------------------------------------------------
+ *
+ * _int_selfuncs.c
+ * Functions for selectivity estimation of intarray operators
+ *
+ * Portions Copyright (c) 1996-2014, 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_contsel);
+PG_FUNCTION_INFO_V1(_int_contjoinsel);
+PG_FUNCTION_INFO_V1(_int_matchsel);
+
+Datum _int_contsel(PG_FUNCTION_ARGS);
+Datum _int_contjoinsel(PG_FUNCTION_ARGS);
+Datum _int_matchsel(PG_FUNCTION_ARGS);
+
+/* lookup table type for binary searching through MCELEMs */
+typedef struct
+{
+ int32 element;
+ float4 frequency;
+} Int4Freq;
+
+
+static Oid transformOperator(Oid oprOid);
+static Selectivity int_querysel(VariableStatData *vardata, Datum constval);
+static Selectivity int_query_opr_selec(ITEM *item, Int4Freq *lookup,
+ int length, float4 minfreq);
+static Selectivity mcelem_int_query_selec(QUERYTYPE *query,
+ Datum *mcelem, int nmcelem,
+ float4 *numbers, int nnumbers);
+
+static int
+compare_val_int4freq(const void *a, const void *b);
+
+#define int_query_opr_selec_no_stats(query) \
+ int_query_opr_selec(GETRQUERY(query), NULL, 0, 0)
+
+
+
+static Oid
+transformOperator(Oid oprOid)
+{
+ HeapTuple tup;
+ Form_pg_operator op;
+ Oid result = InvalidOid;
+
+ tup = SearchSysCache1(OPEROID, ObjectIdGetDatum(oprOid));
+ if (!HeapTupleIsValid(tup))
+ elog(ERROR, "Invalid operator: %u", oprOid);
+
+ op = (Form_pg_operator) GETSTRUCT(tup);
+
+ if (!strcmp(op->oprname.data, "&&"))
+ result = OID_ARRAY_OVERLAP_OP;
+ else if (!strcmp(op->oprname.data, "@>"))
+ result = OID_ARRAY_CONTAINS_OP;
+ else if (!strcmp(op->oprname.data, "<@"))
+ result = OID_ARRAY_CONTAINED_OP;
+
+ ReleaseSysCache(tup);
+
+ if (!OidIsValid(result))
+ elog(ERROR, "Invalid operator: %u", oprOid);
+
+ return result;
+}
+
+/*
+ * _int_contsel -- restriction selectivity for array @>, &&, <@ operators
+ */
+Datum
+_int_contsel(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(DirectFunctionCall4(arraycontsel,
+ PG_GETARG_DATUM(0),
+ ObjectIdGetDatum(transformOperator(PG_GETARG_OID(1))),
+ PG_GETARG_DATUM(2),
+ PG_GETARG_DATUM(3)));
+}
+
+/*
+ * _int_contjoinsel -- join selectivity for array @>, &&, <@ operators
+ */
+Datum
+_int_contjoinsel(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(DirectFunctionCall5(arraycontjoinsel,
+ PG_GETARG_DATUM(0),
+ ObjectIdGetDatum(transformOperator(PG_GETARG_OID(1))),
+ PG_GETARG_DATUM(2),
+ PG_GETARG_DATUM(3),
+ PG_GETARG_DATUM(4)));
+}
+
+
+/*
+ * _int_matchsel -- restriction selectivity function for intarray @@ int_query
+ */
+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;
+ /*
+ * 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);
+ }
+
+ selec = int_querysel(&vardata, ((Const *) other)->constvalue);
+
+ ReleaseVariableStats(vardata);
+
+ CLAMP_PROBABILITY(selec);
+
+ PG_RETURN_FLOAT8((float8) selec);
+}
+
+static Selectivity int_querysel(VariableStatData *vardata, Datum constval) {
+ Selectivity selec;
+ QUERYTYPE *query;
+
+ /* The caller made sure the const is a query, so get it now */
+ query = DatumGetQueryTypeP(constval);
+
+ /* Empty query matches nothing */
+ if (query->size == 0)
+ return (Selectivity) 0.0;
+
+ if (HeapTupleIsValid(vardata->statsTuple))
+ {
+ Form_pg_statistic stats;
+ Datum *values;
+ int nvalues;
+ float4 *numbers;
+ int nnumbers;
+
+ stats = (Form_pg_statistic) GETSTRUCT(vardata->statsTuple);
+
+ /* MCELEM will be an array of INT4 elements for a intarray column */
+ if (get_attstatsslot(vardata->statsTuple,
+ INT4OID, -1,
+ STATISTIC_KIND_MCELEM, InvalidOid,
+ NULL,
+ &values, &nvalues,
+ &numbers, &nnumbers))
+ {
+ /*
+ * There is a most-common-elements slot for the intarray Var, so
+ * use that.
+ */
+ selec = mcelem_int_query_selec(query, values, nvalues,
+ numbers, nnumbers);
+ free_attstatsslot(INT4OID, values, nvalues, numbers, nnumbers);
+ }
+ else
+ {
+ /* No most-common-elements info, so do without */
+ selec = int_query_opr_selec_no_stats(query);
+ }
+ /*
+ * MCE stats count only non-null rows, so adjust for null rows.
+ */
+ selec *= (1.0 - stats->stanullfrac);
+ }
+ else
+ {
+ /* No stats at all, so do without */
+ selec = int_query_opr_selec_no_stats(query);
+ /* we assume no nulls here, so no stanullfrac correction */
+ }
+
+ return selec;
+}
+
+static Selectivity int_query_opr_selec(ITEM *item, Int4Freq *lookup,
+ int length, float4 minfreq)
+{
+ Selectivity selec = 0;
+
+ /* since this function recurses, it could be driven to stack overflow */
+ check_stack_depth();
+ if (item->type == VAL)
+ {
+ Int4Freq *searchres;
+
+ if (lookup == NULL)
+ return (Selectivity) DEFAULT_EQ_SEL;
+
+ searchres = (Int4Freq *) bsearch(&item->val, lookup, length,
+ sizeof(Int4Freq),
+ compare_val_int4freq);
+
+ if (searchres)
+ {
+ /*
+ * The element is in MCELEM. Return precise selectivity (or
+ * at least as precise as ANALYZE could find out).
+ */
+ selec = searchres->frequency;
+ }
+ 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;
+
+ switch (item->val)
+ {
+ case (int32) '!':
+ selec = 1.0 - int_query_opr_selec(item - 1,
+ lookup, length, minfreq);
+ break;
+
+ case (int32) '&':
+ s1 = int_query_opr_selec(item - 1,
+ lookup, length, minfreq);
+ s2 = int_query_opr_selec(item + item->left,
+ lookup, length, minfreq);
+ selec = s1 * s2;
+ break;
+
+ case (int32) '|':
+ s1 = int_query_opr_selec(item - 1,
+ lookup, length, minfreq);
+ s2 = int_query_opr_selec(item + item->left,
+ lookup, length, minfreq);
+ selec = s1 + s2 - s1 * s2;
+ break;
+
+ default:
+ elog(ERROR, "unrecognized operator: %d", item->val);
+ selec = 0; /* keep compiler quiet */
+ break;
+ }
+ }
+
+ /* Clamp intermediate results to stay sane despite roundoff error */
+ CLAMP_PROBABILITY(selec);
+
+ return selec;
+}
+
+/*
+ * Extract data from the pg_statistic arrays into useful format.
+ */
+static Selectivity
+mcelem_int_query_selec(QUERYTYPE *query, Datum *mcelem, int nmcelem,
+ float4 *numbers, int nnumbers)
+{
+ float4 minfreq;
+ Int4Freq *lookup;
+ Selectivity selec;
+ int i;
+
+ /*
+ * There should be two more Numbers than Values, because the last 3 (for intarray)
+ * cells are taken for minimal, maximal and nulls frequency. Punt if not.
+ *
+ */
+ if (nnumbers < nmcelem + 2)
+ return int_query_opr_selec_no_stats(query);
+
+ /*
+ * Transpose the data into a single array so we can use bsearch().
+ */
+ lookup = (Int4Freq *) palloc(sizeof(Int4Freq) * nmcelem);
+ for (i = 0; i < nmcelem; i++)
+ {
+ lookup[i].element = DatumGetInt32(mcelem[i]);
+ lookup[i].frequency = numbers[i];
+ }
+
+ /*
+ * Grab the lowest frequency.
+ */
+ minfreq = numbers[nnumbers - (nnumbers-nmcelem)];
+ selec = int_query_opr_selec(GETRQUERY(query), lookup,
+ nmcelem, minfreq);
+
+ pfree(lookup);
+
+ return selec;
+}
+
+static int
+compare_val_int4freq(const void *a, const void *b)
+{
+ int32 key = *(int32 *) a;
+ const Int4Freq *t = (const Int4Freq *) b;
+ return key - t->element;
+}
\ No newline at end of file
diff --git a/contrib/intarray/intarray--1.0--1.1.sql b/contrib/intarray/intarray--1.0--1.1.sql
new file mode 100644
index 0000000..018dfd4
--- /dev/null
+++ b/contrib/intarray/intarray--1.0--1.1.sql
@@ -0,0 +1,25 @@
+/* contrib/intarray/intarray--1.0--1.1.sql */
+
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "ALTER EXTENSION intarray UPDATE TO '1.1'" to load this file. \quit
+
+CREATE FUNCTION _int_matchsel(internal, oid, internal, integer)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT STABLE;
+
+ALTER OPERATOR @@ (_int4, query_int) SET (RESTRICT = _int_matchsel);
+
+CREATE FUNCTION _int_contsel(internal, oid, internal, integer)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT STABLE;
+
+CREATE FUNCTION _int_contjoinsel(internal, oid, internal, smallint, internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT STABLE;
+
+ALTER OPERATOR && (_int4, _int4) SET (RESTRICT = _int_contsel, JOIN = _int_contjoinsel);
+ALTER OPERATOR @> (_int4, _int4) SET (RESTRICT = _int_contsel, JOIN = _int_contjoinsel);
+ALTER OPERATOR <@ (_int4, _int4) SET (RESTRICT = _int_contsel, JOIN = _int_contjoinsel);
\ No newline at end of file
diff --git a/contrib/intarray/intarray--1.1.sql b/contrib/intarray/intarray--1.1.sql
new file mode 100644
index 0000000..5d4fa39
--- /dev/null
+++ b/contrib/intarray/intarray--1.1.sql
@@ -0,0 +1,500 @@
+/* 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 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 = 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;
+
+CREATE FUNCTION _int_contsel(internal, oid, internal, integer)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT STABLE;
+
+CREATE FUNCTION _int_contjoinsel(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_contsel,
+ JOIN = _int_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 = _int_contsel,
+ JOIN = _int_contjoinsel
+);
+
+CREATE OPERATOR <@ (
+ LEFTARG = _int4,
+ RIGHTARG = _int4,
+ PROCEDURE = _int_contained,
+ COMMUTATOR = '@>',
+ RESTRICT = _int_contsel,
+ JOIN = _int_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.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
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers