btree_gin and btree_gist for enums

Started by Andrew Dunstanalmost 10 years ago39 messages
#1Andrew Dunstan
andrew@dunslane.net
1 attachment(s)

Here is a patch to add enum support to btree_gin and btree_gist. I
didn't include distance operations, as I didn't think it terribly
important, and there isn't a simple way to compute it sanely and
efficiently, so no KNN support.

cheers

andrew

Attachments:

enum-btree-gist-gin.patchtext/x-patch; name=enum-btree-gist-gin.patchDownload
diff --git a/contrib/btree_gin/Makefile b/contrib/btree_gin/Makefile
index 0492091..f8a2d7f 100644
--- a/contrib/btree_gin/Makefile
+++ b/contrib/btree_gin/Makefile
@@ -4,13 +4,13 @@ MODULE_big = btree_gin
 OBJS = btree_gin.o $(WIN32RES)
 
 EXTENSION = btree_gin
-DATA = btree_gin--1.0.sql btree_gin--unpackaged--1.0.sql
+DATA = btree_gin--1.1.sql btree_gin--unpackaged--1.0.sql btree_gin--1.0--1.1.sql
 PGFILEDESC = "btree_gin - B-tree equivalent GIN operator classes"
 
 REGRESS = install_btree_gin int2 int4 int8 float4 float8 money oid \
 	timestamp timestamptz time timetz date interval \
 	macaddr inet cidr text varchar char bytea bit varbit \
-	numeric
+	numeric enum
 
 ifdef USE_PGXS
 PG_CONFIG = pg_config
diff --git a/contrib/btree_gin/btree_gin--1.0--1.1.sql b/contrib/btree_gin/btree_gin--1.0--1.1.sql
new file mode 100644
index 0000000..0c90bbb
--- /dev/null
+++ b/contrib/btree_gin/btree_gin--1.0--1.1.sql
@@ -0,0 +1,47 @@
+/* contrib/btree_gin/btree_gin--1.0--1.1.sql */
+
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "ALTER EXTENSION btree_gin UPDATE TO '1.1'" to load this file. \quit
+
+--
+--
+--
+-- enum ops
+--
+--
+
+
+CREATE FUNCTION gin_extract_value_anyenum(anyenum, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_anyenum(anyenum, anyenum, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_anyenum(anyenum, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_enum_cmp(anyenum, anyenum)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS enum_ops
+DEFAULT FOR TYPE anyenum USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       gin_enum_cmp(anyenum,anyenum),
+    FUNCTION        2       gin_extract_value_anyenum(anyenum, internal),
+    FUNCTION        3       gin_extract_query_anyenum(anyenum, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_anyenum(anyenum,anyenum,int2, internal),
+STORAGE         oid;
diff --git a/contrib/btree_gin/btree_gin--1.0.sql b/contrib/btree_gin/btree_gin--1.0.sql
deleted file mode 100644
index cf867ef..0000000
--- a/contrib/btree_gin/btree_gin--1.0.sql
+++ /dev/null
@@ -1,689 +0,0 @@
-/* contrib/btree_gin/btree_gin--1.0.sql */
-
--- complain if script is sourced in psql, rather than via CREATE EXTENSION
-\echo Use "CREATE EXTENSION btree_gin" to load this file. \quit
-
-CREATE FUNCTION gin_btree_consistent(internal, int2, anyelement, int4, internal, internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_value_int2(int2, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_int2(int2, int2, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_int2(int2, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS int2_ops
-DEFAULT FOR TYPE int2 USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       btint2cmp(int2,int2),
-    FUNCTION        2       gin_extract_value_int2(int2, internal),
-    FUNCTION        3       gin_extract_query_int2(int2, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_int2(int2,int2,int2, internal),
-STORAGE         int2;
-
-CREATE FUNCTION gin_extract_value_int4(int4, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_int4(int4, int4, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_int4(int4, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS int4_ops
-DEFAULT FOR TYPE int4 USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       btint4cmp(int4,int4),
-    FUNCTION        2       gin_extract_value_int4(int4, internal),
-    FUNCTION        3       gin_extract_query_int4(int4, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_int4(int4,int4,int2, internal),
-STORAGE         int4;
-
-CREATE FUNCTION gin_extract_value_int8(int8, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_int8(int8, int8, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_int8(int8, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS int8_ops
-DEFAULT FOR TYPE int8 USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       btint8cmp(int8,int8),
-    FUNCTION        2       gin_extract_value_int8(int8, internal),
-    FUNCTION        3       gin_extract_query_int8(int8, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_int8(int8,int8,int2, internal),
-STORAGE         int8;
-
-CREATE FUNCTION gin_extract_value_float4(float4, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_float4(float4, float4, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_float4(float4, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS float4_ops
-DEFAULT FOR TYPE float4 USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       btfloat4cmp(float4,float4),
-    FUNCTION        2       gin_extract_value_float4(float4, internal),
-    FUNCTION        3       gin_extract_query_float4(float4, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_float4(float4,float4,int2, internal),
-STORAGE         float4;
-
-CREATE FUNCTION gin_extract_value_float8(float8, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_float8(float8, float8, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_float8(float8, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS float8_ops
-DEFAULT FOR TYPE float8 USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       btfloat8cmp(float8,float8),
-    FUNCTION        2       gin_extract_value_float8(float8, internal),
-    FUNCTION        3       gin_extract_query_float8(float8, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_float8(float8,float8,int2, internal),
-STORAGE         float8;
-
-CREATE FUNCTION gin_extract_value_money(money, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_money(money, money, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_money(money, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS money_ops
-DEFAULT FOR TYPE money USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       cash_cmp(money,money),
-    FUNCTION        2       gin_extract_value_money(money, internal),
-    FUNCTION        3       gin_extract_query_money(money, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_money(money,money,int2, internal),
-STORAGE         money;
-
-CREATE FUNCTION gin_extract_value_oid(oid, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_oid(oid, oid, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_oid(oid, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS oid_ops
-DEFAULT FOR TYPE oid USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       btoidcmp(oid,oid),
-    FUNCTION        2       gin_extract_value_oid(oid, internal),
-    FUNCTION        3       gin_extract_query_oid(oid, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_oid(oid,oid,int2, internal),
-STORAGE         oid;
-
-CREATE FUNCTION gin_extract_value_timestamp(timestamp, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_timestamp(timestamp, timestamp, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_timestamp(timestamp, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS timestamp_ops
-DEFAULT FOR TYPE timestamp USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       timestamp_cmp(timestamp,timestamp),
-    FUNCTION        2       gin_extract_value_timestamp(timestamp, internal),
-    FUNCTION        3       gin_extract_query_timestamp(timestamp, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_timestamp(timestamp,timestamp,int2, internal),
-STORAGE         timestamp;
-
-CREATE FUNCTION gin_extract_value_timestamptz(timestamptz, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_timestamptz(timestamptz, timestamptz, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_timestamptz(timestamptz, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS timestamptz_ops
-DEFAULT FOR TYPE timestamptz USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       timestamptz_cmp(timestamptz,timestamptz),
-    FUNCTION        2       gin_extract_value_timestamptz(timestamptz, internal),
-    FUNCTION        3       gin_extract_query_timestamptz(timestamptz, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_timestamptz(timestamptz,timestamptz,int2, internal),
-STORAGE         timestamptz;
-
-CREATE FUNCTION gin_extract_value_time(time, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_time(time, time, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_time(time, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS time_ops
-DEFAULT FOR TYPE time USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       time_cmp(time,time),
-    FUNCTION        2       gin_extract_value_time(time, internal),
-    FUNCTION        3       gin_extract_query_time(time, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_time(time,time,int2, internal),
-STORAGE         time;
-
-CREATE FUNCTION gin_extract_value_timetz(timetz, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_timetz(timetz, timetz, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_timetz(timetz, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS timetz_ops
-DEFAULT FOR TYPE timetz USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       timetz_cmp(timetz,timetz),
-    FUNCTION        2       gin_extract_value_timetz(timetz, internal),
-    FUNCTION        3       gin_extract_query_timetz(timetz, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_timetz(timetz,timetz,int2, internal),
-STORAGE         timetz;
-
-CREATE FUNCTION gin_extract_value_date(date, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_date(date, date, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_date(date, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS date_ops
-DEFAULT FOR TYPE date USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       date_cmp(date,date),
-    FUNCTION        2       gin_extract_value_date(date, internal),
-    FUNCTION        3       gin_extract_query_date(date, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_date(date,date,int2, internal),
-STORAGE         date;
-
-CREATE FUNCTION gin_extract_value_interval(interval, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_interval(interval, interval, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_interval(interval, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS interval_ops
-DEFAULT FOR TYPE interval USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       interval_cmp(interval,interval),
-    FUNCTION        2       gin_extract_value_interval(interval, internal),
-    FUNCTION        3       gin_extract_query_interval(interval, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_interval(interval,interval,int2, internal),
-STORAGE         interval;
-
-CREATE FUNCTION gin_extract_value_macaddr(macaddr, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_macaddr(macaddr, macaddr, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_macaddr(macaddr, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS macaddr_ops
-DEFAULT FOR TYPE macaddr USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       macaddr_cmp(macaddr,macaddr),
-    FUNCTION        2       gin_extract_value_macaddr(macaddr, internal),
-    FUNCTION        3       gin_extract_query_macaddr(macaddr, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_macaddr(macaddr,macaddr,int2, internal),
-STORAGE         macaddr;
-
-CREATE FUNCTION gin_extract_value_inet(inet, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_inet(inet, inet, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_inet(inet, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS inet_ops
-DEFAULT FOR TYPE inet USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       network_cmp(inet,inet),
-    FUNCTION        2       gin_extract_value_inet(inet, internal),
-    FUNCTION        3       gin_extract_query_inet(inet, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_inet(inet,inet,int2, internal),
-STORAGE         inet;
-
-CREATE FUNCTION gin_extract_value_cidr(cidr, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_cidr(cidr, cidr, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_cidr(cidr, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS cidr_ops
-DEFAULT FOR TYPE cidr USING gin
-AS
-    OPERATOR        1       <(inet,inet),
-    OPERATOR        2       <=(inet,inet),
-    OPERATOR        3       =(inet,inet),
-    OPERATOR        4       >=(inet,inet),
-    OPERATOR        5       >(inet,inet),
-    FUNCTION        1       network_cmp(inet,inet),
-    FUNCTION        2       gin_extract_value_cidr(cidr, internal),
-    FUNCTION        3       gin_extract_query_cidr(cidr, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_cidr(cidr,cidr,int2, internal),
-STORAGE         cidr;
-
-CREATE FUNCTION gin_extract_value_text(text, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_text(text, text, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_text(text, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS text_ops
-DEFAULT FOR TYPE text USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       bttextcmp(text,text),
-    FUNCTION        2       gin_extract_value_text(text, internal),
-    FUNCTION        3       gin_extract_query_text(text, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_text(text,text,int2, internal),
-STORAGE         text;
-
-CREATE OPERATOR CLASS varchar_ops
-DEFAULT FOR TYPE varchar USING gin
-AS
-    OPERATOR        1       <(text,text),
-    OPERATOR        2       <=(text,text),
-    OPERATOR        3       =(text,text),
-    OPERATOR        4       >=(text,text),
-    OPERATOR        5       >(text,text),
-    FUNCTION        1       bttextcmp(text,text),
-    FUNCTION        2       gin_extract_value_text(text, internal),
-    FUNCTION        3       gin_extract_query_text(text, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_text(text,text,int2, internal),
-STORAGE         varchar;
-
-CREATE FUNCTION gin_extract_value_char("char", internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_char("char", "char", int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_char("char", internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS char_ops
-DEFAULT FOR TYPE "char" USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       btcharcmp("char","char"),
-    FUNCTION        2       gin_extract_value_char("char", internal),
-    FUNCTION        3       gin_extract_query_char("char", internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_char("char","char",int2, internal),
-STORAGE         "char";
-
-CREATE FUNCTION gin_extract_value_bytea(bytea, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_bytea(bytea, bytea, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_bytea(bytea, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS bytea_ops
-DEFAULT FOR TYPE bytea USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       byteacmp(bytea,bytea),
-    FUNCTION        2       gin_extract_value_bytea(bytea, internal),
-    FUNCTION        3       gin_extract_query_bytea(bytea, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_bytea(bytea,bytea,int2, internal),
-STORAGE         bytea;
-
-CREATE FUNCTION gin_extract_value_bit(bit, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_bit(bit, bit, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_bit(bit, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS bit_ops
-DEFAULT FOR TYPE bit USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       bitcmp(bit,bit),
-    FUNCTION        2       gin_extract_value_bit(bit, internal),
-    FUNCTION        3       gin_extract_query_bit(bit, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_bit(bit,bit,int2, internal),
-STORAGE         bit;
-
-CREATE FUNCTION gin_extract_value_varbit(varbit, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_varbit(varbit, varbit, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_varbit(varbit, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS varbit_ops
-DEFAULT FOR TYPE varbit USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       varbitcmp(varbit,varbit),
-    FUNCTION        2       gin_extract_value_varbit(varbit, internal),
-    FUNCTION        3       gin_extract_query_varbit(varbit, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_varbit(varbit,varbit,int2, internal),
-STORAGE         varbit;
-
-CREATE FUNCTION gin_extract_value_numeric(numeric, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_numeric(numeric, numeric, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_numeric(numeric, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_numeric_cmp(numeric, numeric)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS numeric_ops
-DEFAULT FOR TYPE numeric USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       gin_numeric_cmp(numeric,numeric),
-    FUNCTION        2       gin_extract_value_numeric(numeric, internal),
-    FUNCTION        3       gin_extract_query_numeric(numeric, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_numeric(numeric,numeric,int2, internal),
-STORAGE         numeric;
diff --git a/contrib/btree_gin/btree_gin--1.1.sql b/contrib/btree_gin/btree_gin--1.1.sql
new file mode 100644
index 0000000..f117e4a
--- /dev/null
+++ b/contrib/btree_gin/btree_gin--1.1.sql
@@ -0,0 +1,724 @@
+/* contrib/btree_gin/btree_gin--1.0.sql */
+
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "CREATE EXTENSION btree_gin" to load this file. \quit
+
+CREATE FUNCTION gin_btree_consistent(internal, int2, anyelement, int4, internal, internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_value_int2(int2, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_int2(int2, int2, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_int2(int2, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS int2_ops
+DEFAULT FOR TYPE int2 USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       btint2cmp(int2,int2),
+    FUNCTION        2       gin_extract_value_int2(int2, internal),
+    FUNCTION        3       gin_extract_query_int2(int2, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_int2(int2,int2,int2, internal),
+STORAGE         int2;
+
+CREATE FUNCTION gin_extract_value_int4(int4, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_int4(int4, int4, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_int4(int4, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS int4_ops
+DEFAULT FOR TYPE int4 USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       btint4cmp(int4,int4),
+    FUNCTION        2       gin_extract_value_int4(int4, internal),
+    FUNCTION        3       gin_extract_query_int4(int4, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_int4(int4,int4,int2, internal),
+STORAGE         int4;
+
+CREATE FUNCTION gin_extract_value_int8(int8, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_int8(int8, int8, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_int8(int8, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS int8_ops
+DEFAULT FOR TYPE int8 USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       btint8cmp(int8,int8),
+    FUNCTION        2       gin_extract_value_int8(int8, internal),
+    FUNCTION        3       gin_extract_query_int8(int8, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_int8(int8,int8,int2, internal),
+STORAGE         int8;
+
+CREATE FUNCTION gin_extract_value_float4(float4, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_float4(float4, float4, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_float4(float4, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS float4_ops
+DEFAULT FOR TYPE float4 USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       btfloat4cmp(float4,float4),
+    FUNCTION        2       gin_extract_value_float4(float4, internal),
+    FUNCTION        3       gin_extract_query_float4(float4, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_float4(float4,float4,int2, internal),
+STORAGE         float4;
+
+CREATE FUNCTION gin_extract_value_float8(float8, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_float8(float8, float8, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_float8(float8, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS float8_ops
+DEFAULT FOR TYPE float8 USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       btfloat8cmp(float8,float8),
+    FUNCTION        2       gin_extract_value_float8(float8, internal),
+    FUNCTION        3       gin_extract_query_float8(float8, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_float8(float8,float8,int2, internal),
+STORAGE         float8;
+
+CREATE FUNCTION gin_extract_value_money(money, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_money(money, money, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_money(money, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS money_ops
+DEFAULT FOR TYPE money USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       cash_cmp(money,money),
+    FUNCTION        2       gin_extract_value_money(money, internal),
+    FUNCTION        3       gin_extract_query_money(money, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_money(money,money,int2, internal),
+STORAGE         money;
+
+CREATE FUNCTION gin_extract_value_oid(oid, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_oid(oid, oid, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_oid(oid, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS oid_ops
+DEFAULT FOR TYPE oid USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       btoidcmp(oid,oid),
+    FUNCTION        2       gin_extract_value_oid(oid, internal),
+    FUNCTION        3       gin_extract_query_oid(oid, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_oid(oid,oid,int2, internal),
+STORAGE         oid;
+
+CREATE FUNCTION gin_extract_value_timestamp(timestamp, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_timestamp(timestamp, timestamp, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_timestamp(timestamp, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS timestamp_ops
+DEFAULT FOR TYPE timestamp USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       timestamp_cmp(timestamp,timestamp),
+    FUNCTION        2       gin_extract_value_timestamp(timestamp, internal),
+    FUNCTION        3       gin_extract_query_timestamp(timestamp, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_timestamp(timestamp,timestamp,int2, internal),
+STORAGE         timestamp;
+
+CREATE FUNCTION gin_extract_value_timestamptz(timestamptz, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_timestamptz(timestamptz, timestamptz, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_timestamptz(timestamptz, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS timestamptz_ops
+DEFAULT FOR TYPE timestamptz USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       timestamptz_cmp(timestamptz,timestamptz),
+    FUNCTION        2       gin_extract_value_timestamptz(timestamptz, internal),
+    FUNCTION        3       gin_extract_query_timestamptz(timestamptz, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_timestamptz(timestamptz,timestamptz,int2, internal),
+STORAGE         timestamptz;
+
+CREATE FUNCTION gin_extract_value_time(time, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_time(time, time, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_time(time, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS time_ops
+DEFAULT FOR TYPE time USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       time_cmp(time,time),
+    FUNCTION        2       gin_extract_value_time(time, internal),
+    FUNCTION        3       gin_extract_query_time(time, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_time(time,time,int2, internal),
+STORAGE         time;
+
+CREATE FUNCTION gin_extract_value_timetz(timetz, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_timetz(timetz, timetz, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_timetz(timetz, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS timetz_ops
+DEFAULT FOR TYPE timetz USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       timetz_cmp(timetz,timetz),
+    FUNCTION        2       gin_extract_value_timetz(timetz, internal),
+    FUNCTION        3       gin_extract_query_timetz(timetz, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_timetz(timetz,timetz,int2, internal),
+STORAGE         timetz;
+
+CREATE FUNCTION gin_extract_value_date(date, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_date(date, date, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_date(date, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS date_ops
+DEFAULT FOR TYPE date USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       date_cmp(date,date),
+    FUNCTION        2       gin_extract_value_date(date, internal),
+    FUNCTION        3       gin_extract_query_date(date, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_date(date,date,int2, internal),
+STORAGE         date;
+
+CREATE FUNCTION gin_extract_value_interval(interval, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_interval(interval, interval, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_interval(interval, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS interval_ops
+DEFAULT FOR TYPE interval USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       interval_cmp(interval,interval),
+    FUNCTION        2       gin_extract_value_interval(interval, internal),
+    FUNCTION        3       gin_extract_query_interval(interval, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_interval(interval,interval,int2, internal),
+STORAGE         interval;
+
+CREATE FUNCTION gin_extract_value_macaddr(macaddr, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_macaddr(macaddr, macaddr, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_macaddr(macaddr, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS macaddr_ops
+DEFAULT FOR TYPE macaddr USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       macaddr_cmp(macaddr,macaddr),
+    FUNCTION        2       gin_extract_value_macaddr(macaddr, internal),
+    FUNCTION        3       gin_extract_query_macaddr(macaddr, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_macaddr(macaddr,macaddr,int2, internal),
+STORAGE         macaddr;
+
+CREATE FUNCTION gin_extract_value_inet(inet, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_inet(inet, inet, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_inet(inet, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS inet_ops
+DEFAULT FOR TYPE inet USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       network_cmp(inet,inet),
+    FUNCTION        2       gin_extract_value_inet(inet, internal),
+    FUNCTION        3       gin_extract_query_inet(inet, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_inet(inet,inet,int2, internal),
+STORAGE         inet;
+
+CREATE FUNCTION gin_extract_value_cidr(cidr, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_cidr(cidr, cidr, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_cidr(cidr, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS cidr_ops
+DEFAULT FOR TYPE cidr USING gin
+AS
+    OPERATOR        1       <(inet,inet),
+    OPERATOR        2       <=(inet,inet),
+    OPERATOR        3       =(inet,inet),
+    OPERATOR        4       >=(inet,inet),
+    OPERATOR        5       >(inet,inet),
+    FUNCTION        1       network_cmp(inet,inet),
+    FUNCTION        2       gin_extract_value_cidr(cidr, internal),
+    FUNCTION        3       gin_extract_query_cidr(cidr, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_cidr(cidr,cidr,int2, internal),
+STORAGE         cidr;
+
+CREATE FUNCTION gin_extract_value_text(text, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_text(text, text, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_text(text, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS text_ops
+DEFAULT FOR TYPE text USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       bttextcmp(text,text),
+    FUNCTION        2       gin_extract_value_text(text, internal),
+    FUNCTION        3       gin_extract_query_text(text, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_text(text,text,int2, internal),
+STORAGE         text;
+
+CREATE OPERATOR CLASS varchar_ops
+DEFAULT FOR TYPE varchar USING gin
+AS
+    OPERATOR        1       <(text,text),
+    OPERATOR        2       <=(text,text),
+    OPERATOR        3       =(text,text),
+    OPERATOR        4       >=(text,text),
+    OPERATOR        5       >(text,text),
+    FUNCTION        1       bttextcmp(text,text),
+    FUNCTION        2       gin_extract_value_text(text, internal),
+    FUNCTION        3       gin_extract_query_text(text, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_text(text,text,int2, internal),
+STORAGE         varchar;
+
+CREATE FUNCTION gin_extract_value_char("char", internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_char("char", "char", int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_char("char", internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS char_ops
+DEFAULT FOR TYPE "char" USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       btcharcmp("char","char"),
+    FUNCTION        2       gin_extract_value_char("char", internal),
+    FUNCTION        3       gin_extract_query_char("char", internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_char("char","char",int2, internal),
+STORAGE         "char";
+
+CREATE FUNCTION gin_extract_value_bytea(bytea, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_bytea(bytea, bytea, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_bytea(bytea, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS bytea_ops
+DEFAULT FOR TYPE bytea USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       byteacmp(bytea,bytea),
+    FUNCTION        2       gin_extract_value_bytea(bytea, internal),
+    FUNCTION        3       gin_extract_query_bytea(bytea, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_bytea(bytea,bytea,int2, internal),
+STORAGE         bytea;
+
+CREATE FUNCTION gin_extract_value_bit(bit, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_bit(bit, bit, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_bit(bit, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS bit_ops
+DEFAULT FOR TYPE bit USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       bitcmp(bit,bit),
+    FUNCTION        2       gin_extract_value_bit(bit, internal),
+    FUNCTION        3       gin_extract_query_bit(bit, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_bit(bit,bit,int2, internal),
+STORAGE         bit;
+
+CREATE FUNCTION gin_extract_value_varbit(varbit, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_varbit(varbit, varbit, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_varbit(varbit, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS varbit_ops
+DEFAULT FOR TYPE varbit USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       varbitcmp(varbit,varbit),
+    FUNCTION        2       gin_extract_value_varbit(varbit, internal),
+    FUNCTION        3       gin_extract_query_varbit(varbit, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_varbit(varbit,varbit,int2, internal),
+STORAGE         varbit;
+
+CREATE FUNCTION gin_extract_value_numeric(numeric, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_numeric(numeric, numeric, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_numeric(numeric, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_numeric_cmp(numeric, numeric)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS numeric_ops
+DEFAULT FOR TYPE numeric USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       gin_numeric_cmp(numeric,numeric),
+    FUNCTION        2       gin_extract_value_numeric(numeric, internal),
+    FUNCTION        3       gin_extract_query_numeric(numeric, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_numeric(numeric,numeric,int2, internal),
+STORAGE         numeric;
+
+CREATE FUNCTION gin_extract_value_anyenum(anyenum, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_anyenum(anyenum, anyenum, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_anyenum(anyenum, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_enum_cmp(anyenum, anyenum)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS enum_ops
+DEFAULT FOR TYPE anyenum USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       gin_enum_cmp(anyenum,anyenum),
+    FUNCTION        2       gin_extract_value_anyenum(anyenum, internal),
+    FUNCTION        3       gin_extract_query_anyenum(anyenum, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_anyenum(anyenum,anyenum,int2, internal),
+STORAGE         oid;
diff --git a/contrib/btree_gin/btree_gin.c b/contrib/btree_gin/btree_gin.c
index f74e912..0ea3d70 100644
--- a/contrib/btree_gin/btree_gin.c
+++ b/contrib/btree_gin/btree_gin.c
@@ -422,3 +422,47 @@ leftmostvalue_numeric(void)
 }
 
 GIN_SUPPORT(numeric, true, leftmostvalue_numeric, gin_numeric_cmp)
+
+/*
+ * Use a similar trick to that used for numeric for enums, since we don't
+ * actually know the leftmost value of any enum without knowing the concrete
+ * type, so we use a dummy leftmost value of InvalidOid.
+ */
+
+
+#define ENUM_IS_LEFTMOST(x)	((x) == InvalidOid)
+
+PG_FUNCTION_INFO_V1(gin_enum_cmp);
+
+Datum
+gin_enum_cmp(PG_FUNCTION_ARGS)
+{
+	Oid		a = PG_GETARG_OID(0);
+	Oid		b = PG_GETARG_OID(1);
+	int		res = 0;
+
+	if (ENUM_IS_LEFTMOST(a))
+	{
+		res = (ENUM_IS_LEFTMOST(b)) ? 0 : -1;
+	}
+	else if (ENUM_IS_LEFTMOST(b))
+	{
+		res = 1;
+	}
+	else
+	{
+		res = DatumGetInt32(DirectFunctionCall2(enum_cmp,
+												ObjectIdGetDatum(a),
+												ObjectIdGetDatum(b)));
+	}
+
+	PG_RETURN_INT32(res);
+}
+
+static Datum
+leftmostvalue_enum(void)
+{
+	return ObjectIdGetDatum(InvalidOid);
+}
+
+GIN_SUPPORT(anyenum, false, leftmostvalue_enum, gin_enum_cmp)
diff --git a/contrib/btree_gin/btree_gin.control b/contrib/btree_gin/btree_gin.control
index 3b2cb2d..d96436e 100644
--- a/contrib/btree_gin/btree_gin.control
+++ b/contrib/btree_gin/btree_gin.control
@@ -1,5 +1,5 @@
 # btree_gin extension
 comment = 'support for indexing common datatypes in GIN'
-default_version = '1.0'
+default_version = '1.1'
 module_pathname = '$libdir/btree_gin'
 relocatable = true
diff --git a/contrib/btree_gin/expected/enum.out b/contrib/btree_gin/expected/enum.out
new file mode 100644
index 0000000..4e02b2d
--- /dev/null
+++ b/contrib/btree_gin/expected/enum.out
@@ -0,0 +1,58 @@
+set enable_seqscan=off;
+CREATE TYPE rainbow AS ENUM ('r','o','y','g','b','i','v');
+CREATE TABLE test_enum (
+	i rainbow
+);
+INSERT INTO test_enum VALUES ('v'),('y'),('r'),('g'),('o'),('i'),('b');
+CREATE INDEX idx_enum ON test_enum USING gin (i);
+SELECT * FROM test_enum WHERE i<'g'::rainbow ORDER BY i;
+ i 
+---
+ r
+ o
+ y
+(3 rows)
+
+SELECT * FROM test_enum WHERE i<='g'::rainbow ORDER BY i;
+ i 
+---
+ r
+ o
+ y
+ g
+(4 rows)
+
+SELECT * FROM test_enum WHERE i='g'::rainbow ORDER BY i;
+ i 
+---
+ g
+(1 row)
+
+SELECT * FROM test_enum WHERE i>='g'::rainbow ORDER BY i;
+ i 
+---
+ g
+ b
+ i
+ v
+(4 rows)
+
+SELECT * FROM test_enum WHERE i>'g'::rainbow ORDER BY i;
+ i 
+---
+ b
+ i
+ v
+(3 rows)
+
+explain (costs off) SELECT * FROM test_enum WHERE i>='g'::rainbow ORDER BY i;
+                  QUERY PLAN                   
+-----------------------------------------------
+ Sort
+   Sort Key: i
+   ->  Bitmap Heap Scan on test_enum
+         Recheck Cond: (i >= 'g'::rainbow)
+         ->  Bitmap Index Scan on idx_enum
+               Index Cond: (i >= 'g'::rainbow)
+(6 rows)
+
diff --git a/contrib/btree_gin/sql/enum.sql b/contrib/btree_gin/sql/enum.sql
new file mode 100644
index 0000000..9ee8f4c
--- /dev/null
+++ b/contrib/btree_gin/sql/enum.sql
@@ -0,0 +1,19 @@
+set enable_seqscan=off;
+
+CREATE TYPE rainbow AS ENUM ('r','o','y','g','b','i','v');
+
+CREATE TABLE test_enum (
+	i rainbow
+);
+
+INSERT INTO test_enum VALUES ('v'),('y'),('r'),('g'),('o'),('i'),('b');
+
+CREATE INDEX idx_enum ON test_enum USING gin (i);
+
+SELECT * FROM test_enum WHERE i<'g'::rainbow ORDER BY i;
+SELECT * FROM test_enum WHERE i<='g'::rainbow ORDER BY i;
+SELECT * FROM test_enum WHERE i='g'::rainbow ORDER BY i;
+SELECT * FROM test_enum WHERE i>='g'::rainbow ORDER BY i;
+SELECT * FROM test_enum WHERE i>'g'::rainbow ORDER BY i;
+
+explain (costs off) SELECT * FROM test_enum WHERE i>='g'::rainbow ORDER BY i;
diff --git a/contrib/btree_gist/Makefile b/contrib/btree_gist/Makefile
index a4b2cc7..ec38c4f 100644
--- a/contrib/btree_gist/Makefile
+++ b/contrib/btree_gist/Makefile
@@ -6,16 +6,16 @@ OBJS =  btree_gist.o btree_utils_num.o btree_utils_var.o btree_int2.o \
         btree_int4.o btree_int8.o btree_float4.o btree_float8.o btree_cash.o \
         btree_oid.o btree_ts.o btree_time.o btree_date.o btree_interval.o \
         btree_macaddr.o btree_inet.o btree_text.o btree_bytea.o btree_bit.o \
-        btree_numeric.o $(WIN32RES)
+        btree_numeric.o btree_enum.o $(WIN32RES)
 
 EXTENSION = btree_gist
-DATA = btree_gist--1.1.sql btree_gist--unpackaged--1.0.sql \
-	btree_gist--1.0--1.1.sql
+DATA = btree_gist--1.2.sql btree_gist--unpackaged--1.0.sql \
+	btree_gist--1.0--1.1.sql btree_gist--1.1--1.2.sql
 PGFILEDESC = "btree_gist - B-tree equivalent GiST operator classes"
 
 REGRESS = init int2 int4 int8 float4 float8 cash oid timestamp timestamptz \
         time timetz date interval macaddr inet cidr text varchar char bytea \
-        bit varbit numeric not_equal
+        bit varbit numeric enum not_equal
 
 SHLIB_LINK += $(filter -lm, $(LIBS))
 
diff --git a/contrib/btree_gist/btree_enum.c b/contrib/btree_gist/btree_enum.c
new file mode 100644
index 0000000..6126962
--- /dev/null
+++ b/contrib/btree_gist/btree_enum.c
@@ -0,0 +1,186 @@
+/*
+ * contrib/btree_gist/btree_enum.c
+ */
+#include "postgres.h"
+#include "utils/builtins.h"
+
+#include "btree_gist.h"
+#include "btree_utils_num.h"
+
+/* enums are really Oids, so we just use the same structure */
+
+typedef struct
+{
+	Oid			lower;
+	Oid			upper;
+} oidKEY;
+
+/*
+** enum ops
+*/
+PG_FUNCTION_INFO_V1(gbt_enum_compress);
+PG_FUNCTION_INFO_V1(gbt_enum_fetch);
+PG_FUNCTION_INFO_V1(gbt_enum_union);
+PG_FUNCTION_INFO_V1(gbt_enum_picksplit);
+PG_FUNCTION_INFO_V1(gbt_enum_consistent);
+PG_FUNCTION_INFO_V1(gbt_enum_penalty);
+PG_FUNCTION_INFO_V1(gbt_enum_same);
+
+
+static bool
+gbt_enumgt(const void *a, const void *b)
+{
+	return DatumGetBool(
+						DirectFunctionCall2(enum_gt, ObjectIdGetDatum(*((const Oid *) a)), ObjectIdGetDatum(*((const Oid *) b)))
+		);
+}
+static bool
+gbt_enumge(const void *a, const void *b)
+{
+	return DatumGetBool(
+						DirectFunctionCall2(enum_ge, ObjectIdGetDatum(*((const Oid *) a)), ObjectIdGetDatum(*((const Oid *) b)))
+		);
+}
+static bool
+gbt_enumeq(const void *a, const void *b)
+{
+	return (*((const Oid *) a) == *((const Oid *) b));
+}
+static bool
+gbt_enumle(const void *a, const void *b)
+{
+	return DatumGetBool(
+						DirectFunctionCall2(enum_le, ObjectIdGetDatum(*((const Oid *) a)), ObjectIdGetDatum(*((const Oid *) b)))
+		);
+}
+static bool
+gbt_enumlt(const void *a, const void *b)
+{
+	return DatumGetBool(
+						DirectFunctionCall2(enum_lt, ObjectIdGetDatum(*((const Oid *) a)), ObjectIdGetDatum(*((const Oid *) b)))
+		);
+}
+
+static int
+gbt_enumkey_cmp(const void *a, const void *b)
+{
+	oidKEY	   *ia = (oidKEY *) (((const Nsrt *) a)->t);
+	oidKEY	   *ib = (oidKEY *) (((const Nsrt *) b)->t);
+
+	if (ia->lower == ib->lower)
+	{
+		if (ia->upper == ib->upper)
+			return 0;
+
+		return DatumGetInt32(
+			DirectFunctionCall2(enum_cmp, ObjectIdGetDatum(ia->upper), ObjectIdGetDatum(ib->upper))
+			);
+	}
+
+	return DatumGetInt32(
+		DirectFunctionCall2(enum_cmp, ObjectIdGetDatum(ia->lower), ObjectIdGetDatum(ib->lower))
+		);
+}
+
+static const gbtree_ninfo tinfo =
+{
+	gbt_t_enum,
+	sizeof(Oid),
+	8,							/* sizeof(gbtreekey8) */
+	gbt_enumgt,
+	gbt_enumge,
+	gbt_enumeq,
+	gbt_enumle,
+	gbt_enumlt,
+	gbt_enumkey_cmp,
+	NULL /* no KNN support at least for now */
+};
+
+
+/**************************************************
+ * Enum ops
+ **************************************************/
+
+
+Datum
+gbt_enum_compress(PG_FUNCTION_ARGS)
+{
+	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+
+	PG_RETURN_POINTER(gbt_num_compress(entry, &tinfo));
+}
+
+Datum
+gbt_enum_fetch(PG_FUNCTION_ARGS)
+{
+	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+
+	PG_RETURN_POINTER(gbt_num_fetch(entry, &tinfo));
+}
+
+Datum
+gbt_enum_consistent(PG_FUNCTION_ARGS)
+{
+	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+	Oid			query = PG_GETARG_OID(1);
+	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
+
+	/* Oid		subtype = PG_GETARG_OID(3); */
+	bool	   *recheck = (bool *) PG_GETARG_POINTER(4);
+	oidKEY	   *kkk = (oidKEY *) DatumGetPointer(entry->key);
+	GBT_NUMKEY_R key;
+
+	/* All cases served by this function are exact */
+	*recheck = false;
+
+	key.lower = (GBT_NUMKEY *) &kkk->lower;
+	key.upper = (GBT_NUMKEY *) &kkk->upper;
+
+	PG_RETURN_BOOL(
+				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo)
+		);
+}
+
+Datum
+gbt_enum_union(PG_FUNCTION_ARGS)
+{
+	GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
+	void	   *out = palloc(sizeof(oidKEY));
+
+	*(int *) PG_GETARG_POINTER(1) = sizeof(oidKEY);
+	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
+}
+
+
+Datum
+gbt_enum_penalty(PG_FUNCTION_ARGS)
+{
+	oidKEY	   *origentry = (oidKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
+	oidKEY	   *newentry = (oidKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
+	float	   *result = (float *) PG_GETARG_POINTER(2);
+
+	penalty_num(result, origentry->lower, origentry->upper, newentry->lower, newentry->upper);
+
+	PG_RETURN_POINTER(result);
+}
+
+Datum
+gbt_enum_picksplit(PG_FUNCTION_ARGS)
+{
+	PG_RETURN_POINTER(gbt_num_picksplit(
+									(GistEntryVector *) PG_GETARG_POINTER(0),
+									  (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
+										&tinfo
+										));
+}
+
+Datum
+gbt_enum_same(PG_FUNCTION_ARGS)
+{
+	oidKEY	   *b1 = (oidKEY *) PG_GETARG_POINTER(0);
+	oidKEY	   *b2 = (oidKEY *) PG_GETARG_POINTER(1);
+	bool	   *result = (bool *) PG_GETARG_POINTER(2);
+
+	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
+	PG_RETURN_POINTER(result);
+}
diff --git a/contrib/btree_gist/btree_gist--1.1--1.2.sql b/contrib/btree_gist/btree_gist--1.1--1.2.sql
new file mode 100644
index 0000000..f3e8d90
--- /dev/null
+++ b/contrib/btree_gist/btree_gist--1.1--1.2.sql
@@ -0,0 +1,69 @@
+/* contrib/btree_gist/btree_gist--1.1--1.2.sql */
+
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "ALTER EXTENSION btree_gist UPDATE TO '1.2'" to load this file. \quit
+
+--
+--
+--
+-- enum ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_enum_consistent(internal,anyenum,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_union(internal, internal)
+RETURNS gbtreekey4
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_same(gbtreekey8, gbtreekey8, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_enum_ops
+DEFAULT FOR TYPE anyenum USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_enum_consistent (internal, anyenum, int2, oid, internal),
+	FUNCTION	2	gbt_enum_union (internal, internal),
+	FUNCTION	3	gbt_enum_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_enum_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_enum_picksplit (internal, internal),
+	FUNCTION	7	gbt_enum_same (gbtreekey8, gbtreekey8, internal),
+	STORAGE		gbtreekey8;
+
+ALTER OPERATOR FAMILY gist_enum_ops USING gist ADD
+	OPERATOR	6	<> (anyenum, anyenum) ,
+	FUNCTION	9 (anyenum, anyenum) gbt_enum_fetch (internal) ;
diff --git a/contrib/btree_gist/btree_gist--1.1.sql b/contrib/btree_gist/btree_gist--1.1.sql
deleted file mode 100644
index f0a4682..0000000
--- a/contrib/btree_gist/btree_gist--1.1.sql
+++ /dev/null
@@ -1,1570 +0,0 @@
-/* contrib/btree_gist/btree_gist--1.0.sql */
-
--- complain if script is sourced in psql, rather than via CREATE EXTENSION
-\echo Use "CREATE EXTENSION btree_gist" to load this file. \quit
-
-CREATE FUNCTION gbtreekey4_in(cstring)
-RETURNS gbtreekey4
-AS 'MODULE_PATHNAME', 'gbtreekey_in'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbtreekey4_out(gbtreekey4)
-RETURNS cstring
-AS 'MODULE_PATHNAME', 'gbtreekey_out'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE TYPE gbtreekey4 (
-	INTERNALLENGTH = 4,
-	INPUT  = gbtreekey4_in,
-	OUTPUT = gbtreekey4_out
-);
-
-CREATE FUNCTION gbtreekey8_in(cstring)
-RETURNS gbtreekey8
-AS 'MODULE_PATHNAME', 'gbtreekey_in'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbtreekey8_out(gbtreekey8)
-RETURNS cstring
-AS 'MODULE_PATHNAME', 'gbtreekey_out'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE TYPE gbtreekey8 (
-	INTERNALLENGTH = 8,
-	INPUT  = gbtreekey8_in,
-	OUTPUT = gbtreekey8_out
-);
-
-CREATE FUNCTION gbtreekey16_in(cstring)
-RETURNS gbtreekey16
-AS 'MODULE_PATHNAME', 'gbtreekey_in'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbtreekey16_out(gbtreekey16)
-RETURNS cstring
-AS 'MODULE_PATHNAME', 'gbtreekey_out'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE TYPE gbtreekey16 (
-	INTERNALLENGTH = 16,
-	INPUT  = gbtreekey16_in,
-	OUTPUT = gbtreekey16_out
-);
-
-CREATE FUNCTION gbtreekey32_in(cstring)
-RETURNS gbtreekey32
-AS 'MODULE_PATHNAME', 'gbtreekey_in'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbtreekey32_out(gbtreekey32)
-RETURNS cstring
-AS 'MODULE_PATHNAME', 'gbtreekey_out'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE TYPE gbtreekey32 (
-	INTERNALLENGTH = 32,
-	INPUT  = gbtreekey32_in,
-	OUTPUT = gbtreekey32_out
-);
-
-CREATE FUNCTION gbtreekey_var_in(cstring)
-RETURNS gbtreekey_var
-AS 'MODULE_PATHNAME', 'gbtreekey_in'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbtreekey_var_out(gbtreekey_var)
-RETURNS cstring
-AS 'MODULE_PATHNAME', 'gbtreekey_out'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE TYPE gbtreekey_var (
-	INTERNALLENGTH = VARIABLE,
-	INPUT  = gbtreekey_var_in,
-	OUTPUT = gbtreekey_var_out,
-	STORAGE = EXTENDED
-);
-
---distance operators
-
-CREATE FUNCTION cash_dist(money, money)
-RETURNS money
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE OPERATOR <-> (
-	LEFTARG = money,
-	RIGHTARG = money,
-	PROCEDURE = cash_dist,
-	COMMUTATOR = '<->'
-);
-
-CREATE FUNCTION date_dist(date, date)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE OPERATOR <-> (
-	LEFTARG = date,
-	RIGHTARG = date,
-	PROCEDURE = date_dist,
-	COMMUTATOR = '<->'
-);
-
-CREATE FUNCTION float4_dist(float4, float4)
-RETURNS float4
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE OPERATOR <-> (
-	LEFTARG = float4,
-	RIGHTARG = float4,
-	PROCEDURE = float4_dist,
-	COMMUTATOR = '<->'
-);
-
-CREATE FUNCTION float8_dist(float8, float8)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE OPERATOR <-> (
-	LEFTARG = float8,
-	RIGHTARG = float8,
-	PROCEDURE = float8_dist,
-	COMMUTATOR = '<->'
-);
-
-CREATE FUNCTION int2_dist(int2, int2)
-RETURNS int2
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE OPERATOR <-> (
-	LEFTARG = int2,
-	RIGHTARG = int2,
-	PROCEDURE = int2_dist,
-	COMMUTATOR = '<->'
-);
-
-CREATE FUNCTION int4_dist(int4, int4)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE OPERATOR <-> (
-	LEFTARG = int4,
-	RIGHTARG = int4,
-	PROCEDURE = int4_dist,
-	COMMUTATOR = '<->'
-);
-
-CREATE FUNCTION int8_dist(int8, int8)
-RETURNS int8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE OPERATOR <-> (
-	LEFTARG = int8,
-	RIGHTARG = int8,
-	PROCEDURE = int8_dist,
-	COMMUTATOR = '<->'
-);
-
-CREATE FUNCTION interval_dist(interval, interval)
-RETURNS interval
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE OPERATOR <-> (
-	LEFTARG = interval,
-	RIGHTARG = interval,
-	PROCEDURE = interval_dist,
-	COMMUTATOR = '<->'
-);
-
-CREATE FUNCTION oid_dist(oid, oid)
-RETURNS oid
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE OPERATOR <-> (
-	LEFTARG = oid,
-	RIGHTARG = oid,
-	PROCEDURE = oid_dist,
-	COMMUTATOR = '<->'
-);
-
-CREATE FUNCTION time_dist(time, time)
-RETURNS interval
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE OPERATOR <-> (
-	LEFTARG = time,
-	RIGHTARG = time,
-	PROCEDURE = time_dist,
-	COMMUTATOR = '<->'
-);
-
-CREATE FUNCTION ts_dist(timestamp, timestamp)
-RETURNS interval
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE OPERATOR <-> (
-	LEFTARG = timestamp,
-	RIGHTARG = timestamp,
-	PROCEDURE = ts_dist,
-	COMMUTATOR = '<->'
-);
-
-CREATE FUNCTION tstz_dist(timestamptz, timestamptz)
-RETURNS interval
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE OPERATOR <-> (
-	LEFTARG = timestamptz,
-	RIGHTARG = timestamptz,
-	PROCEDURE = tstz_dist,
-	COMMUTATOR = '<->'
-);
-
-
---
---
---
--- oid ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_oid_consistent(internal,oid,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_oid_distance(internal,oid,int2,oid,internal)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_oid_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_oid_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_decompress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_var_decompress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_var_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_oid_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_oid_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_oid_union(internal, internal)
-RETURNS gbtreekey8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_oid_same(gbtreekey8, gbtreekey8, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_oid_ops
-DEFAULT FOR TYPE oid USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_oid_consistent (internal, oid, int2, oid, internal),
-	FUNCTION	2	gbt_oid_union (internal, internal),
-	FUNCTION	3	gbt_oid_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_oid_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_oid_picksplit (internal, internal),
-	FUNCTION	7	gbt_oid_same (gbtreekey8, gbtreekey8, internal),
-	STORAGE		gbtreekey8;
-
--- Add operators that are new in 9.1.  We do it like this, leaving them
--- "loose" in the operator family rather than bound into the opclass, because
--- that's the only state that can be reproduced during an upgrade from 9.0.
-ALTER OPERATOR FAMILY gist_oid_ops USING gist ADD
-	OPERATOR	6	<> (oid, oid) ,
-	OPERATOR	15	<-> (oid, oid) FOR ORDER BY pg_catalog.oid_ops ,
-	FUNCTION	8 (oid, oid) gbt_oid_distance (internal, oid, int2, oid, internal) ,
-	-- Also add support function for index-only-scans, added in 9.5.
-	FUNCTION	9 (oid, oid) gbt_oid_fetch (internal) ;
-
-
---
---
---
--- int2 ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_int2_consistent(internal,int2,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int2_distance(internal,int2,int2,oid,internal)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int2_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int2_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int2_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int2_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int2_union(internal, internal)
-RETURNS gbtreekey4
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int2_same(gbtreekey4, gbtreekey4, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_int2_ops
-DEFAULT FOR TYPE int2 USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_int2_consistent (internal, int2, int2, oid, internal),
-	FUNCTION	2	gbt_int2_union (internal, internal),
-	FUNCTION	3	gbt_int2_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_int2_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_int2_picksplit (internal, internal),
-	FUNCTION	7	gbt_int2_same (gbtreekey4, gbtreekey4, internal),
-	STORAGE		gbtreekey4;
-
-ALTER OPERATOR FAMILY gist_int2_ops USING gist ADD
-	OPERATOR	6	<> (int2, int2) ,
-	OPERATOR	15	<-> (int2, int2) FOR ORDER BY pg_catalog.integer_ops ,
-	FUNCTION	8 (int2, int2) gbt_int2_distance (internal, int2, int2, oid, internal) ,
-	FUNCTION	9 (int2, int2) gbt_int2_fetch (internal) ;
-
---
---
---
--- int4 ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_int4_consistent(internal,int4,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int4_distance(internal,int4,int2,oid,internal)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int4_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int4_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int4_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int4_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int4_union(internal, internal)
-RETURNS gbtreekey8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int4_same(gbtreekey8, gbtreekey8, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_int4_ops
-DEFAULT FOR TYPE int4 USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_int4_consistent (internal, int4, int2, oid, internal),
-	FUNCTION	2	gbt_int4_union (internal, internal),
-	FUNCTION	3	gbt_int4_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_int4_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_int4_picksplit (internal, internal),
-	FUNCTION	7	gbt_int4_same (gbtreekey8, gbtreekey8, internal),
-	STORAGE		gbtreekey8;
-
-ALTER OPERATOR FAMILY gist_int4_ops USING gist ADD
-	OPERATOR	6	<> (int4, int4) ,
-	OPERATOR	15	<-> (int4, int4) FOR ORDER BY pg_catalog.integer_ops ,
-	FUNCTION	8 (int4, int4) gbt_int4_distance (internal, int4, int2, oid, internal) ,
-	FUNCTION	9 (int4, int4) gbt_int4_fetch (internal) ;
-
-
---
---
---
--- int8 ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_int8_consistent(internal,int8,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int8_distance(internal,int8,int2,oid,internal)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int8_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int8_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int8_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int8_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int8_union(internal, internal)
-RETURNS gbtreekey16
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int8_same(gbtreekey16, gbtreekey16, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_int8_ops
-DEFAULT FOR TYPE int8 USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_int8_consistent (internal, int8, int2, oid, internal),
-	FUNCTION	2	gbt_int8_union (internal, internal),
-	FUNCTION	3	gbt_int8_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_int8_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_int8_picksplit (internal, internal),
-	FUNCTION	7	gbt_int8_same (gbtreekey16, gbtreekey16, internal),
-	STORAGE		gbtreekey16;
-
-ALTER OPERATOR FAMILY gist_int8_ops USING gist ADD
-	OPERATOR	6	<> (int8, int8) ,
-	OPERATOR	15	<-> (int8, int8) FOR ORDER BY pg_catalog.integer_ops ,
-	FUNCTION	8 (int8, int8) gbt_int8_distance (internal, int8, int2, oid, internal) ,
-	FUNCTION	9 (int8, int8) gbt_int8_fetch (internal) ;
-
---
---
---
--- float4 ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_float4_consistent(internal,float4,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float4_distance(internal,float4,int2,oid,internal)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float4_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float4_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float4_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float4_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float4_union(internal, internal)
-RETURNS gbtreekey8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float4_same(gbtreekey8, gbtreekey8, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_float4_ops
-DEFAULT FOR TYPE float4 USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_float4_consistent (internal, float4, int2, oid, internal),
-	FUNCTION	2	gbt_float4_union (internal, internal),
-	FUNCTION	3	gbt_float4_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_float4_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_float4_picksplit (internal, internal),
-	FUNCTION	7	gbt_float4_same (gbtreekey8, gbtreekey8, internal),
-	STORAGE		gbtreekey8;
-
-ALTER OPERATOR FAMILY gist_float4_ops USING gist ADD
-	OPERATOR	6	<> (float4, float4) ,
-	OPERATOR	15	<-> (float4, float4) FOR ORDER BY pg_catalog.float_ops ,
-	FUNCTION	8 (float4, float4) gbt_float4_distance (internal, float4, int2, oid, internal) ,
-	FUNCTION	9 (float4, float4) gbt_float4_fetch (internal) ;
-
---
---
---
--- float8 ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_float8_consistent(internal,float8,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float8_distance(internal,float8,int2,oid,internal)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float8_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float8_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float8_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float8_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float8_union(internal, internal)
-RETURNS gbtreekey16
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float8_same(gbtreekey16, gbtreekey16, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_float8_ops
-DEFAULT FOR TYPE float8 USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_float8_consistent (internal, float8, int2, oid, internal),
-	FUNCTION	2	gbt_float8_union (internal, internal),
-	FUNCTION	3	gbt_float8_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_float8_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_float8_picksplit (internal, internal),
-	FUNCTION	7	gbt_float8_same (gbtreekey16, gbtreekey16, internal),
-	STORAGE		gbtreekey16;
-
-ALTER OPERATOR FAMILY gist_float8_ops USING gist ADD
-	OPERATOR	6	<> (float8, float8) ,
-	OPERATOR	15	<-> (float8, float8) FOR ORDER BY pg_catalog.float_ops ,
-	FUNCTION	8 (float8, float8) gbt_float8_distance (internal, float8, int2, oid, internal) ,
-	FUNCTION	9 (float8, float8) gbt_float8_fetch (internal) ;
-
---
---
---
--- timestamp ops
---
---
---
-
-CREATE FUNCTION gbt_ts_consistent(internal,timestamp,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_ts_distance(internal,timestamp,int2,oid,internal)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_tstz_consistent(internal,timestamptz,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_tstz_distance(internal,timestamptz,int2,oid,internal)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_ts_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_tstz_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_ts_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_ts_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_ts_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_ts_union(internal, internal)
-RETURNS gbtreekey16
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_ts_same(gbtreekey16, gbtreekey16, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_timestamp_ops
-DEFAULT FOR TYPE timestamp USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_ts_consistent (internal, timestamp, int2, oid, internal),
-	FUNCTION	2	gbt_ts_union (internal, internal),
-	FUNCTION	3	gbt_ts_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_ts_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_ts_picksplit (internal, internal),
-	FUNCTION	7	gbt_ts_same (gbtreekey16, gbtreekey16, internal),
-	STORAGE		gbtreekey16;
-
-ALTER OPERATOR FAMILY gist_timestamp_ops USING gist ADD
-	OPERATOR	6	<> (timestamp, timestamp) ,
-	OPERATOR	15	<-> (timestamp, timestamp) FOR ORDER BY pg_catalog.interval_ops ,
-	FUNCTION	8 (timestamp, timestamp) gbt_ts_distance (internal, timestamp, int2, oid, internal) ,
-	FUNCTION	9 (timestamp, timestamp) gbt_ts_fetch (internal) ;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_timestamptz_ops
-DEFAULT FOR TYPE timestamptz USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_tstz_consistent (internal, timestamptz, int2, oid, internal),
-	FUNCTION	2	gbt_ts_union (internal, internal),
-	FUNCTION	3	gbt_tstz_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_ts_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_ts_picksplit (internal, internal),
-	FUNCTION	7	gbt_ts_same (gbtreekey16, gbtreekey16, internal),
-	STORAGE		gbtreekey16;
-
-ALTER OPERATOR FAMILY gist_timestamptz_ops USING gist ADD
-	OPERATOR	6	<> (timestamptz, timestamptz) ,
-	OPERATOR	15	<-> (timestamptz, timestamptz) FOR ORDER BY pg_catalog.interval_ops ,
-	FUNCTION	8 (timestamptz, timestamptz) gbt_tstz_distance (internal, timestamptz, int2, oid, internal) ,
-	FUNCTION	9 (timestamptz, timestamptz) gbt_ts_fetch (internal) ;
-
---
---
---
--- time ops
---
---
---
-
-CREATE FUNCTION gbt_time_consistent(internal,time,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_time_distance(internal,time,int2,oid,internal)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_timetz_consistent(internal,timetz,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_time_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_timetz_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_time_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_time_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_time_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_time_union(internal, internal)
-RETURNS gbtreekey16
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_time_same(gbtreekey16, gbtreekey16, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_time_ops
-DEFAULT FOR TYPE time USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_time_consistent (internal, time, int2, oid, internal),
-	FUNCTION	2	gbt_time_union (internal, internal),
-	FUNCTION	3	gbt_time_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_time_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_time_picksplit (internal, internal),
-	FUNCTION	7	gbt_time_same (gbtreekey16, gbtreekey16, internal),
-	STORAGE		gbtreekey16;
-
-ALTER OPERATOR FAMILY gist_time_ops USING gist ADD
-	OPERATOR	6	<> (time, time) ,
-	OPERATOR	15	<-> (time, time) FOR ORDER BY pg_catalog.interval_ops ,
-	FUNCTION	8 (time, time) gbt_time_distance (internal, time, int2, oid, internal) ,
-	FUNCTION	9 (time, time) gbt_time_fetch (internal) ;
-
-
-CREATE OPERATOR CLASS gist_timetz_ops
-DEFAULT FOR TYPE timetz USING gist
-AS
-	OPERATOR	1	<   ,
-	OPERATOR	2	<=  ,
-	OPERATOR	3	=   ,
-	OPERATOR	4	>=  ,
-	OPERATOR	5	>   ,
-	FUNCTION	1	gbt_timetz_consistent (internal, timetz, int2, oid, internal),
-	FUNCTION	2	gbt_time_union (internal, internal),
-	FUNCTION	3	gbt_timetz_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_time_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_time_picksplit (internal, internal),
-	FUNCTION	7	gbt_time_same (gbtreekey16, gbtreekey16, internal),
-	STORAGE		gbtreekey16;
-
-ALTER OPERATOR FAMILY gist_timetz_ops USING gist ADD
-	OPERATOR	6	<> (timetz, timetz) ;
-	-- no 'fetch' function, as the compress function is lossy.
-
-
---
---
---
--- date ops
---
---
---
-
-CREATE FUNCTION gbt_date_consistent(internal,date,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_date_distance(internal,date,int2,oid,internal)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_date_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_date_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_date_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_date_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_date_union(internal, internal)
-RETURNS gbtreekey8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_date_same(gbtreekey8, gbtreekey8, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_date_ops
-DEFAULT FOR TYPE date USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_date_consistent (internal, date, int2, oid, internal),
-	FUNCTION	2	gbt_date_union (internal, internal),
-	FUNCTION	3	gbt_date_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_date_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_date_picksplit (internal, internal),
-	FUNCTION	7	gbt_date_same (gbtreekey8, gbtreekey8, internal),
-	STORAGE		gbtreekey8;
-
-ALTER OPERATOR FAMILY gist_date_ops USING gist ADD
-	OPERATOR	6	<> (date, date) ,
-	OPERATOR	15	<-> (date, date) FOR ORDER BY pg_catalog.integer_ops ,
-	FUNCTION	8 (date, date) gbt_date_distance (internal, date, int2, oid, internal) ,
-	FUNCTION	9 (date, date) gbt_date_fetch (internal) ;
-
-
---
---
---
--- interval ops
---
---
---
-
-CREATE FUNCTION gbt_intv_consistent(internal,interval,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_intv_distance(internal,interval,int2,oid,internal)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_intv_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_intv_decompress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_intv_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_intv_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_intv_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_intv_union(internal, internal)
-RETURNS gbtreekey32
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_intv_same(gbtreekey32, gbtreekey32, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_interval_ops
-DEFAULT FOR TYPE interval USING gist
-AS
-	OPERATOR	1	< ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	= ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	> ,
-	FUNCTION	1	gbt_intv_consistent (internal, interval, int2, oid, internal),
-	FUNCTION	2	gbt_intv_union (internal, internal),
-	FUNCTION	3	gbt_intv_compress (internal),
-	FUNCTION	4	gbt_intv_decompress (internal),
-	FUNCTION	5	gbt_intv_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_intv_picksplit (internal, internal),
-	FUNCTION	7	gbt_intv_same (gbtreekey32, gbtreekey32, internal),
-	STORAGE		gbtreekey32;
-
-ALTER OPERATOR FAMILY gist_interval_ops USING gist ADD
-	OPERATOR	6	<> (interval, interval) ,
-	OPERATOR	15	<-> (interval, interval) FOR ORDER BY pg_catalog.interval_ops ,
-	FUNCTION	8 (interval, interval) gbt_intv_distance (internal, interval, int2, oid, internal) ,
-	FUNCTION	9 (interval, interval) gbt_intv_fetch (internal) ;
-
-
---
---
---
--- cash ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_cash_consistent(internal,money,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_cash_distance(internal,money,int2,oid,internal)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_cash_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_cash_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_cash_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_cash_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_cash_union(internal, internal)
-RETURNS gbtreekey16
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_cash_same(gbtreekey16, gbtreekey16, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_cash_ops
-DEFAULT FOR TYPE money USING gist
-AS
-	OPERATOR	1	< ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	= ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	> ,
-	FUNCTION	1	gbt_cash_consistent (internal, money, int2, oid, internal),
-	FUNCTION	2	gbt_cash_union (internal, internal),
-	FUNCTION	3	gbt_cash_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_cash_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_cash_picksplit (internal, internal),
-	FUNCTION	7	gbt_cash_same (gbtreekey16, gbtreekey16, internal),
-	STORAGE		gbtreekey16;
-
-ALTER OPERATOR FAMILY gist_cash_ops USING gist ADD
-	OPERATOR	6	<> (money, money) ,
-	OPERATOR	15	<-> (money, money) FOR ORDER BY pg_catalog.money_ops ,
-	FUNCTION	8 (money, money) gbt_cash_distance (internal, money, int2, oid, internal) ,
-	FUNCTION	9 (money, money) gbt_cash_fetch (internal) ;
-
-
---
---
---
--- macaddr ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_macad_consistent(internal,macaddr,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_macad_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_macad_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_macad_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_macad_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_macad_union(internal, internal)
-RETURNS gbtreekey16
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_macad_same(gbtreekey16, gbtreekey16, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_macaddr_ops
-DEFAULT FOR TYPE macaddr USING gist
-AS
-	OPERATOR	1	< ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	= ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	> ,
-	FUNCTION	1	gbt_macad_consistent (internal, macaddr, int2, oid, internal),
-	FUNCTION	2	gbt_macad_union (internal, internal),
-	FUNCTION	3	gbt_macad_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_macad_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_macad_picksplit (internal, internal),
-	FUNCTION	7	gbt_macad_same (gbtreekey16, gbtreekey16, internal),
-	STORAGE		gbtreekey16;
-
-ALTER OPERATOR FAMILY gist_macaddr_ops USING gist ADD
-	OPERATOR	6	<> (macaddr, macaddr) ,
-	FUNCTION	9 (macaddr, macaddr) gbt_macad_fetch (internal);
-
-
---
---
---
--- text/ bpchar ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_text_consistent(internal,text,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_bpchar_consistent(internal,bpchar,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_text_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_bpchar_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_text_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_text_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_text_union(internal, internal)
-RETURNS gbtreekey_var
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_text_same(gbtreekey_var, gbtreekey_var, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_text_ops
-DEFAULT FOR TYPE text USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_text_consistent (internal, text, int2, oid, internal),
-	FUNCTION	2	gbt_text_union (internal, internal),
-	FUNCTION	3	gbt_text_compress (internal),
-	FUNCTION	4	gbt_var_decompress (internal),
-	FUNCTION	5	gbt_text_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_text_picksplit (internal, internal),
-	FUNCTION	7	gbt_text_same (gbtreekey_var, gbtreekey_var, internal),
-	STORAGE			gbtreekey_var;
-
-ALTER OPERATOR FAMILY gist_text_ops USING gist ADD
-	OPERATOR	6	<> (text, text) ,
-	FUNCTION	9 (text, text) gbt_var_fetch (internal) ;
-
-
----- Create the operator class
-CREATE OPERATOR CLASS gist_bpchar_ops
-DEFAULT FOR TYPE bpchar USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_bpchar_consistent (internal, bpchar , int2, oid, internal),
-	FUNCTION	2	gbt_text_union (internal, internal),
-	FUNCTION	3	gbt_bpchar_compress (internal),
-	FUNCTION	4	gbt_var_decompress (internal),
-	FUNCTION	5	gbt_text_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_text_picksplit (internal, internal),
-	FUNCTION	7	gbt_text_same (gbtreekey_var, gbtreekey_var, internal),
-	STORAGE			gbtreekey_var;
-
-ALTER OPERATOR FAMILY gist_bpchar_ops USING gist ADD
-	OPERATOR	6	<> (bpchar, bpchar) ,
-	FUNCTION	9 (bpchar, bpchar) gbt_var_fetch (internal) ;
-
---
---
--- bytea ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_bytea_consistent(internal,bytea,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_bytea_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_bytea_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_bytea_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_bytea_union(internal, internal)
-RETURNS gbtreekey_var
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_bytea_same(gbtreekey_var, gbtreekey_var, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_bytea_ops
-DEFAULT FOR TYPE bytea USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_bytea_consistent (internal, bytea, int2, oid, internal),
-	FUNCTION	2	gbt_bytea_union (internal, internal),
-	FUNCTION	3	gbt_bytea_compress (internal),
-	FUNCTION	4	gbt_var_decompress (internal),
-	FUNCTION	5	gbt_bytea_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_bytea_picksplit (internal, internal),
-	FUNCTION	7	gbt_bytea_same (gbtreekey_var, gbtreekey_var, internal),
-	STORAGE			gbtreekey_var;
-
-ALTER OPERATOR FAMILY gist_bytea_ops USING gist ADD
-	OPERATOR	6	<> (bytea, bytea) ,
-	FUNCTION	9 (bytea, bytea) gbt_var_fetch (internal) ;
-
-
---
---
---
--- numeric ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_numeric_consistent(internal,numeric,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_numeric_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_numeric_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_numeric_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_numeric_union(internal, internal)
-RETURNS gbtreekey_var
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_numeric_same(gbtreekey_var, gbtreekey_var, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_numeric_ops
-DEFAULT FOR TYPE numeric USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_numeric_consistent (internal, numeric, int2, oid, internal),
-	FUNCTION	2	gbt_numeric_union (internal, internal),
-	FUNCTION	3	gbt_numeric_compress (internal),
-	FUNCTION	4	gbt_var_decompress (internal),
-	FUNCTION	5	gbt_numeric_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_numeric_picksplit (internal, internal),
-	FUNCTION	7	gbt_numeric_same (gbtreekey_var, gbtreekey_var, internal),
-	STORAGE			gbtreekey_var;
-
-ALTER OPERATOR FAMILY gist_numeric_ops USING gist ADD
-	OPERATOR	6	<> (numeric, numeric) ,
-	FUNCTION	9 (numeric, numeric) gbt_var_fetch (internal) ;
-
-
---
---
--- bit ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_bit_consistent(internal,bit,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_bit_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_bit_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_bit_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_bit_union(internal, internal)
-RETURNS gbtreekey_var
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_bit_same(gbtreekey_var, gbtreekey_var, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_bit_ops
-DEFAULT FOR TYPE bit USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_bit_consistent (internal, bit, int2, oid, internal),
-	FUNCTION	2	gbt_bit_union (internal, internal),
-	FUNCTION	3	gbt_bit_compress (internal),
-	FUNCTION	4	gbt_var_decompress (internal),
-	FUNCTION	5	gbt_bit_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_bit_picksplit (internal, internal),
-	FUNCTION	7	gbt_bit_same (gbtreekey_var, gbtreekey_var, internal),
-	STORAGE			gbtreekey_var;
-
-ALTER OPERATOR FAMILY gist_bit_ops USING gist ADD
-	OPERATOR	6	<> (bit, bit) ,
-	FUNCTION	9 (bit, bit) gbt_var_fetch (internal) ;
-
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_vbit_ops
-DEFAULT FOR TYPE varbit USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_bit_consistent (internal, bit, int2, oid, internal),
-	FUNCTION	2	gbt_bit_union (internal, internal),
-	FUNCTION	3	gbt_bit_compress (internal),
-	FUNCTION	4	gbt_var_decompress (internal),
-	FUNCTION	5	gbt_bit_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_bit_picksplit (internal, internal),
-	FUNCTION	7	gbt_bit_same (gbtreekey_var, gbtreekey_var, internal),
-	STORAGE			gbtreekey_var;
-
-ALTER OPERATOR FAMILY gist_vbit_ops USING gist ADD
-	OPERATOR	6	<> (varbit, varbit) ,
-	FUNCTION	9 (varbit, varbit) gbt_var_fetch (internal) ;
-
-
---
---
---
--- inet/cidr ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_inet_consistent(internal,inet,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_inet_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_inet_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_inet_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_inet_union(internal, internal)
-RETURNS gbtreekey16
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_inet_same(gbtreekey16, gbtreekey16, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_inet_ops
-DEFAULT FOR TYPE inet USING gist
-AS
-	OPERATOR	1	<   ,
-	OPERATOR	2	<=  ,
-	OPERATOR	3	=   ,
-	OPERATOR	4	>=  ,
-	OPERATOR	5	>   ,
-	FUNCTION	1	gbt_inet_consistent (internal, inet, int2, oid, internal),
-	FUNCTION	2	gbt_inet_union (internal, internal),
-	FUNCTION	3	gbt_inet_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_inet_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_inet_picksplit (internal, internal),
-	FUNCTION	7	gbt_inet_same (gbtreekey16, gbtreekey16, internal),
-	STORAGE		gbtreekey16;
-
-ALTER OPERATOR FAMILY gist_inet_ops USING gist ADD
-	OPERATOR	6	<>  (inet, inet) ;
-	-- no fetch support, the compress function is lossy
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_cidr_ops
-DEFAULT FOR TYPE cidr USING gist
-AS
-	OPERATOR	1	<  (inet, inet)  ,
-	OPERATOR	2	<= (inet, inet)  ,
-	OPERATOR	3	=  (inet, inet)  ,
-	OPERATOR	4	>= (inet, inet)  ,
-	OPERATOR	5	>  (inet, inet)  ,
-	FUNCTION	1	gbt_inet_consistent (internal, inet, int2, oid, internal),
-	FUNCTION	2	gbt_inet_union (internal, internal),
-	FUNCTION	3	gbt_inet_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_inet_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_inet_picksplit (internal, internal),
-	FUNCTION	7	gbt_inet_same (gbtreekey16, gbtreekey16, internal),
-	STORAGE		gbtreekey16;
-
-ALTER OPERATOR FAMILY gist_cidr_ops USING gist ADD
-	OPERATOR	6	<> (inet, inet) ;
-	-- no fetch support, the compress function is lossy
diff --git a/contrib/btree_gist/btree_gist--1.2.sql b/contrib/btree_gist/btree_gist--1.2.sql
new file mode 100644
index 0000000..f5d2de7
--- /dev/null
+++ b/contrib/btree_gist/btree_gist--1.2.sql
@@ -0,0 +1,1635 @@
+/* contrib/btree_gist/btree_gist--1.0.sql */
+
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "CREATE EXTENSION btree_gist" to load this file. \quit
+
+CREATE FUNCTION gbtreekey4_in(cstring)
+RETURNS gbtreekey4
+AS 'MODULE_PATHNAME', 'gbtreekey_in'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbtreekey4_out(gbtreekey4)
+RETURNS cstring
+AS 'MODULE_PATHNAME', 'gbtreekey_out'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE TYPE gbtreekey4 (
+	INTERNALLENGTH = 4,
+	INPUT  = gbtreekey4_in,
+	OUTPUT = gbtreekey4_out
+);
+
+CREATE FUNCTION gbtreekey8_in(cstring)
+RETURNS gbtreekey8
+AS 'MODULE_PATHNAME', 'gbtreekey_in'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbtreekey8_out(gbtreekey8)
+RETURNS cstring
+AS 'MODULE_PATHNAME', 'gbtreekey_out'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE TYPE gbtreekey8 (
+	INTERNALLENGTH = 8,
+	INPUT  = gbtreekey8_in,
+	OUTPUT = gbtreekey8_out
+);
+
+CREATE FUNCTION gbtreekey16_in(cstring)
+RETURNS gbtreekey16
+AS 'MODULE_PATHNAME', 'gbtreekey_in'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbtreekey16_out(gbtreekey16)
+RETURNS cstring
+AS 'MODULE_PATHNAME', 'gbtreekey_out'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE TYPE gbtreekey16 (
+	INTERNALLENGTH = 16,
+	INPUT  = gbtreekey16_in,
+	OUTPUT = gbtreekey16_out
+);
+
+CREATE FUNCTION gbtreekey32_in(cstring)
+RETURNS gbtreekey32
+AS 'MODULE_PATHNAME', 'gbtreekey_in'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbtreekey32_out(gbtreekey32)
+RETURNS cstring
+AS 'MODULE_PATHNAME', 'gbtreekey_out'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE TYPE gbtreekey32 (
+	INTERNALLENGTH = 32,
+	INPUT  = gbtreekey32_in,
+	OUTPUT = gbtreekey32_out
+);
+
+CREATE FUNCTION gbtreekey_var_in(cstring)
+RETURNS gbtreekey_var
+AS 'MODULE_PATHNAME', 'gbtreekey_in'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbtreekey_var_out(gbtreekey_var)
+RETURNS cstring
+AS 'MODULE_PATHNAME', 'gbtreekey_out'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE TYPE gbtreekey_var (
+	INTERNALLENGTH = VARIABLE,
+	INPUT  = gbtreekey_var_in,
+	OUTPUT = gbtreekey_var_out,
+	STORAGE = EXTENDED
+);
+
+--distance operators
+
+CREATE FUNCTION cash_dist(money, money)
+RETURNS money
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR <-> (
+	LEFTARG = money,
+	RIGHTARG = money,
+	PROCEDURE = cash_dist,
+	COMMUTATOR = '<->'
+);
+
+CREATE FUNCTION date_dist(date, date)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR <-> (
+	LEFTARG = date,
+	RIGHTARG = date,
+	PROCEDURE = date_dist,
+	COMMUTATOR = '<->'
+);
+
+CREATE FUNCTION float4_dist(float4, float4)
+RETURNS float4
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR <-> (
+	LEFTARG = float4,
+	RIGHTARG = float4,
+	PROCEDURE = float4_dist,
+	COMMUTATOR = '<->'
+);
+
+CREATE FUNCTION float8_dist(float8, float8)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR <-> (
+	LEFTARG = float8,
+	RIGHTARG = float8,
+	PROCEDURE = float8_dist,
+	COMMUTATOR = '<->'
+);
+
+CREATE FUNCTION int2_dist(int2, int2)
+RETURNS int2
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR <-> (
+	LEFTARG = int2,
+	RIGHTARG = int2,
+	PROCEDURE = int2_dist,
+	COMMUTATOR = '<->'
+);
+
+CREATE FUNCTION int4_dist(int4, int4)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR <-> (
+	LEFTARG = int4,
+	RIGHTARG = int4,
+	PROCEDURE = int4_dist,
+	COMMUTATOR = '<->'
+);
+
+CREATE FUNCTION int8_dist(int8, int8)
+RETURNS int8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR <-> (
+	LEFTARG = int8,
+	RIGHTARG = int8,
+	PROCEDURE = int8_dist,
+	COMMUTATOR = '<->'
+);
+
+CREATE FUNCTION interval_dist(interval, interval)
+RETURNS interval
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR <-> (
+	LEFTARG = interval,
+	RIGHTARG = interval,
+	PROCEDURE = interval_dist,
+	COMMUTATOR = '<->'
+);
+
+CREATE FUNCTION oid_dist(oid, oid)
+RETURNS oid
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR <-> (
+	LEFTARG = oid,
+	RIGHTARG = oid,
+	PROCEDURE = oid_dist,
+	COMMUTATOR = '<->'
+);
+
+CREATE FUNCTION time_dist(time, time)
+RETURNS interval
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR <-> (
+	LEFTARG = time,
+	RIGHTARG = time,
+	PROCEDURE = time_dist,
+	COMMUTATOR = '<->'
+);
+
+CREATE FUNCTION ts_dist(timestamp, timestamp)
+RETURNS interval
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR <-> (
+	LEFTARG = timestamp,
+	RIGHTARG = timestamp,
+	PROCEDURE = ts_dist,
+	COMMUTATOR = '<->'
+);
+
+CREATE FUNCTION tstz_dist(timestamptz, timestamptz)
+RETURNS interval
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR <-> (
+	LEFTARG = timestamptz,
+	RIGHTARG = timestamptz,
+	PROCEDURE = tstz_dist,
+	COMMUTATOR = '<->'
+);
+
+
+--
+--
+--
+-- oid ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_oid_consistent(internal,oid,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_oid_distance(internal,oid,int2,oid,internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_oid_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_oid_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_decompress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_var_decompress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_var_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_oid_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_oid_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_oid_union(internal, internal)
+RETURNS gbtreekey8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_oid_same(gbtreekey8, gbtreekey8, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_oid_ops
+DEFAULT FOR TYPE oid USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_oid_consistent (internal, oid, int2, oid, internal),
+	FUNCTION	2	gbt_oid_union (internal, internal),
+	FUNCTION	3	gbt_oid_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_oid_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_oid_picksplit (internal, internal),
+	FUNCTION	7	gbt_oid_same (gbtreekey8, gbtreekey8, internal),
+	STORAGE		gbtreekey8;
+
+-- Add operators that are new in 9.1.  We do it like this, leaving them
+-- "loose" in the operator family rather than bound into the opclass, because
+-- that's the only state that can be reproduced during an upgrade from 9.0.
+ALTER OPERATOR FAMILY gist_oid_ops USING gist ADD
+	OPERATOR	6	<> (oid, oid) ,
+	OPERATOR	15	<-> (oid, oid) FOR ORDER BY pg_catalog.oid_ops ,
+	FUNCTION	8 (oid, oid) gbt_oid_distance (internal, oid, int2, oid, internal) ,
+	-- Also add support function for index-only-scans, added in 9.5.
+	FUNCTION	9 (oid, oid) gbt_oid_fetch (internal) ;
+
+
+--
+--
+--
+-- enum ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_enum_consistent(internal,anyenum,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_union(internal, internal)
+RETURNS gbtreekey4
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_same(gbtreekey8, gbtreekey8, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_enum_ops
+DEFAULT FOR TYPE anyenum USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_enum_consistent (internal, anyenum, int2, oid, internal),
+	FUNCTION	2	gbt_enum_union (internal, internal),
+	FUNCTION	3	gbt_enum_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_enum_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_enum_picksplit (internal, internal),
+	FUNCTION	7	gbt_enum_same (gbtreekey8, gbtreekey8, internal),
+	STORAGE		gbtreekey8;
+
+ALTER OPERATOR FAMILY gist_enum_ops USING gist ADD
+	OPERATOR	6	<> (anyenum, anyenum) ,
+	FUNCTION	9 (anyenum, anyenum) gbt_enum_fetch (internal) ;
+
+--
+--
+--
+-- int2 ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_int2_consistent(internal,int2,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int2_distance(internal,int2,int2,oid,internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int2_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int2_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int2_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int2_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int2_union(internal, internal)
+RETURNS gbtreekey4
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int2_same(gbtreekey4, gbtreekey4, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_int2_ops
+DEFAULT FOR TYPE int2 USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_int2_consistent (internal, int2, int2, oid, internal),
+	FUNCTION	2	gbt_int2_union (internal, internal),
+	FUNCTION	3	gbt_int2_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_int2_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_int2_picksplit (internal, internal),
+	FUNCTION	7	gbt_int2_same (gbtreekey4, gbtreekey4, internal),
+	STORAGE		gbtreekey4;
+
+ALTER OPERATOR FAMILY gist_int2_ops USING gist ADD
+	OPERATOR	6	<> (int2, int2) ,
+	OPERATOR	15	<-> (int2, int2) FOR ORDER BY pg_catalog.integer_ops ,
+	FUNCTION	8 (int2, int2) gbt_int2_distance (internal, int2, int2, oid, internal) ,
+	FUNCTION	9 (int2, int2) gbt_int2_fetch (internal) ;
+
+--
+--
+--
+-- int4 ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_int4_consistent(internal,int4,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int4_distance(internal,int4,int2,oid,internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int4_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int4_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int4_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int4_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int4_union(internal, internal)
+RETURNS gbtreekey8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int4_same(gbtreekey8, gbtreekey8, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_int4_ops
+DEFAULT FOR TYPE int4 USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_int4_consistent (internal, int4, int2, oid, internal),
+	FUNCTION	2	gbt_int4_union (internal, internal),
+	FUNCTION	3	gbt_int4_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_int4_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_int4_picksplit (internal, internal),
+	FUNCTION	7	gbt_int4_same (gbtreekey8, gbtreekey8, internal),
+	STORAGE		gbtreekey8;
+
+ALTER OPERATOR FAMILY gist_int4_ops USING gist ADD
+	OPERATOR	6	<> (int4, int4) ,
+	OPERATOR	15	<-> (int4, int4) FOR ORDER BY pg_catalog.integer_ops ,
+	FUNCTION	8 (int4, int4) gbt_int4_distance (internal, int4, int2, oid, internal) ,
+	FUNCTION	9 (int4, int4) gbt_int4_fetch (internal) ;
+
+
+--
+--
+--
+-- int8 ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_int8_consistent(internal,int8,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int8_distance(internal,int8,int2,oid,internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int8_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int8_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int8_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int8_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int8_union(internal, internal)
+RETURNS gbtreekey16
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int8_same(gbtreekey16, gbtreekey16, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_int8_ops
+DEFAULT FOR TYPE int8 USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_int8_consistent (internal, int8, int2, oid, internal),
+	FUNCTION	2	gbt_int8_union (internal, internal),
+	FUNCTION	3	gbt_int8_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_int8_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_int8_picksplit (internal, internal),
+	FUNCTION	7	gbt_int8_same (gbtreekey16, gbtreekey16, internal),
+	STORAGE		gbtreekey16;
+
+ALTER OPERATOR FAMILY gist_int8_ops USING gist ADD
+	OPERATOR	6	<> (int8, int8) ,
+	OPERATOR	15	<-> (int8, int8) FOR ORDER BY pg_catalog.integer_ops ,
+	FUNCTION	8 (int8, int8) gbt_int8_distance (internal, int8, int2, oid, internal) ,
+	FUNCTION	9 (int8, int8) gbt_int8_fetch (internal) ;
+
+--
+--
+--
+-- float4 ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_float4_consistent(internal,float4,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float4_distance(internal,float4,int2,oid,internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float4_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float4_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float4_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float4_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float4_union(internal, internal)
+RETURNS gbtreekey8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float4_same(gbtreekey8, gbtreekey8, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_float4_ops
+DEFAULT FOR TYPE float4 USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_float4_consistent (internal, float4, int2, oid, internal),
+	FUNCTION	2	gbt_float4_union (internal, internal),
+	FUNCTION	3	gbt_float4_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_float4_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_float4_picksplit (internal, internal),
+	FUNCTION	7	gbt_float4_same (gbtreekey8, gbtreekey8, internal),
+	STORAGE		gbtreekey8;
+
+ALTER OPERATOR FAMILY gist_float4_ops USING gist ADD
+	OPERATOR	6	<> (float4, float4) ,
+	OPERATOR	15	<-> (float4, float4) FOR ORDER BY pg_catalog.float_ops ,
+	FUNCTION	8 (float4, float4) gbt_float4_distance (internal, float4, int2, oid, internal) ,
+	FUNCTION	9 (float4, float4) gbt_float4_fetch (internal) ;
+
+--
+--
+--
+-- float8 ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_float8_consistent(internal,float8,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float8_distance(internal,float8,int2,oid,internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float8_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float8_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float8_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float8_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float8_union(internal, internal)
+RETURNS gbtreekey16
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float8_same(gbtreekey16, gbtreekey16, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_float8_ops
+DEFAULT FOR TYPE float8 USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_float8_consistent (internal, float8, int2, oid, internal),
+	FUNCTION	2	gbt_float8_union (internal, internal),
+	FUNCTION	3	gbt_float8_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_float8_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_float8_picksplit (internal, internal),
+	FUNCTION	7	gbt_float8_same (gbtreekey16, gbtreekey16, internal),
+	STORAGE		gbtreekey16;
+
+ALTER OPERATOR FAMILY gist_float8_ops USING gist ADD
+	OPERATOR	6	<> (float8, float8) ,
+	OPERATOR	15	<-> (float8, float8) FOR ORDER BY pg_catalog.float_ops ,
+	FUNCTION	8 (float8, float8) gbt_float8_distance (internal, float8, int2, oid, internal) ,
+	FUNCTION	9 (float8, float8) gbt_float8_fetch (internal) ;
+
+--
+--
+--
+-- timestamp ops
+--
+--
+--
+
+CREATE FUNCTION gbt_ts_consistent(internal,timestamp,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_ts_distance(internal,timestamp,int2,oid,internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_tstz_consistent(internal,timestamptz,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_tstz_distance(internal,timestamptz,int2,oid,internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_ts_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_tstz_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_ts_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_ts_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_ts_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_ts_union(internal, internal)
+RETURNS gbtreekey16
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_ts_same(gbtreekey16, gbtreekey16, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_timestamp_ops
+DEFAULT FOR TYPE timestamp USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_ts_consistent (internal, timestamp, int2, oid, internal),
+	FUNCTION	2	gbt_ts_union (internal, internal),
+	FUNCTION	3	gbt_ts_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_ts_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_ts_picksplit (internal, internal),
+	FUNCTION	7	gbt_ts_same (gbtreekey16, gbtreekey16, internal),
+	STORAGE		gbtreekey16;
+
+ALTER OPERATOR FAMILY gist_timestamp_ops USING gist ADD
+	OPERATOR	6	<> (timestamp, timestamp) ,
+	OPERATOR	15	<-> (timestamp, timestamp) FOR ORDER BY pg_catalog.interval_ops ,
+	FUNCTION	8 (timestamp, timestamp) gbt_ts_distance (internal, timestamp, int2, oid, internal) ,
+	FUNCTION	9 (timestamp, timestamp) gbt_ts_fetch (internal) ;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_timestamptz_ops
+DEFAULT FOR TYPE timestamptz USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_tstz_consistent (internal, timestamptz, int2, oid, internal),
+	FUNCTION	2	gbt_ts_union (internal, internal),
+	FUNCTION	3	gbt_tstz_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_ts_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_ts_picksplit (internal, internal),
+	FUNCTION	7	gbt_ts_same (gbtreekey16, gbtreekey16, internal),
+	STORAGE		gbtreekey16;
+
+ALTER OPERATOR FAMILY gist_timestamptz_ops USING gist ADD
+	OPERATOR	6	<> (timestamptz, timestamptz) ,
+	OPERATOR	15	<-> (timestamptz, timestamptz) FOR ORDER BY pg_catalog.interval_ops ,
+	FUNCTION	8 (timestamptz, timestamptz) gbt_tstz_distance (internal, timestamptz, int2, oid, internal) ,
+	FUNCTION	9 (timestamptz, timestamptz) gbt_ts_fetch (internal) ;
+
+--
+--
+--
+-- time ops
+--
+--
+--
+
+CREATE FUNCTION gbt_time_consistent(internal,time,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_time_distance(internal,time,int2,oid,internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_timetz_consistent(internal,timetz,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_time_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_timetz_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_time_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_time_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_time_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_time_union(internal, internal)
+RETURNS gbtreekey16
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_time_same(gbtreekey16, gbtreekey16, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_time_ops
+DEFAULT FOR TYPE time USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_time_consistent (internal, time, int2, oid, internal),
+	FUNCTION	2	gbt_time_union (internal, internal),
+	FUNCTION	3	gbt_time_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_time_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_time_picksplit (internal, internal),
+	FUNCTION	7	gbt_time_same (gbtreekey16, gbtreekey16, internal),
+	STORAGE		gbtreekey16;
+
+ALTER OPERATOR FAMILY gist_time_ops USING gist ADD
+	OPERATOR	6	<> (time, time) ,
+	OPERATOR	15	<-> (time, time) FOR ORDER BY pg_catalog.interval_ops ,
+	FUNCTION	8 (time, time) gbt_time_distance (internal, time, int2, oid, internal) ,
+	FUNCTION	9 (time, time) gbt_time_fetch (internal) ;
+
+
+CREATE OPERATOR CLASS gist_timetz_ops
+DEFAULT FOR TYPE timetz USING gist
+AS
+	OPERATOR	1	<   ,
+	OPERATOR	2	<=  ,
+	OPERATOR	3	=   ,
+	OPERATOR	4	>=  ,
+	OPERATOR	5	>   ,
+	FUNCTION	1	gbt_timetz_consistent (internal, timetz, int2, oid, internal),
+	FUNCTION	2	gbt_time_union (internal, internal),
+	FUNCTION	3	gbt_timetz_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_time_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_time_picksplit (internal, internal),
+	FUNCTION	7	gbt_time_same (gbtreekey16, gbtreekey16, internal),
+	STORAGE		gbtreekey16;
+
+ALTER OPERATOR FAMILY gist_timetz_ops USING gist ADD
+	OPERATOR	6	<> (timetz, timetz) ;
+	-- no 'fetch' function, as the compress function is lossy.
+
+
+--
+--
+--
+-- date ops
+--
+--
+--
+
+CREATE FUNCTION gbt_date_consistent(internal,date,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_date_distance(internal,date,int2,oid,internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_date_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_date_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_date_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_date_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_date_union(internal, internal)
+RETURNS gbtreekey8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_date_same(gbtreekey8, gbtreekey8, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_date_ops
+DEFAULT FOR TYPE date USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_date_consistent (internal, date, int2, oid, internal),
+	FUNCTION	2	gbt_date_union (internal, internal),
+	FUNCTION	3	gbt_date_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_date_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_date_picksplit (internal, internal),
+	FUNCTION	7	gbt_date_same (gbtreekey8, gbtreekey8, internal),
+	STORAGE		gbtreekey8;
+
+ALTER OPERATOR FAMILY gist_date_ops USING gist ADD
+	OPERATOR	6	<> (date, date) ,
+	OPERATOR	15	<-> (date, date) FOR ORDER BY pg_catalog.integer_ops ,
+	FUNCTION	8 (date, date) gbt_date_distance (internal, date, int2, oid, internal) ,
+	FUNCTION	9 (date, date) gbt_date_fetch (internal) ;
+
+
+--
+--
+--
+-- interval ops
+--
+--
+--
+
+CREATE FUNCTION gbt_intv_consistent(internal,interval,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_intv_distance(internal,interval,int2,oid,internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_intv_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_intv_decompress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_intv_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_intv_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_intv_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_intv_union(internal, internal)
+RETURNS gbtreekey32
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_intv_same(gbtreekey32, gbtreekey32, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_interval_ops
+DEFAULT FOR TYPE interval USING gist
+AS
+	OPERATOR	1	< ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	= ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	> ,
+	FUNCTION	1	gbt_intv_consistent (internal, interval, int2, oid, internal),
+	FUNCTION	2	gbt_intv_union (internal, internal),
+	FUNCTION	3	gbt_intv_compress (internal),
+	FUNCTION	4	gbt_intv_decompress (internal),
+	FUNCTION	5	gbt_intv_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_intv_picksplit (internal, internal),
+	FUNCTION	7	gbt_intv_same (gbtreekey32, gbtreekey32, internal),
+	STORAGE		gbtreekey32;
+
+ALTER OPERATOR FAMILY gist_interval_ops USING gist ADD
+	OPERATOR	6	<> (interval, interval) ,
+	OPERATOR	15	<-> (interval, interval) FOR ORDER BY pg_catalog.interval_ops ,
+	FUNCTION	8 (interval, interval) gbt_intv_distance (internal, interval, int2, oid, internal) ,
+	FUNCTION	9 (interval, interval) gbt_intv_fetch (internal) ;
+
+
+--
+--
+--
+-- cash ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_cash_consistent(internal,money,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_cash_distance(internal,money,int2,oid,internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_cash_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_cash_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_cash_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_cash_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_cash_union(internal, internal)
+RETURNS gbtreekey16
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_cash_same(gbtreekey16, gbtreekey16, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_cash_ops
+DEFAULT FOR TYPE money USING gist
+AS
+	OPERATOR	1	< ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	= ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	> ,
+	FUNCTION	1	gbt_cash_consistent (internal, money, int2, oid, internal),
+	FUNCTION	2	gbt_cash_union (internal, internal),
+	FUNCTION	3	gbt_cash_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_cash_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_cash_picksplit (internal, internal),
+	FUNCTION	7	gbt_cash_same (gbtreekey16, gbtreekey16, internal),
+	STORAGE		gbtreekey16;
+
+ALTER OPERATOR FAMILY gist_cash_ops USING gist ADD
+	OPERATOR	6	<> (money, money) ,
+	OPERATOR	15	<-> (money, money) FOR ORDER BY pg_catalog.money_ops ,
+	FUNCTION	8 (money, money) gbt_cash_distance (internal, money, int2, oid, internal) ,
+	FUNCTION	9 (money, money) gbt_cash_fetch (internal) ;
+
+
+--
+--
+--
+-- macaddr ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_macad_consistent(internal,macaddr,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_macad_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_macad_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_macad_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_macad_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_macad_union(internal, internal)
+RETURNS gbtreekey16
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_macad_same(gbtreekey16, gbtreekey16, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_macaddr_ops
+DEFAULT FOR TYPE macaddr USING gist
+AS
+	OPERATOR	1	< ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	= ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	> ,
+	FUNCTION	1	gbt_macad_consistent (internal, macaddr, int2, oid, internal),
+	FUNCTION	2	gbt_macad_union (internal, internal),
+	FUNCTION	3	gbt_macad_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_macad_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_macad_picksplit (internal, internal),
+	FUNCTION	7	gbt_macad_same (gbtreekey16, gbtreekey16, internal),
+	STORAGE		gbtreekey16;
+
+ALTER OPERATOR FAMILY gist_macaddr_ops USING gist ADD
+	OPERATOR	6	<> (macaddr, macaddr) ,
+	FUNCTION	9 (macaddr, macaddr) gbt_macad_fetch (internal);
+
+
+--
+--
+--
+-- text/ bpchar ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_text_consistent(internal,text,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bpchar_consistent(internal,bpchar,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_text_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bpchar_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_text_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_text_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_text_union(internal, internal)
+RETURNS gbtreekey_var
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_text_same(gbtreekey_var, gbtreekey_var, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_text_ops
+DEFAULT FOR TYPE text USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_text_consistent (internal, text, int2, oid, internal),
+	FUNCTION	2	gbt_text_union (internal, internal),
+	FUNCTION	3	gbt_text_compress (internal),
+	FUNCTION	4	gbt_var_decompress (internal),
+	FUNCTION	5	gbt_text_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_text_picksplit (internal, internal),
+	FUNCTION	7	gbt_text_same (gbtreekey_var, gbtreekey_var, internal),
+	STORAGE			gbtreekey_var;
+
+ALTER OPERATOR FAMILY gist_text_ops USING gist ADD
+	OPERATOR	6	<> (text, text) ,
+	FUNCTION	9 (text, text) gbt_var_fetch (internal) ;
+
+
+---- Create the operator class
+CREATE OPERATOR CLASS gist_bpchar_ops
+DEFAULT FOR TYPE bpchar USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_bpchar_consistent (internal, bpchar , int2, oid, internal),
+	FUNCTION	2	gbt_text_union (internal, internal),
+	FUNCTION	3	gbt_bpchar_compress (internal),
+	FUNCTION	4	gbt_var_decompress (internal),
+	FUNCTION	5	gbt_text_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_text_picksplit (internal, internal),
+	FUNCTION	7	gbt_text_same (gbtreekey_var, gbtreekey_var, internal),
+	STORAGE			gbtreekey_var;
+
+ALTER OPERATOR FAMILY gist_bpchar_ops USING gist ADD
+	OPERATOR	6	<> (bpchar, bpchar) ,
+	FUNCTION	9 (bpchar, bpchar) gbt_var_fetch (internal) ;
+
+--
+--
+-- bytea ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_bytea_consistent(internal,bytea,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bytea_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bytea_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bytea_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bytea_union(internal, internal)
+RETURNS gbtreekey_var
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bytea_same(gbtreekey_var, gbtreekey_var, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_bytea_ops
+DEFAULT FOR TYPE bytea USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_bytea_consistent (internal, bytea, int2, oid, internal),
+	FUNCTION	2	gbt_bytea_union (internal, internal),
+	FUNCTION	3	gbt_bytea_compress (internal),
+	FUNCTION	4	gbt_var_decompress (internal),
+	FUNCTION	5	gbt_bytea_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_bytea_picksplit (internal, internal),
+	FUNCTION	7	gbt_bytea_same (gbtreekey_var, gbtreekey_var, internal),
+	STORAGE			gbtreekey_var;
+
+ALTER OPERATOR FAMILY gist_bytea_ops USING gist ADD
+	OPERATOR	6	<> (bytea, bytea) ,
+	FUNCTION	9 (bytea, bytea) gbt_var_fetch (internal) ;
+
+
+--
+--
+--
+-- numeric ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_numeric_consistent(internal,numeric,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_numeric_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_numeric_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_numeric_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_numeric_union(internal, internal)
+RETURNS gbtreekey_var
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_numeric_same(gbtreekey_var, gbtreekey_var, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_numeric_ops
+DEFAULT FOR TYPE numeric USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_numeric_consistent (internal, numeric, int2, oid, internal),
+	FUNCTION	2	gbt_numeric_union (internal, internal),
+	FUNCTION	3	gbt_numeric_compress (internal),
+	FUNCTION	4	gbt_var_decompress (internal),
+	FUNCTION	5	gbt_numeric_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_numeric_picksplit (internal, internal),
+	FUNCTION	7	gbt_numeric_same (gbtreekey_var, gbtreekey_var, internal),
+	STORAGE			gbtreekey_var;
+
+ALTER OPERATOR FAMILY gist_numeric_ops USING gist ADD
+	OPERATOR	6	<> (numeric, numeric) ,
+	FUNCTION	9 (numeric, numeric) gbt_var_fetch (internal) ;
+
+
+--
+--
+-- bit ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_bit_consistent(internal,bit,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bit_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bit_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bit_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bit_union(internal, internal)
+RETURNS gbtreekey_var
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bit_same(gbtreekey_var, gbtreekey_var, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_bit_ops
+DEFAULT FOR TYPE bit USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_bit_consistent (internal, bit, int2, oid, internal),
+	FUNCTION	2	gbt_bit_union (internal, internal),
+	FUNCTION	3	gbt_bit_compress (internal),
+	FUNCTION	4	gbt_var_decompress (internal),
+	FUNCTION	5	gbt_bit_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_bit_picksplit (internal, internal),
+	FUNCTION	7	gbt_bit_same (gbtreekey_var, gbtreekey_var, internal),
+	STORAGE			gbtreekey_var;
+
+ALTER OPERATOR FAMILY gist_bit_ops USING gist ADD
+	OPERATOR	6	<> (bit, bit) ,
+	FUNCTION	9 (bit, bit) gbt_var_fetch (internal) ;
+
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_vbit_ops
+DEFAULT FOR TYPE varbit USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_bit_consistent (internal, bit, int2, oid, internal),
+	FUNCTION	2	gbt_bit_union (internal, internal),
+	FUNCTION	3	gbt_bit_compress (internal),
+	FUNCTION	4	gbt_var_decompress (internal),
+	FUNCTION	5	gbt_bit_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_bit_picksplit (internal, internal),
+	FUNCTION	7	gbt_bit_same (gbtreekey_var, gbtreekey_var, internal),
+	STORAGE			gbtreekey_var;
+
+ALTER OPERATOR FAMILY gist_vbit_ops USING gist ADD
+	OPERATOR	6	<> (varbit, varbit) ,
+	FUNCTION	9 (varbit, varbit) gbt_var_fetch (internal) ;
+
+
+--
+--
+--
+-- inet/cidr ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_inet_consistent(internal,inet,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_inet_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_inet_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_inet_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_inet_union(internal, internal)
+RETURNS gbtreekey16
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_inet_same(gbtreekey16, gbtreekey16, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_inet_ops
+DEFAULT FOR TYPE inet USING gist
+AS
+	OPERATOR	1	<   ,
+	OPERATOR	2	<=  ,
+	OPERATOR	3	=   ,
+	OPERATOR	4	>=  ,
+	OPERATOR	5	>   ,
+	FUNCTION	1	gbt_inet_consistent (internal, inet, int2, oid, internal),
+	FUNCTION	2	gbt_inet_union (internal, internal),
+	FUNCTION	3	gbt_inet_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_inet_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_inet_picksplit (internal, internal),
+	FUNCTION	7	gbt_inet_same (gbtreekey16, gbtreekey16, internal),
+	STORAGE		gbtreekey16;
+
+ALTER OPERATOR FAMILY gist_inet_ops USING gist ADD
+	OPERATOR	6	<>  (inet, inet) ;
+	-- no fetch support, the compress function is lossy
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_cidr_ops
+DEFAULT FOR TYPE cidr USING gist
+AS
+	OPERATOR	1	<  (inet, inet)  ,
+	OPERATOR	2	<= (inet, inet)  ,
+	OPERATOR	3	=  (inet, inet)  ,
+	OPERATOR	4	>= (inet, inet)  ,
+	OPERATOR	5	>  (inet, inet)  ,
+	FUNCTION	1	gbt_inet_consistent (internal, inet, int2, oid, internal),
+	FUNCTION	2	gbt_inet_union (internal, internal),
+	FUNCTION	3	gbt_inet_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_inet_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_inet_picksplit (internal, internal),
+	FUNCTION	7	gbt_inet_same (gbtreekey16, gbtreekey16, internal),
+	STORAGE		gbtreekey16;
+
+ALTER OPERATOR FAMILY gist_cidr_ops USING gist ADD
+	OPERATOR	6	<> (inet, inet) ;
+	-- no fetch support, the compress function is lossy
diff --git a/contrib/btree_gist/btree_gist.control b/contrib/btree_gist/btree_gist.control
index c7adfeb..74d0e92 100644
--- a/contrib/btree_gist/btree_gist.control
+++ b/contrib/btree_gist/btree_gist.control
@@ -1,5 +1,5 @@
 # btree_gist extension
 comment = 'support for indexing common datatypes in GiST'
-default_version = '1.1'
+default_version = '1.2'
 module_pathname = '$libdir/btree_gist'
 relocatable = true
diff --git a/contrib/btree_gist/btree_gist.h b/contrib/btree_gist/btree_gist.h
index dcffbb5..61f8d83 100644
--- a/contrib/btree_gist/btree_gist.h
+++ b/contrib/btree_gist/btree_gist.h
@@ -31,7 +31,8 @@ enum gbtree_type
 	gbt_t_bpchar,
 	gbt_t_bytea,
 	gbt_t_bit,
-	gbt_t_inet
+	gbt_t_inet,
+	gbt_t_enum
 };
 
 
diff --git a/contrib/btree_gist/btree_utils_num.c b/contrib/btree_gist/btree_utils_num.c
index 99cb41f..79f40a9 100644
--- a/contrib/btree_gist/btree_utils_num.c
+++ b/contrib/btree_gist/btree_utils_num.c
@@ -48,6 +48,7 @@ gbt_num_compress(GISTENTRY *entry, const gbtree_ninfo *tinfo)
 				leaf = &v.i8;
 				break;
 			case gbt_t_oid:
+			case gbt_t_enum:
 				v.i4 = DatumGetObjectId(entry->key);
 				leaf = &v.i4;
 				break;
@@ -122,6 +123,7 @@ gbt_num_fetch(GISTENTRY *entry, const gbtree_ninfo *tinfo)
 			datum = Int64GetDatum(*(int64 *) entry->key);
 			break;
 		case gbt_t_oid:
+		case gbt_t_enum:
 			datum = ObjectIdGetDatum(*(Oid *) entry->key);
 			break;
 		case gbt_t_float4:
diff --git a/contrib/btree_gist/expected/enum.out b/contrib/btree_gist/expected/enum.out
new file mode 100644
index 0000000..c4b769d
--- /dev/null
+++ b/contrib/btree_gist/expected/enum.out
@@ -0,0 +1,91 @@
+-- enum check
+create type rainbow as enum ('r','o','y','g','b','i','v');
+CREATE TABLE enumtmp (a rainbow);
+\copy enumtmp from 'data/enum.data'
+SET enable_seqscan=on;
+select a, count(*) from enumtmp group by a order by 1;
+ a | count 
+---+-------
+ r |    76
+ o |    78
+ y |    73
+ g |    75
+ b |    77
+ i |    78
+ v |    75
+   |    63
+(8 rows)
+
+SELECT count(*) FROM enumtmp WHERE a <  'g'::rainbow;
+ count 
+-------
+   227
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a <= 'g'::rainbow;
+ count 
+-------
+   302
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a  = 'g'::rainbow;
+ count 
+-------
+    75
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a >= 'g'::rainbow;
+ count 
+-------
+   305
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a >  'g'::rainbow;
+ count 
+-------
+   230
+(1 row)
+
+CREATE INDEX enumidx ON enumtmp USING gist ( a );
+SET enable_seqscan=off;
+SELECT count(*) FROM enumtmp WHERE a <  'g'::rainbow;
+ count 
+-------
+   227
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a <= 'g'::rainbow;
+ count 
+-------
+   302
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a  = 'g'::rainbow;
+ count 
+-------
+    75
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a >= 'g'::rainbow;
+ count 
+-------
+   305
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a >  'g'::rainbow;
+ count 
+-------
+   230
+(1 row)
+
+EXPLAIN (COSTS OFF)
+SELECT count(*) FROM enumtmp WHERE a >= 'g'::rainbow;
+                  QUERY PLAN                   
+-----------------------------------------------
+ Aggregate
+   ->  Bitmap Heap Scan on enumtmp
+         Recheck Cond: (a >= 'g'::rainbow)
+         ->  Bitmap Index Scan on enumidx
+               Index Cond: (a >= 'g'::rainbow)
+(5 rows)
+
diff --git a/contrib/btree_gist/sql/enum.sql b/contrib/btree_gist/sql/enum.sql
new file mode 100644
index 0000000..476211e
--- /dev/null
+++ b/contrib/btree_gist/sql/enum.sql
@@ -0,0 +1,38 @@
+-- enum check
+
+create type rainbow as enum ('r','o','y','g','b','i','v');
+
+CREATE TABLE enumtmp (a rainbow);
+
+\copy enumtmp from 'data/enum.data'
+
+SET enable_seqscan=on;
+
+select a, count(*) from enumtmp group by a order by 1;
+
+SELECT count(*) FROM enumtmp WHERE a <  'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a <= 'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a  = 'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a >= 'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a >  'g'::rainbow;
+
+CREATE INDEX enumidx ON enumtmp USING gist ( a );
+
+SET enable_seqscan=off;
+
+SELECT count(*) FROM enumtmp WHERE a <  'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a <= 'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a  = 'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a >= 'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a >  'g'::rainbow;
+
+EXPLAIN (COSTS OFF)
+SELECT count(*) FROM enumtmp WHERE a >= 'g'::rainbow;
diff --git a/doc/src/sgml/btree-gin.sgml b/doc/src/sgml/btree-gin.sgml
index 2b081db..f407e92 100644
--- a/doc/src/sgml/btree-gin.sgml
+++ b/doc/src/sgml/btree-gin.sgml
@@ -16,7 +16,8 @@
   <type>time without time zone</>, <type>date</>, <type>interval</>,
   <type>oid</>, <type>money</>, <type>"char"</>,
   <type>varchar</>, <type>text</>, <type>bytea</>, <type>bit</>,
-  <type>varbit</>, <type>macaddr</>, <type>inet</>, and <type>cidr</>.
+  <type>varbit</>, <type>macaddr</>, <type>inet</>, <type>cidr</>,
+  and all <type>enum</> types.
  </para>
 
  <para>
diff --git a/doc/src/sgml/btree-gist.sgml b/doc/src/sgml/btree-gist.sgml
index f4afc09..6db5ae3 100644
--- a/doc/src/sgml/btree-gist.sgml
+++ b/doc/src/sgml/btree-gist.sgml
@@ -16,7 +16,8 @@
   <type>time without time zone</>, <type>date</>, <type>interval</>,
   <type>oid</>, <type>money</>, <type>char</>,
   <type>varchar</>, <type>text</>, <type>bytea</>, <type>bit</>,
-  <type>varbit</>, <type>macaddr</>, <type>inet</>, and <type>cidr</>.
+  <type>varbit</>, <type>macaddr</>, <type>inet</>, <type>cidr</>,
+  and all <type>enum</> types. 
  </para>
 
  <para>
#2Andrew Dunstan
andrew@dunslane.net
In reply to: Andrew Dunstan (#1)
1 attachment(s)
Re: btree_gin and btree_gist for enums

On 03/17/2016 06:44 AM, Andrew Dunstan wrote:

Here is a patch to add enum support to btree_gin and btree_gist. I
didn't include distance operations, as I didn't think it terribly
important, and there isn't a simple way to compute it sanely and
efficiently, so no KNN support.

This time including the data file for the gist regression tests.

cheers

andrew

Attachments:

enum-btree-gist-gin-2.patchtext/x-patch; name=enum-btree-gist-gin-2.patchDownload
diff --git a/contrib/btree_gin/Makefile b/contrib/btree_gin/Makefile
index 0492091..f8a2d7f 100644
--- a/contrib/btree_gin/Makefile
+++ b/contrib/btree_gin/Makefile
@@ -4,13 +4,13 @@ MODULE_big = btree_gin
 OBJS = btree_gin.o $(WIN32RES)
 
 EXTENSION = btree_gin
-DATA = btree_gin--1.0.sql btree_gin--unpackaged--1.0.sql
+DATA = btree_gin--1.1.sql btree_gin--unpackaged--1.0.sql btree_gin--1.0--1.1.sql
 PGFILEDESC = "btree_gin - B-tree equivalent GIN operator classes"
 
 REGRESS = install_btree_gin int2 int4 int8 float4 float8 money oid \
 	timestamp timestamptz time timetz date interval \
 	macaddr inet cidr text varchar char bytea bit varbit \
-	numeric
+	numeric enum
 
 ifdef USE_PGXS
 PG_CONFIG = pg_config
diff --git a/contrib/btree_gin/btree_gin--1.0--1.1.sql b/contrib/btree_gin/btree_gin--1.0--1.1.sql
new file mode 100644
index 0000000..0c90bbb
--- /dev/null
+++ b/contrib/btree_gin/btree_gin--1.0--1.1.sql
@@ -0,0 +1,47 @@
+/* contrib/btree_gin/btree_gin--1.0--1.1.sql */
+
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "ALTER EXTENSION btree_gin UPDATE TO '1.1'" to load this file. \quit
+
+--
+--
+--
+-- enum ops
+--
+--
+
+
+CREATE FUNCTION gin_extract_value_anyenum(anyenum, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_anyenum(anyenum, anyenum, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_anyenum(anyenum, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_enum_cmp(anyenum, anyenum)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS enum_ops
+DEFAULT FOR TYPE anyenum USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       gin_enum_cmp(anyenum,anyenum),
+    FUNCTION        2       gin_extract_value_anyenum(anyenum, internal),
+    FUNCTION        3       gin_extract_query_anyenum(anyenum, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_anyenum(anyenum,anyenum,int2, internal),
+STORAGE         oid;
diff --git a/contrib/btree_gin/btree_gin--1.0.sql b/contrib/btree_gin/btree_gin--1.0.sql
deleted file mode 100644
index cf867ef..0000000
--- a/contrib/btree_gin/btree_gin--1.0.sql
+++ /dev/null
@@ -1,689 +0,0 @@
-/* contrib/btree_gin/btree_gin--1.0.sql */
-
--- complain if script is sourced in psql, rather than via CREATE EXTENSION
-\echo Use "CREATE EXTENSION btree_gin" to load this file. \quit
-
-CREATE FUNCTION gin_btree_consistent(internal, int2, anyelement, int4, internal, internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_value_int2(int2, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_int2(int2, int2, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_int2(int2, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS int2_ops
-DEFAULT FOR TYPE int2 USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       btint2cmp(int2,int2),
-    FUNCTION        2       gin_extract_value_int2(int2, internal),
-    FUNCTION        3       gin_extract_query_int2(int2, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_int2(int2,int2,int2, internal),
-STORAGE         int2;
-
-CREATE FUNCTION gin_extract_value_int4(int4, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_int4(int4, int4, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_int4(int4, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS int4_ops
-DEFAULT FOR TYPE int4 USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       btint4cmp(int4,int4),
-    FUNCTION        2       gin_extract_value_int4(int4, internal),
-    FUNCTION        3       gin_extract_query_int4(int4, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_int4(int4,int4,int2, internal),
-STORAGE         int4;
-
-CREATE FUNCTION gin_extract_value_int8(int8, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_int8(int8, int8, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_int8(int8, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS int8_ops
-DEFAULT FOR TYPE int8 USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       btint8cmp(int8,int8),
-    FUNCTION        2       gin_extract_value_int8(int8, internal),
-    FUNCTION        3       gin_extract_query_int8(int8, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_int8(int8,int8,int2, internal),
-STORAGE         int8;
-
-CREATE FUNCTION gin_extract_value_float4(float4, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_float4(float4, float4, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_float4(float4, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS float4_ops
-DEFAULT FOR TYPE float4 USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       btfloat4cmp(float4,float4),
-    FUNCTION        2       gin_extract_value_float4(float4, internal),
-    FUNCTION        3       gin_extract_query_float4(float4, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_float4(float4,float4,int2, internal),
-STORAGE         float4;
-
-CREATE FUNCTION gin_extract_value_float8(float8, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_float8(float8, float8, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_float8(float8, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS float8_ops
-DEFAULT FOR TYPE float8 USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       btfloat8cmp(float8,float8),
-    FUNCTION        2       gin_extract_value_float8(float8, internal),
-    FUNCTION        3       gin_extract_query_float8(float8, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_float8(float8,float8,int2, internal),
-STORAGE         float8;
-
-CREATE FUNCTION gin_extract_value_money(money, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_money(money, money, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_money(money, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS money_ops
-DEFAULT FOR TYPE money USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       cash_cmp(money,money),
-    FUNCTION        2       gin_extract_value_money(money, internal),
-    FUNCTION        3       gin_extract_query_money(money, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_money(money,money,int2, internal),
-STORAGE         money;
-
-CREATE FUNCTION gin_extract_value_oid(oid, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_oid(oid, oid, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_oid(oid, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS oid_ops
-DEFAULT FOR TYPE oid USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       btoidcmp(oid,oid),
-    FUNCTION        2       gin_extract_value_oid(oid, internal),
-    FUNCTION        3       gin_extract_query_oid(oid, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_oid(oid,oid,int2, internal),
-STORAGE         oid;
-
-CREATE FUNCTION gin_extract_value_timestamp(timestamp, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_timestamp(timestamp, timestamp, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_timestamp(timestamp, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS timestamp_ops
-DEFAULT FOR TYPE timestamp USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       timestamp_cmp(timestamp,timestamp),
-    FUNCTION        2       gin_extract_value_timestamp(timestamp, internal),
-    FUNCTION        3       gin_extract_query_timestamp(timestamp, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_timestamp(timestamp,timestamp,int2, internal),
-STORAGE         timestamp;
-
-CREATE FUNCTION gin_extract_value_timestamptz(timestamptz, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_timestamptz(timestamptz, timestamptz, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_timestamptz(timestamptz, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS timestamptz_ops
-DEFAULT FOR TYPE timestamptz USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       timestamptz_cmp(timestamptz,timestamptz),
-    FUNCTION        2       gin_extract_value_timestamptz(timestamptz, internal),
-    FUNCTION        3       gin_extract_query_timestamptz(timestamptz, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_timestamptz(timestamptz,timestamptz,int2, internal),
-STORAGE         timestamptz;
-
-CREATE FUNCTION gin_extract_value_time(time, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_time(time, time, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_time(time, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS time_ops
-DEFAULT FOR TYPE time USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       time_cmp(time,time),
-    FUNCTION        2       gin_extract_value_time(time, internal),
-    FUNCTION        3       gin_extract_query_time(time, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_time(time,time,int2, internal),
-STORAGE         time;
-
-CREATE FUNCTION gin_extract_value_timetz(timetz, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_timetz(timetz, timetz, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_timetz(timetz, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS timetz_ops
-DEFAULT FOR TYPE timetz USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       timetz_cmp(timetz,timetz),
-    FUNCTION        2       gin_extract_value_timetz(timetz, internal),
-    FUNCTION        3       gin_extract_query_timetz(timetz, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_timetz(timetz,timetz,int2, internal),
-STORAGE         timetz;
-
-CREATE FUNCTION gin_extract_value_date(date, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_date(date, date, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_date(date, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS date_ops
-DEFAULT FOR TYPE date USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       date_cmp(date,date),
-    FUNCTION        2       gin_extract_value_date(date, internal),
-    FUNCTION        3       gin_extract_query_date(date, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_date(date,date,int2, internal),
-STORAGE         date;
-
-CREATE FUNCTION gin_extract_value_interval(interval, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_interval(interval, interval, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_interval(interval, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS interval_ops
-DEFAULT FOR TYPE interval USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       interval_cmp(interval,interval),
-    FUNCTION        2       gin_extract_value_interval(interval, internal),
-    FUNCTION        3       gin_extract_query_interval(interval, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_interval(interval,interval,int2, internal),
-STORAGE         interval;
-
-CREATE FUNCTION gin_extract_value_macaddr(macaddr, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_macaddr(macaddr, macaddr, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_macaddr(macaddr, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS macaddr_ops
-DEFAULT FOR TYPE macaddr USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       macaddr_cmp(macaddr,macaddr),
-    FUNCTION        2       gin_extract_value_macaddr(macaddr, internal),
-    FUNCTION        3       gin_extract_query_macaddr(macaddr, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_macaddr(macaddr,macaddr,int2, internal),
-STORAGE         macaddr;
-
-CREATE FUNCTION gin_extract_value_inet(inet, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_inet(inet, inet, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_inet(inet, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS inet_ops
-DEFAULT FOR TYPE inet USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       network_cmp(inet,inet),
-    FUNCTION        2       gin_extract_value_inet(inet, internal),
-    FUNCTION        3       gin_extract_query_inet(inet, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_inet(inet,inet,int2, internal),
-STORAGE         inet;
-
-CREATE FUNCTION gin_extract_value_cidr(cidr, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_cidr(cidr, cidr, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_cidr(cidr, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS cidr_ops
-DEFAULT FOR TYPE cidr USING gin
-AS
-    OPERATOR        1       <(inet,inet),
-    OPERATOR        2       <=(inet,inet),
-    OPERATOR        3       =(inet,inet),
-    OPERATOR        4       >=(inet,inet),
-    OPERATOR        5       >(inet,inet),
-    FUNCTION        1       network_cmp(inet,inet),
-    FUNCTION        2       gin_extract_value_cidr(cidr, internal),
-    FUNCTION        3       gin_extract_query_cidr(cidr, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_cidr(cidr,cidr,int2, internal),
-STORAGE         cidr;
-
-CREATE FUNCTION gin_extract_value_text(text, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_text(text, text, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_text(text, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS text_ops
-DEFAULT FOR TYPE text USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       bttextcmp(text,text),
-    FUNCTION        2       gin_extract_value_text(text, internal),
-    FUNCTION        3       gin_extract_query_text(text, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_text(text,text,int2, internal),
-STORAGE         text;
-
-CREATE OPERATOR CLASS varchar_ops
-DEFAULT FOR TYPE varchar USING gin
-AS
-    OPERATOR        1       <(text,text),
-    OPERATOR        2       <=(text,text),
-    OPERATOR        3       =(text,text),
-    OPERATOR        4       >=(text,text),
-    OPERATOR        5       >(text,text),
-    FUNCTION        1       bttextcmp(text,text),
-    FUNCTION        2       gin_extract_value_text(text, internal),
-    FUNCTION        3       gin_extract_query_text(text, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_text(text,text,int2, internal),
-STORAGE         varchar;
-
-CREATE FUNCTION gin_extract_value_char("char", internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_char("char", "char", int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_char("char", internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS char_ops
-DEFAULT FOR TYPE "char" USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       btcharcmp("char","char"),
-    FUNCTION        2       gin_extract_value_char("char", internal),
-    FUNCTION        3       gin_extract_query_char("char", internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_char("char","char",int2, internal),
-STORAGE         "char";
-
-CREATE FUNCTION gin_extract_value_bytea(bytea, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_bytea(bytea, bytea, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_bytea(bytea, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS bytea_ops
-DEFAULT FOR TYPE bytea USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       byteacmp(bytea,bytea),
-    FUNCTION        2       gin_extract_value_bytea(bytea, internal),
-    FUNCTION        3       gin_extract_query_bytea(bytea, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_bytea(bytea,bytea,int2, internal),
-STORAGE         bytea;
-
-CREATE FUNCTION gin_extract_value_bit(bit, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_bit(bit, bit, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_bit(bit, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS bit_ops
-DEFAULT FOR TYPE bit USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       bitcmp(bit,bit),
-    FUNCTION        2       gin_extract_value_bit(bit, internal),
-    FUNCTION        3       gin_extract_query_bit(bit, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_bit(bit,bit,int2, internal),
-STORAGE         bit;
-
-CREATE FUNCTION gin_extract_value_varbit(varbit, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_varbit(varbit, varbit, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_varbit(varbit, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS varbit_ops
-DEFAULT FOR TYPE varbit USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       varbitcmp(varbit,varbit),
-    FUNCTION        2       gin_extract_value_varbit(varbit, internal),
-    FUNCTION        3       gin_extract_query_varbit(varbit, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_varbit(varbit,varbit,int2, internal),
-STORAGE         varbit;
-
-CREATE FUNCTION gin_extract_value_numeric(numeric, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_numeric(numeric, numeric, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_numeric(numeric, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_numeric_cmp(numeric, numeric)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS numeric_ops
-DEFAULT FOR TYPE numeric USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       gin_numeric_cmp(numeric,numeric),
-    FUNCTION        2       gin_extract_value_numeric(numeric, internal),
-    FUNCTION        3       gin_extract_query_numeric(numeric, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_numeric(numeric,numeric,int2, internal),
-STORAGE         numeric;
diff --git a/contrib/btree_gin/btree_gin--1.1.sql b/contrib/btree_gin/btree_gin--1.1.sql
new file mode 100644
index 0000000..f117e4a
--- /dev/null
+++ b/contrib/btree_gin/btree_gin--1.1.sql
@@ -0,0 +1,724 @@
+/* contrib/btree_gin/btree_gin--1.0.sql */
+
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "CREATE EXTENSION btree_gin" to load this file. \quit
+
+CREATE FUNCTION gin_btree_consistent(internal, int2, anyelement, int4, internal, internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_value_int2(int2, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_int2(int2, int2, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_int2(int2, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS int2_ops
+DEFAULT FOR TYPE int2 USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       btint2cmp(int2,int2),
+    FUNCTION        2       gin_extract_value_int2(int2, internal),
+    FUNCTION        3       gin_extract_query_int2(int2, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_int2(int2,int2,int2, internal),
+STORAGE         int2;
+
+CREATE FUNCTION gin_extract_value_int4(int4, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_int4(int4, int4, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_int4(int4, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS int4_ops
+DEFAULT FOR TYPE int4 USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       btint4cmp(int4,int4),
+    FUNCTION        2       gin_extract_value_int4(int4, internal),
+    FUNCTION        3       gin_extract_query_int4(int4, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_int4(int4,int4,int2, internal),
+STORAGE         int4;
+
+CREATE FUNCTION gin_extract_value_int8(int8, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_int8(int8, int8, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_int8(int8, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS int8_ops
+DEFAULT FOR TYPE int8 USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       btint8cmp(int8,int8),
+    FUNCTION        2       gin_extract_value_int8(int8, internal),
+    FUNCTION        3       gin_extract_query_int8(int8, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_int8(int8,int8,int2, internal),
+STORAGE         int8;
+
+CREATE FUNCTION gin_extract_value_float4(float4, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_float4(float4, float4, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_float4(float4, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS float4_ops
+DEFAULT FOR TYPE float4 USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       btfloat4cmp(float4,float4),
+    FUNCTION        2       gin_extract_value_float4(float4, internal),
+    FUNCTION        3       gin_extract_query_float4(float4, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_float4(float4,float4,int2, internal),
+STORAGE         float4;
+
+CREATE FUNCTION gin_extract_value_float8(float8, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_float8(float8, float8, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_float8(float8, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS float8_ops
+DEFAULT FOR TYPE float8 USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       btfloat8cmp(float8,float8),
+    FUNCTION        2       gin_extract_value_float8(float8, internal),
+    FUNCTION        3       gin_extract_query_float8(float8, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_float8(float8,float8,int2, internal),
+STORAGE         float8;
+
+CREATE FUNCTION gin_extract_value_money(money, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_money(money, money, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_money(money, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS money_ops
+DEFAULT FOR TYPE money USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       cash_cmp(money,money),
+    FUNCTION        2       gin_extract_value_money(money, internal),
+    FUNCTION        3       gin_extract_query_money(money, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_money(money,money,int2, internal),
+STORAGE         money;
+
+CREATE FUNCTION gin_extract_value_oid(oid, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_oid(oid, oid, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_oid(oid, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS oid_ops
+DEFAULT FOR TYPE oid USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       btoidcmp(oid,oid),
+    FUNCTION        2       gin_extract_value_oid(oid, internal),
+    FUNCTION        3       gin_extract_query_oid(oid, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_oid(oid,oid,int2, internal),
+STORAGE         oid;
+
+CREATE FUNCTION gin_extract_value_timestamp(timestamp, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_timestamp(timestamp, timestamp, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_timestamp(timestamp, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS timestamp_ops
+DEFAULT FOR TYPE timestamp USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       timestamp_cmp(timestamp,timestamp),
+    FUNCTION        2       gin_extract_value_timestamp(timestamp, internal),
+    FUNCTION        3       gin_extract_query_timestamp(timestamp, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_timestamp(timestamp,timestamp,int2, internal),
+STORAGE         timestamp;
+
+CREATE FUNCTION gin_extract_value_timestamptz(timestamptz, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_timestamptz(timestamptz, timestamptz, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_timestamptz(timestamptz, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS timestamptz_ops
+DEFAULT FOR TYPE timestamptz USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       timestamptz_cmp(timestamptz,timestamptz),
+    FUNCTION        2       gin_extract_value_timestamptz(timestamptz, internal),
+    FUNCTION        3       gin_extract_query_timestamptz(timestamptz, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_timestamptz(timestamptz,timestamptz,int2, internal),
+STORAGE         timestamptz;
+
+CREATE FUNCTION gin_extract_value_time(time, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_time(time, time, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_time(time, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS time_ops
+DEFAULT FOR TYPE time USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       time_cmp(time,time),
+    FUNCTION        2       gin_extract_value_time(time, internal),
+    FUNCTION        3       gin_extract_query_time(time, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_time(time,time,int2, internal),
+STORAGE         time;
+
+CREATE FUNCTION gin_extract_value_timetz(timetz, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_timetz(timetz, timetz, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_timetz(timetz, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS timetz_ops
+DEFAULT FOR TYPE timetz USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       timetz_cmp(timetz,timetz),
+    FUNCTION        2       gin_extract_value_timetz(timetz, internal),
+    FUNCTION        3       gin_extract_query_timetz(timetz, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_timetz(timetz,timetz,int2, internal),
+STORAGE         timetz;
+
+CREATE FUNCTION gin_extract_value_date(date, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_date(date, date, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_date(date, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS date_ops
+DEFAULT FOR TYPE date USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       date_cmp(date,date),
+    FUNCTION        2       gin_extract_value_date(date, internal),
+    FUNCTION        3       gin_extract_query_date(date, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_date(date,date,int2, internal),
+STORAGE         date;
+
+CREATE FUNCTION gin_extract_value_interval(interval, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_interval(interval, interval, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_interval(interval, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS interval_ops
+DEFAULT FOR TYPE interval USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       interval_cmp(interval,interval),
+    FUNCTION        2       gin_extract_value_interval(interval, internal),
+    FUNCTION        3       gin_extract_query_interval(interval, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_interval(interval,interval,int2, internal),
+STORAGE         interval;
+
+CREATE FUNCTION gin_extract_value_macaddr(macaddr, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_macaddr(macaddr, macaddr, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_macaddr(macaddr, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS macaddr_ops
+DEFAULT FOR TYPE macaddr USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       macaddr_cmp(macaddr,macaddr),
+    FUNCTION        2       gin_extract_value_macaddr(macaddr, internal),
+    FUNCTION        3       gin_extract_query_macaddr(macaddr, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_macaddr(macaddr,macaddr,int2, internal),
+STORAGE         macaddr;
+
+CREATE FUNCTION gin_extract_value_inet(inet, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_inet(inet, inet, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_inet(inet, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS inet_ops
+DEFAULT FOR TYPE inet USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       network_cmp(inet,inet),
+    FUNCTION        2       gin_extract_value_inet(inet, internal),
+    FUNCTION        3       gin_extract_query_inet(inet, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_inet(inet,inet,int2, internal),
+STORAGE         inet;
+
+CREATE FUNCTION gin_extract_value_cidr(cidr, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_cidr(cidr, cidr, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_cidr(cidr, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS cidr_ops
+DEFAULT FOR TYPE cidr USING gin
+AS
+    OPERATOR        1       <(inet,inet),
+    OPERATOR        2       <=(inet,inet),
+    OPERATOR        3       =(inet,inet),
+    OPERATOR        4       >=(inet,inet),
+    OPERATOR        5       >(inet,inet),
+    FUNCTION        1       network_cmp(inet,inet),
+    FUNCTION        2       gin_extract_value_cidr(cidr, internal),
+    FUNCTION        3       gin_extract_query_cidr(cidr, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_cidr(cidr,cidr,int2, internal),
+STORAGE         cidr;
+
+CREATE FUNCTION gin_extract_value_text(text, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_text(text, text, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_text(text, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS text_ops
+DEFAULT FOR TYPE text USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       bttextcmp(text,text),
+    FUNCTION        2       gin_extract_value_text(text, internal),
+    FUNCTION        3       gin_extract_query_text(text, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_text(text,text,int2, internal),
+STORAGE         text;
+
+CREATE OPERATOR CLASS varchar_ops
+DEFAULT FOR TYPE varchar USING gin
+AS
+    OPERATOR        1       <(text,text),
+    OPERATOR        2       <=(text,text),
+    OPERATOR        3       =(text,text),
+    OPERATOR        4       >=(text,text),
+    OPERATOR        5       >(text,text),
+    FUNCTION        1       bttextcmp(text,text),
+    FUNCTION        2       gin_extract_value_text(text, internal),
+    FUNCTION        3       gin_extract_query_text(text, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_text(text,text,int2, internal),
+STORAGE         varchar;
+
+CREATE FUNCTION gin_extract_value_char("char", internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_char("char", "char", int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_char("char", internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS char_ops
+DEFAULT FOR TYPE "char" USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       btcharcmp("char","char"),
+    FUNCTION        2       gin_extract_value_char("char", internal),
+    FUNCTION        3       gin_extract_query_char("char", internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_char("char","char",int2, internal),
+STORAGE         "char";
+
+CREATE FUNCTION gin_extract_value_bytea(bytea, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_bytea(bytea, bytea, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_bytea(bytea, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS bytea_ops
+DEFAULT FOR TYPE bytea USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       byteacmp(bytea,bytea),
+    FUNCTION        2       gin_extract_value_bytea(bytea, internal),
+    FUNCTION        3       gin_extract_query_bytea(bytea, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_bytea(bytea,bytea,int2, internal),
+STORAGE         bytea;
+
+CREATE FUNCTION gin_extract_value_bit(bit, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_bit(bit, bit, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_bit(bit, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS bit_ops
+DEFAULT FOR TYPE bit USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       bitcmp(bit,bit),
+    FUNCTION        2       gin_extract_value_bit(bit, internal),
+    FUNCTION        3       gin_extract_query_bit(bit, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_bit(bit,bit,int2, internal),
+STORAGE         bit;
+
+CREATE FUNCTION gin_extract_value_varbit(varbit, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_varbit(varbit, varbit, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_varbit(varbit, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS varbit_ops
+DEFAULT FOR TYPE varbit USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       varbitcmp(varbit,varbit),
+    FUNCTION        2       gin_extract_value_varbit(varbit, internal),
+    FUNCTION        3       gin_extract_query_varbit(varbit, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_varbit(varbit,varbit,int2, internal),
+STORAGE         varbit;
+
+CREATE FUNCTION gin_extract_value_numeric(numeric, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_numeric(numeric, numeric, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_numeric(numeric, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_numeric_cmp(numeric, numeric)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS numeric_ops
+DEFAULT FOR TYPE numeric USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       gin_numeric_cmp(numeric,numeric),
+    FUNCTION        2       gin_extract_value_numeric(numeric, internal),
+    FUNCTION        3       gin_extract_query_numeric(numeric, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_numeric(numeric,numeric,int2, internal),
+STORAGE         numeric;
+
+CREATE FUNCTION gin_extract_value_anyenum(anyenum, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_anyenum(anyenum, anyenum, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_anyenum(anyenum, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_enum_cmp(anyenum, anyenum)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS enum_ops
+DEFAULT FOR TYPE anyenum USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       gin_enum_cmp(anyenum,anyenum),
+    FUNCTION        2       gin_extract_value_anyenum(anyenum, internal),
+    FUNCTION        3       gin_extract_query_anyenum(anyenum, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_anyenum(anyenum,anyenum,int2, internal),
+STORAGE         oid;
diff --git a/contrib/btree_gin/btree_gin.c b/contrib/btree_gin/btree_gin.c
index f74e912..0ea3d70 100644
--- a/contrib/btree_gin/btree_gin.c
+++ b/contrib/btree_gin/btree_gin.c
@@ -422,3 +422,47 @@ leftmostvalue_numeric(void)
 }
 
 GIN_SUPPORT(numeric, true, leftmostvalue_numeric, gin_numeric_cmp)
+
+/*
+ * Use a similar trick to that used for numeric for enums, since we don't
+ * actually know the leftmost value of any enum without knowing the concrete
+ * type, so we use a dummy leftmost value of InvalidOid.
+ */
+
+
+#define ENUM_IS_LEFTMOST(x)	((x) == InvalidOid)
+
+PG_FUNCTION_INFO_V1(gin_enum_cmp);
+
+Datum
+gin_enum_cmp(PG_FUNCTION_ARGS)
+{
+	Oid		a = PG_GETARG_OID(0);
+	Oid		b = PG_GETARG_OID(1);
+	int		res = 0;
+
+	if (ENUM_IS_LEFTMOST(a))
+	{
+		res = (ENUM_IS_LEFTMOST(b)) ? 0 : -1;
+	}
+	else if (ENUM_IS_LEFTMOST(b))
+	{
+		res = 1;
+	}
+	else
+	{
+		res = DatumGetInt32(DirectFunctionCall2(enum_cmp,
+												ObjectIdGetDatum(a),
+												ObjectIdGetDatum(b)));
+	}
+
+	PG_RETURN_INT32(res);
+}
+
+static Datum
+leftmostvalue_enum(void)
+{
+	return ObjectIdGetDatum(InvalidOid);
+}
+
+GIN_SUPPORT(anyenum, false, leftmostvalue_enum, gin_enum_cmp)
diff --git a/contrib/btree_gin/btree_gin.control b/contrib/btree_gin/btree_gin.control
index 3b2cb2d..d96436e 100644
--- a/contrib/btree_gin/btree_gin.control
+++ b/contrib/btree_gin/btree_gin.control
@@ -1,5 +1,5 @@
 # btree_gin extension
 comment = 'support for indexing common datatypes in GIN'
-default_version = '1.0'
+default_version = '1.1'
 module_pathname = '$libdir/btree_gin'
 relocatable = true
diff --git a/contrib/btree_gin/expected/enum.out b/contrib/btree_gin/expected/enum.out
new file mode 100644
index 0000000..4e02b2d
--- /dev/null
+++ b/contrib/btree_gin/expected/enum.out
@@ -0,0 +1,58 @@
+set enable_seqscan=off;
+CREATE TYPE rainbow AS ENUM ('r','o','y','g','b','i','v');
+CREATE TABLE test_enum (
+	i rainbow
+);
+INSERT INTO test_enum VALUES ('v'),('y'),('r'),('g'),('o'),('i'),('b');
+CREATE INDEX idx_enum ON test_enum USING gin (i);
+SELECT * FROM test_enum WHERE i<'g'::rainbow ORDER BY i;
+ i 
+---
+ r
+ o
+ y
+(3 rows)
+
+SELECT * FROM test_enum WHERE i<='g'::rainbow ORDER BY i;
+ i 
+---
+ r
+ o
+ y
+ g
+(4 rows)
+
+SELECT * FROM test_enum WHERE i='g'::rainbow ORDER BY i;
+ i 
+---
+ g
+(1 row)
+
+SELECT * FROM test_enum WHERE i>='g'::rainbow ORDER BY i;
+ i 
+---
+ g
+ b
+ i
+ v
+(4 rows)
+
+SELECT * FROM test_enum WHERE i>'g'::rainbow ORDER BY i;
+ i 
+---
+ b
+ i
+ v
+(3 rows)
+
+explain (costs off) SELECT * FROM test_enum WHERE i>='g'::rainbow ORDER BY i;
+                  QUERY PLAN                   
+-----------------------------------------------
+ Sort
+   Sort Key: i
+   ->  Bitmap Heap Scan on test_enum
+         Recheck Cond: (i >= 'g'::rainbow)
+         ->  Bitmap Index Scan on idx_enum
+               Index Cond: (i >= 'g'::rainbow)
+(6 rows)
+
diff --git a/contrib/btree_gin/sql/enum.sql b/contrib/btree_gin/sql/enum.sql
new file mode 100644
index 0000000..9ee8f4c
--- /dev/null
+++ b/contrib/btree_gin/sql/enum.sql
@@ -0,0 +1,19 @@
+set enable_seqscan=off;
+
+CREATE TYPE rainbow AS ENUM ('r','o','y','g','b','i','v');
+
+CREATE TABLE test_enum (
+	i rainbow
+);
+
+INSERT INTO test_enum VALUES ('v'),('y'),('r'),('g'),('o'),('i'),('b');
+
+CREATE INDEX idx_enum ON test_enum USING gin (i);
+
+SELECT * FROM test_enum WHERE i<'g'::rainbow ORDER BY i;
+SELECT * FROM test_enum WHERE i<='g'::rainbow ORDER BY i;
+SELECT * FROM test_enum WHERE i='g'::rainbow ORDER BY i;
+SELECT * FROM test_enum WHERE i>='g'::rainbow ORDER BY i;
+SELECT * FROM test_enum WHERE i>'g'::rainbow ORDER BY i;
+
+explain (costs off) SELECT * FROM test_enum WHERE i>='g'::rainbow ORDER BY i;
diff --git a/contrib/btree_gist/Makefile b/contrib/btree_gist/Makefile
index a4b2cc7..ec38c4f 100644
--- a/contrib/btree_gist/Makefile
+++ b/contrib/btree_gist/Makefile
@@ -6,16 +6,16 @@ OBJS =  btree_gist.o btree_utils_num.o btree_utils_var.o btree_int2.o \
         btree_int4.o btree_int8.o btree_float4.o btree_float8.o btree_cash.o \
         btree_oid.o btree_ts.o btree_time.o btree_date.o btree_interval.o \
         btree_macaddr.o btree_inet.o btree_text.o btree_bytea.o btree_bit.o \
-        btree_numeric.o $(WIN32RES)
+        btree_numeric.o btree_enum.o $(WIN32RES)
 
 EXTENSION = btree_gist
-DATA = btree_gist--1.1.sql btree_gist--unpackaged--1.0.sql \
-	btree_gist--1.0--1.1.sql
+DATA = btree_gist--1.2.sql btree_gist--unpackaged--1.0.sql \
+	btree_gist--1.0--1.1.sql btree_gist--1.1--1.2.sql
 PGFILEDESC = "btree_gist - B-tree equivalent GiST operator classes"
 
 REGRESS = init int2 int4 int8 float4 float8 cash oid timestamp timestamptz \
         time timetz date interval macaddr inet cidr text varchar char bytea \
-        bit varbit numeric not_equal
+        bit varbit numeric enum not_equal
 
 SHLIB_LINK += $(filter -lm, $(LIBS))
 
diff --git a/contrib/btree_gist/btree_enum.c b/contrib/btree_gist/btree_enum.c
new file mode 100644
index 0000000..6126962
--- /dev/null
+++ b/contrib/btree_gist/btree_enum.c
@@ -0,0 +1,186 @@
+/*
+ * contrib/btree_gist/btree_enum.c
+ */
+#include "postgres.h"
+#include "utils/builtins.h"
+
+#include "btree_gist.h"
+#include "btree_utils_num.h"
+
+/* enums are really Oids, so we just use the same structure */
+
+typedef struct
+{
+	Oid			lower;
+	Oid			upper;
+} oidKEY;
+
+/*
+** enum ops
+*/
+PG_FUNCTION_INFO_V1(gbt_enum_compress);
+PG_FUNCTION_INFO_V1(gbt_enum_fetch);
+PG_FUNCTION_INFO_V1(gbt_enum_union);
+PG_FUNCTION_INFO_V1(gbt_enum_picksplit);
+PG_FUNCTION_INFO_V1(gbt_enum_consistent);
+PG_FUNCTION_INFO_V1(gbt_enum_penalty);
+PG_FUNCTION_INFO_V1(gbt_enum_same);
+
+
+static bool
+gbt_enumgt(const void *a, const void *b)
+{
+	return DatumGetBool(
+						DirectFunctionCall2(enum_gt, ObjectIdGetDatum(*((const Oid *) a)), ObjectIdGetDatum(*((const Oid *) b)))
+		);
+}
+static bool
+gbt_enumge(const void *a, const void *b)
+{
+	return DatumGetBool(
+						DirectFunctionCall2(enum_ge, ObjectIdGetDatum(*((const Oid *) a)), ObjectIdGetDatum(*((const Oid *) b)))
+		);
+}
+static bool
+gbt_enumeq(const void *a, const void *b)
+{
+	return (*((const Oid *) a) == *((const Oid *) b));
+}
+static bool
+gbt_enumle(const void *a, const void *b)
+{
+	return DatumGetBool(
+						DirectFunctionCall2(enum_le, ObjectIdGetDatum(*((const Oid *) a)), ObjectIdGetDatum(*((const Oid *) b)))
+		);
+}
+static bool
+gbt_enumlt(const void *a, const void *b)
+{
+	return DatumGetBool(
+						DirectFunctionCall2(enum_lt, ObjectIdGetDatum(*((const Oid *) a)), ObjectIdGetDatum(*((const Oid *) b)))
+		);
+}
+
+static int
+gbt_enumkey_cmp(const void *a, const void *b)
+{
+	oidKEY	   *ia = (oidKEY *) (((const Nsrt *) a)->t);
+	oidKEY	   *ib = (oidKEY *) (((const Nsrt *) b)->t);
+
+	if (ia->lower == ib->lower)
+	{
+		if (ia->upper == ib->upper)
+			return 0;
+
+		return DatumGetInt32(
+			DirectFunctionCall2(enum_cmp, ObjectIdGetDatum(ia->upper), ObjectIdGetDatum(ib->upper))
+			);
+	}
+
+	return DatumGetInt32(
+		DirectFunctionCall2(enum_cmp, ObjectIdGetDatum(ia->lower), ObjectIdGetDatum(ib->lower))
+		);
+}
+
+static const gbtree_ninfo tinfo =
+{
+	gbt_t_enum,
+	sizeof(Oid),
+	8,							/* sizeof(gbtreekey8) */
+	gbt_enumgt,
+	gbt_enumge,
+	gbt_enumeq,
+	gbt_enumle,
+	gbt_enumlt,
+	gbt_enumkey_cmp,
+	NULL /* no KNN support at least for now */
+};
+
+
+/**************************************************
+ * Enum ops
+ **************************************************/
+
+
+Datum
+gbt_enum_compress(PG_FUNCTION_ARGS)
+{
+	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+
+	PG_RETURN_POINTER(gbt_num_compress(entry, &tinfo));
+}
+
+Datum
+gbt_enum_fetch(PG_FUNCTION_ARGS)
+{
+	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+
+	PG_RETURN_POINTER(gbt_num_fetch(entry, &tinfo));
+}
+
+Datum
+gbt_enum_consistent(PG_FUNCTION_ARGS)
+{
+	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+	Oid			query = PG_GETARG_OID(1);
+	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
+
+	/* Oid		subtype = PG_GETARG_OID(3); */
+	bool	   *recheck = (bool *) PG_GETARG_POINTER(4);
+	oidKEY	   *kkk = (oidKEY *) DatumGetPointer(entry->key);
+	GBT_NUMKEY_R key;
+
+	/* All cases served by this function are exact */
+	*recheck = false;
+
+	key.lower = (GBT_NUMKEY *) &kkk->lower;
+	key.upper = (GBT_NUMKEY *) &kkk->upper;
+
+	PG_RETURN_BOOL(
+				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo)
+		);
+}
+
+Datum
+gbt_enum_union(PG_FUNCTION_ARGS)
+{
+	GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
+	void	   *out = palloc(sizeof(oidKEY));
+
+	*(int *) PG_GETARG_POINTER(1) = sizeof(oidKEY);
+	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
+}
+
+
+Datum
+gbt_enum_penalty(PG_FUNCTION_ARGS)
+{
+	oidKEY	   *origentry = (oidKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
+	oidKEY	   *newentry = (oidKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
+	float	   *result = (float *) PG_GETARG_POINTER(2);
+
+	penalty_num(result, origentry->lower, origentry->upper, newentry->lower, newentry->upper);
+
+	PG_RETURN_POINTER(result);
+}
+
+Datum
+gbt_enum_picksplit(PG_FUNCTION_ARGS)
+{
+	PG_RETURN_POINTER(gbt_num_picksplit(
+									(GistEntryVector *) PG_GETARG_POINTER(0),
+									  (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
+										&tinfo
+										));
+}
+
+Datum
+gbt_enum_same(PG_FUNCTION_ARGS)
+{
+	oidKEY	   *b1 = (oidKEY *) PG_GETARG_POINTER(0);
+	oidKEY	   *b2 = (oidKEY *) PG_GETARG_POINTER(1);
+	bool	   *result = (bool *) PG_GETARG_POINTER(2);
+
+	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
+	PG_RETURN_POINTER(result);
+}
diff --git a/contrib/btree_gist/btree_gist--1.1--1.2.sql b/contrib/btree_gist/btree_gist--1.1--1.2.sql
new file mode 100644
index 0000000..f3e8d90
--- /dev/null
+++ b/contrib/btree_gist/btree_gist--1.1--1.2.sql
@@ -0,0 +1,69 @@
+/* contrib/btree_gist/btree_gist--1.1--1.2.sql */
+
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "ALTER EXTENSION btree_gist UPDATE TO '1.2'" to load this file. \quit
+
+--
+--
+--
+-- enum ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_enum_consistent(internal,anyenum,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_union(internal, internal)
+RETURNS gbtreekey4
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_same(gbtreekey8, gbtreekey8, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_enum_ops
+DEFAULT FOR TYPE anyenum USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_enum_consistent (internal, anyenum, int2, oid, internal),
+	FUNCTION	2	gbt_enum_union (internal, internal),
+	FUNCTION	3	gbt_enum_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_enum_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_enum_picksplit (internal, internal),
+	FUNCTION	7	gbt_enum_same (gbtreekey8, gbtreekey8, internal),
+	STORAGE		gbtreekey8;
+
+ALTER OPERATOR FAMILY gist_enum_ops USING gist ADD
+	OPERATOR	6	<> (anyenum, anyenum) ,
+	FUNCTION	9 (anyenum, anyenum) gbt_enum_fetch (internal) ;
diff --git a/contrib/btree_gist/btree_gist--1.1.sql b/contrib/btree_gist/btree_gist--1.1.sql
deleted file mode 100644
index f0a4682..0000000
--- a/contrib/btree_gist/btree_gist--1.1.sql
+++ /dev/null
@@ -1,1570 +0,0 @@
-/* contrib/btree_gist/btree_gist--1.0.sql */
-
--- complain if script is sourced in psql, rather than via CREATE EXTENSION
-\echo Use "CREATE EXTENSION btree_gist" to load this file. \quit
-
-CREATE FUNCTION gbtreekey4_in(cstring)
-RETURNS gbtreekey4
-AS 'MODULE_PATHNAME', 'gbtreekey_in'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbtreekey4_out(gbtreekey4)
-RETURNS cstring
-AS 'MODULE_PATHNAME', 'gbtreekey_out'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE TYPE gbtreekey4 (
-	INTERNALLENGTH = 4,
-	INPUT  = gbtreekey4_in,
-	OUTPUT = gbtreekey4_out
-);
-
-CREATE FUNCTION gbtreekey8_in(cstring)
-RETURNS gbtreekey8
-AS 'MODULE_PATHNAME', 'gbtreekey_in'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbtreekey8_out(gbtreekey8)
-RETURNS cstring
-AS 'MODULE_PATHNAME', 'gbtreekey_out'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE TYPE gbtreekey8 (
-	INTERNALLENGTH = 8,
-	INPUT  = gbtreekey8_in,
-	OUTPUT = gbtreekey8_out
-);
-
-CREATE FUNCTION gbtreekey16_in(cstring)
-RETURNS gbtreekey16
-AS 'MODULE_PATHNAME', 'gbtreekey_in'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbtreekey16_out(gbtreekey16)
-RETURNS cstring
-AS 'MODULE_PATHNAME', 'gbtreekey_out'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE TYPE gbtreekey16 (
-	INTERNALLENGTH = 16,
-	INPUT  = gbtreekey16_in,
-	OUTPUT = gbtreekey16_out
-);
-
-CREATE FUNCTION gbtreekey32_in(cstring)
-RETURNS gbtreekey32
-AS 'MODULE_PATHNAME', 'gbtreekey_in'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbtreekey32_out(gbtreekey32)
-RETURNS cstring
-AS 'MODULE_PATHNAME', 'gbtreekey_out'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE TYPE gbtreekey32 (
-	INTERNALLENGTH = 32,
-	INPUT  = gbtreekey32_in,
-	OUTPUT = gbtreekey32_out
-);
-
-CREATE FUNCTION gbtreekey_var_in(cstring)
-RETURNS gbtreekey_var
-AS 'MODULE_PATHNAME', 'gbtreekey_in'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbtreekey_var_out(gbtreekey_var)
-RETURNS cstring
-AS 'MODULE_PATHNAME', 'gbtreekey_out'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE TYPE gbtreekey_var (
-	INTERNALLENGTH = VARIABLE,
-	INPUT  = gbtreekey_var_in,
-	OUTPUT = gbtreekey_var_out,
-	STORAGE = EXTENDED
-);
-
---distance operators
-
-CREATE FUNCTION cash_dist(money, money)
-RETURNS money
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE OPERATOR <-> (
-	LEFTARG = money,
-	RIGHTARG = money,
-	PROCEDURE = cash_dist,
-	COMMUTATOR = '<->'
-);
-
-CREATE FUNCTION date_dist(date, date)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE OPERATOR <-> (
-	LEFTARG = date,
-	RIGHTARG = date,
-	PROCEDURE = date_dist,
-	COMMUTATOR = '<->'
-);
-
-CREATE FUNCTION float4_dist(float4, float4)
-RETURNS float4
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE OPERATOR <-> (
-	LEFTARG = float4,
-	RIGHTARG = float4,
-	PROCEDURE = float4_dist,
-	COMMUTATOR = '<->'
-);
-
-CREATE FUNCTION float8_dist(float8, float8)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE OPERATOR <-> (
-	LEFTARG = float8,
-	RIGHTARG = float8,
-	PROCEDURE = float8_dist,
-	COMMUTATOR = '<->'
-);
-
-CREATE FUNCTION int2_dist(int2, int2)
-RETURNS int2
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE OPERATOR <-> (
-	LEFTARG = int2,
-	RIGHTARG = int2,
-	PROCEDURE = int2_dist,
-	COMMUTATOR = '<->'
-);
-
-CREATE FUNCTION int4_dist(int4, int4)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE OPERATOR <-> (
-	LEFTARG = int4,
-	RIGHTARG = int4,
-	PROCEDURE = int4_dist,
-	COMMUTATOR = '<->'
-);
-
-CREATE FUNCTION int8_dist(int8, int8)
-RETURNS int8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE OPERATOR <-> (
-	LEFTARG = int8,
-	RIGHTARG = int8,
-	PROCEDURE = int8_dist,
-	COMMUTATOR = '<->'
-);
-
-CREATE FUNCTION interval_dist(interval, interval)
-RETURNS interval
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE OPERATOR <-> (
-	LEFTARG = interval,
-	RIGHTARG = interval,
-	PROCEDURE = interval_dist,
-	COMMUTATOR = '<->'
-);
-
-CREATE FUNCTION oid_dist(oid, oid)
-RETURNS oid
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE OPERATOR <-> (
-	LEFTARG = oid,
-	RIGHTARG = oid,
-	PROCEDURE = oid_dist,
-	COMMUTATOR = '<->'
-);
-
-CREATE FUNCTION time_dist(time, time)
-RETURNS interval
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE OPERATOR <-> (
-	LEFTARG = time,
-	RIGHTARG = time,
-	PROCEDURE = time_dist,
-	COMMUTATOR = '<->'
-);
-
-CREATE FUNCTION ts_dist(timestamp, timestamp)
-RETURNS interval
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE OPERATOR <-> (
-	LEFTARG = timestamp,
-	RIGHTARG = timestamp,
-	PROCEDURE = ts_dist,
-	COMMUTATOR = '<->'
-);
-
-CREATE FUNCTION tstz_dist(timestamptz, timestamptz)
-RETURNS interval
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE OPERATOR <-> (
-	LEFTARG = timestamptz,
-	RIGHTARG = timestamptz,
-	PROCEDURE = tstz_dist,
-	COMMUTATOR = '<->'
-);
-
-
---
---
---
--- oid ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_oid_consistent(internal,oid,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_oid_distance(internal,oid,int2,oid,internal)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_oid_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_oid_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_decompress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_var_decompress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_var_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_oid_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_oid_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_oid_union(internal, internal)
-RETURNS gbtreekey8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_oid_same(gbtreekey8, gbtreekey8, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_oid_ops
-DEFAULT FOR TYPE oid USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_oid_consistent (internal, oid, int2, oid, internal),
-	FUNCTION	2	gbt_oid_union (internal, internal),
-	FUNCTION	3	gbt_oid_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_oid_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_oid_picksplit (internal, internal),
-	FUNCTION	7	gbt_oid_same (gbtreekey8, gbtreekey8, internal),
-	STORAGE		gbtreekey8;
-
--- Add operators that are new in 9.1.  We do it like this, leaving them
--- "loose" in the operator family rather than bound into the opclass, because
--- that's the only state that can be reproduced during an upgrade from 9.0.
-ALTER OPERATOR FAMILY gist_oid_ops USING gist ADD
-	OPERATOR	6	<> (oid, oid) ,
-	OPERATOR	15	<-> (oid, oid) FOR ORDER BY pg_catalog.oid_ops ,
-	FUNCTION	8 (oid, oid) gbt_oid_distance (internal, oid, int2, oid, internal) ,
-	-- Also add support function for index-only-scans, added in 9.5.
-	FUNCTION	9 (oid, oid) gbt_oid_fetch (internal) ;
-
-
---
---
---
--- int2 ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_int2_consistent(internal,int2,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int2_distance(internal,int2,int2,oid,internal)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int2_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int2_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int2_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int2_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int2_union(internal, internal)
-RETURNS gbtreekey4
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int2_same(gbtreekey4, gbtreekey4, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_int2_ops
-DEFAULT FOR TYPE int2 USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_int2_consistent (internal, int2, int2, oid, internal),
-	FUNCTION	2	gbt_int2_union (internal, internal),
-	FUNCTION	3	gbt_int2_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_int2_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_int2_picksplit (internal, internal),
-	FUNCTION	7	gbt_int2_same (gbtreekey4, gbtreekey4, internal),
-	STORAGE		gbtreekey4;
-
-ALTER OPERATOR FAMILY gist_int2_ops USING gist ADD
-	OPERATOR	6	<> (int2, int2) ,
-	OPERATOR	15	<-> (int2, int2) FOR ORDER BY pg_catalog.integer_ops ,
-	FUNCTION	8 (int2, int2) gbt_int2_distance (internal, int2, int2, oid, internal) ,
-	FUNCTION	9 (int2, int2) gbt_int2_fetch (internal) ;
-
---
---
---
--- int4 ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_int4_consistent(internal,int4,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int4_distance(internal,int4,int2,oid,internal)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int4_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int4_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int4_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int4_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int4_union(internal, internal)
-RETURNS gbtreekey8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int4_same(gbtreekey8, gbtreekey8, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_int4_ops
-DEFAULT FOR TYPE int4 USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_int4_consistent (internal, int4, int2, oid, internal),
-	FUNCTION	2	gbt_int4_union (internal, internal),
-	FUNCTION	3	gbt_int4_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_int4_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_int4_picksplit (internal, internal),
-	FUNCTION	7	gbt_int4_same (gbtreekey8, gbtreekey8, internal),
-	STORAGE		gbtreekey8;
-
-ALTER OPERATOR FAMILY gist_int4_ops USING gist ADD
-	OPERATOR	6	<> (int4, int4) ,
-	OPERATOR	15	<-> (int4, int4) FOR ORDER BY pg_catalog.integer_ops ,
-	FUNCTION	8 (int4, int4) gbt_int4_distance (internal, int4, int2, oid, internal) ,
-	FUNCTION	9 (int4, int4) gbt_int4_fetch (internal) ;
-
-
---
---
---
--- int8 ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_int8_consistent(internal,int8,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int8_distance(internal,int8,int2,oid,internal)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int8_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int8_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int8_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int8_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int8_union(internal, internal)
-RETURNS gbtreekey16
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int8_same(gbtreekey16, gbtreekey16, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_int8_ops
-DEFAULT FOR TYPE int8 USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_int8_consistent (internal, int8, int2, oid, internal),
-	FUNCTION	2	gbt_int8_union (internal, internal),
-	FUNCTION	3	gbt_int8_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_int8_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_int8_picksplit (internal, internal),
-	FUNCTION	7	gbt_int8_same (gbtreekey16, gbtreekey16, internal),
-	STORAGE		gbtreekey16;
-
-ALTER OPERATOR FAMILY gist_int8_ops USING gist ADD
-	OPERATOR	6	<> (int8, int8) ,
-	OPERATOR	15	<-> (int8, int8) FOR ORDER BY pg_catalog.integer_ops ,
-	FUNCTION	8 (int8, int8) gbt_int8_distance (internal, int8, int2, oid, internal) ,
-	FUNCTION	9 (int8, int8) gbt_int8_fetch (internal) ;
-
---
---
---
--- float4 ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_float4_consistent(internal,float4,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float4_distance(internal,float4,int2,oid,internal)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float4_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float4_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float4_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float4_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float4_union(internal, internal)
-RETURNS gbtreekey8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float4_same(gbtreekey8, gbtreekey8, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_float4_ops
-DEFAULT FOR TYPE float4 USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_float4_consistent (internal, float4, int2, oid, internal),
-	FUNCTION	2	gbt_float4_union (internal, internal),
-	FUNCTION	3	gbt_float4_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_float4_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_float4_picksplit (internal, internal),
-	FUNCTION	7	gbt_float4_same (gbtreekey8, gbtreekey8, internal),
-	STORAGE		gbtreekey8;
-
-ALTER OPERATOR FAMILY gist_float4_ops USING gist ADD
-	OPERATOR	6	<> (float4, float4) ,
-	OPERATOR	15	<-> (float4, float4) FOR ORDER BY pg_catalog.float_ops ,
-	FUNCTION	8 (float4, float4) gbt_float4_distance (internal, float4, int2, oid, internal) ,
-	FUNCTION	9 (float4, float4) gbt_float4_fetch (internal) ;
-
---
---
---
--- float8 ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_float8_consistent(internal,float8,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float8_distance(internal,float8,int2,oid,internal)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float8_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float8_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float8_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float8_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float8_union(internal, internal)
-RETURNS gbtreekey16
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float8_same(gbtreekey16, gbtreekey16, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_float8_ops
-DEFAULT FOR TYPE float8 USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_float8_consistent (internal, float8, int2, oid, internal),
-	FUNCTION	2	gbt_float8_union (internal, internal),
-	FUNCTION	3	gbt_float8_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_float8_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_float8_picksplit (internal, internal),
-	FUNCTION	7	gbt_float8_same (gbtreekey16, gbtreekey16, internal),
-	STORAGE		gbtreekey16;
-
-ALTER OPERATOR FAMILY gist_float8_ops USING gist ADD
-	OPERATOR	6	<> (float8, float8) ,
-	OPERATOR	15	<-> (float8, float8) FOR ORDER BY pg_catalog.float_ops ,
-	FUNCTION	8 (float8, float8) gbt_float8_distance (internal, float8, int2, oid, internal) ,
-	FUNCTION	9 (float8, float8) gbt_float8_fetch (internal) ;
-
---
---
---
--- timestamp ops
---
---
---
-
-CREATE FUNCTION gbt_ts_consistent(internal,timestamp,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_ts_distance(internal,timestamp,int2,oid,internal)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_tstz_consistent(internal,timestamptz,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_tstz_distance(internal,timestamptz,int2,oid,internal)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_ts_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_tstz_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_ts_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_ts_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_ts_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_ts_union(internal, internal)
-RETURNS gbtreekey16
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_ts_same(gbtreekey16, gbtreekey16, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_timestamp_ops
-DEFAULT FOR TYPE timestamp USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_ts_consistent (internal, timestamp, int2, oid, internal),
-	FUNCTION	2	gbt_ts_union (internal, internal),
-	FUNCTION	3	gbt_ts_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_ts_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_ts_picksplit (internal, internal),
-	FUNCTION	7	gbt_ts_same (gbtreekey16, gbtreekey16, internal),
-	STORAGE		gbtreekey16;
-
-ALTER OPERATOR FAMILY gist_timestamp_ops USING gist ADD
-	OPERATOR	6	<> (timestamp, timestamp) ,
-	OPERATOR	15	<-> (timestamp, timestamp) FOR ORDER BY pg_catalog.interval_ops ,
-	FUNCTION	8 (timestamp, timestamp) gbt_ts_distance (internal, timestamp, int2, oid, internal) ,
-	FUNCTION	9 (timestamp, timestamp) gbt_ts_fetch (internal) ;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_timestamptz_ops
-DEFAULT FOR TYPE timestamptz USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_tstz_consistent (internal, timestamptz, int2, oid, internal),
-	FUNCTION	2	gbt_ts_union (internal, internal),
-	FUNCTION	3	gbt_tstz_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_ts_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_ts_picksplit (internal, internal),
-	FUNCTION	7	gbt_ts_same (gbtreekey16, gbtreekey16, internal),
-	STORAGE		gbtreekey16;
-
-ALTER OPERATOR FAMILY gist_timestamptz_ops USING gist ADD
-	OPERATOR	6	<> (timestamptz, timestamptz) ,
-	OPERATOR	15	<-> (timestamptz, timestamptz) FOR ORDER BY pg_catalog.interval_ops ,
-	FUNCTION	8 (timestamptz, timestamptz) gbt_tstz_distance (internal, timestamptz, int2, oid, internal) ,
-	FUNCTION	9 (timestamptz, timestamptz) gbt_ts_fetch (internal) ;
-
---
---
---
--- time ops
---
---
---
-
-CREATE FUNCTION gbt_time_consistent(internal,time,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_time_distance(internal,time,int2,oid,internal)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_timetz_consistent(internal,timetz,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_time_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_timetz_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_time_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_time_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_time_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_time_union(internal, internal)
-RETURNS gbtreekey16
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_time_same(gbtreekey16, gbtreekey16, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_time_ops
-DEFAULT FOR TYPE time USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_time_consistent (internal, time, int2, oid, internal),
-	FUNCTION	2	gbt_time_union (internal, internal),
-	FUNCTION	3	gbt_time_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_time_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_time_picksplit (internal, internal),
-	FUNCTION	7	gbt_time_same (gbtreekey16, gbtreekey16, internal),
-	STORAGE		gbtreekey16;
-
-ALTER OPERATOR FAMILY gist_time_ops USING gist ADD
-	OPERATOR	6	<> (time, time) ,
-	OPERATOR	15	<-> (time, time) FOR ORDER BY pg_catalog.interval_ops ,
-	FUNCTION	8 (time, time) gbt_time_distance (internal, time, int2, oid, internal) ,
-	FUNCTION	9 (time, time) gbt_time_fetch (internal) ;
-
-
-CREATE OPERATOR CLASS gist_timetz_ops
-DEFAULT FOR TYPE timetz USING gist
-AS
-	OPERATOR	1	<   ,
-	OPERATOR	2	<=  ,
-	OPERATOR	3	=   ,
-	OPERATOR	4	>=  ,
-	OPERATOR	5	>   ,
-	FUNCTION	1	gbt_timetz_consistent (internal, timetz, int2, oid, internal),
-	FUNCTION	2	gbt_time_union (internal, internal),
-	FUNCTION	3	gbt_timetz_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_time_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_time_picksplit (internal, internal),
-	FUNCTION	7	gbt_time_same (gbtreekey16, gbtreekey16, internal),
-	STORAGE		gbtreekey16;
-
-ALTER OPERATOR FAMILY gist_timetz_ops USING gist ADD
-	OPERATOR	6	<> (timetz, timetz) ;
-	-- no 'fetch' function, as the compress function is lossy.
-
-
---
---
---
--- date ops
---
---
---
-
-CREATE FUNCTION gbt_date_consistent(internal,date,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_date_distance(internal,date,int2,oid,internal)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_date_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_date_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_date_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_date_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_date_union(internal, internal)
-RETURNS gbtreekey8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_date_same(gbtreekey8, gbtreekey8, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_date_ops
-DEFAULT FOR TYPE date USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_date_consistent (internal, date, int2, oid, internal),
-	FUNCTION	2	gbt_date_union (internal, internal),
-	FUNCTION	3	gbt_date_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_date_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_date_picksplit (internal, internal),
-	FUNCTION	7	gbt_date_same (gbtreekey8, gbtreekey8, internal),
-	STORAGE		gbtreekey8;
-
-ALTER OPERATOR FAMILY gist_date_ops USING gist ADD
-	OPERATOR	6	<> (date, date) ,
-	OPERATOR	15	<-> (date, date) FOR ORDER BY pg_catalog.integer_ops ,
-	FUNCTION	8 (date, date) gbt_date_distance (internal, date, int2, oid, internal) ,
-	FUNCTION	9 (date, date) gbt_date_fetch (internal) ;
-
-
---
---
---
--- interval ops
---
---
---
-
-CREATE FUNCTION gbt_intv_consistent(internal,interval,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_intv_distance(internal,interval,int2,oid,internal)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_intv_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_intv_decompress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_intv_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_intv_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_intv_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_intv_union(internal, internal)
-RETURNS gbtreekey32
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_intv_same(gbtreekey32, gbtreekey32, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_interval_ops
-DEFAULT FOR TYPE interval USING gist
-AS
-	OPERATOR	1	< ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	= ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	> ,
-	FUNCTION	1	gbt_intv_consistent (internal, interval, int2, oid, internal),
-	FUNCTION	2	gbt_intv_union (internal, internal),
-	FUNCTION	3	gbt_intv_compress (internal),
-	FUNCTION	4	gbt_intv_decompress (internal),
-	FUNCTION	5	gbt_intv_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_intv_picksplit (internal, internal),
-	FUNCTION	7	gbt_intv_same (gbtreekey32, gbtreekey32, internal),
-	STORAGE		gbtreekey32;
-
-ALTER OPERATOR FAMILY gist_interval_ops USING gist ADD
-	OPERATOR	6	<> (interval, interval) ,
-	OPERATOR	15	<-> (interval, interval) FOR ORDER BY pg_catalog.interval_ops ,
-	FUNCTION	8 (interval, interval) gbt_intv_distance (internal, interval, int2, oid, internal) ,
-	FUNCTION	9 (interval, interval) gbt_intv_fetch (internal) ;
-
-
---
---
---
--- cash ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_cash_consistent(internal,money,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_cash_distance(internal,money,int2,oid,internal)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_cash_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_cash_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_cash_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_cash_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_cash_union(internal, internal)
-RETURNS gbtreekey16
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_cash_same(gbtreekey16, gbtreekey16, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_cash_ops
-DEFAULT FOR TYPE money USING gist
-AS
-	OPERATOR	1	< ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	= ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	> ,
-	FUNCTION	1	gbt_cash_consistent (internal, money, int2, oid, internal),
-	FUNCTION	2	gbt_cash_union (internal, internal),
-	FUNCTION	3	gbt_cash_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_cash_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_cash_picksplit (internal, internal),
-	FUNCTION	7	gbt_cash_same (gbtreekey16, gbtreekey16, internal),
-	STORAGE		gbtreekey16;
-
-ALTER OPERATOR FAMILY gist_cash_ops USING gist ADD
-	OPERATOR	6	<> (money, money) ,
-	OPERATOR	15	<-> (money, money) FOR ORDER BY pg_catalog.money_ops ,
-	FUNCTION	8 (money, money) gbt_cash_distance (internal, money, int2, oid, internal) ,
-	FUNCTION	9 (money, money) gbt_cash_fetch (internal) ;
-
-
---
---
---
--- macaddr ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_macad_consistent(internal,macaddr,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_macad_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_macad_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_macad_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_macad_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_macad_union(internal, internal)
-RETURNS gbtreekey16
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_macad_same(gbtreekey16, gbtreekey16, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_macaddr_ops
-DEFAULT FOR TYPE macaddr USING gist
-AS
-	OPERATOR	1	< ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	= ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	> ,
-	FUNCTION	1	gbt_macad_consistent (internal, macaddr, int2, oid, internal),
-	FUNCTION	2	gbt_macad_union (internal, internal),
-	FUNCTION	3	gbt_macad_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_macad_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_macad_picksplit (internal, internal),
-	FUNCTION	7	gbt_macad_same (gbtreekey16, gbtreekey16, internal),
-	STORAGE		gbtreekey16;
-
-ALTER OPERATOR FAMILY gist_macaddr_ops USING gist ADD
-	OPERATOR	6	<> (macaddr, macaddr) ,
-	FUNCTION	9 (macaddr, macaddr) gbt_macad_fetch (internal);
-
-
---
---
---
--- text/ bpchar ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_text_consistent(internal,text,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_bpchar_consistent(internal,bpchar,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_text_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_bpchar_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_text_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_text_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_text_union(internal, internal)
-RETURNS gbtreekey_var
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_text_same(gbtreekey_var, gbtreekey_var, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_text_ops
-DEFAULT FOR TYPE text USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_text_consistent (internal, text, int2, oid, internal),
-	FUNCTION	2	gbt_text_union (internal, internal),
-	FUNCTION	3	gbt_text_compress (internal),
-	FUNCTION	4	gbt_var_decompress (internal),
-	FUNCTION	5	gbt_text_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_text_picksplit (internal, internal),
-	FUNCTION	7	gbt_text_same (gbtreekey_var, gbtreekey_var, internal),
-	STORAGE			gbtreekey_var;
-
-ALTER OPERATOR FAMILY gist_text_ops USING gist ADD
-	OPERATOR	6	<> (text, text) ,
-	FUNCTION	9 (text, text) gbt_var_fetch (internal) ;
-
-
----- Create the operator class
-CREATE OPERATOR CLASS gist_bpchar_ops
-DEFAULT FOR TYPE bpchar USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_bpchar_consistent (internal, bpchar , int2, oid, internal),
-	FUNCTION	2	gbt_text_union (internal, internal),
-	FUNCTION	3	gbt_bpchar_compress (internal),
-	FUNCTION	4	gbt_var_decompress (internal),
-	FUNCTION	5	gbt_text_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_text_picksplit (internal, internal),
-	FUNCTION	7	gbt_text_same (gbtreekey_var, gbtreekey_var, internal),
-	STORAGE			gbtreekey_var;
-
-ALTER OPERATOR FAMILY gist_bpchar_ops USING gist ADD
-	OPERATOR	6	<> (bpchar, bpchar) ,
-	FUNCTION	9 (bpchar, bpchar) gbt_var_fetch (internal) ;
-
---
---
--- bytea ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_bytea_consistent(internal,bytea,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_bytea_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_bytea_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_bytea_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_bytea_union(internal, internal)
-RETURNS gbtreekey_var
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_bytea_same(gbtreekey_var, gbtreekey_var, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_bytea_ops
-DEFAULT FOR TYPE bytea USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_bytea_consistent (internal, bytea, int2, oid, internal),
-	FUNCTION	2	gbt_bytea_union (internal, internal),
-	FUNCTION	3	gbt_bytea_compress (internal),
-	FUNCTION	4	gbt_var_decompress (internal),
-	FUNCTION	5	gbt_bytea_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_bytea_picksplit (internal, internal),
-	FUNCTION	7	gbt_bytea_same (gbtreekey_var, gbtreekey_var, internal),
-	STORAGE			gbtreekey_var;
-
-ALTER OPERATOR FAMILY gist_bytea_ops USING gist ADD
-	OPERATOR	6	<> (bytea, bytea) ,
-	FUNCTION	9 (bytea, bytea) gbt_var_fetch (internal) ;
-
-
---
---
---
--- numeric ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_numeric_consistent(internal,numeric,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_numeric_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_numeric_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_numeric_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_numeric_union(internal, internal)
-RETURNS gbtreekey_var
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_numeric_same(gbtreekey_var, gbtreekey_var, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_numeric_ops
-DEFAULT FOR TYPE numeric USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_numeric_consistent (internal, numeric, int2, oid, internal),
-	FUNCTION	2	gbt_numeric_union (internal, internal),
-	FUNCTION	3	gbt_numeric_compress (internal),
-	FUNCTION	4	gbt_var_decompress (internal),
-	FUNCTION	5	gbt_numeric_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_numeric_picksplit (internal, internal),
-	FUNCTION	7	gbt_numeric_same (gbtreekey_var, gbtreekey_var, internal),
-	STORAGE			gbtreekey_var;
-
-ALTER OPERATOR FAMILY gist_numeric_ops USING gist ADD
-	OPERATOR	6	<> (numeric, numeric) ,
-	FUNCTION	9 (numeric, numeric) gbt_var_fetch (internal) ;
-
-
---
---
--- bit ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_bit_consistent(internal,bit,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_bit_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_bit_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_bit_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_bit_union(internal, internal)
-RETURNS gbtreekey_var
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_bit_same(gbtreekey_var, gbtreekey_var, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_bit_ops
-DEFAULT FOR TYPE bit USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_bit_consistent (internal, bit, int2, oid, internal),
-	FUNCTION	2	gbt_bit_union (internal, internal),
-	FUNCTION	3	gbt_bit_compress (internal),
-	FUNCTION	4	gbt_var_decompress (internal),
-	FUNCTION	5	gbt_bit_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_bit_picksplit (internal, internal),
-	FUNCTION	7	gbt_bit_same (gbtreekey_var, gbtreekey_var, internal),
-	STORAGE			gbtreekey_var;
-
-ALTER OPERATOR FAMILY gist_bit_ops USING gist ADD
-	OPERATOR	6	<> (bit, bit) ,
-	FUNCTION	9 (bit, bit) gbt_var_fetch (internal) ;
-
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_vbit_ops
-DEFAULT FOR TYPE varbit USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_bit_consistent (internal, bit, int2, oid, internal),
-	FUNCTION	2	gbt_bit_union (internal, internal),
-	FUNCTION	3	gbt_bit_compress (internal),
-	FUNCTION	4	gbt_var_decompress (internal),
-	FUNCTION	5	gbt_bit_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_bit_picksplit (internal, internal),
-	FUNCTION	7	gbt_bit_same (gbtreekey_var, gbtreekey_var, internal),
-	STORAGE			gbtreekey_var;
-
-ALTER OPERATOR FAMILY gist_vbit_ops USING gist ADD
-	OPERATOR	6	<> (varbit, varbit) ,
-	FUNCTION	9 (varbit, varbit) gbt_var_fetch (internal) ;
-
-
---
---
---
--- inet/cidr ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_inet_consistent(internal,inet,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_inet_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_inet_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_inet_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_inet_union(internal, internal)
-RETURNS gbtreekey16
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_inet_same(gbtreekey16, gbtreekey16, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_inet_ops
-DEFAULT FOR TYPE inet USING gist
-AS
-	OPERATOR	1	<   ,
-	OPERATOR	2	<=  ,
-	OPERATOR	3	=   ,
-	OPERATOR	4	>=  ,
-	OPERATOR	5	>   ,
-	FUNCTION	1	gbt_inet_consistent (internal, inet, int2, oid, internal),
-	FUNCTION	2	gbt_inet_union (internal, internal),
-	FUNCTION	3	gbt_inet_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_inet_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_inet_picksplit (internal, internal),
-	FUNCTION	7	gbt_inet_same (gbtreekey16, gbtreekey16, internal),
-	STORAGE		gbtreekey16;
-
-ALTER OPERATOR FAMILY gist_inet_ops USING gist ADD
-	OPERATOR	6	<>  (inet, inet) ;
-	-- no fetch support, the compress function is lossy
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_cidr_ops
-DEFAULT FOR TYPE cidr USING gist
-AS
-	OPERATOR	1	<  (inet, inet)  ,
-	OPERATOR	2	<= (inet, inet)  ,
-	OPERATOR	3	=  (inet, inet)  ,
-	OPERATOR	4	>= (inet, inet)  ,
-	OPERATOR	5	>  (inet, inet)  ,
-	FUNCTION	1	gbt_inet_consistent (internal, inet, int2, oid, internal),
-	FUNCTION	2	gbt_inet_union (internal, internal),
-	FUNCTION	3	gbt_inet_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_inet_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_inet_picksplit (internal, internal),
-	FUNCTION	7	gbt_inet_same (gbtreekey16, gbtreekey16, internal),
-	STORAGE		gbtreekey16;
-
-ALTER OPERATOR FAMILY gist_cidr_ops USING gist ADD
-	OPERATOR	6	<> (inet, inet) ;
-	-- no fetch support, the compress function is lossy
diff --git a/contrib/btree_gist/btree_gist--1.2.sql b/contrib/btree_gist/btree_gist--1.2.sql
new file mode 100644
index 0000000..f5d2de7
--- /dev/null
+++ b/contrib/btree_gist/btree_gist--1.2.sql
@@ -0,0 +1,1635 @@
+/* contrib/btree_gist/btree_gist--1.0.sql */
+
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "CREATE EXTENSION btree_gist" to load this file. \quit
+
+CREATE FUNCTION gbtreekey4_in(cstring)
+RETURNS gbtreekey4
+AS 'MODULE_PATHNAME', 'gbtreekey_in'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbtreekey4_out(gbtreekey4)
+RETURNS cstring
+AS 'MODULE_PATHNAME', 'gbtreekey_out'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE TYPE gbtreekey4 (
+	INTERNALLENGTH = 4,
+	INPUT  = gbtreekey4_in,
+	OUTPUT = gbtreekey4_out
+);
+
+CREATE FUNCTION gbtreekey8_in(cstring)
+RETURNS gbtreekey8
+AS 'MODULE_PATHNAME', 'gbtreekey_in'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbtreekey8_out(gbtreekey8)
+RETURNS cstring
+AS 'MODULE_PATHNAME', 'gbtreekey_out'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE TYPE gbtreekey8 (
+	INTERNALLENGTH = 8,
+	INPUT  = gbtreekey8_in,
+	OUTPUT = gbtreekey8_out
+);
+
+CREATE FUNCTION gbtreekey16_in(cstring)
+RETURNS gbtreekey16
+AS 'MODULE_PATHNAME', 'gbtreekey_in'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbtreekey16_out(gbtreekey16)
+RETURNS cstring
+AS 'MODULE_PATHNAME', 'gbtreekey_out'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE TYPE gbtreekey16 (
+	INTERNALLENGTH = 16,
+	INPUT  = gbtreekey16_in,
+	OUTPUT = gbtreekey16_out
+);
+
+CREATE FUNCTION gbtreekey32_in(cstring)
+RETURNS gbtreekey32
+AS 'MODULE_PATHNAME', 'gbtreekey_in'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbtreekey32_out(gbtreekey32)
+RETURNS cstring
+AS 'MODULE_PATHNAME', 'gbtreekey_out'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE TYPE gbtreekey32 (
+	INTERNALLENGTH = 32,
+	INPUT  = gbtreekey32_in,
+	OUTPUT = gbtreekey32_out
+);
+
+CREATE FUNCTION gbtreekey_var_in(cstring)
+RETURNS gbtreekey_var
+AS 'MODULE_PATHNAME', 'gbtreekey_in'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbtreekey_var_out(gbtreekey_var)
+RETURNS cstring
+AS 'MODULE_PATHNAME', 'gbtreekey_out'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE TYPE gbtreekey_var (
+	INTERNALLENGTH = VARIABLE,
+	INPUT  = gbtreekey_var_in,
+	OUTPUT = gbtreekey_var_out,
+	STORAGE = EXTENDED
+);
+
+--distance operators
+
+CREATE FUNCTION cash_dist(money, money)
+RETURNS money
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR <-> (
+	LEFTARG = money,
+	RIGHTARG = money,
+	PROCEDURE = cash_dist,
+	COMMUTATOR = '<->'
+);
+
+CREATE FUNCTION date_dist(date, date)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR <-> (
+	LEFTARG = date,
+	RIGHTARG = date,
+	PROCEDURE = date_dist,
+	COMMUTATOR = '<->'
+);
+
+CREATE FUNCTION float4_dist(float4, float4)
+RETURNS float4
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR <-> (
+	LEFTARG = float4,
+	RIGHTARG = float4,
+	PROCEDURE = float4_dist,
+	COMMUTATOR = '<->'
+);
+
+CREATE FUNCTION float8_dist(float8, float8)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR <-> (
+	LEFTARG = float8,
+	RIGHTARG = float8,
+	PROCEDURE = float8_dist,
+	COMMUTATOR = '<->'
+);
+
+CREATE FUNCTION int2_dist(int2, int2)
+RETURNS int2
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR <-> (
+	LEFTARG = int2,
+	RIGHTARG = int2,
+	PROCEDURE = int2_dist,
+	COMMUTATOR = '<->'
+);
+
+CREATE FUNCTION int4_dist(int4, int4)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR <-> (
+	LEFTARG = int4,
+	RIGHTARG = int4,
+	PROCEDURE = int4_dist,
+	COMMUTATOR = '<->'
+);
+
+CREATE FUNCTION int8_dist(int8, int8)
+RETURNS int8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR <-> (
+	LEFTARG = int8,
+	RIGHTARG = int8,
+	PROCEDURE = int8_dist,
+	COMMUTATOR = '<->'
+);
+
+CREATE FUNCTION interval_dist(interval, interval)
+RETURNS interval
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR <-> (
+	LEFTARG = interval,
+	RIGHTARG = interval,
+	PROCEDURE = interval_dist,
+	COMMUTATOR = '<->'
+);
+
+CREATE FUNCTION oid_dist(oid, oid)
+RETURNS oid
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR <-> (
+	LEFTARG = oid,
+	RIGHTARG = oid,
+	PROCEDURE = oid_dist,
+	COMMUTATOR = '<->'
+);
+
+CREATE FUNCTION time_dist(time, time)
+RETURNS interval
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR <-> (
+	LEFTARG = time,
+	RIGHTARG = time,
+	PROCEDURE = time_dist,
+	COMMUTATOR = '<->'
+);
+
+CREATE FUNCTION ts_dist(timestamp, timestamp)
+RETURNS interval
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR <-> (
+	LEFTARG = timestamp,
+	RIGHTARG = timestamp,
+	PROCEDURE = ts_dist,
+	COMMUTATOR = '<->'
+);
+
+CREATE FUNCTION tstz_dist(timestamptz, timestamptz)
+RETURNS interval
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR <-> (
+	LEFTARG = timestamptz,
+	RIGHTARG = timestamptz,
+	PROCEDURE = tstz_dist,
+	COMMUTATOR = '<->'
+);
+
+
+--
+--
+--
+-- oid ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_oid_consistent(internal,oid,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_oid_distance(internal,oid,int2,oid,internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_oid_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_oid_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_decompress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_var_decompress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_var_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_oid_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_oid_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_oid_union(internal, internal)
+RETURNS gbtreekey8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_oid_same(gbtreekey8, gbtreekey8, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_oid_ops
+DEFAULT FOR TYPE oid USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_oid_consistent (internal, oid, int2, oid, internal),
+	FUNCTION	2	gbt_oid_union (internal, internal),
+	FUNCTION	3	gbt_oid_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_oid_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_oid_picksplit (internal, internal),
+	FUNCTION	7	gbt_oid_same (gbtreekey8, gbtreekey8, internal),
+	STORAGE		gbtreekey8;
+
+-- Add operators that are new in 9.1.  We do it like this, leaving them
+-- "loose" in the operator family rather than bound into the opclass, because
+-- that's the only state that can be reproduced during an upgrade from 9.0.
+ALTER OPERATOR FAMILY gist_oid_ops USING gist ADD
+	OPERATOR	6	<> (oid, oid) ,
+	OPERATOR	15	<-> (oid, oid) FOR ORDER BY pg_catalog.oid_ops ,
+	FUNCTION	8 (oid, oid) gbt_oid_distance (internal, oid, int2, oid, internal) ,
+	-- Also add support function for index-only-scans, added in 9.5.
+	FUNCTION	9 (oid, oid) gbt_oid_fetch (internal) ;
+
+
+--
+--
+--
+-- enum ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_enum_consistent(internal,anyenum,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_union(internal, internal)
+RETURNS gbtreekey4
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_same(gbtreekey8, gbtreekey8, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_enum_ops
+DEFAULT FOR TYPE anyenum USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_enum_consistent (internal, anyenum, int2, oid, internal),
+	FUNCTION	2	gbt_enum_union (internal, internal),
+	FUNCTION	3	gbt_enum_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_enum_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_enum_picksplit (internal, internal),
+	FUNCTION	7	gbt_enum_same (gbtreekey8, gbtreekey8, internal),
+	STORAGE		gbtreekey8;
+
+ALTER OPERATOR FAMILY gist_enum_ops USING gist ADD
+	OPERATOR	6	<> (anyenum, anyenum) ,
+	FUNCTION	9 (anyenum, anyenum) gbt_enum_fetch (internal) ;
+
+--
+--
+--
+-- int2 ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_int2_consistent(internal,int2,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int2_distance(internal,int2,int2,oid,internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int2_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int2_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int2_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int2_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int2_union(internal, internal)
+RETURNS gbtreekey4
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int2_same(gbtreekey4, gbtreekey4, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_int2_ops
+DEFAULT FOR TYPE int2 USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_int2_consistent (internal, int2, int2, oid, internal),
+	FUNCTION	2	gbt_int2_union (internal, internal),
+	FUNCTION	3	gbt_int2_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_int2_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_int2_picksplit (internal, internal),
+	FUNCTION	7	gbt_int2_same (gbtreekey4, gbtreekey4, internal),
+	STORAGE		gbtreekey4;
+
+ALTER OPERATOR FAMILY gist_int2_ops USING gist ADD
+	OPERATOR	6	<> (int2, int2) ,
+	OPERATOR	15	<-> (int2, int2) FOR ORDER BY pg_catalog.integer_ops ,
+	FUNCTION	8 (int2, int2) gbt_int2_distance (internal, int2, int2, oid, internal) ,
+	FUNCTION	9 (int2, int2) gbt_int2_fetch (internal) ;
+
+--
+--
+--
+-- int4 ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_int4_consistent(internal,int4,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int4_distance(internal,int4,int2,oid,internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int4_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int4_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int4_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int4_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int4_union(internal, internal)
+RETURNS gbtreekey8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int4_same(gbtreekey8, gbtreekey8, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_int4_ops
+DEFAULT FOR TYPE int4 USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_int4_consistent (internal, int4, int2, oid, internal),
+	FUNCTION	2	gbt_int4_union (internal, internal),
+	FUNCTION	3	gbt_int4_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_int4_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_int4_picksplit (internal, internal),
+	FUNCTION	7	gbt_int4_same (gbtreekey8, gbtreekey8, internal),
+	STORAGE		gbtreekey8;
+
+ALTER OPERATOR FAMILY gist_int4_ops USING gist ADD
+	OPERATOR	6	<> (int4, int4) ,
+	OPERATOR	15	<-> (int4, int4) FOR ORDER BY pg_catalog.integer_ops ,
+	FUNCTION	8 (int4, int4) gbt_int4_distance (internal, int4, int2, oid, internal) ,
+	FUNCTION	9 (int4, int4) gbt_int4_fetch (internal) ;
+
+
+--
+--
+--
+-- int8 ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_int8_consistent(internal,int8,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int8_distance(internal,int8,int2,oid,internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int8_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int8_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int8_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int8_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int8_union(internal, internal)
+RETURNS gbtreekey16
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int8_same(gbtreekey16, gbtreekey16, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_int8_ops
+DEFAULT FOR TYPE int8 USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_int8_consistent (internal, int8, int2, oid, internal),
+	FUNCTION	2	gbt_int8_union (internal, internal),
+	FUNCTION	3	gbt_int8_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_int8_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_int8_picksplit (internal, internal),
+	FUNCTION	7	gbt_int8_same (gbtreekey16, gbtreekey16, internal),
+	STORAGE		gbtreekey16;
+
+ALTER OPERATOR FAMILY gist_int8_ops USING gist ADD
+	OPERATOR	6	<> (int8, int8) ,
+	OPERATOR	15	<-> (int8, int8) FOR ORDER BY pg_catalog.integer_ops ,
+	FUNCTION	8 (int8, int8) gbt_int8_distance (internal, int8, int2, oid, internal) ,
+	FUNCTION	9 (int8, int8) gbt_int8_fetch (internal) ;
+
+--
+--
+--
+-- float4 ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_float4_consistent(internal,float4,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float4_distance(internal,float4,int2,oid,internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float4_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float4_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float4_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float4_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float4_union(internal, internal)
+RETURNS gbtreekey8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float4_same(gbtreekey8, gbtreekey8, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_float4_ops
+DEFAULT FOR TYPE float4 USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_float4_consistent (internal, float4, int2, oid, internal),
+	FUNCTION	2	gbt_float4_union (internal, internal),
+	FUNCTION	3	gbt_float4_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_float4_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_float4_picksplit (internal, internal),
+	FUNCTION	7	gbt_float4_same (gbtreekey8, gbtreekey8, internal),
+	STORAGE		gbtreekey8;
+
+ALTER OPERATOR FAMILY gist_float4_ops USING gist ADD
+	OPERATOR	6	<> (float4, float4) ,
+	OPERATOR	15	<-> (float4, float4) FOR ORDER BY pg_catalog.float_ops ,
+	FUNCTION	8 (float4, float4) gbt_float4_distance (internal, float4, int2, oid, internal) ,
+	FUNCTION	9 (float4, float4) gbt_float4_fetch (internal) ;
+
+--
+--
+--
+-- float8 ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_float8_consistent(internal,float8,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float8_distance(internal,float8,int2,oid,internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float8_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float8_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float8_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float8_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float8_union(internal, internal)
+RETURNS gbtreekey16
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float8_same(gbtreekey16, gbtreekey16, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_float8_ops
+DEFAULT FOR TYPE float8 USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_float8_consistent (internal, float8, int2, oid, internal),
+	FUNCTION	2	gbt_float8_union (internal, internal),
+	FUNCTION	3	gbt_float8_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_float8_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_float8_picksplit (internal, internal),
+	FUNCTION	7	gbt_float8_same (gbtreekey16, gbtreekey16, internal),
+	STORAGE		gbtreekey16;
+
+ALTER OPERATOR FAMILY gist_float8_ops USING gist ADD
+	OPERATOR	6	<> (float8, float8) ,
+	OPERATOR	15	<-> (float8, float8) FOR ORDER BY pg_catalog.float_ops ,
+	FUNCTION	8 (float8, float8) gbt_float8_distance (internal, float8, int2, oid, internal) ,
+	FUNCTION	9 (float8, float8) gbt_float8_fetch (internal) ;
+
+--
+--
+--
+-- timestamp ops
+--
+--
+--
+
+CREATE FUNCTION gbt_ts_consistent(internal,timestamp,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_ts_distance(internal,timestamp,int2,oid,internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_tstz_consistent(internal,timestamptz,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_tstz_distance(internal,timestamptz,int2,oid,internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_ts_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_tstz_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_ts_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_ts_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_ts_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_ts_union(internal, internal)
+RETURNS gbtreekey16
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_ts_same(gbtreekey16, gbtreekey16, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_timestamp_ops
+DEFAULT FOR TYPE timestamp USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_ts_consistent (internal, timestamp, int2, oid, internal),
+	FUNCTION	2	gbt_ts_union (internal, internal),
+	FUNCTION	3	gbt_ts_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_ts_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_ts_picksplit (internal, internal),
+	FUNCTION	7	gbt_ts_same (gbtreekey16, gbtreekey16, internal),
+	STORAGE		gbtreekey16;
+
+ALTER OPERATOR FAMILY gist_timestamp_ops USING gist ADD
+	OPERATOR	6	<> (timestamp, timestamp) ,
+	OPERATOR	15	<-> (timestamp, timestamp) FOR ORDER BY pg_catalog.interval_ops ,
+	FUNCTION	8 (timestamp, timestamp) gbt_ts_distance (internal, timestamp, int2, oid, internal) ,
+	FUNCTION	9 (timestamp, timestamp) gbt_ts_fetch (internal) ;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_timestamptz_ops
+DEFAULT FOR TYPE timestamptz USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_tstz_consistent (internal, timestamptz, int2, oid, internal),
+	FUNCTION	2	gbt_ts_union (internal, internal),
+	FUNCTION	3	gbt_tstz_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_ts_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_ts_picksplit (internal, internal),
+	FUNCTION	7	gbt_ts_same (gbtreekey16, gbtreekey16, internal),
+	STORAGE		gbtreekey16;
+
+ALTER OPERATOR FAMILY gist_timestamptz_ops USING gist ADD
+	OPERATOR	6	<> (timestamptz, timestamptz) ,
+	OPERATOR	15	<-> (timestamptz, timestamptz) FOR ORDER BY pg_catalog.interval_ops ,
+	FUNCTION	8 (timestamptz, timestamptz) gbt_tstz_distance (internal, timestamptz, int2, oid, internal) ,
+	FUNCTION	9 (timestamptz, timestamptz) gbt_ts_fetch (internal) ;
+
+--
+--
+--
+-- time ops
+--
+--
+--
+
+CREATE FUNCTION gbt_time_consistent(internal,time,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_time_distance(internal,time,int2,oid,internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_timetz_consistent(internal,timetz,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_time_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_timetz_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_time_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_time_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_time_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_time_union(internal, internal)
+RETURNS gbtreekey16
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_time_same(gbtreekey16, gbtreekey16, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_time_ops
+DEFAULT FOR TYPE time USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_time_consistent (internal, time, int2, oid, internal),
+	FUNCTION	2	gbt_time_union (internal, internal),
+	FUNCTION	3	gbt_time_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_time_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_time_picksplit (internal, internal),
+	FUNCTION	7	gbt_time_same (gbtreekey16, gbtreekey16, internal),
+	STORAGE		gbtreekey16;
+
+ALTER OPERATOR FAMILY gist_time_ops USING gist ADD
+	OPERATOR	6	<> (time, time) ,
+	OPERATOR	15	<-> (time, time) FOR ORDER BY pg_catalog.interval_ops ,
+	FUNCTION	8 (time, time) gbt_time_distance (internal, time, int2, oid, internal) ,
+	FUNCTION	9 (time, time) gbt_time_fetch (internal) ;
+
+
+CREATE OPERATOR CLASS gist_timetz_ops
+DEFAULT FOR TYPE timetz USING gist
+AS
+	OPERATOR	1	<   ,
+	OPERATOR	2	<=  ,
+	OPERATOR	3	=   ,
+	OPERATOR	4	>=  ,
+	OPERATOR	5	>   ,
+	FUNCTION	1	gbt_timetz_consistent (internal, timetz, int2, oid, internal),
+	FUNCTION	2	gbt_time_union (internal, internal),
+	FUNCTION	3	gbt_timetz_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_time_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_time_picksplit (internal, internal),
+	FUNCTION	7	gbt_time_same (gbtreekey16, gbtreekey16, internal),
+	STORAGE		gbtreekey16;
+
+ALTER OPERATOR FAMILY gist_timetz_ops USING gist ADD
+	OPERATOR	6	<> (timetz, timetz) ;
+	-- no 'fetch' function, as the compress function is lossy.
+
+
+--
+--
+--
+-- date ops
+--
+--
+--
+
+CREATE FUNCTION gbt_date_consistent(internal,date,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_date_distance(internal,date,int2,oid,internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_date_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_date_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_date_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_date_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_date_union(internal, internal)
+RETURNS gbtreekey8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_date_same(gbtreekey8, gbtreekey8, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_date_ops
+DEFAULT FOR TYPE date USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_date_consistent (internal, date, int2, oid, internal),
+	FUNCTION	2	gbt_date_union (internal, internal),
+	FUNCTION	3	gbt_date_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_date_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_date_picksplit (internal, internal),
+	FUNCTION	7	gbt_date_same (gbtreekey8, gbtreekey8, internal),
+	STORAGE		gbtreekey8;
+
+ALTER OPERATOR FAMILY gist_date_ops USING gist ADD
+	OPERATOR	6	<> (date, date) ,
+	OPERATOR	15	<-> (date, date) FOR ORDER BY pg_catalog.integer_ops ,
+	FUNCTION	8 (date, date) gbt_date_distance (internal, date, int2, oid, internal) ,
+	FUNCTION	9 (date, date) gbt_date_fetch (internal) ;
+
+
+--
+--
+--
+-- interval ops
+--
+--
+--
+
+CREATE FUNCTION gbt_intv_consistent(internal,interval,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_intv_distance(internal,interval,int2,oid,internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_intv_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_intv_decompress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_intv_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_intv_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_intv_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_intv_union(internal, internal)
+RETURNS gbtreekey32
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_intv_same(gbtreekey32, gbtreekey32, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_interval_ops
+DEFAULT FOR TYPE interval USING gist
+AS
+	OPERATOR	1	< ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	= ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	> ,
+	FUNCTION	1	gbt_intv_consistent (internal, interval, int2, oid, internal),
+	FUNCTION	2	gbt_intv_union (internal, internal),
+	FUNCTION	3	gbt_intv_compress (internal),
+	FUNCTION	4	gbt_intv_decompress (internal),
+	FUNCTION	5	gbt_intv_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_intv_picksplit (internal, internal),
+	FUNCTION	7	gbt_intv_same (gbtreekey32, gbtreekey32, internal),
+	STORAGE		gbtreekey32;
+
+ALTER OPERATOR FAMILY gist_interval_ops USING gist ADD
+	OPERATOR	6	<> (interval, interval) ,
+	OPERATOR	15	<-> (interval, interval) FOR ORDER BY pg_catalog.interval_ops ,
+	FUNCTION	8 (interval, interval) gbt_intv_distance (internal, interval, int2, oid, internal) ,
+	FUNCTION	9 (interval, interval) gbt_intv_fetch (internal) ;
+
+
+--
+--
+--
+-- cash ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_cash_consistent(internal,money,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_cash_distance(internal,money,int2,oid,internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_cash_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_cash_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_cash_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_cash_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_cash_union(internal, internal)
+RETURNS gbtreekey16
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_cash_same(gbtreekey16, gbtreekey16, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_cash_ops
+DEFAULT FOR TYPE money USING gist
+AS
+	OPERATOR	1	< ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	= ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	> ,
+	FUNCTION	1	gbt_cash_consistent (internal, money, int2, oid, internal),
+	FUNCTION	2	gbt_cash_union (internal, internal),
+	FUNCTION	3	gbt_cash_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_cash_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_cash_picksplit (internal, internal),
+	FUNCTION	7	gbt_cash_same (gbtreekey16, gbtreekey16, internal),
+	STORAGE		gbtreekey16;
+
+ALTER OPERATOR FAMILY gist_cash_ops USING gist ADD
+	OPERATOR	6	<> (money, money) ,
+	OPERATOR	15	<-> (money, money) FOR ORDER BY pg_catalog.money_ops ,
+	FUNCTION	8 (money, money) gbt_cash_distance (internal, money, int2, oid, internal) ,
+	FUNCTION	9 (money, money) gbt_cash_fetch (internal) ;
+
+
+--
+--
+--
+-- macaddr ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_macad_consistent(internal,macaddr,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_macad_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_macad_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_macad_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_macad_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_macad_union(internal, internal)
+RETURNS gbtreekey16
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_macad_same(gbtreekey16, gbtreekey16, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_macaddr_ops
+DEFAULT FOR TYPE macaddr USING gist
+AS
+	OPERATOR	1	< ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	= ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	> ,
+	FUNCTION	1	gbt_macad_consistent (internal, macaddr, int2, oid, internal),
+	FUNCTION	2	gbt_macad_union (internal, internal),
+	FUNCTION	3	gbt_macad_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_macad_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_macad_picksplit (internal, internal),
+	FUNCTION	7	gbt_macad_same (gbtreekey16, gbtreekey16, internal),
+	STORAGE		gbtreekey16;
+
+ALTER OPERATOR FAMILY gist_macaddr_ops USING gist ADD
+	OPERATOR	6	<> (macaddr, macaddr) ,
+	FUNCTION	9 (macaddr, macaddr) gbt_macad_fetch (internal);
+
+
+--
+--
+--
+-- text/ bpchar ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_text_consistent(internal,text,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bpchar_consistent(internal,bpchar,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_text_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bpchar_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_text_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_text_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_text_union(internal, internal)
+RETURNS gbtreekey_var
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_text_same(gbtreekey_var, gbtreekey_var, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_text_ops
+DEFAULT FOR TYPE text USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_text_consistent (internal, text, int2, oid, internal),
+	FUNCTION	2	gbt_text_union (internal, internal),
+	FUNCTION	3	gbt_text_compress (internal),
+	FUNCTION	4	gbt_var_decompress (internal),
+	FUNCTION	5	gbt_text_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_text_picksplit (internal, internal),
+	FUNCTION	7	gbt_text_same (gbtreekey_var, gbtreekey_var, internal),
+	STORAGE			gbtreekey_var;
+
+ALTER OPERATOR FAMILY gist_text_ops USING gist ADD
+	OPERATOR	6	<> (text, text) ,
+	FUNCTION	9 (text, text) gbt_var_fetch (internal) ;
+
+
+---- Create the operator class
+CREATE OPERATOR CLASS gist_bpchar_ops
+DEFAULT FOR TYPE bpchar USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_bpchar_consistent (internal, bpchar , int2, oid, internal),
+	FUNCTION	2	gbt_text_union (internal, internal),
+	FUNCTION	3	gbt_bpchar_compress (internal),
+	FUNCTION	4	gbt_var_decompress (internal),
+	FUNCTION	5	gbt_text_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_text_picksplit (internal, internal),
+	FUNCTION	7	gbt_text_same (gbtreekey_var, gbtreekey_var, internal),
+	STORAGE			gbtreekey_var;
+
+ALTER OPERATOR FAMILY gist_bpchar_ops USING gist ADD
+	OPERATOR	6	<> (bpchar, bpchar) ,
+	FUNCTION	9 (bpchar, bpchar) gbt_var_fetch (internal) ;
+
+--
+--
+-- bytea ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_bytea_consistent(internal,bytea,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bytea_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bytea_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bytea_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bytea_union(internal, internal)
+RETURNS gbtreekey_var
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bytea_same(gbtreekey_var, gbtreekey_var, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_bytea_ops
+DEFAULT FOR TYPE bytea USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_bytea_consistent (internal, bytea, int2, oid, internal),
+	FUNCTION	2	gbt_bytea_union (internal, internal),
+	FUNCTION	3	gbt_bytea_compress (internal),
+	FUNCTION	4	gbt_var_decompress (internal),
+	FUNCTION	5	gbt_bytea_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_bytea_picksplit (internal, internal),
+	FUNCTION	7	gbt_bytea_same (gbtreekey_var, gbtreekey_var, internal),
+	STORAGE			gbtreekey_var;
+
+ALTER OPERATOR FAMILY gist_bytea_ops USING gist ADD
+	OPERATOR	6	<> (bytea, bytea) ,
+	FUNCTION	9 (bytea, bytea) gbt_var_fetch (internal) ;
+
+
+--
+--
+--
+-- numeric ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_numeric_consistent(internal,numeric,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_numeric_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_numeric_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_numeric_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_numeric_union(internal, internal)
+RETURNS gbtreekey_var
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_numeric_same(gbtreekey_var, gbtreekey_var, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_numeric_ops
+DEFAULT FOR TYPE numeric USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_numeric_consistent (internal, numeric, int2, oid, internal),
+	FUNCTION	2	gbt_numeric_union (internal, internal),
+	FUNCTION	3	gbt_numeric_compress (internal),
+	FUNCTION	4	gbt_var_decompress (internal),
+	FUNCTION	5	gbt_numeric_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_numeric_picksplit (internal, internal),
+	FUNCTION	7	gbt_numeric_same (gbtreekey_var, gbtreekey_var, internal),
+	STORAGE			gbtreekey_var;
+
+ALTER OPERATOR FAMILY gist_numeric_ops USING gist ADD
+	OPERATOR	6	<> (numeric, numeric) ,
+	FUNCTION	9 (numeric, numeric) gbt_var_fetch (internal) ;
+
+
+--
+--
+-- bit ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_bit_consistent(internal,bit,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bit_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bit_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bit_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bit_union(internal, internal)
+RETURNS gbtreekey_var
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bit_same(gbtreekey_var, gbtreekey_var, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_bit_ops
+DEFAULT FOR TYPE bit USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_bit_consistent (internal, bit, int2, oid, internal),
+	FUNCTION	2	gbt_bit_union (internal, internal),
+	FUNCTION	3	gbt_bit_compress (internal),
+	FUNCTION	4	gbt_var_decompress (internal),
+	FUNCTION	5	gbt_bit_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_bit_picksplit (internal, internal),
+	FUNCTION	7	gbt_bit_same (gbtreekey_var, gbtreekey_var, internal),
+	STORAGE			gbtreekey_var;
+
+ALTER OPERATOR FAMILY gist_bit_ops USING gist ADD
+	OPERATOR	6	<> (bit, bit) ,
+	FUNCTION	9 (bit, bit) gbt_var_fetch (internal) ;
+
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_vbit_ops
+DEFAULT FOR TYPE varbit USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_bit_consistent (internal, bit, int2, oid, internal),
+	FUNCTION	2	gbt_bit_union (internal, internal),
+	FUNCTION	3	gbt_bit_compress (internal),
+	FUNCTION	4	gbt_var_decompress (internal),
+	FUNCTION	5	gbt_bit_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_bit_picksplit (internal, internal),
+	FUNCTION	7	gbt_bit_same (gbtreekey_var, gbtreekey_var, internal),
+	STORAGE			gbtreekey_var;
+
+ALTER OPERATOR FAMILY gist_vbit_ops USING gist ADD
+	OPERATOR	6	<> (varbit, varbit) ,
+	FUNCTION	9 (varbit, varbit) gbt_var_fetch (internal) ;
+
+
+--
+--
+--
+-- inet/cidr ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_inet_consistent(internal,inet,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_inet_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_inet_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_inet_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_inet_union(internal, internal)
+RETURNS gbtreekey16
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_inet_same(gbtreekey16, gbtreekey16, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_inet_ops
+DEFAULT FOR TYPE inet USING gist
+AS
+	OPERATOR	1	<   ,
+	OPERATOR	2	<=  ,
+	OPERATOR	3	=   ,
+	OPERATOR	4	>=  ,
+	OPERATOR	5	>   ,
+	FUNCTION	1	gbt_inet_consistent (internal, inet, int2, oid, internal),
+	FUNCTION	2	gbt_inet_union (internal, internal),
+	FUNCTION	3	gbt_inet_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_inet_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_inet_picksplit (internal, internal),
+	FUNCTION	7	gbt_inet_same (gbtreekey16, gbtreekey16, internal),
+	STORAGE		gbtreekey16;
+
+ALTER OPERATOR FAMILY gist_inet_ops USING gist ADD
+	OPERATOR	6	<>  (inet, inet) ;
+	-- no fetch support, the compress function is lossy
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_cidr_ops
+DEFAULT FOR TYPE cidr USING gist
+AS
+	OPERATOR	1	<  (inet, inet)  ,
+	OPERATOR	2	<= (inet, inet)  ,
+	OPERATOR	3	=  (inet, inet)  ,
+	OPERATOR	4	>= (inet, inet)  ,
+	OPERATOR	5	>  (inet, inet)  ,
+	FUNCTION	1	gbt_inet_consistent (internal, inet, int2, oid, internal),
+	FUNCTION	2	gbt_inet_union (internal, internal),
+	FUNCTION	3	gbt_inet_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_inet_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_inet_picksplit (internal, internal),
+	FUNCTION	7	gbt_inet_same (gbtreekey16, gbtreekey16, internal),
+	STORAGE		gbtreekey16;
+
+ALTER OPERATOR FAMILY gist_cidr_ops USING gist ADD
+	OPERATOR	6	<> (inet, inet) ;
+	-- no fetch support, the compress function is lossy
diff --git a/contrib/btree_gist/btree_gist.control b/contrib/btree_gist/btree_gist.control
index c7adfeb..74d0e92 100644
--- a/contrib/btree_gist/btree_gist.control
+++ b/contrib/btree_gist/btree_gist.control
@@ -1,5 +1,5 @@
 # btree_gist extension
 comment = 'support for indexing common datatypes in GiST'
-default_version = '1.1'
+default_version = '1.2'
 module_pathname = '$libdir/btree_gist'
 relocatable = true
diff --git a/contrib/btree_gist/btree_gist.h b/contrib/btree_gist/btree_gist.h
index dcffbb5..61f8d83 100644
--- a/contrib/btree_gist/btree_gist.h
+++ b/contrib/btree_gist/btree_gist.h
@@ -31,7 +31,8 @@ enum gbtree_type
 	gbt_t_bpchar,
 	gbt_t_bytea,
 	gbt_t_bit,
-	gbt_t_inet
+	gbt_t_inet,
+	gbt_t_enum
 };
 
 
diff --git a/contrib/btree_gist/btree_utils_num.c b/contrib/btree_gist/btree_utils_num.c
index 99cb41f..79f40a9 100644
--- a/contrib/btree_gist/btree_utils_num.c
+++ b/contrib/btree_gist/btree_utils_num.c
@@ -48,6 +48,7 @@ gbt_num_compress(GISTENTRY *entry, const gbtree_ninfo *tinfo)
 				leaf = &v.i8;
 				break;
 			case gbt_t_oid:
+			case gbt_t_enum:
 				v.i4 = DatumGetObjectId(entry->key);
 				leaf = &v.i4;
 				break;
@@ -122,6 +123,7 @@ gbt_num_fetch(GISTENTRY *entry, const gbtree_ninfo *tinfo)
 			datum = Int64GetDatum(*(int64 *) entry->key);
 			break;
 		case gbt_t_oid:
+		case gbt_t_enum:
 			datum = ObjectIdGetDatum(*(Oid *) entry->key);
 			break;
 		case gbt_t_float4:
diff --git a/contrib/btree_gist/data/enum.data b/contrib/btree_gist/data/enum.data
new file mode 100644
index 0000000..d03bfce
--- /dev/null
+++ b/contrib/btree_gist/data/enum.data
@@ -0,0 +1,595 @@
+r
+v
+i
+b
+r
+\N
+y
+v
+g
+o
+y
+b
+o
+o
+o
+o
+v
+r
+i
+o
+b
+r
+g
+b
+i
+o
+r
+r
+r
+\N
+o
+b
+v
+y
+o
+\N
+i
+o
+o
+g
+g
+b
+y
+v
+g
+g
+\N
+v
+g
+i
+i
+\N
+v
+y
+i
+r
+\N
+r
+\N
+g
+\N
+g
+\N
+v
+g
+y
+v
+r
+v
+r
+v
+y
+i
+i
+v
+y
+v
+i
+b
+i
+i
+r
+r
+\N
+\N
+y
+r
+g
+i
+y
+i
+i
+r
+g
+y
+\N
+i
+o
+r
+y
+y
+g
+o
+o
+g
+y
+r
+g
+v
+r
+i
+r
+i
+r
+y
+v
+b
+i
+o
+r
+\N
+o
+i
+v
+o
+b
+\N
+b
+g
+y
+o
+v
+b
+i
+v
+v
+o
+y
+i
+i
+i
+g
+b
+b
+g
+r
+i
+y
+o
+\N
+r
+\N
+i
+i
+g
+v
+o
+y
+y
+o
+i
+b
+r
+y
+y
+o
+g
+g
+g
+\N
+y
+o
+v
+g
+y
+g
+v
+\N
+i
+o
+v
+b
+b
+\N
+y
+v
+\N
+v
+\N
+i
+\N
+r
+b
+r
+o
+r
+b
+o
+g
+i
+r
+b
+g
+g
+y
+b
+b
+g
+y
+g
+v
+v
+b
+\N
+i
+v
+y
+b
+b
+o
+g
+b
+v
+g
+g
+b
+\N
+y
+r
+r
+b
+\N
+r
+g
+i
+o
+v
+\N
+o
+r
+b
+o
+b
+i
+\N
+\N
+y
+b
+y
+\N
+i
+i
+i
+o
+y
+o
+i
+b
+o
+g
+r
+\N
+b
+y
+\N
+g
+b
+y
+y
+o
+o
+b
+g
+i
+i
+v
+b
+o
+o
+v
+i
+g
+i
+o
+r
+o
+i
+i
+r
+b
+g
+o
+o
+y
+v
+g
+g
+g
+r
+o
+i
+i
+g
+\N
+o
+v
+b
+b
+v
+i
+g
+y
+i
+i
+g
+r
+y
+i
+b
+\N
+g
+y
+o
+\N
+i
+i
+b
+v
+o
+b
+v
+r
+g
+o
+v
+v
+y
+r
+v
+g
+\N
+v
+v
+b
+y
+o
+g
+i
+o
+b
+r
+y
+r
+v
+b
+b
+\N
+i
+v
+y
+r
+b
+i
+y
+g
+\N
+g
+r
+y
+y
+g
+b
+o
+v
+r
+i
+g
+r
+b
+b
+b
+\N
+y
+y
+y
+i
+o
+r
+g
+g
+i
+y
+g
+y
+v
+o
+o
+g
+\N
+b
+v
+o
+y
+r
+\N
+o
+i
+g
+\N
+i
+i
+i
+o
+b
+\N
+\N
+b
+\N
+v
+v
+r
+\N
+o
+b
+r
+o
+b
+o
+r
+y
+\N
+r
+i
+b
+b
+y
+v
+r
+g
+r
+r
+\N
+g
+\N
+v
+v
+y
+r
+o
+r
+o
+i
+o
+\N
+r
+\N
+i
+v
+b
+v
+\N
+b
+r
+v
+o
+\N
+i
+r
+b
+g
+o
+\N
+o
+g
+r
+v
+y
+g
+v
+r
+b
+r
+v
+o
+g
+i
+i
+g
+i
+y
+b
+i
+y
+r
+y
+o
+r
+b
+y
+y
+b
+y
+g
+b
+\N
+r
+g
+b
+o
+y
+o
+g
+r
+g
+b
+\N
+v
+v
+v
+g
+b
+y
+v
+o
+v
+g
+o
+g
+i
+b
+v
+i
+r
+r
+i
+b
+i
+b
+o
+\N
+\N
+y
+r
+g
+v
+o
+y
+\N
+g
+v
+o
+b
+v
+v
+\N
+r
+v
+y
+g
+b
+o
+v
+b
+v
+b
+r
+r
+i
+r
+v
+y
+v
+y
+o
+v
+g
+i
+r
+o
+o
+i
+y
+r
+\N
+y
+r
+b
+y
+y
+\N
+b
+\N
+\N
+i
+v
diff --git a/contrib/btree_gist/expected/enum.out b/contrib/btree_gist/expected/enum.out
new file mode 100644
index 0000000..c4b769d
--- /dev/null
+++ b/contrib/btree_gist/expected/enum.out
@@ -0,0 +1,91 @@
+-- enum check
+create type rainbow as enum ('r','o','y','g','b','i','v');
+CREATE TABLE enumtmp (a rainbow);
+\copy enumtmp from 'data/enum.data'
+SET enable_seqscan=on;
+select a, count(*) from enumtmp group by a order by 1;
+ a | count 
+---+-------
+ r |    76
+ o |    78
+ y |    73
+ g |    75
+ b |    77
+ i |    78
+ v |    75
+   |    63
+(8 rows)
+
+SELECT count(*) FROM enumtmp WHERE a <  'g'::rainbow;
+ count 
+-------
+   227
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a <= 'g'::rainbow;
+ count 
+-------
+   302
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a  = 'g'::rainbow;
+ count 
+-------
+    75
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a >= 'g'::rainbow;
+ count 
+-------
+   305
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a >  'g'::rainbow;
+ count 
+-------
+   230
+(1 row)
+
+CREATE INDEX enumidx ON enumtmp USING gist ( a );
+SET enable_seqscan=off;
+SELECT count(*) FROM enumtmp WHERE a <  'g'::rainbow;
+ count 
+-------
+   227
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a <= 'g'::rainbow;
+ count 
+-------
+   302
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a  = 'g'::rainbow;
+ count 
+-------
+    75
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a >= 'g'::rainbow;
+ count 
+-------
+   305
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a >  'g'::rainbow;
+ count 
+-------
+   230
+(1 row)
+
+EXPLAIN (COSTS OFF)
+SELECT count(*) FROM enumtmp WHERE a >= 'g'::rainbow;
+                  QUERY PLAN                   
+-----------------------------------------------
+ Aggregate
+   ->  Bitmap Heap Scan on enumtmp
+         Recheck Cond: (a >= 'g'::rainbow)
+         ->  Bitmap Index Scan on enumidx
+               Index Cond: (a >= 'g'::rainbow)
+(5 rows)
+
diff --git a/contrib/btree_gist/sql/enum.sql b/contrib/btree_gist/sql/enum.sql
new file mode 100644
index 0000000..476211e
--- /dev/null
+++ b/contrib/btree_gist/sql/enum.sql
@@ -0,0 +1,38 @@
+-- enum check
+
+create type rainbow as enum ('r','o','y','g','b','i','v');
+
+CREATE TABLE enumtmp (a rainbow);
+
+\copy enumtmp from 'data/enum.data'
+
+SET enable_seqscan=on;
+
+select a, count(*) from enumtmp group by a order by 1;
+
+SELECT count(*) FROM enumtmp WHERE a <  'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a <= 'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a  = 'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a >= 'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a >  'g'::rainbow;
+
+CREATE INDEX enumidx ON enumtmp USING gist ( a );
+
+SET enable_seqscan=off;
+
+SELECT count(*) FROM enumtmp WHERE a <  'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a <= 'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a  = 'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a >= 'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a >  'g'::rainbow;
+
+EXPLAIN (COSTS OFF)
+SELECT count(*) FROM enumtmp WHERE a >= 'g'::rainbow;
diff --git a/doc/src/sgml/btree-gin.sgml b/doc/src/sgml/btree-gin.sgml
index 2b081db..f407e92 100644
--- a/doc/src/sgml/btree-gin.sgml
+++ b/doc/src/sgml/btree-gin.sgml
@@ -16,7 +16,8 @@
   <type>time without time zone</>, <type>date</>, <type>interval</>,
   <type>oid</>, <type>money</>, <type>"char"</>,
   <type>varchar</>, <type>text</>, <type>bytea</>, <type>bit</>,
-  <type>varbit</>, <type>macaddr</>, <type>inet</>, and <type>cidr</>.
+  <type>varbit</>, <type>macaddr</>, <type>inet</>, <type>cidr</>,
+  and all <type>enum</> types.
  </para>
 
  <para>
diff --git a/doc/src/sgml/btree-gist.sgml b/doc/src/sgml/btree-gist.sgml
index f4afc09..6db5ae3 100644
--- a/doc/src/sgml/btree-gist.sgml
+++ b/doc/src/sgml/btree-gist.sgml
@@ -16,7 +16,8 @@
   <type>time without time zone</>, <type>date</>, <type>interval</>,
   <type>oid</>, <type>money</>, <type>char</>,
   <type>varchar</>, <type>text</>, <type>bytea</>, <type>bit</>,
-  <type>varbit</>, <type>macaddr</>, <type>inet</>, and <type>cidr</>.
+  <type>varbit</>, <type>macaddr</>, <type>inet</>, <type>cidr</>,
+  and all <type>enum</> types. 
  </para>
 
  <para>
#3Robert Haas
robertmhaas@gmail.com
In reply to: Andrew Dunstan (#2)
Re: btree_gin and btree_gist for enums

On Thu, Mar 17, 2016 at 11:21 AM, Andrew Dunstan <andrew@dunslane.net> wrote:

On 03/17/2016 06:44 AM, Andrew Dunstan wrote:

Here is a patch to add enum support to btree_gin and btree_gist. I didn't
include distance operations, as I didn't think it terribly important, and
there isn't a simple way to compute it sanely and efficiently, so no KNN
support.

This time including the data file for the gist regression tests.

Are you intending this as a 9.7 submission? Because it's pretty late for 9.6.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#4Andrew Dunstan
andrew@dunslane.net
In reply to: Robert Haas (#3)
Re: btree_gin and btree_gist for enums

On 03/18/2016 09:54 AM, Robert Haas wrote:

On Thu, Mar 17, 2016 at 11:21 AM, Andrew Dunstan <andrew@dunslane.net> wrote:

On 03/17/2016 06:44 AM, Andrew Dunstan wrote:

Here is a patch to add enum support to btree_gin and btree_gist. I didn't
include distance operations, as I didn't think it terribly important, and
there isn't a simple way to compute it sanely and efficiently, so no KNN
support.

This time including the data file for the gist regression tests.

Are you intending this as a 9.7 submission? Because it's pretty late for 9.6.

I guess so. I would certainly find it hard to argue that it should be in
9.6 unless there is a consensus on it.

cheers

andrew

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#5Matt Wilmas
pgsql_lists@realplain.com
In reply to: Andrew Dunstan (#1)
Re: btree_gin and btree_gist for enums

Hi Andrew, all,

First message here! I didn't get around to sending an intro/"thank you all"
e-mail yet, and a small performance (?) patch+idea(s)... (CPU stuff, since
I don't otherwise know much about PG internals.) Anyway...

----- Original Message -----
From: "Andrew Dunstan"
Sent: Thursday, March 17, 2016

Here is a patch to add enum support to btree_gin and btree_gist. I
didn't include distance operations, as I didn't think it terribly
important, and there isn't a simple way to compute it sanely and
efficiently, so no KNN support.

Major thanks for coming up with this a week after your "enums and indexing"
message. My love of all things Postgres has a lot to do with being able to
do nearly anything one could want (coming from MySQL :-/)! So I was like,
"Wait, what?" when you brought up the subject, since this was something I
hadn't actually tried, but was planning to use btree_gin/gist with a good
mix of stuff, including enums (array and scalar).

At first I thought it was just arrays of enums, until this patch for the
contrib extensions (for the btree parts with GIN/GiST; plus GiST
exclusion?), and your blog posts... [1]http://adpgtech.blogspot.com/2016/03/gist-and-gin-support-for-enums.html[2]http://adpgtech.blogspot.com/2016/03/gin-indexing-array-of-enums.html I wasn't certain from the second
post whether your array solution can be used today without this patch (yes,
just tried 9.5). So, two separate issues, and the patch addresses scalar
stuff, IIUC.

It would be *really* nice to have this in 9.6. It seems it's simply filling
out functionality that should already be there, right? An oversight/bug fix
so it works "as advertised?" :-) Is any other btree type-compatibility
missing from these modules? (I notice the btree_gin docs don't mention
"numeric," but it works.)

I just looked over the patch, and the actual code addition/changes seem
pretty small and straightforward (or am I wrong?). And it's not changing
anything in the core, so...

Well, just wanted to argue my case! :^)

[1]: http://adpgtech.blogspot.com/2016/03/gist-and-gin-support-for-enums.html
[2]: http://adpgtech.blogspot.com/2016/03/gin-indexing-array-of-enums.html

cheers

andrew

Thanks,
Matt

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#6Andrew Dunstan
andrew@dunslane.net
In reply to: Matt Wilmas (#5)
Re: btree_gin and btree_gist for enums

On 03/24/2016 12:40 PM, Matt Wilmas wrote:

It would be *really* nice to have this in 9.6. It seems it's simply
filling out functionality that should already be there, right? An
oversight/bug fix so it works "as advertised?" :-)

I think that would be stretching the process a bit far. I'm certainly
not prepared to commit it unless there is a general consensus to make an
exception for it.

Is any other btree type-compatibility missing from these modules? (I
notice the btree_gin docs don't mention "numeric," but it works.)

uuid would be another type that should be fairly easily covered but isn't.

I just looked over the patch, and the actual code addition/changes
seem pretty small and straightforward (or am I wrong?).

Yes, sure, it's all fairly simple. Took me a little while to understand
what I was doing, but once I did it was pretty much plain sailing.

cheers

andrew

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#7Andrew Dunstan
andrew@dunslane.net
In reply to: Matt Wilmas (#5)
Re: btree_gin and btree_gist for enums

On 03/24/2016 12:40 PM, Matt Wilmas wrote:

(I notice the btree_gin docs don't mention "numeric," but it works.)

Numeric does work - we have regression tests to prove it, do we should
fix the docs. But I'm also curious to know why apparently we don't have
distance operator support for numeric.

cheers

andrew

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#8Emre Hasegeli
emre@hasegeli.com
In reply to: Andrew Dunstan (#2)
Re: btree_gin and btree_gist for enums

Here is a patch to add enum support to btree_gin and btree_gist. I didn't
include distance operations, as I didn't think it terribly important, and
there isn't a simple way to compute it sanely and efficiently, so no KNN
support.

I don't think we can implement a meaningful distance operator for enums.

This time including the data file for the gist regression tests.

It doesn't apply to HEAD anymore. I have tested it on b12fd41.

The GiST part of it doesn't really work. The current patch compares
oids. We need to change it to compare enumsortorder. I could make it
fail easily:

regression=# create type e as enum ('0', '2', '3');
CREATE TYPE
regression=# alter type e add value '1' after '0';
ALTER TYPE
regression=# create table t as select (i % 4)::text::e from generate_series(0, 100000) as i;
SELECT 100001
regression=# create index on t using gist (e);
SEGFAULT

+ALTER OPERATOR FAMILY gist_enum_ops USING gist ADD

Why don't we just create it with those changes?

+ * Use a similar trick to that used for numeric for enums, since we don't

Do you mean "similar trick that is used" or "trick similar to numeric"?

+ * actually know the leftmost value of any enum without knowing the concrete
+ * type, so we use a dummy leftmost value of InvalidOid.
+    return DatumGetBool(
+                        DirectFunctionCall2(enum_gt, ObjectIdGetDatum(*((const Oid *) a)), ObjectIdGetDatum(*((const Oid *) b)))
+        );

Wouldn't it be nice to refactor enum_cmp_internal() to accept typcache
and use it there like the rangetypes?

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#9Andrew Dunstan
andrew@dunslane.net
In reply to: Emre Hasegeli (#8)
Re: btree_gin and btree_gist for enums

On 11/04/2016 04:14 PM, Emre Hasegeli wrote:

Here is a patch to add enum support to btree_gin and btree_gist. I didn't
include distance operations, as I didn't think it terribly important, and
there isn't a simple way to compute it sanely and efficiently, so no KNN
support.

I don't think we can implement a meaningful distance operator for enums.

Probably.

This time including the data file for the gist regression tests.

It doesn't apply to HEAD anymore. I have tested it on b12fd41.

I'll fix the bitrot..

The GiST part of it doesn't really work. The current patch compares
oids. We need to change it to compare enumsortorder. I could make it
fail easily:

ouch. Ok,I'll work on this.

+ALTER OPERATOR FAMILY gist_enum_ops USING gist ADD

Why don't we just create it with those changes?

I'll take a look.

+ * Use a similar trick to that used for numeric for enums, since we don't

Do you mean "similar trick that is used" or "trick similar to numeric"?

This is perfectly legal English. It means "... a similar trick to the
one used for numeric ... ". I'll change it to that if you think it's
clearer.

+ * actually know the leftmost value of any enum without knowing the concrete
+ * type, so we use a dummy leftmost value of InvalidOid.
+    return DatumGetBool(
+                        DirectFunctionCall2(enum_gt, ObjectIdGetDatum(*((const Oid *) a)), ObjectIdGetDatum(*((const Oid *) b)))
+        );

Wouldn't it be nice to refactor enum_cmp_internal() to accept typcache
and use it there like the rangetypes?

Not sure. Will look.

Thanks for the review.

cheers

andrew

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#10Andrew Dunstan
andrew@dunslane.net
In reply to: Emre Hasegeli (#8)
Re: btree_gin and btree_gist for enums

On 11/04/2016 04:14 PM, Emre Hasegeli wrote:

The GiST part of it doesn't really work. The current patch compares
oids. We need to change it to compare enumsortorder. I could make it
fail easily:

regression=# create type e as enum ('0', '2', '3');
CREATE TYPE
regression=# alter type e add value '1' after '0';
ALTER TYPE
regression=# create table t as select (i % 4)::text::e from generate_series(0, 100000) as i;
SELECT 100001
regression=# create index on t using gist (e);
SEGFAULT

It calls the enum routines which use the sortorder if necessary. It's
not necessary to use sortorder in the case of evenly numbered enum oids
as we have carefully arranged for them to be directly comparable, and
all the initially allocated oids are even, a very nifty efficiency
measure devised by Tom when we added enum extension.

The real problem here is that enum_cmp_internal assumes that
fcinfo->flinfo has been set up, and DirectFunctionCallN doesn't, it sets
it to NULL.

The patch below cures the problem. I'm not sure if there is a better
way. Thoughts?

cheers

andrew

diff --git a/src/backend/utils/adt/enum.c b/src/backend/utils/adt/enum.c
index 47d5355..64ba7a7 100644
--- a/src/backend/utils/adt/enum.c
+++ b/src/backend/utils/adt/enum.c
@@ -261,7 +261,7 @@ enum_send(PG_FUNCTION_ARGS)
  static int
  enum_cmp_internal(Oid arg1, Oid arg2, FunctionCallInfo fcinfo)
  {
-   TypeCacheEntry *tcache;
+   TypeCacheEntry *tcache = NULL;

/* Equal OIDs are equal no matter what */
if (arg1 == arg2)
@@ -277,7 +277,8 @@ enum_cmp_internal(Oid arg1, Oid arg2,
FunctionCallInfo fcinfo)
}

     /* Locate the typcache entry for the enum type */
-   tcache = (TypeCacheEntry *) fcinfo->flinfo->fn_extra;
+   if (fcinfo->flinfo != NULL)
+       tcache = (TypeCacheEntry *) fcinfo->flinfo->fn_extra;
     if (tcache == NULL)
     {
         HeapTuple   enum_tup;
@@ -296,7 +297,8 @@ enum_cmp_internal(Oid arg1, Oid arg2, 
FunctionCallInfo fcinfo)
         ReleaseSysCache(enum_tup);
         /* Now locate and remember the typcache entry */
         tcache = lookup_type_cache(typeoid, 0);
-       fcinfo->flinfo->fn_extra = (void *) tcache;
+       if (fcinfo->flinfo != NULL)
+           fcinfo->flinfo->fn_extra = (void *) tcache;
     }

/* The remaining comparison logic is in typcache.c */

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#11Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andrew Dunstan (#10)
Re: btree_gin and btree_gist for enums

Andrew Dunstan <andrew@dunslane.net> writes:

The real problem here is that enum_cmp_internal assumes that
fcinfo->flinfo has been set up, and DirectFunctionCallN doesn't, it sets
it to NULL.
The patch below cures the problem. I'm not sure if there is a better
way. Thoughts?

That may be a good fix for robustness purposes, but it seems pretty horrid
from an efficiency standpoint. Where is this call, and should we be
modifying it to provide a flinfo?

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#12Andrew Dunstan
andrew@dunslane.net
In reply to: Tom Lane (#11)
1 attachment(s)
Re: btree_gin and btree_gist for enums

On 11/05/2016 11:46 AM, Tom Lane wrote:

Andrew Dunstan <andrew@dunslane.net> writes:

The real problem here is that enum_cmp_internal assumes that
fcinfo->flinfo has been set up, and DirectFunctionCallN doesn't, it sets
it to NULL.
The patch below cures the problem. I'm not sure if there is a better
way. Thoughts?

That may be a good fix for robustness purposes, but it seems pretty horrid
from an efficiency standpoint. Where is this call, and should we be
modifying it to provide a flinfo?

See attached updated patch that adds enum support to btree_gist and
btree_gin

I thought of providing an flinfo, but I couldn't see a simple way to do
it that would provide something much longer lived than the function
call, in which case it seemed a bit pointless. That's why I asked for
assistance :-)

cheers

andrew

Attachments:

enum-btree-gist-gin-3.patchtext/x-diff; name=enum-btree-gist-gin-3.patchDownload
diff --git a/contrib/btree_gin/Makefile b/contrib/btree_gin/Makefile
index 0492091..f8a2d7f 100644
--- a/contrib/btree_gin/Makefile
+++ b/contrib/btree_gin/Makefile
@@ -4,13 +4,13 @@ MODULE_big = btree_gin
 OBJS = btree_gin.o $(WIN32RES)
 
 EXTENSION = btree_gin
-DATA = btree_gin--1.0.sql btree_gin--unpackaged--1.0.sql
+DATA = btree_gin--1.1.sql btree_gin--unpackaged--1.0.sql btree_gin--1.0--1.1.sql
 PGFILEDESC = "btree_gin - B-tree equivalent GIN operator classes"
 
 REGRESS = install_btree_gin int2 int4 int8 float4 float8 money oid \
 	timestamp timestamptz time timetz date interval \
 	macaddr inet cidr text varchar char bytea bit varbit \
-	numeric
+	numeric enum
 
 ifdef USE_PGXS
 PG_CONFIG = pg_config
diff --git a/contrib/btree_gin/btree_gin--1.0--1.1.sql b/contrib/btree_gin/btree_gin--1.0--1.1.sql
new file mode 100644
index 0000000..0c90bbb
--- /dev/null
+++ b/contrib/btree_gin/btree_gin--1.0--1.1.sql
@@ -0,0 +1,47 @@
+/* contrib/btree_gin/btree_gin--1.0--1.1.sql */
+
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "ALTER EXTENSION btree_gin UPDATE TO '1.1'" to load this file. \quit
+
+--
+--
+--
+-- enum ops
+--
+--
+
+
+CREATE FUNCTION gin_extract_value_anyenum(anyenum, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_anyenum(anyenum, anyenum, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_anyenum(anyenum, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_enum_cmp(anyenum, anyenum)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS enum_ops
+DEFAULT FOR TYPE anyenum USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       gin_enum_cmp(anyenum,anyenum),
+    FUNCTION        2       gin_extract_value_anyenum(anyenum, internal),
+    FUNCTION        3       gin_extract_query_anyenum(anyenum, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_anyenum(anyenum,anyenum,int2, internal),
+STORAGE         oid;
diff --git a/contrib/btree_gin/btree_gin--1.0.sql b/contrib/btree_gin/btree_gin--1.0.sql
deleted file mode 100644
index cf867ef..0000000
--- a/contrib/btree_gin/btree_gin--1.0.sql
+++ /dev/null
@@ -1,689 +0,0 @@
-/* contrib/btree_gin/btree_gin--1.0.sql */
-
--- complain if script is sourced in psql, rather than via CREATE EXTENSION
-\echo Use "CREATE EXTENSION btree_gin" to load this file. \quit
-
-CREATE FUNCTION gin_btree_consistent(internal, int2, anyelement, int4, internal, internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_value_int2(int2, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_int2(int2, int2, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_int2(int2, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS int2_ops
-DEFAULT FOR TYPE int2 USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       btint2cmp(int2,int2),
-    FUNCTION        2       gin_extract_value_int2(int2, internal),
-    FUNCTION        3       gin_extract_query_int2(int2, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_int2(int2,int2,int2, internal),
-STORAGE         int2;
-
-CREATE FUNCTION gin_extract_value_int4(int4, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_int4(int4, int4, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_int4(int4, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS int4_ops
-DEFAULT FOR TYPE int4 USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       btint4cmp(int4,int4),
-    FUNCTION        2       gin_extract_value_int4(int4, internal),
-    FUNCTION        3       gin_extract_query_int4(int4, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_int4(int4,int4,int2, internal),
-STORAGE         int4;
-
-CREATE FUNCTION gin_extract_value_int8(int8, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_int8(int8, int8, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_int8(int8, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS int8_ops
-DEFAULT FOR TYPE int8 USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       btint8cmp(int8,int8),
-    FUNCTION        2       gin_extract_value_int8(int8, internal),
-    FUNCTION        3       gin_extract_query_int8(int8, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_int8(int8,int8,int2, internal),
-STORAGE         int8;
-
-CREATE FUNCTION gin_extract_value_float4(float4, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_float4(float4, float4, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_float4(float4, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS float4_ops
-DEFAULT FOR TYPE float4 USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       btfloat4cmp(float4,float4),
-    FUNCTION        2       gin_extract_value_float4(float4, internal),
-    FUNCTION        3       gin_extract_query_float4(float4, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_float4(float4,float4,int2, internal),
-STORAGE         float4;
-
-CREATE FUNCTION gin_extract_value_float8(float8, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_float8(float8, float8, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_float8(float8, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS float8_ops
-DEFAULT FOR TYPE float8 USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       btfloat8cmp(float8,float8),
-    FUNCTION        2       gin_extract_value_float8(float8, internal),
-    FUNCTION        3       gin_extract_query_float8(float8, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_float8(float8,float8,int2, internal),
-STORAGE         float8;
-
-CREATE FUNCTION gin_extract_value_money(money, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_money(money, money, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_money(money, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS money_ops
-DEFAULT FOR TYPE money USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       cash_cmp(money,money),
-    FUNCTION        2       gin_extract_value_money(money, internal),
-    FUNCTION        3       gin_extract_query_money(money, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_money(money,money,int2, internal),
-STORAGE         money;
-
-CREATE FUNCTION gin_extract_value_oid(oid, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_oid(oid, oid, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_oid(oid, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS oid_ops
-DEFAULT FOR TYPE oid USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       btoidcmp(oid,oid),
-    FUNCTION        2       gin_extract_value_oid(oid, internal),
-    FUNCTION        3       gin_extract_query_oid(oid, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_oid(oid,oid,int2, internal),
-STORAGE         oid;
-
-CREATE FUNCTION gin_extract_value_timestamp(timestamp, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_timestamp(timestamp, timestamp, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_timestamp(timestamp, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS timestamp_ops
-DEFAULT FOR TYPE timestamp USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       timestamp_cmp(timestamp,timestamp),
-    FUNCTION        2       gin_extract_value_timestamp(timestamp, internal),
-    FUNCTION        3       gin_extract_query_timestamp(timestamp, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_timestamp(timestamp,timestamp,int2, internal),
-STORAGE         timestamp;
-
-CREATE FUNCTION gin_extract_value_timestamptz(timestamptz, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_timestamptz(timestamptz, timestamptz, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_timestamptz(timestamptz, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS timestamptz_ops
-DEFAULT FOR TYPE timestamptz USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       timestamptz_cmp(timestamptz,timestamptz),
-    FUNCTION        2       gin_extract_value_timestamptz(timestamptz, internal),
-    FUNCTION        3       gin_extract_query_timestamptz(timestamptz, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_timestamptz(timestamptz,timestamptz,int2, internal),
-STORAGE         timestamptz;
-
-CREATE FUNCTION gin_extract_value_time(time, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_time(time, time, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_time(time, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS time_ops
-DEFAULT FOR TYPE time USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       time_cmp(time,time),
-    FUNCTION        2       gin_extract_value_time(time, internal),
-    FUNCTION        3       gin_extract_query_time(time, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_time(time,time,int2, internal),
-STORAGE         time;
-
-CREATE FUNCTION gin_extract_value_timetz(timetz, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_timetz(timetz, timetz, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_timetz(timetz, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS timetz_ops
-DEFAULT FOR TYPE timetz USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       timetz_cmp(timetz,timetz),
-    FUNCTION        2       gin_extract_value_timetz(timetz, internal),
-    FUNCTION        3       gin_extract_query_timetz(timetz, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_timetz(timetz,timetz,int2, internal),
-STORAGE         timetz;
-
-CREATE FUNCTION gin_extract_value_date(date, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_date(date, date, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_date(date, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS date_ops
-DEFAULT FOR TYPE date USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       date_cmp(date,date),
-    FUNCTION        2       gin_extract_value_date(date, internal),
-    FUNCTION        3       gin_extract_query_date(date, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_date(date,date,int2, internal),
-STORAGE         date;
-
-CREATE FUNCTION gin_extract_value_interval(interval, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_interval(interval, interval, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_interval(interval, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS interval_ops
-DEFAULT FOR TYPE interval USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       interval_cmp(interval,interval),
-    FUNCTION        2       gin_extract_value_interval(interval, internal),
-    FUNCTION        3       gin_extract_query_interval(interval, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_interval(interval,interval,int2, internal),
-STORAGE         interval;
-
-CREATE FUNCTION gin_extract_value_macaddr(macaddr, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_macaddr(macaddr, macaddr, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_macaddr(macaddr, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS macaddr_ops
-DEFAULT FOR TYPE macaddr USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       macaddr_cmp(macaddr,macaddr),
-    FUNCTION        2       gin_extract_value_macaddr(macaddr, internal),
-    FUNCTION        3       gin_extract_query_macaddr(macaddr, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_macaddr(macaddr,macaddr,int2, internal),
-STORAGE         macaddr;
-
-CREATE FUNCTION gin_extract_value_inet(inet, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_inet(inet, inet, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_inet(inet, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS inet_ops
-DEFAULT FOR TYPE inet USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       network_cmp(inet,inet),
-    FUNCTION        2       gin_extract_value_inet(inet, internal),
-    FUNCTION        3       gin_extract_query_inet(inet, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_inet(inet,inet,int2, internal),
-STORAGE         inet;
-
-CREATE FUNCTION gin_extract_value_cidr(cidr, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_cidr(cidr, cidr, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_cidr(cidr, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS cidr_ops
-DEFAULT FOR TYPE cidr USING gin
-AS
-    OPERATOR        1       <(inet,inet),
-    OPERATOR        2       <=(inet,inet),
-    OPERATOR        3       =(inet,inet),
-    OPERATOR        4       >=(inet,inet),
-    OPERATOR        5       >(inet,inet),
-    FUNCTION        1       network_cmp(inet,inet),
-    FUNCTION        2       gin_extract_value_cidr(cidr, internal),
-    FUNCTION        3       gin_extract_query_cidr(cidr, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_cidr(cidr,cidr,int2, internal),
-STORAGE         cidr;
-
-CREATE FUNCTION gin_extract_value_text(text, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_text(text, text, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_text(text, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS text_ops
-DEFAULT FOR TYPE text USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       bttextcmp(text,text),
-    FUNCTION        2       gin_extract_value_text(text, internal),
-    FUNCTION        3       gin_extract_query_text(text, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_text(text,text,int2, internal),
-STORAGE         text;
-
-CREATE OPERATOR CLASS varchar_ops
-DEFAULT FOR TYPE varchar USING gin
-AS
-    OPERATOR        1       <(text,text),
-    OPERATOR        2       <=(text,text),
-    OPERATOR        3       =(text,text),
-    OPERATOR        4       >=(text,text),
-    OPERATOR        5       >(text,text),
-    FUNCTION        1       bttextcmp(text,text),
-    FUNCTION        2       gin_extract_value_text(text, internal),
-    FUNCTION        3       gin_extract_query_text(text, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_text(text,text,int2, internal),
-STORAGE         varchar;
-
-CREATE FUNCTION gin_extract_value_char("char", internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_char("char", "char", int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_char("char", internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS char_ops
-DEFAULT FOR TYPE "char" USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       btcharcmp("char","char"),
-    FUNCTION        2       gin_extract_value_char("char", internal),
-    FUNCTION        3       gin_extract_query_char("char", internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_char("char","char",int2, internal),
-STORAGE         "char";
-
-CREATE FUNCTION gin_extract_value_bytea(bytea, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_bytea(bytea, bytea, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_bytea(bytea, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS bytea_ops
-DEFAULT FOR TYPE bytea USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       byteacmp(bytea,bytea),
-    FUNCTION        2       gin_extract_value_bytea(bytea, internal),
-    FUNCTION        3       gin_extract_query_bytea(bytea, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_bytea(bytea,bytea,int2, internal),
-STORAGE         bytea;
-
-CREATE FUNCTION gin_extract_value_bit(bit, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_bit(bit, bit, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_bit(bit, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS bit_ops
-DEFAULT FOR TYPE bit USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       bitcmp(bit,bit),
-    FUNCTION        2       gin_extract_value_bit(bit, internal),
-    FUNCTION        3       gin_extract_query_bit(bit, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_bit(bit,bit,int2, internal),
-STORAGE         bit;
-
-CREATE FUNCTION gin_extract_value_varbit(varbit, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_varbit(varbit, varbit, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_varbit(varbit, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS varbit_ops
-DEFAULT FOR TYPE varbit USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       varbitcmp(varbit,varbit),
-    FUNCTION        2       gin_extract_value_varbit(varbit, internal),
-    FUNCTION        3       gin_extract_query_varbit(varbit, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_varbit(varbit,varbit,int2, internal),
-STORAGE         varbit;
-
-CREATE FUNCTION gin_extract_value_numeric(numeric, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_compare_prefix_numeric(numeric, numeric, int2, internal)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_extract_query_numeric(numeric, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE FUNCTION gin_numeric_cmp(numeric, numeric)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C STRICT IMMUTABLE;
-
-CREATE OPERATOR CLASS numeric_ops
-DEFAULT FOR TYPE numeric USING gin
-AS
-    OPERATOR        1       <,
-    OPERATOR        2       <=,
-    OPERATOR        3       =,
-    OPERATOR        4       >=,
-    OPERATOR        5       >,
-    FUNCTION        1       gin_numeric_cmp(numeric,numeric),
-    FUNCTION        2       gin_extract_value_numeric(numeric, internal),
-    FUNCTION        3       gin_extract_query_numeric(numeric, internal, int2, internal, internal),
-    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
-    FUNCTION        5       gin_compare_prefix_numeric(numeric,numeric,int2, internal),
-STORAGE         numeric;
diff --git a/contrib/btree_gin/btree_gin--1.1.sql b/contrib/btree_gin/btree_gin--1.1.sql
new file mode 100644
index 0000000..f117e4a
--- /dev/null
+++ b/contrib/btree_gin/btree_gin--1.1.sql
@@ -0,0 +1,724 @@
+/* contrib/btree_gin/btree_gin--1.0.sql */
+
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "CREATE EXTENSION btree_gin" to load this file. \quit
+
+CREATE FUNCTION gin_btree_consistent(internal, int2, anyelement, int4, internal, internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_value_int2(int2, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_int2(int2, int2, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_int2(int2, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS int2_ops
+DEFAULT FOR TYPE int2 USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       btint2cmp(int2,int2),
+    FUNCTION        2       gin_extract_value_int2(int2, internal),
+    FUNCTION        3       gin_extract_query_int2(int2, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_int2(int2,int2,int2, internal),
+STORAGE         int2;
+
+CREATE FUNCTION gin_extract_value_int4(int4, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_int4(int4, int4, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_int4(int4, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS int4_ops
+DEFAULT FOR TYPE int4 USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       btint4cmp(int4,int4),
+    FUNCTION        2       gin_extract_value_int4(int4, internal),
+    FUNCTION        3       gin_extract_query_int4(int4, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_int4(int4,int4,int2, internal),
+STORAGE         int4;
+
+CREATE FUNCTION gin_extract_value_int8(int8, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_int8(int8, int8, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_int8(int8, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS int8_ops
+DEFAULT FOR TYPE int8 USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       btint8cmp(int8,int8),
+    FUNCTION        2       gin_extract_value_int8(int8, internal),
+    FUNCTION        3       gin_extract_query_int8(int8, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_int8(int8,int8,int2, internal),
+STORAGE         int8;
+
+CREATE FUNCTION gin_extract_value_float4(float4, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_float4(float4, float4, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_float4(float4, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS float4_ops
+DEFAULT FOR TYPE float4 USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       btfloat4cmp(float4,float4),
+    FUNCTION        2       gin_extract_value_float4(float4, internal),
+    FUNCTION        3       gin_extract_query_float4(float4, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_float4(float4,float4,int2, internal),
+STORAGE         float4;
+
+CREATE FUNCTION gin_extract_value_float8(float8, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_float8(float8, float8, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_float8(float8, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS float8_ops
+DEFAULT FOR TYPE float8 USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       btfloat8cmp(float8,float8),
+    FUNCTION        2       gin_extract_value_float8(float8, internal),
+    FUNCTION        3       gin_extract_query_float8(float8, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_float8(float8,float8,int2, internal),
+STORAGE         float8;
+
+CREATE FUNCTION gin_extract_value_money(money, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_money(money, money, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_money(money, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS money_ops
+DEFAULT FOR TYPE money USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       cash_cmp(money,money),
+    FUNCTION        2       gin_extract_value_money(money, internal),
+    FUNCTION        3       gin_extract_query_money(money, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_money(money,money,int2, internal),
+STORAGE         money;
+
+CREATE FUNCTION gin_extract_value_oid(oid, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_oid(oid, oid, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_oid(oid, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS oid_ops
+DEFAULT FOR TYPE oid USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       btoidcmp(oid,oid),
+    FUNCTION        2       gin_extract_value_oid(oid, internal),
+    FUNCTION        3       gin_extract_query_oid(oid, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_oid(oid,oid,int2, internal),
+STORAGE         oid;
+
+CREATE FUNCTION gin_extract_value_timestamp(timestamp, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_timestamp(timestamp, timestamp, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_timestamp(timestamp, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS timestamp_ops
+DEFAULT FOR TYPE timestamp USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       timestamp_cmp(timestamp,timestamp),
+    FUNCTION        2       gin_extract_value_timestamp(timestamp, internal),
+    FUNCTION        3       gin_extract_query_timestamp(timestamp, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_timestamp(timestamp,timestamp,int2, internal),
+STORAGE         timestamp;
+
+CREATE FUNCTION gin_extract_value_timestamptz(timestamptz, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_timestamptz(timestamptz, timestamptz, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_timestamptz(timestamptz, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS timestamptz_ops
+DEFAULT FOR TYPE timestamptz USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       timestamptz_cmp(timestamptz,timestamptz),
+    FUNCTION        2       gin_extract_value_timestamptz(timestamptz, internal),
+    FUNCTION        3       gin_extract_query_timestamptz(timestamptz, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_timestamptz(timestamptz,timestamptz,int2, internal),
+STORAGE         timestamptz;
+
+CREATE FUNCTION gin_extract_value_time(time, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_time(time, time, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_time(time, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS time_ops
+DEFAULT FOR TYPE time USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       time_cmp(time,time),
+    FUNCTION        2       gin_extract_value_time(time, internal),
+    FUNCTION        3       gin_extract_query_time(time, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_time(time,time,int2, internal),
+STORAGE         time;
+
+CREATE FUNCTION gin_extract_value_timetz(timetz, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_timetz(timetz, timetz, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_timetz(timetz, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS timetz_ops
+DEFAULT FOR TYPE timetz USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       timetz_cmp(timetz,timetz),
+    FUNCTION        2       gin_extract_value_timetz(timetz, internal),
+    FUNCTION        3       gin_extract_query_timetz(timetz, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_timetz(timetz,timetz,int2, internal),
+STORAGE         timetz;
+
+CREATE FUNCTION gin_extract_value_date(date, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_date(date, date, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_date(date, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS date_ops
+DEFAULT FOR TYPE date USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       date_cmp(date,date),
+    FUNCTION        2       gin_extract_value_date(date, internal),
+    FUNCTION        3       gin_extract_query_date(date, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_date(date,date,int2, internal),
+STORAGE         date;
+
+CREATE FUNCTION gin_extract_value_interval(interval, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_interval(interval, interval, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_interval(interval, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS interval_ops
+DEFAULT FOR TYPE interval USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       interval_cmp(interval,interval),
+    FUNCTION        2       gin_extract_value_interval(interval, internal),
+    FUNCTION        3       gin_extract_query_interval(interval, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_interval(interval,interval,int2, internal),
+STORAGE         interval;
+
+CREATE FUNCTION gin_extract_value_macaddr(macaddr, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_macaddr(macaddr, macaddr, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_macaddr(macaddr, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS macaddr_ops
+DEFAULT FOR TYPE macaddr USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       macaddr_cmp(macaddr,macaddr),
+    FUNCTION        2       gin_extract_value_macaddr(macaddr, internal),
+    FUNCTION        3       gin_extract_query_macaddr(macaddr, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_macaddr(macaddr,macaddr,int2, internal),
+STORAGE         macaddr;
+
+CREATE FUNCTION gin_extract_value_inet(inet, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_inet(inet, inet, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_inet(inet, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS inet_ops
+DEFAULT FOR TYPE inet USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       network_cmp(inet,inet),
+    FUNCTION        2       gin_extract_value_inet(inet, internal),
+    FUNCTION        3       gin_extract_query_inet(inet, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_inet(inet,inet,int2, internal),
+STORAGE         inet;
+
+CREATE FUNCTION gin_extract_value_cidr(cidr, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_cidr(cidr, cidr, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_cidr(cidr, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS cidr_ops
+DEFAULT FOR TYPE cidr USING gin
+AS
+    OPERATOR        1       <(inet,inet),
+    OPERATOR        2       <=(inet,inet),
+    OPERATOR        3       =(inet,inet),
+    OPERATOR        4       >=(inet,inet),
+    OPERATOR        5       >(inet,inet),
+    FUNCTION        1       network_cmp(inet,inet),
+    FUNCTION        2       gin_extract_value_cidr(cidr, internal),
+    FUNCTION        3       gin_extract_query_cidr(cidr, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_cidr(cidr,cidr,int2, internal),
+STORAGE         cidr;
+
+CREATE FUNCTION gin_extract_value_text(text, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_text(text, text, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_text(text, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS text_ops
+DEFAULT FOR TYPE text USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       bttextcmp(text,text),
+    FUNCTION        2       gin_extract_value_text(text, internal),
+    FUNCTION        3       gin_extract_query_text(text, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_text(text,text,int2, internal),
+STORAGE         text;
+
+CREATE OPERATOR CLASS varchar_ops
+DEFAULT FOR TYPE varchar USING gin
+AS
+    OPERATOR        1       <(text,text),
+    OPERATOR        2       <=(text,text),
+    OPERATOR        3       =(text,text),
+    OPERATOR        4       >=(text,text),
+    OPERATOR        5       >(text,text),
+    FUNCTION        1       bttextcmp(text,text),
+    FUNCTION        2       gin_extract_value_text(text, internal),
+    FUNCTION        3       gin_extract_query_text(text, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_text(text,text,int2, internal),
+STORAGE         varchar;
+
+CREATE FUNCTION gin_extract_value_char("char", internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_char("char", "char", int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_char("char", internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS char_ops
+DEFAULT FOR TYPE "char" USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       btcharcmp("char","char"),
+    FUNCTION        2       gin_extract_value_char("char", internal),
+    FUNCTION        3       gin_extract_query_char("char", internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_char("char","char",int2, internal),
+STORAGE         "char";
+
+CREATE FUNCTION gin_extract_value_bytea(bytea, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_bytea(bytea, bytea, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_bytea(bytea, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS bytea_ops
+DEFAULT FOR TYPE bytea USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       byteacmp(bytea,bytea),
+    FUNCTION        2       gin_extract_value_bytea(bytea, internal),
+    FUNCTION        3       gin_extract_query_bytea(bytea, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_bytea(bytea,bytea,int2, internal),
+STORAGE         bytea;
+
+CREATE FUNCTION gin_extract_value_bit(bit, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_bit(bit, bit, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_bit(bit, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS bit_ops
+DEFAULT FOR TYPE bit USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       bitcmp(bit,bit),
+    FUNCTION        2       gin_extract_value_bit(bit, internal),
+    FUNCTION        3       gin_extract_query_bit(bit, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_bit(bit,bit,int2, internal),
+STORAGE         bit;
+
+CREATE FUNCTION gin_extract_value_varbit(varbit, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_varbit(varbit, varbit, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_varbit(varbit, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS varbit_ops
+DEFAULT FOR TYPE varbit USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       varbitcmp(varbit,varbit),
+    FUNCTION        2       gin_extract_value_varbit(varbit, internal),
+    FUNCTION        3       gin_extract_query_varbit(varbit, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_varbit(varbit,varbit,int2, internal),
+STORAGE         varbit;
+
+CREATE FUNCTION gin_extract_value_numeric(numeric, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_numeric(numeric, numeric, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_numeric(numeric, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_numeric_cmp(numeric, numeric)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS numeric_ops
+DEFAULT FOR TYPE numeric USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       gin_numeric_cmp(numeric,numeric),
+    FUNCTION        2       gin_extract_value_numeric(numeric, internal),
+    FUNCTION        3       gin_extract_query_numeric(numeric, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_numeric(numeric,numeric,int2, internal),
+STORAGE         numeric;
+
+CREATE FUNCTION gin_extract_value_anyenum(anyenum, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_anyenum(anyenum, anyenum, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_anyenum(anyenum, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_enum_cmp(anyenum, anyenum)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS enum_ops
+DEFAULT FOR TYPE anyenum USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       gin_enum_cmp(anyenum,anyenum),
+    FUNCTION        2       gin_extract_value_anyenum(anyenum, internal),
+    FUNCTION        3       gin_extract_query_anyenum(anyenum, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_anyenum(anyenum,anyenum,int2, internal),
+STORAGE         oid;
diff --git a/contrib/btree_gin/btree_gin--1.1.sql.save b/contrib/btree_gin/btree_gin--1.1.sql.save
new file mode 100644
index 0000000..f117e4a
--- /dev/null
+++ b/contrib/btree_gin/btree_gin--1.1.sql.save
@@ -0,0 +1,724 @@
+/* contrib/btree_gin/btree_gin--1.0.sql */
+
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "CREATE EXTENSION btree_gin" to load this file. \quit
+
+CREATE FUNCTION gin_btree_consistent(internal, int2, anyelement, int4, internal, internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_value_int2(int2, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_int2(int2, int2, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_int2(int2, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS int2_ops
+DEFAULT FOR TYPE int2 USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       btint2cmp(int2,int2),
+    FUNCTION        2       gin_extract_value_int2(int2, internal),
+    FUNCTION        3       gin_extract_query_int2(int2, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_int2(int2,int2,int2, internal),
+STORAGE         int2;
+
+CREATE FUNCTION gin_extract_value_int4(int4, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_int4(int4, int4, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_int4(int4, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS int4_ops
+DEFAULT FOR TYPE int4 USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       btint4cmp(int4,int4),
+    FUNCTION        2       gin_extract_value_int4(int4, internal),
+    FUNCTION        3       gin_extract_query_int4(int4, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_int4(int4,int4,int2, internal),
+STORAGE         int4;
+
+CREATE FUNCTION gin_extract_value_int8(int8, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_int8(int8, int8, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_int8(int8, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS int8_ops
+DEFAULT FOR TYPE int8 USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       btint8cmp(int8,int8),
+    FUNCTION        2       gin_extract_value_int8(int8, internal),
+    FUNCTION        3       gin_extract_query_int8(int8, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_int8(int8,int8,int2, internal),
+STORAGE         int8;
+
+CREATE FUNCTION gin_extract_value_float4(float4, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_float4(float4, float4, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_float4(float4, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS float4_ops
+DEFAULT FOR TYPE float4 USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       btfloat4cmp(float4,float4),
+    FUNCTION        2       gin_extract_value_float4(float4, internal),
+    FUNCTION        3       gin_extract_query_float4(float4, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_float4(float4,float4,int2, internal),
+STORAGE         float4;
+
+CREATE FUNCTION gin_extract_value_float8(float8, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_float8(float8, float8, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_float8(float8, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS float8_ops
+DEFAULT FOR TYPE float8 USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       btfloat8cmp(float8,float8),
+    FUNCTION        2       gin_extract_value_float8(float8, internal),
+    FUNCTION        3       gin_extract_query_float8(float8, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_float8(float8,float8,int2, internal),
+STORAGE         float8;
+
+CREATE FUNCTION gin_extract_value_money(money, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_money(money, money, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_money(money, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS money_ops
+DEFAULT FOR TYPE money USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       cash_cmp(money,money),
+    FUNCTION        2       gin_extract_value_money(money, internal),
+    FUNCTION        3       gin_extract_query_money(money, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_money(money,money,int2, internal),
+STORAGE         money;
+
+CREATE FUNCTION gin_extract_value_oid(oid, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_oid(oid, oid, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_oid(oid, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS oid_ops
+DEFAULT FOR TYPE oid USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       btoidcmp(oid,oid),
+    FUNCTION        2       gin_extract_value_oid(oid, internal),
+    FUNCTION        3       gin_extract_query_oid(oid, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_oid(oid,oid,int2, internal),
+STORAGE         oid;
+
+CREATE FUNCTION gin_extract_value_timestamp(timestamp, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_timestamp(timestamp, timestamp, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_timestamp(timestamp, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS timestamp_ops
+DEFAULT FOR TYPE timestamp USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       timestamp_cmp(timestamp,timestamp),
+    FUNCTION        2       gin_extract_value_timestamp(timestamp, internal),
+    FUNCTION        3       gin_extract_query_timestamp(timestamp, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_timestamp(timestamp,timestamp,int2, internal),
+STORAGE         timestamp;
+
+CREATE FUNCTION gin_extract_value_timestamptz(timestamptz, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_timestamptz(timestamptz, timestamptz, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_timestamptz(timestamptz, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS timestamptz_ops
+DEFAULT FOR TYPE timestamptz USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       timestamptz_cmp(timestamptz,timestamptz),
+    FUNCTION        2       gin_extract_value_timestamptz(timestamptz, internal),
+    FUNCTION        3       gin_extract_query_timestamptz(timestamptz, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_timestamptz(timestamptz,timestamptz,int2, internal),
+STORAGE         timestamptz;
+
+CREATE FUNCTION gin_extract_value_time(time, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_time(time, time, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_time(time, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS time_ops
+DEFAULT FOR TYPE time USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       time_cmp(time,time),
+    FUNCTION        2       gin_extract_value_time(time, internal),
+    FUNCTION        3       gin_extract_query_time(time, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_time(time,time,int2, internal),
+STORAGE         time;
+
+CREATE FUNCTION gin_extract_value_timetz(timetz, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_timetz(timetz, timetz, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_timetz(timetz, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS timetz_ops
+DEFAULT FOR TYPE timetz USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       timetz_cmp(timetz,timetz),
+    FUNCTION        2       gin_extract_value_timetz(timetz, internal),
+    FUNCTION        3       gin_extract_query_timetz(timetz, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_timetz(timetz,timetz,int2, internal),
+STORAGE         timetz;
+
+CREATE FUNCTION gin_extract_value_date(date, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_date(date, date, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_date(date, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS date_ops
+DEFAULT FOR TYPE date USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       date_cmp(date,date),
+    FUNCTION        2       gin_extract_value_date(date, internal),
+    FUNCTION        3       gin_extract_query_date(date, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_date(date,date,int2, internal),
+STORAGE         date;
+
+CREATE FUNCTION gin_extract_value_interval(interval, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_interval(interval, interval, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_interval(interval, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS interval_ops
+DEFAULT FOR TYPE interval USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       interval_cmp(interval,interval),
+    FUNCTION        2       gin_extract_value_interval(interval, internal),
+    FUNCTION        3       gin_extract_query_interval(interval, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_interval(interval,interval,int2, internal),
+STORAGE         interval;
+
+CREATE FUNCTION gin_extract_value_macaddr(macaddr, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_macaddr(macaddr, macaddr, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_macaddr(macaddr, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS macaddr_ops
+DEFAULT FOR TYPE macaddr USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       macaddr_cmp(macaddr,macaddr),
+    FUNCTION        2       gin_extract_value_macaddr(macaddr, internal),
+    FUNCTION        3       gin_extract_query_macaddr(macaddr, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_macaddr(macaddr,macaddr,int2, internal),
+STORAGE         macaddr;
+
+CREATE FUNCTION gin_extract_value_inet(inet, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_inet(inet, inet, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_inet(inet, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS inet_ops
+DEFAULT FOR TYPE inet USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       network_cmp(inet,inet),
+    FUNCTION        2       gin_extract_value_inet(inet, internal),
+    FUNCTION        3       gin_extract_query_inet(inet, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_inet(inet,inet,int2, internal),
+STORAGE         inet;
+
+CREATE FUNCTION gin_extract_value_cidr(cidr, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_cidr(cidr, cidr, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_cidr(cidr, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS cidr_ops
+DEFAULT FOR TYPE cidr USING gin
+AS
+    OPERATOR        1       <(inet,inet),
+    OPERATOR        2       <=(inet,inet),
+    OPERATOR        3       =(inet,inet),
+    OPERATOR        4       >=(inet,inet),
+    OPERATOR        5       >(inet,inet),
+    FUNCTION        1       network_cmp(inet,inet),
+    FUNCTION        2       gin_extract_value_cidr(cidr, internal),
+    FUNCTION        3       gin_extract_query_cidr(cidr, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_cidr(cidr,cidr,int2, internal),
+STORAGE         cidr;
+
+CREATE FUNCTION gin_extract_value_text(text, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_text(text, text, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_text(text, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS text_ops
+DEFAULT FOR TYPE text USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       bttextcmp(text,text),
+    FUNCTION        2       gin_extract_value_text(text, internal),
+    FUNCTION        3       gin_extract_query_text(text, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_text(text,text,int2, internal),
+STORAGE         text;
+
+CREATE OPERATOR CLASS varchar_ops
+DEFAULT FOR TYPE varchar USING gin
+AS
+    OPERATOR        1       <(text,text),
+    OPERATOR        2       <=(text,text),
+    OPERATOR        3       =(text,text),
+    OPERATOR        4       >=(text,text),
+    OPERATOR        5       >(text,text),
+    FUNCTION        1       bttextcmp(text,text),
+    FUNCTION        2       gin_extract_value_text(text, internal),
+    FUNCTION        3       gin_extract_query_text(text, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_text(text,text,int2, internal),
+STORAGE         varchar;
+
+CREATE FUNCTION gin_extract_value_char("char", internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_char("char", "char", int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_char("char", internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS char_ops
+DEFAULT FOR TYPE "char" USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       btcharcmp("char","char"),
+    FUNCTION        2       gin_extract_value_char("char", internal),
+    FUNCTION        3       gin_extract_query_char("char", internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_char("char","char",int2, internal),
+STORAGE         "char";
+
+CREATE FUNCTION gin_extract_value_bytea(bytea, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_bytea(bytea, bytea, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_bytea(bytea, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS bytea_ops
+DEFAULT FOR TYPE bytea USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       byteacmp(bytea,bytea),
+    FUNCTION        2       gin_extract_value_bytea(bytea, internal),
+    FUNCTION        3       gin_extract_query_bytea(bytea, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_bytea(bytea,bytea,int2, internal),
+STORAGE         bytea;
+
+CREATE FUNCTION gin_extract_value_bit(bit, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_bit(bit, bit, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_bit(bit, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS bit_ops
+DEFAULT FOR TYPE bit USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       bitcmp(bit,bit),
+    FUNCTION        2       gin_extract_value_bit(bit, internal),
+    FUNCTION        3       gin_extract_query_bit(bit, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_bit(bit,bit,int2, internal),
+STORAGE         bit;
+
+CREATE FUNCTION gin_extract_value_varbit(varbit, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_varbit(varbit, varbit, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_varbit(varbit, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS varbit_ops
+DEFAULT FOR TYPE varbit USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       varbitcmp(varbit,varbit),
+    FUNCTION        2       gin_extract_value_varbit(varbit, internal),
+    FUNCTION        3       gin_extract_query_varbit(varbit, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_varbit(varbit,varbit,int2, internal),
+STORAGE         varbit;
+
+CREATE FUNCTION gin_extract_value_numeric(numeric, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_numeric(numeric, numeric, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_numeric(numeric, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_numeric_cmp(numeric, numeric)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS numeric_ops
+DEFAULT FOR TYPE numeric USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       gin_numeric_cmp(numeric,numeric),
+    FUNCTION        2       gin_extract_value_numeric(numeric, internal),
+    FUNCTION        3       gin_extract_query_numeric(numeric, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_numeric(numeric,numeric,int2, internal),
+STORAGE         numeric;
+
+CREATE FUNCTION gin_extract_value_anyenum(anyenum, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_anyenum(anyenum, anyenum, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_anyenum(anyenum, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_enum_cmp(anyenum, anyenum)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS enum_ops
+DEFAULT FOR TYPE anyenum USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       gin_enum_cmp(anyenum,anyenum),
+    FUNCTION        2       gin_extract_value_anyenum(anyenum, internal),
+    FUNCTION        3       gin_extract_query_anyenum(anyenum, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_anyenum(anyenum,anyenum,int2, internal),
+STORAGE         oid;
diff --git a/contrib/btree_gin/btree_gin.c b/contrib/btree_gin/btree_gin.c
index 030b610..1cb58f5 100644
--- a/contrib/btree_gin/btree_gin.c
+++ b/contrib/btree_gin/btree_gin.c
@@ -416,3 +416,47 @@ leftmostvalue_numeric(void)
 }
 
 GIN_SUPPORT(numeric, true, leftmostvalue_numeric, gin_numeric_cmp)
+
+/*
+ * Use a similar trick to the one used for numeric for enums, since we don't
+ * actually know the leftmost value of any enum without knowing the concrete
+ * type, so we use a dummy leftmost value of InvalidOid.
+ */
+
+
+#define ENUM_IS_LEFTMOST(x)	((x) == InvalidOid)
+
+PG_FUNCTION_INFO_V1(gin_enum_cmp);
+
+Datum
+gin_enum_cmp(PG_FUNCTION_ARGS)
+{
+	Oid		a = PG_GETARG_OID(0);
+	Oid		b = PG_GETARG_OID(1);
+	int		res = 0;
+
+	if (ENUM_IS_LEFTMOST(a))
+	{
+		res = (ENUM_IS_LEFTMOST(b)) ? 0 : -1;
+	}
+	else if (ENUM_IS_LEFTMOST(b))
+	{
+		res = 1;
+	}
+	else
+	{
+		res = DatumGetInt32(DirectFunctionCall2(enum_cmp,
+												ObjectIdGetDatum(a),
+												ObjectIdGetDatum(b)));
+	}
+
+	PG_RETURN_INT32(res);
+}
+
+static Datum
+leftmostvalue_enum(void)
+{
+	return ObjectIdGetDatum(InvalidOid);
+}
+
+GIN_SUPPORT(anyenum, false, leftmostvalue_enum, gin_enum_cmp)
diff --git a/contrib/btree_gin/btree_gin.control b/contrib/btree_gin/btree_gin.control
index 3b2cb2d..d96436e 100644
--- a/contrib/btree_gin/btree_gin.control
+++ b/contrib/btree_gin/btree_gin.control
@@ -1,5 +1,5 @@
 # btree_gin extension
 comment = 'support for indexing common datatypes in GIN'
-default_version = '1.0'
+default_version = '1.1'
 module_pathname = '$libdir/btree_gin'
 relocatable = true
diff --git a/contrib/btree_gin/expected/enum.out b/contrib/btree_gin/expected/enum.out
new file mode 100644
index 0000000..4e02b2d
--- /dev/null
+++ b/contrib/btree_gin/expected/enum.out
@@ -0,0 +1,58 @@
+set enable_seqscan=off;
+CREATE TYPE rainbow AS ENUM ('r','o','y','g','b','i','v');
+CREATE TABLE test_enum (
+	i rainbow
+);
+INSERT INTO test_enum VALUES ('v'),('y'),('r'),('g'),('o'),('i'),('b');
+CREATE INDEX idx_enum ON test_enum USING gin (i);
+SELECT * FROM test_enum WHERE i<'g'::rainbow ORDER BY i;
+ i 
+---
+ r
+ o
+ y
+(3 rows)
+
+SELECT * FROM test_enum WHERE i<='g'::rainbow ORDER BY i;
+ i 
+---
+ r
+ o
+ y
+ g
+(4 rows)
+
+SELECT * FROM test_enum WHERE i='g'::rainbow ORDER BY i;
+ i 
+---
+ g
+(1 row)
+
+SELECT * FROM test_enum WHERE i>='g'::rainbow ORDER BY i;
+ i 
+---
+ g
+ b
+ i
+ v
+(4 rows)
+
+SELECT * FROM test_enum WHERE i>'g'::rainbow ORDER BY i;
+ i 
+---
+ b
+ i
+ v
+(3 rows)
+
+explain (costs off) SELECT * FROM test_enum WHERE i>='g'::rainbow ORDER BY i;
+                  QUERY PLAN                   
+-----------------------------------------------
+ Sort
+   Sort Key: i
+   ->  Bitmap Heap Scan on test_enum
+         Recheck Cond: (i >= 'g'::rainbow)
+         ->  Bitmap Index Scan on idx_enum
+               Index Cond: (i >= 'g'::rainbow)
+(6 rows)
+
diff --git a/contrib/btree_gin/sql/enum.sql b/contrib/btree_gin/sql/enum.sql
new file mode 100644
index 0000000..9ee8f4c
--- /dev/null
+++ b/contrib/btree_gin/sql/enum.sql
@@ -0,0 +1,19 @@
+set enable_seqscan=off;
+
+CREATE TYPE rainbow AS ENUM ('r','o','y','g','b','i','v');
+
+CREATE TABLE test_enum (
+	i rainbow
+);
+
+INSERT INTO test_enum VALUES ('v'),('y'),('r'),('g'),('o'),('i'),('b');
+
+CREATE INDEX idx_enum ON test_enum USING gin (i);
+
+SELECT * FROM test_enum WHERE i<'g'::rainbow ORDER BY i;
+SELECT * FROM test_enum WHERE i<='g'::rainbow ORDER BY i;
+SELECT * FROM test_enum WHERE i='g'::rainbow ORDER BY i;
+SELECT * FROM test_enum WHERE i>='g'::rainbow ORDER BY i;
+SELECT * FROM test_enum WHERE i>'g'::rainbow ORDER BY i;
+
+explain (costs off) SELECT * FROM test_enum WHERE i>='g'::rainbow ORDER BY i;
diff --git a/contrib/btree_gist/Makefile b/contrib/btree_gist/Makefile
index 5134f72..4f48181 100644
--- a/contrib/btree_gist/Makefile
+++ b/contrib/btree_gist/Makefile
@@ -6,16 +6,16 @@ OBJS =  btree_gist.o btree_utils_num.o btree_utils_var.o btree_int2.o \
         btree_int4.o btree_int8.o btree_float4.o btree_float8.o btree_cash.o \
         btree_oid.o btree_ts.o btree_time.o btree_date.o btree_interval.o \
         btree_macaddr.o btree_inet.o btree_text.o btree_bytea.o btree_bit.o \
-        btree_numeric.o $(WIN32RES)
+        btree_numeric.o btree_enum.o $(WIN32RES)
 
 EXTENSION = btree_gist
-DATA = btree_gist--1.2.sql btree_gist--1.1--1.2.sql btree_gist--1.0--1.1.sql \
-	btree_gist--unpackaged--1.0.sql
+DATA = btree_gist--1.3.sql btree_gist--1.2--1.3.sql btree_gist--1.1--1.2.sql \
+	btree_gist--1.0--1.1.sql btree_gist--unpackaged--1.0.sql
 PGFILEDESC = "btree_gist - B-tree equivalent GiST operator classes"
 
 REGRESS = init int2 int4 int8 float4 float8 cash oid timestamp timestamptz \
         time timetz date interval macaddr inet cidr text varchar char bytea \
-        bit varbit numeric not_equal
+        bit varbit numeric enum not_equal
 
 SHLIB_LINK += $(filter -lm, $(LIBS))
 
diff --git a/contrib/btree_gist/btree_enum.c b/contrib/btree_gist/btree_enum.c
new file mode 100644
index 0000000..6126962
--- /dev/null
+++ b/contrib/btree_gist/btree_enum.c
@@ -0,0 +1,186 @@
+/*
+ * contrib/btree_gist/btree_enum.c
+ */
+#include "postgres.h"
+#include "utils/builtins.h"
+
+#include "btree_gist.h"
+#include "btree_utils_num.h"
+
+/* enums are really Oids, so we just use the same structure */
+
+typedef struct
+{
+	Oid			lower;
+	Oid			upper;
+} oidKEY;
+
+/*
+** enum ops
+*/
+PG_FUNCTION_INFO_V1(gbt_enum_compress);
+PG_FUNCTION_INFO_V1(gbt_enum_fetch);
+PG_FUNCTION_INFO_V1(gbt_enum_union);
+PG_FUNCTION_INFO_V1(gbt_enum_picksplit);
+PG_FUNCTION_INFO_V1(gbt_enum_consistent);
+PG_FUNCTION_INFO_V1(gbt_enum_penalty);
+PG_FUNCTION_INFO_V1(gbt_enum_same);
+
+
+static bool
+gbt_enumgt(const void *a, const void *b)
+{
+	return DatumGetBool(
+						DirectFunctionCall2(enum_gt, ObjectIdGetDatum(*((const Oid *) a)), ObjectIdGetDatum(*((const Oid *) b)))
+		);
+}
+static bool
+gbt_enumge(const void *a, const void *b)
+{
+	return DatumGetBool(
+						DirectFunctionCall2(enum_ge, ObjectIdGetDatum(*((const Oid *) a)), ObjectIdGetDatum(*((const Oid *) b)))
+		);
+}
+static bool
+gbt_enumeq(const void *a, const void *b)
+{
+	return (*((const Oid *) a) == *((const Oid *) b));
+}
+static bool
+gbt_enumle(const void *a, const void *b)
+{
+	return DatumGetBool(
+						DirectFunctionCall2(enum_le, ObjectIdGetDatum(*((const Oid *) a)), ObjectIdGetDatum(*((const Oid *) b)))
+		);
+}
+static bool
+gbt_enumlt(const void *a, const void *b)
+{
+	return DatumGetBool(
+						DirectFunctionCall2(enum_lt, ObjectIdGetDatum(*((const Oid *) a)), ObjectIdGetDatum(*((const Oid *) b)))
+		);
+}
+
+static int
+gbt_enumkey_cmp(const void *a, const void *b)
+{
+	oidKEY	   *ia = (oidKEY *) (((const Nsrt *) a)->t);
+	oidKEY	   *ib = (oidKEY *) (((const Nsrt *) b)->t);
+
+	if (ia->lower == ib->lower)
+	{
+		if (ia->upper == ib->upper)
+			return 0;
+
+		return DatumGetInt32(
+			DirectFunctionCall2(enum_cmp, ObjectIdGetDatum(ia->upper), ObjectIdGetDatum(ib->upper))
+			);
+	}
+
+	return DatumGetInt32(
+		DirectFunctionCall2(enum_cmp, ObjectIdGetDatum(ia->lower), ObjectIdGetDatum(ib->lower))
+		);
+}
+
+static const gbtree_ninfo tinfo =
+{
+	gbt_t_enum,
+	sizeof(Oid),
+	8,							/* sizeof(gbtreekey8) */
+	gbt_enumgt,
+	gbt_enumge,
+	gbt_enumeq,
+	gbt_enumle,
+	gbt_enumlt,
+	gbt_enumkey_cmp,
+	NULL /* no KNN support at least for now */
+};
+
+
+/**************************************************
+ * Enum ops
+ **************************************************/
+
+
+Datum
+gbt_enum_compress(PG_FUNCTION_ARGS)
+{
+	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+
+	PG_RETURN_POINTER(gbt_num_compress(entry, &tinfo));
+}
+
+Datum
+gbt_enum_fetch(PG_FUNCTION_ARGS)
+{
+	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+
+	PG_RETURN_POINTER(gbt_num_fetch(entry, &tinfo));
+}
+
+Datum
+gbt_enum_consistent(PG_FUNCTION_ARGS)
+{
+	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+	Oid			query = PG_GETARG_OID(1);
+	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
+
+	/* Oid		subtype = PG_GETARG_OID(3); */
+	bool	   *recheck = (bool *) PG_GETARG_POINTER(4);
+	oidKEY	   *kkk = (oidKEY *) DatumGetPointer(entry->key);
+	GBT_NUMKEY_R key;
+
+	/* All cases served by this function are exact */
+	*recheck = false;
+
+	key.lower = (GBT_NUMKEY *) &kkk->lower;
+	key.upper = (GBT_NUMKEY *) &kkk->upper;
+
+	PG_RETURN_BOOL(
+				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo)
+		);
+}
+
+Datum
+gbt_enum_union(PG_FUNCTION_ARGS)
+{
+	GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
+	void	   *out = palloc(sizeof(oidKEY));
+
+	*(int *) PG_GETARG_POINTER(1) = sizeof(oidKEY);
+	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
+}
+
+
+Datum
+gbt_enum_penalty(PG_FUNCTION_ARGS)
+{
+	oidKEY	   *origentry = (oidKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
+	oidKEY	   *newentry = (oidKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
+	float	   *result = (float *) PG_GETARG_POINTER(2);
+
+	penalty_num(result, origentry->lower, origentry->upper, newentry->lower, newentry->upper);
+
+	PG_RETURN_POINTER(result);
+}
+
+Datum
+gbt_enum_picksplit(PG_FUNCTION_ARGS)
+{
+	PG_RETURN_POINTER(gbt_num_picksplit(
+									(GistEntryVector *) PG_GETARG_POINTER(0),
+									  (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
+										&tinfo
+										));
+}
+
+Datum
+gbt_enum_same(PG_FUNCTION_ARGS)
+{
+	oidKEY	   *b1 = (oidKEY *) PG_GETARG_POINTER(0);
+	oidKEY	   *b2 = (oidKEY *) PG_GETARG_POINTER(1);
+	bool	   *result = (bool *) PG_GETARG_POINTER(2);
+
+	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
+	PG_RETURN_POINTER(result);
+}
diff --git a/contrib/btree_gist/btree_gist--1.2--1.3.sql b/contrib/btree_gist/btree_gist--1.2--1.3.sql
new file mode 100644
index 0000000..6c40624
--- /dev/null
+++ b/contrib/btree_gist/btree_gist--1.2--1.3.sql
@@ -0,0 +1,69 @@
+/* contrib/btree_gist/btree_gist--1.2--1.3.sql */
+
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "ALTER EXTENSION btree_gist UPDATE TO '1.3'" to load this file. \quit
+
+--
+--
+--
+-- enum ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_enum_consistent(internal,anyenum,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_union(internal, internal)
+RETURNS gbtreekey4
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_same(gbtreekey8, gbtreekey8, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_enum_ops
+DEFAULT FOR TYPE anyenum USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_enum_consistent (internal, anyenum, int2, oid, internal),
+	FUNCTION	2	gbt_enum_union (internal, internal),
+	FUNCTION	3	gbt_enum_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_enum_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_enum_picksplit (internal, internal),
+	FUNCTION	7	gbt_enum_same (gbtreekey8, gbtreekey8, internal),
+	STORAGE		gbtreekey8;
+
+ALTER OPERATOR FAMILY gist_enum_ops USING gist ADD
+	OPERATOR	6	<> (anyenum, anyenum) ,
+	FUNCTION	9 (anyenum, anyenum) gbt_enum_fetch (internal) ;
diff --git a/contrib/btree_gist/btree_gist--1.2.sql b/contrib/btree_gist/btree_gist--1.2.sql
deleted file mode 100644
index 1efe753..0000000
--- a/contrib/btree_gist/btree_gist--1.2.sql
+++ /dev/null
@@ -1,1570 +0,0 @@
-/* contrib/btree_gist/btree_gist--1.2.sql */
-
--- complain if script is sourced in psql, rather than via CREATE EXTENSION
-\echo Use "CREATE EXTENSION btree_gist" to load this file. \quit
-
-CREATE FUNCTION gbtreekey4_in(cstring)
-RETURNS gbtreekey4
-AS 'MODULE_PATHNAME', 'gbtreekey_in'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbtreekey4_out(gbtreekey4)
-RETURNS cstring
-AS 'MODULE_PATHNAME', 'gbtreekey_out'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE TYPE gbtreekey4 (
-	INTERNALLENGTH = 4,
-	INPUT  = gbtreekey4_in,
-	OUTPUT = gbtreekey4_out
-);
-
-CREATE FUNCTION gbtreekey8_in(cstring)
-RETURNS gbtreekey8
-AS 'MODULE_PATHNAME', 'gbtreekey_in'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbtreekey8_out(gbtreekey8)
-RETURNS cstring
-AS 'MODULE_PATHNAME', 'gbtreekey_out'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE TYPE gbtreekey8 (
-	INTERNALLENGTH = 8,
-	INPUT  = gbtreekey8_in,
-	OUTPUT = gbtreekey8_out
-);
-
-CREATE FUNCTION gbtreekey16_in(cstring)
-RETURNS gbtreekey16
-AS 'MODULE_PATHNAME', 'gbtreekey_in'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbtreekey16_out(gbtreekey16)
-RETURNS cstring
-AS 'MODULE_PATHNAME', 'gbtreekey_out'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE TYPE gbtreekey16 (
-	INTERNALLENGTH = 16,
-	INPUT  = gbtreekey16_in,
-	OUTPUT = gbtreekey16_out
-);
-
-CREATE FUNCTION gbtreekey32_in(cstring)
-RETURNS gbtreekey32
-AS 'MODULE_PATHNAME', 'gbtreekey_in'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbtreekey32_out(gbtreekey32)
-RETURNS cstring
-AS 'MODULE_PATHNAME', 'gbtreekey_out'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE TYPE gbtreekey32 (
-	INTERNALLENGTH = 32,
-	INPUT  = gbtreekey32_in,
-	OUTPUT = gbtreekey32_out
-);
-
-CREATE FUNCTION gbtreekey_var_in(cstring)
-RETURNS gbtreekey_var
-AS 'MODULE_PATHNAME', 'gbtreekey_in'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbtreekey_var_out(gbtreekey_var)
-RETURNS cstring
-AS 'MODULE_PATHNAME', 'gbtreekey_out'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE TYPE gbtreekey_var (
-	INTERNALLENGTH = VARIABLE,
-	INPUT  = gbtreekey_var_in,
-	OUTPUT = gbtreekey_var_out,
-	STORAGE = EXTENDED
-);
-
---distance operators
-
-CREATE FUNCTION cash_dist(money, money)
-RETURNS money
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE OPERATOR <-> (
-	LEFTARG = money,
-	RIGHTARG = money,
-	PROCEDURE = cash_dist,
-	COMMUTATOR = '<->'
-);
-
-CREATE FUNCTION date_dist(date, date)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE OPERATOR <-> (
-	LEFTARG = date,
-	RIGHTARG = date,
-	PROCEDURE = date_dist,
-	COMMUTATOR = '<->'
-);
-
-CREATE FUNCTION float4_dist(float4, float4)
-RETURNS float4
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE OPERATOR <-> (
-	LEFTARG = float4,
-	RIGHTARG = float4,
-	PROCEDURE = float4_dist,
-	COMMUTATOR = '<->'
-);
-
-CREATE FUNCTION float8_dist(float8, float8)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE OPERATOR <-> (
-	LEFTARG = float8,
-	RIGHTARG = float8,
-	PROCEDURE = float8_dist,
-	COMMUTATOR = '<->'
-);
-
-CREATE FUNCTION int2_dist(int2, int2)
-RETURNS int2
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE OPERATOR <-> (
-	LEFTARG = int2,
-	RIGHTARG = int2,
-	PROCEDURE = int2_dist,
-	COMMUTATOR = '<->'
-);
-
-CREATE FUNCTION int4_dist(int4, int4)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE OPERATOR <-> (
-	LEFTARG = int4,
-	RIGHTARG = int4,
-	PROCEDURE = int4_dist,
-	COMMUTATOR = '<->'
-);
-
-CREATE FUNCTION int8_dist(int8, int8)
-RETURNS int8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE OPERATOR <-> (
-	LEFTARG = int8,
-	RIGHTARG = int8,
-	PROCEDURE = int8_dist,
-	COMMUTATOR = '<->'
-);
-
-CREATE FUNCTION interval_dist(interval, interval)
-RETURNS interval
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE OPERATOR <-> (
-	LEFTARG = interval,
-	RIGHTARG = interval,
-	PROCEDURE = interval_dist,
-	COMMUTATOR = '<->'
-);
-
-CREATE FUNCTION oid_dist(oid, oid)
-RETURNS oid
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE OPERATOR <-> (
-	LEFTARG = oid,
-	RIGHTARG = oid,
-	PROCEDURE = oid_dist,
-	COMMUTATOR = '<->'
-);
-
-CREATE FUNCTION time_dist(time, time)
-RETURNS interval
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE OPERATOR <-> (
-	LEFTARG = time,
-	RIGHTARG = time,
-	PROCEDURE = time_dist,
-	COMMUTATOR = '<->'
-);
-
-CREATE FUNCTION ts_dist(timestamp, timestamp)
-RETURNS interval
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE OPERATOR <-> (
-	LEFTARG = timestamp,
-	RIGHTARG = timestamp,
-	PROCEDURE = ts_dist,
-	COMMUTATOR = '<->'
-);
-
-CREATE FUNCTION tstz_dist(timestamptz, timestamptz)
-RETURNS interval
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE OPERATOR <-> (
-	LEFTARG = timestamptz,
-	RIGHTARG = timestamptz,
-	PROCEDURE = tstz_dist,
-	COMMUTATOR = '<->'
-);
-
-
---
---
---
--- oid ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_oid_consistent(internal,oid,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_oid_distance(internal,oid,int2,oid,internal)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_oid_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_oid_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_decompress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_var_decompress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_var_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_oid_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_oid_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_oid_union(internal, internal)
-RETURNS gbtreekey8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_oid_same(gbtreekey8, gbtreekey8, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_oid_ops
-DEFAULT FOR TYPE oid USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_oid_consistent (internal, oid, int2, oid, internal),
-	FUNCTION	2	gbt_oid_union (internal, internal),
-	FUNCTION	3	gbt_oid_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_oid_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_oid_picksplit (internal, internal),
-	FUNCTION	7	gbt_oid_same (gbtreekey8, gbtreekey8, internal),
-	STORAGE		gbtreekey8;
-
--- Add operators that are new in 9.1.  We do it like this, leaving them
--- "loose" in the operator family rather than bound into the opclass, because
--- that's the only state that can be reproduced during an upgrade from 9.0.
-ALTER OPERATOR FAMILY gist_oid_ops USING gist ADD
-	OPERATOR	6	<> (oid, oid) ,
-	OPERATOR	15	<-> (oid, oid) FOR ORDER BY pg_catalog.oid_ops ,
-	FUNCTION	8 (oid, oid) gbt_oid_distance (internal, oid, int2, oid, internal) ,
-	-- Also add support function for index-only-scans, added in 9.5.
-	FUNCTION	9 (oid, oid) gbt_oid_fetch (internal) ;
-
-
---
---
---
--- int2 ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_int2_consistent(internal,int2,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int2_distance(internal,int2,int2,oid,internal)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int2_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int2_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int2_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int2_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int2_union(internal, internal)
-RETURNS gbtreekey4
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int2_same(gbtreekey4, gbtreekey4, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_int2_ops
-DEFAULT FOR TYPE int2 USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_int2_consistent (internal, int2, int2, oid, internal),
-	FUNCTION	2	gbt_int2_union (internal, internal),
-	FUNCTION	3	gbt_int2_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_int2_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_int2_picksplit (internal, internal),
-	FUNCTION	7	gbt_int2_same (gbtreekey4, gbtreekey4, internal),
-	STORAGE		gbtreekey4;
-
-ALTER OPERATOR FAMILY gist_int2_ops USING gist ADD
-	OPERATOR	6	<> (int2, int2) ,
-	OPERATOR	15	<-> (int2, int2) FOR ORDER BY pg_catalog.integer_ops ,
-	FUNCTION	8 (int2, int2) gbt_int2_distance (internal, int2, int2, oid, internal) ,
-	FUNCTION	9 (int2, int2) gbt_int2_fetch (internal) ;
-
---
---
---
--- int4 ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_int4_consistent(internal,int4,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int4_distance(internal,int4,int2,oid,internal)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int4_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int4_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int4_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int4_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int4_union(internal, internal)
-RETURNS gbtreekey8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int4_same(gbtreekey8, gbtreekey8, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_int4_ops
-DEFAULT FOR TYPE int4 USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_int4_consistent (internal, int4, int2, oid, internal),
-	FUNCTION	2	gbt_int4_union (internal, internal),
-	FUNCTION	3	gbt_int4_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_int4_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_int4_picksplit (internal, internal),
-	FUNCTION	7	gbt_int4_same (gbtreekey8, gbtreekey8, internal),
-	STORAGE		gbtreekey8;
-
-ALTER OPERATOR FAMILY gist_int4_ops USING gist ADD
-	OPERATOR	6	<> (int4, int4) ,
-	OPERATOR	15	<-> (int4, int4) FOR ORDER BY pg_catalog.integer_ops ,
-	FUNCTION	8 (int4, int4) gbt_int4_distance (internal, int4, int2, oid, internal) ,
-	FUNCTION	9 (int4, int4) gbt_int4_fetch (internal) ;
-
-
---
---
---
--- int8 ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_int8_consistent(internal,int8,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int8_distance(internal,int8,int2,oid,internal)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int8_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int8_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int8_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int8_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int8_union(internal, internal)
-RETURNS gbtreekey16
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_int8_same(gbtreekey16, gbtreekey16, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_int8_ops
-DEFAULT FOR TYPE int8 USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_int8_consistent (internal, int8, int2, oid, internal),
-	FUNCTION	2	gbt_int8_union (internal, internal),
-	FUNCTION	3	gbt_int8_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_int8_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_int8_picksplit (internal, internal),
-	FUNCTION	7	gbt_int8_same (gbtreekey16, gbtreekey16, internal),
-	STORAGE		gbtreekey16;
-
-ALTER OPERATOR FAMILY gist_int8_ops USING gist ADD
-	OPERATOR	6	<> (int8, int8) ,
-	OPERATOR	15	<-> (int8, int8) FOR ORDER BY pg_catalog.integer_ops ,
-	FUNCTION	8 (int8, int8) gbt_int8_distance (internal, int8, int2, oid, internal) ,
-	FUNCTION	9 (int8, int8) gbt_int8_fetch (internal) ;
-
---
---
---
--- float4 ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_float4_consistent(internal,float4,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float4_distance(internal,float4,int2,oid,internal)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float4_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float4_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float4_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float4_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float4_union(internal, internal)
-RETURNS gbtreekey8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float4_same(gbtreekey8, gbtreekey8, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_float4_ops
-DEFAULT FOR TYPE float4 USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_float4_consistent (internal, float4, int2, oid, internal),
-	FUNCTION	2	gbt_float4_union (internal, internal),
-	FUNCTION	3	gbt_float4_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_float4_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_float4_picksplit (internal, internal),
-	FUNCTION	7	gbt_float4_same (gbtreekey8, gbtreekey8, internal),
-	STORAGE		gbtreekey8;
-
-ALTER OPERATOR FAMILY gist_float4_ops USING gist ADD
-	OPERATOR	6	<> (float4, float4) ,
-	OPERATOR	15	<-> (float4, float4) FOR ORDER BY pg_catalog.float_ops ,
-	FUNCTION	8 (float4, float4) gbt_float4_distance (internal, float4, int2, oid, internal) ,
-	FUNCTION	9 (float4, float4) gbt_float4_fetch (internal) ;
-
---
---
---
--- float8 ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_float8_consistent(internal,float8,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float8_distance(internal,float8,int2,oid,internal)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float8_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float8_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float8_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float8_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float8_union(internal, internal)
-RETURNS gbtreekey16
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_float8_same(gbtreekey16, gbtreekey16, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_float8_ops
-DEFAULT FOR TYPE float8 USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_float8_consistent (internal, float8, int2, oid, internal),
-	FUNCTION	2	gbt_float8_union (internal, internal),
-	FUNCTION	3	gbt_float8_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_float8_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_float8_picksplit (internal, internal),
-	FUNCTION	7	gbt_float8_same (gbtreekey16, gbtreekey16, internal),
-	STORAGE		gbtreekey16;
-
-ALTER OPERATOR FAMILY gist_float8_ops USING gist ADD
-	OPERATOR	6	<> (float8, float8) ,
-	OPERATOR	15	<-> (float8, float8) FOR ORDER BY pg_catalog.float_ops ,
-	FUNCTION	8 (float8, float8) gbt_float8_distance (internal, float8, int2, oid, internal) ,
-	FUNCTION	9 (float8, float8) gbt_float8_fetch (internal) ;
-
---
---
---
--- timestamp ops
---
---
---
-
-CREATE FUNCTION gbt_ts_consistent(internal,timestamp,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_ts_distance(internal,timestamp,int2,oid,internal)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_tstz_consistent(internal,timestamptz,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_tstz_distance(internal,timestamptz,int2,oid,internal)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_ts_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_tstz_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_ts_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_ts_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_ts_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_ts_union(internal, internal)
-RETURNS gbtreekey16
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_ts_same(gbtreekey16, gbtreekey16, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_timestamp_ops
-DEFAULT FOR TYPE timestamp USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_ts_consistent (internal, timestamp, int2, oid, internal),
-	FUNCTION	2	gbt_ts_union (internal, internal),
-	FUNCTION	3	gbt_ts_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_ts_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_ts_picksplit (internal, internal),
-	FUNCTION	7	gbt_ts_same (gbtreekey16, gbtreekey16, internal),
-	STORAGE		gbtreekey16;
-
-ALTER OPERATOR FAMILY gist_timestamp_ops USING gist ADD
-	OPERATOR	6	<> (timestamp, timestamp) ,
-	OPERATOR	15	<-> (timestamp, timestamp) FOR ORDER BY pg_catalog.interval_ops ,
-	FUNCTION	8 (timestamp, timestamp) gbt_ts_distance (internal, timestamp, int2, oid, internal) ,
-	FUNCTION	9 (timestamp, timestamp) gbt_ts_fetch (internal) ;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_timestamptz_ops
-DEFAULT FOR TYPE timestamptz USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_tstz_consistent (internal, timestamptz, int2, oid, internal),
-	FUNCTION	2	gbt_ts_union (internal, internal),
-	FUNCTION	3	gbt_tstz_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_ts_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_ts_picksplit (internal, internal),
-	FUNCTION	7	gbt_ts_same (gbtreekey16, gbtreekey16, internal),
-	STORAGE		gbtreekey16;
-
-ALTER OPERATOR FAMILY gist_timestamptz_ops USING gist ADD
-	OPERATOR	6	<> (timestamptz, timestamptz) ,
-	OPERATOR	15	<-> (timestamptz, timestamptz) FOR ORDER BY pg_catalog.interval_ops ,
-	FUNCTION	8 (timestamptz, timestamptz) gbt_tstz_distance (internal, timestamptz, int2, oid, internal) ,
-	FUNCTION	9 (timestamptz, timestamptz) gbt_ts_fetch (internal) ;
-
---
---
---
--- time ops
---
---
---
-
-CREATE FUNCTION gbt_time_consistent(internal,time,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_time_distance(internal,time,int2,oid,internal)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_timetz_consistent(internal,timetz,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_time_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_timetz_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_time_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_time_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_time_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_time_union(internal, internal)
-RETURNS gbtreekey16
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_time_same(gbtreekey16, gbtreekey16, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_time_ops
-DEFAULT FOR TYPE time USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_time_consistent (internal, time, int2, oid, internal),
-	FUNCTION	2	gbt_time_union (internal, internal),
-	FUNCTION	3	gbt_time_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_time_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_time_picksplit (internal, internal),
-	FUNCTION	7	gbt_time_same (gbtreekey16, gbtreekey16, internal),
-	STORAGE		gbtreekey16;
-
-ALTER OPERATOR FAMILY gist_time_ops USING gist ADD
-	OPERATOR	6	<> (time, time) ,
-	OPERATOR	15	<-> (time, time) FOR ORDER BY pg_catalog.interval_ops ,
-	FUNCTION	8 (time, time) gbt_time_distance (internal, time, int2, oid, internal) ,
-	FUNCTION	9 (time, time) gbt_time_fetch (internal) ;
-
-
-CREATE OPERATOR CLASS gist_timetz_ops
-DEFAULT FOR TYPE timetz USING gist
-AS
-	OPERATOR	1	<   ,
-	OPERATOR	2	<=  ,
-	OPERATOR	3	=   ,
-	OPERATOR	4	>=  ,
-	OPERATOR	5	>   ,
-	FUNCTION	1	gbt_timetz_consistent (internal, timetz, int2, oid, internal),
-	FUNCTION	2	gbt_time_union (internal, internal),
-	FUNCTION	3	gbt_timetz_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_time_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_time_picksplit (internal, internal),
-	FUNCTION	7	gbt_time_same (gbtreekey16, gbtreekey16, internal),
-	STORAGE		gbtreekey16;
-
-ALTER OPERATOR FAMILY gist_timetz_ops USING gist ADD
-	OPERATOR	6	<> (timetz, timetz) ;
-	-- no 'fetch' function, as the compress function is lossy.
-
-
---
---
---
--- date ops
---
---
---
-
-CREATE FUNCTION gbt_date_consistent(internal,date,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_date_distance(internal,date,int2,oid,internal)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_date_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_date_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_date_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_date_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_date_union(internal, internal)
-RETURNS gbtreekey8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_date_same(gbtreekey8, gbtreekey8, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_date_ops
-DEFAULT FOR TYPE date USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_date_consistent (internal, date, int2, oid, internal),
-	FUNCTION	2	gbt_date_union (internal, internal),
-	FUNCTION	3	gbt_date_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_date_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_date_picksplit (internal, internal),
-	FUNCTION	7	gbt_date_same (gbtreekey8, gbtreekey8, internal),
-	STORAGE		gbtreekey8;
-
-ALTER OPERATOR FAMILY gist_date_ops USING gist ADD
-	OPERATOR	6	<> (date, date) ,
-	OPERATOR	15	<-> (date, date) FOR ORDER BY pg_catalog.integer_ops ,
-	FUNCTION	8 (date, date) gbt_date_distance (internal, date, int2, oid, internal) ,
-	FUNCTION	9 (date, date) gbt_date_fetch (internal) ;
-
-
---
---
---
--- interval ops
---
---
---
-
-CREATE FUNCTION gbt_intv_consistent(internal,interval,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_intv_distance(internal,interval,int2,oid,internal)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_intv_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_intv_decompress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_intv_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_intv_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_intv_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_intv_union(internal, internal)
-RETURNS gbtreekey32
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_intv_same(gbtreekey32, gbtreekey32, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_interval_ops
-DEFAULT FOR TYPE interval USING gist
-AS
-	OPERATOR	1	< ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	= ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	> ,
-	FUNCTION	1	gbt_intv_consistent (internal, interval, int2, oid, internal),
-	FUNCTION	2	gbt_intv_union (internal, internal),
-	FUNCTION	3	gbt_intv_compress (internal),
-	FUNCTION	4	gbt_intv_decompress (internal),
-	FUNCTION	5	gbt_intv_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_intv_picksplit (internal, internal),
-	FUNCTION	7	gbt_intv_same (gbtreekey32, gbtreekey32, internal),
-	STORAGE		gbtreekey32;
-
-ALTER OPERATOR FAMILY gist_interval_ops USING gist ADD
-	OPERATOR	6	<> (interval, interval) ,
-	OPERATOR	15	<-> (interval, interval) FOR ORDER BY pg_catalog.interval_ops ,
-	FUNCTION	8 (interval, interval) gbt_intv_distance (internal, interval, int2, oid, internal) ,
-	FUNCTION	9 (interval, interval) gbt_intv_fetch (internal) ;
-
-
---
---
---
--- cash ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_cash_consistent(internal,money,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_cash_distance(internal,money,int2,oid,internal)
-RETURNS float8
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_cash_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_cash_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_cash_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_cash_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_cash_union(internal, internal)
-RETURNS gbtreekey16
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_cash_same(gbtreekey16, gbtreekey16, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_cash_ops
-DEFAULT FOR TYPE money USING gist
-AS
-	OPERATOR	1	< ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	= ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	> ,
-	FUNCTION	1	gbt_cash_consistent (internal, money, int2, oid, internal),
-	FUNCTION	2	gbt_cash_union (internal, internal),
-	FUNCTION	3	gbt_cash_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_cash_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_cash_picksplit (internal, internal),
-	FUNCTION	7	gbt_cash_same (gbtreekey16, gbtreekey16, internal),
-	STORAGE		gbtreekey16;
-
-ALTER OPERATOR FAMILY gist_cash_ops USING gist ADD
-	OPERATOR	6	<> (money, money) ,
-	OPERATOR	15	<-> (money, money) FOR ORDER BY pg_catalog.money_ops ,
-	FUNCTION	8 (money, money) gbt_cash_distance (internal, money, int2, oid, internal) ,
-	FUNCTION	9 (money, money) gbt_cash_fetch (internal) ;
-
-
---
---
---
--- macaddr ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_macad_consistent(internal,macaddr,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_macad_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_macad_fetch(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_macad_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_macad_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_macad_union(internal, internal)
-RETURNS gbtreekey16
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_macad_same(gbtreekey16, gbtreekey16, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_macaddr_ops
-DEFAULT FOR TYPE macaddr USING gist
-AS
-	OPERATOR	1	< ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	= ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	> ,
-	FUNCTION	1	gbt_macad_consistent (internal, macaddr, int2, oid, internal),
-	FUNCTION	2	gbt_macad_union (internal, internal),
-	FUNCTION	3	gbt_macad_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_macad_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_macad_picksplit (internal, internal),
-	FUNCTION	7	gbt_macad_same (gbtreekey16, gbtreekey16, internal),
-	STORAGE		gbtreekey16;
-
-ALTER OPERATOR FAMILY gist_macaddr_ops USING gist ADD
-	OPERATOR	6	<> (macaddr, macaddr) ,
-	FUNCTION	9 (macaddr, macaddr) gbt_macad_fetch (internal);
-
-
---
---
---
--- text/ bpchar ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_text_consistent(internal,text,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_bpchar_consistent(internal,bpchar,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_text_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_bpchar_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_text_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_text_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_text_union(internal, internal)
-RETURNS gbtreekey_var
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_text_same(gbtreekey_var, gbtreekey_var, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_text_ops
-DEFAULT FOR TYPE text USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_text_consistent (internal, text, int2, oid, internal),
-	FUNCTION	2	gbt_text_union (internal, internal),
-	FUNCTION	3	gbt_text_compress (internal),
-	FUNCTION	4	gbt_var_decompress (internal),
-	FUNCTION	5	gbt_text_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_text_picksplit (internal, internal),
-	FUNCTION	7	gbt_text_same (gbtreekey_var, gbtreekey_var, internal),
-	STORAGE			gbtreekey_var;
-
-ALTER OPERATOR FAMILY gist_text_ops USING gist ADD
-	OPERATOR	6	<> (text, text) ,
-	FUNCTION	9 (text, text) gbt_var_fetch (internal) ;
-
-
----- Create the operator class
-CREATE OPERATOR CLASS gist_bpchar_ops
-DEFAULT FOR TYPE bpchar USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_bpchar_consistent (internal, bpchar , int2, oid, internal),
-	FUNCTION	2	gbt_text_union (internal, internal),
-	FUNCTION	3	gbt_bpchar_compress (internal),
-	FUNCTION	4	gbt_var_decompress (internal),
-	FUNCTION	5	gbt_text_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_text_picksplit (internal, internal),
-	FUNCTION	7	gbt_text_same (gbtreekey_var, gbtreekey_var, internal),
-	STORAGE			gbtreekey_var;
-
-ALTER OPERATOR FAMILY gist_bpchar_ops USING gist ADD
-	OPERATOR	6	<> (bpchar, bpchar) ,
-	FUNCTION	9 (bpchar, bpchar) gbt_var_fetch (internal) ;
-
---
---
--- bytea ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_bytea_consistent(internal,bytea,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_bytea_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_bytea_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_bytea_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_bytea_union(internal, internal)
-RETURNS gbtreekey_var
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_bytea_same(gbtreekey_var, gbtreekey_var, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_bytea_ops
-DEFAULT FOR TYPE bytea USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_bytea_consistent (internal, bytea, int2, oid, internal),
-	FUNCTION	2	gbt_bytea_union (internal, internal),
-	FUNCTION	3	gbt_bytea_compress (internal),
-	FUNCTION	4	gbt_var_decompress (internal),
-	FUNCTION	5	gbt_bytea_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_bytea_picksplit (internal, internal),
-	FUNCTION	7	gbt_bytea_same (gbtreekey_var, gbtreekey_var, internal),
-	STORAGE			gbtreekey_var;
-
-ALTER OPERATOR FAMILY gist_bytea_ops USING gist ADD
-	OPERATOR	6	<> (bytea, bytea) ,
-	FUNCTION	9 (bytea, bytea) gbt_var_fetch (internal) ;
-
-
---
---
---
--- numeric ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_numeric_consistent(internal,numeric,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_numeric_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_numeric_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_numeric_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_numeric_union(internal, internal)
-RETURNS gbtreekey_var
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_numeric_same(gbtreekey_var, gbtreekey_var, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_numeric_ops
-DEFAULT FOR TYPE numeric USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_numeric_consistent (internal, numeric, int2, oid, internal),
-	FUNCTION	2	gbt_numeric_union (internal, internal),
-	FUNCTION	3	gbt_numeric_compress (internal),
-	FUNCTION	4	gbt_var_decompress (internal),
-	FUNCTION	5	gbt_numeric_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_numeric_picksplit (internal, internal),
-	FUNCTION	7	gbt_numeric_same (gbtreekey_var, gbtreekey_var, internal),
-	STORAGE			gbtreekey_var;
-
-ALTER OPERATOR FAMILY gist_numeric_ops USING gist ADD
-	OPERATOR	6	<> (numeric, numeric) ,
-	FUNCTION	9 (numeric, numeric) gbt_var_fetch (internal) ;
-
-
---
---
--- bit ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_bit_consistent(internal,bit,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_bit_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_bit_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_bit_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_bit_union(internal, internal)
-RETURNS gbtreekey_var
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_bit_same(gbtreekey_var, gbtreekey_var, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_bit_ops
-DEFAULT FOR TYPE bit USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_bit_consistent (internal, bit, int2, oid, internal),
-	FUNCTION	2	gbt_bit_union (internal, internal),
-	FUNCTION	3	gbt_bit_compress (internal),
-	FUNCTION	4	gbt_var_decompress (internal),
-	FUNCTION	5	gbt_bit_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_bit_picksplit (internal, internal),
-	FUNCTION	7	gbt_bit_same (gbtreekey_var, gbtreekey_var, internal),
-	STORAGE			gbtreekey_var;
-
-ALTER OPERATOR FAMILY gist_bit_ops USING gist ADD
-	OPERATOR	6	<> (bit, bit) ,
-	FUNCTION	9 (bit, bit) gbt_var_fetch (internal) ;
-
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_vbit_ops
-DEFAULT FOR TYPE varbit USING gist
-AS
-	OPERATOR	1	<  ,
-	OPERATOR	2	<= ,
-	OPERATOR	3	=  ,
-	OPERATOR	4	>= ,
-	OPERATOR	5	>  ,
-	FUNCTION	1	gbt_bit_consistent (internal, bit, int2, oid, internal),
-	FUNCTION	2	gbt_bit_union (internal, internal),
-	FUNCTION	3	gbt_bit_compress (internal),
-	FUNCTION	4	gbt_var_decompress (internal),
-	FUNCTION	5	gbt_bit_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_bit_picksplit (internal, internal),
-	FUNCTION	7	gbt_bit_same (gbtreekey_var, gbtreekey_var, internal),
-	STORAGE			gbtreekey_var;
-
-ALTER OPERATOR FAMILY gist_vbit_ops USING gist ADD
-	OPERATOR	6	<> (varbit, varbit) ,
-	FUNCTION	9 (varbit, varbit) gbt_var_fetch (internal) ;
-
-
---
---
---
--- inet/cidr ops
---
---
---
--- define the GiST support methods
-CREATE FUNCTION gbt_inet_consistent(internal,inet,int2,oid,internal)
-RETURNS bool
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_inet_compress(internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_inet_penalty(internal,internal,internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_inet_picksplit(internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_inet_union(internal, internal)
-RETURNS gbtreekey16
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gbt_inet_same(gbtreekey16, gbtreekey16, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_inet_ops
-DEFAULT FOR TYPE inet USING gist
-AS
-	OPERATOR	1	<   ,
-	OPERATOR	2	<=  ,
-	OPERATOR	3	=   ,
-	OPERATOR	4	>=  ,
-	OPERATOR	5	>   ,
-	FUNCTION	1	gbt_inet_consistent (internal, inet, int2, oid, internal),
-	FUNCTION	2	gbt_inet_union (internal, internal),
-	FUNCTION	3	gbt_inet_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_inet_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_inet_picksplit (internal, internal),
-	FUNCTION	7	gbt_inet_same (gbtreekey16, gbtreekey16, internal),
-	STORAGE		gbtreekey16;
-
-ALTER OPERATOR FAMILY gist_inet_ops USING gist ADD
-	OPERATOR	6	<>  (inet, inet) ;
-	-- no fetch support, the compress function is lossy
-
--- Create the operator class
-CREATE OPERATOR CLASS gist_cidr_ops
-DEFAULT FOR TYPE cidr USING gist
-AS
-	OPERATOR	1	<  (inet, inet)  ,
-	OPERATOR	2	<= (inet, inet)  ,
-	OPERATOR	3	=  (inet, inet)  ,
-	OPERATOR	4	>= (inet, inet)  ,
-	OPERATOR	5	>  (inet, inet)  ,
-	FUNCTION	1	gbt_inet_consistent (internal, inet, int2, oid, internal),
-	FUNCTION	2	gbt_inet_union (internal, internal),
-	FUNCTION	3	gbt_inet_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
-	FUNCTION	5	gbt_inet_penalty (internal, internal, internal),
-	FUNCTION	6	gbt_inet_picksplit (internal, internal),
-	FUNCTION	7	gbt_inet_same (gbtreekey16, gbtreekey16, internal),
-	STORAGE		gbtreekey16;
-
-ALTER OPERATOR FAMILY gist_cidr_ops USING gist ADD
-	OPERATOR	6	<> (inet, inet) ;
-	-- no fetch support, the compress function is lossy
diff --git a/contrib/btree_gist/btree_gist--1.3.sql b/contrib/btree_gist/btree_gist--1.3.sql
new file mode 100644
index 0000000..ebd8321
--- /dev/null
+++ b/contrib/btree_gist/btree_gist--1.3.sql
@@ -0,0 +1,1635 @@
+/* contrib/btree_gist/btree_gist--1.2.sql */
+
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "CREATE EXTENSION btree_gist" to load this file. \quit
+
+CREATE FUNCTION gbtreekey4_in(cstring)
+RETURNS gbtreekey4
+AS 'MODULE_PATHNAME', 'gbtreekey_in'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbtreekey4_out(gbtreekey4)
+RETURNS cstring
+AS 'MODULE_PATHNAME', 'gbtreekey_out'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE TYPE gbtreekey4 (
+	INTERNALLENGTH = 4,
+	INPUT  = gbtreekey4_in,
+	OUTPUT = gbtreekey4_out
+);
+
+CREATE FUNCTION gbtreekey8_in(cstring)
+RETURNS gbtreekey8
+AS 'MODULE_PATHNAME', 'gbtreekey_in'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbtreekey8_out(gbtreekey8)
+RETURNS cstring
+AS 'MODULE_PATHNAME', 'gbtreekey_out'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE TYPE gbtreekey8 (
+	INTERNALLENGTH = 8,
+	INPUT  = gbtreekey8_in,
+	OUTPUT = gbtreekey8_out
+);
+
+CREATE FUNCTION gbtreekey16_in(cstring)
+RETURNS gbtreekey16
+AS 'MODULE_PATHNAME', 'gbtreekey_in'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbtreekey16_out(gbtreekey16)
+RETURNS cstring
+AS 'MODULE_PATHNAME', 'gbtreekey_out'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE TYPE gbtreekey16 (
+	INTERNALLENGTH = 16,
+	INPUT  = gbtreekey16_in,
+	OUTPUT = gbtreekey16_out
+);
+
+CREATE FUNCTION gbtreekey32_in(cstring)
+RETURNS gbtreekey32
+AS 'MODULE_PATHNAME', 'gbtreekey_in'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbtreekey32_out(gbtreekey32)
+RETURNS cstring
+AS 'MODULE_PATHNAME', 'gbtreekey_out'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE TYPE gbtreekey32 (
+	INTERNALLENGTH = 32,
+	INPUT  = gbtreekey32_in,
+	OUTPUT = gbtreekey32_out
+);
+
+CREATE FUNCTION gbtreekey_var_in(cstring)
+RETURNS gbtreekey_var
+AS 'MODULE_PATHNAME', 'gbtreekey_in'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbtreekey_var_out(gbtreekey_var)
+RETURNS cstring
+AS 'MODULE_PATHNAME', 'gbtreekey_out'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE TYPE gbtreekey_var (
+	INTERNALLENGTH = VARIABLE,
+	INPUT  = gbtreekey_var_in,
+	OUTPUT = gbtreekey_var_out,
+	STORAGE = EXTENDED
+);
+
+--distance operators
+
+CREATE FUNCTION cash_dist(money, money)
+RETURNS money
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR <-> (
+	LEFTARG = money,
+	RIGHTARG = money,
+	PROCEDURE = cash_dist,
+	COMMUTATOR = '<->'
+);
+
+CREATE FUNCTION date_dist(date, date)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR <-> (
+	LEFTARG = date,
+	RIGHTARG = date,
+	PROCEDURE = date_dist,
+	COMMUTATOR = '<->'
+);
+
+CREATE FUNCTION float4_dist(float4, float4)
+RETURNS float4
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR <-> (
+	LEFTARG = float4,
+	RIGHTARG = float4,
+	PROCEDURE = float4_dist,
+	COMMUTATOR = '<->'
+);
+
+CREATE FUNCTION float8_dist(float8, float8)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR <-> (
+	LEFTARG = float8,
+	RIGHTARG = float8,
+	PROCEDURE = float8_dist,
+	COMMUTATOR = '<->'
+);
+
+CREATE FUNCTION int2_dist(int2, int2)
+RETURNS int2
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR <-> (
+	LEFTARG = int2,
+	RIGHTARG = int2,
+	PROCEDURE = int2_dist,
+	COMMUTATOR = '<->'
+);
+
+CREATE FUNCTION int4_dist(int4, int4)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR <-> (
+	LEFTARG = int4,
+	RIGHTARG = int4,
+	PROCEDURE = int4_dist,
+	COMMUTATOR = '<->'
+);
+
+CREATE FUNCTION int8_dist(int8, int8)
+RETURNS int8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR <-> (
+	LEFTARG = int8,
+	RIGHTARG = int8,
+	PROCEDURE = int8_dist,
+	COMMUTATOR = '<->'
+);
+
+CREATE FUNCTION interval_dist(interval, interval)
+RETURNS interval
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR <-> (
+	LEFTARG = interval,
+	RIGHTARG = interval,
+	PROCEDURE = interval_dist,
+	COMMUTATOR = '<->'
+);
+
+CREATE FUNCTION oid_dist(oid, oid)
+RETURNS oid
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR <-> (
+	LEFTARG = oid,
+	RIGHTARG = oid,
+	PROCEDURE = oid_dist,
+	COMMUTATOR = '<->'
+);
+
+CREATE FUNCTION time_dist(time, time)
+RETURNS interval
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR <-> (
+	LEFTARG = time,
+	RIGHTARG = time,
+	PROCEDURE = time_dist,
+	COMMUTATOR = '<->'
+);
+
+CREATE FUNCTION ts_dist(timestamp, timestamp)
+RETURNS interval
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR <-> (
+	LEFTARG = timestamp,
+	RIGHTARG = timestamp,
+	PROCEDURE = ts_dist,
+	COMMUTATOR = '<->'
+);
+
+CREATE FUNCTION tstz_dist(timestamptz, timestamptz)
+RETURNS interval
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR <-> (
+	LEFTARG = timestamptz,
+	RIGHTARG = timestamptz,
+	PROCEDURE = tstz_dist,
+	COMMUTATOR = '<->'
+);
+
+
+--
+--
+--
+-- oid ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_oid_consistent(internal,oid,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_oid_distance(internal,oid,int2,oid,internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_oid_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_oid_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_decompress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_var_decompress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_var_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_oid_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_oid_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_oid_union(internal, internal)
+RETURNS gbtreekey8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_oid_same(gbtreekey8, gbtreekey8, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_oid_ops
+DEFAULT FOR TYPE oid USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_oid_consistent (internal, oid, int2, oid, internal),
+	FUNCTION	2	gbt_oid_union (internal, internal),
+	FUNCTION	3	gbt_oid_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_oid_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_oid_picksplit (internal, internal),
+	FUNCTION	7	gbt_oid_same (gbtreekey8, gbtreekey8, internal),
+	STORAGE		gbtreekey8;
+
+-- Add operators that are new in 9.1.  We do it like this, leaving them
+-- "loose" in the operator family rather than bound into the opclass, because
+-- that's the only state that can be reproduced during an upgrade from 9.0.
+ALTER OPERATOR FAMILY gist_oid_ops USING gist ADD
+	OPERATOR	6	<> (oid, oid) ,
+	OPERATOR	15	<-> (oid, oid) FOR ORDER BY pg_catalog.oid_ops ,
+	FUNCTION	8 (oid, oid) gbt_oid_distance (internal, oid, int2, oid, internal) ,
+	-- Also add support function for index-only-scans, added in 9.5.
+	FUNCTION	9 (oid, oid) gbt_oid_fetch (internal) ;
+
+
+--
+--
+--
+-- int2 ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_int2_consistent(internal,int2,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int2_distance(internal,int2,int2,oid,internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int2_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int2_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int2_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int2_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int2_union(internal, internal)
+RETURNS gbtreekey4
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int2_same(gbtreekey4, gbtreekey4, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_int2_ops
+DEFAULT FOR TYPE int2 USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_int2_consistent (internal, int2, int2, oid, internal),
+	FUNCTION	2	gbt_int2_union (internal, internal),
+	FUNCTION	3	gbt_int2_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_int2_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_int2_picksplit (internal, internal),
+	FUNCTION	7	gbt_int2_same (gbtreekey4, gbtreekey4, internal),
+	STORAGE		gbtreekey4;
+
+ALTER OPERATOR FAMILY gist_int2_ops USING gist ADD
+	OPERATOR	6	<> (int2, int2) ,
+	OPERATOR	15	<-> (int2, int2) FOR ORDER BY pg_catalog.integer_ops ,
+	FUNCTION	8 (int2, int2) gbt_int2_distance (internal, int2, int2, oid, internal) ,
+	FUNCTION	9 (int2, int2) gbt_int2_fetch (internal) ;
+
+--
+--
+--
+-- int4 ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_int4_consistent(internal,int4,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int4_distance(internal,int4,int2,oid,internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int4_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int4_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int4_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int4_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int4_union(internal, internal)
+RETURNS gbtreekey8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int4_same(gbtreekey8, gbtreekey8, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_int4_ops
+DEFAULT FOR TYPE int4 USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_int4_consistent (internal, int4, int2, oid, internal),
+	FUNCTION	2	gbt_int4_union (internal, internal),
+	FUNCTION	3	gbt_int4_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_int4_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_int4_picksplit (internal, internal),
+	FUNCTION	7	gbt_int4_same (gbtreekey8, gbtreekey8, internal),
+	STORAGE		gbtreekey8;
+
+ALTER OPERATOR FAMILY gist_int4_ops USING gist ADD
+	OPERATOR	6	<> (int4, int4) ,
+	OPERATOR	15	<-> (int4, int4) FOR ORDER BY pg_catalog.integer_ops ,
+	FUNCTION	8 (int4, int4) gbt_int4_distance (internal, int4, int2, oid, internal) ,
+	FUNCTION	9 (int4, int4) gbt_int4_fetch (internal) ;
+
+
+--
+--
+--
+-- int8 ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_int8_consistent(internal,int8,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int8_distance(internal,int8,int2,oid,internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int8_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int8_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int8_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int8_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int8_union(internal, internal)
+RETURNS gbtreekey16
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_int8_same(gbtreekey16, gbtreekey16, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_int8_ops
+DEFAULT FOR TYPE int8 USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_int8_consistent (internal, int8, int2, oid, internal),
+	FUNCTION	2	gbt_int8_union (internal, internal),
+	FUNCTION	3	gbt_int8_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_int8_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_int8_picksplit (internal, internal),
+	FUNCTION	7	gbt_int8_same (gbtreekey16, gbtreekey16, internal),
+	STORAGE		gbtreekey16;
+
+ALTER OPERATOR FAMILY gist_int8_ops USING gist ADD
+	OPERATOR	6	<> (int8, int8) ,
+	OPERATOR	15	<-> (int8, int8) FOR ORDER BY pg_catalog.integer_ops ,
+	FUNCTION	8 (int8, int8) gbt_int8_distance (internal, int8, int2, oid, internal) ,
+	FUNCTION	9 (int8, int8) gbt_int8_fetch (internal) ;
+
+--
+--
+--
+-- float4 ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_float4_consistent(internal,float4,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float4_distance(internal,float4,int2,oid,internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float4_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float4_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float4_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float4_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float4_union(internal, internal)
+RETURNS gbtreekey8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float4_same(gbtreekey8, gbtreekey8, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_float4_ops
+DEFAULT FOR TYPE float4 USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_float4_consistent (internal, float4, int2, oid, internal),
+	FUNCTION	2	gbt_float4_union (internal, internal),
+	FUNCTION	3	gbt_float4_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_float4_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_float4_picksplit (internal, internal),
+	FUNCTION	7	gbt_float4_same (gbtreekey8, gbtreekey8, internal),
+	STORAGE		gbtreekey8;
+
+ALTER OPERATOR FAMILY gist_float4_ops USING gist ADD
+	OPERATOR	6	<> (float4, float4) ,
+	OPERATOR	15	<-> (float4, float4) FOR ORDER BY pg_catalog.float_ops ,
+	FUNCTION	8 (float4, float4) gbt_float4_distance (internal, float4, int2, oid, internal) ,
+	FUNCTION	9 (float4, float4) gbt_float4_fetch (internal) ;
+
+--
+--
+--
+-- float8 ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_float8_consistent(internal,float8,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float8_distance(internal,float8,int2,oid,internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float8_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float8_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float8_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float8_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float8_union(internal, internal)
+RETURNS gbtreekey16
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_float8_same(gbtreekey16, gbtreekey16, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_float8_ops
+DEFAULT FOR TYPE float8 USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_float8_consistent (internal, float8, int2, oid, internal),
+	FUNCTION	2	gbt_float8_union (internal, internal),
+	FUNCTION	3	gbt_float8_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_float8_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_float8_picksplit (internal, internal),
+	FUNCTION	7	gbt_float8_same (gbtreekey16, gbtreekey16, internal),
+	STORAGE		gbtreekey16;
+
+ALTER OPERATOR FAMILY gist_float8_ops USING gist ADD
+	OPERATOR	6	<> (float8, float8) ,
+	OPERATOR	15	<-> (float8, float8) FOR ORDER BY pg_catalog.float_ops ,
+	FUNCTION	8 (float8, float8) gbt_float8_distance (internal, float8, int2, oid, internal) ,
+	FUNCTION	9 (float8, float8) gbt_float8_fetch (internal) ;
+
+--
+--
+--
+-- timestamp ops
+--
+--
+--
+
+CREATE FUNCTION gbt_ts_consistent(internal,timestamp,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_ts_distance(internal,timestamp,int2,oid,internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_tstz_consistent(internal,timestamptz,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_tstz_distance(internal,timestamptz,int2,oid,internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_ts_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_tstz_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_ts_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_ts_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_ts_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_ts_union(internal, internal)
+RETURNS gbtreekey16
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_ts_same(gbtreekey16, gbtreekey16, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_timestamp_ops
+DEFAULT FOR TYPE timestamp USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_ts_consistent (internal, timestamp, int2, oid, internal),
+	FUNCTION	2	gbt_ts_union (internal, internal),
+	FUNCTION	3	gbt_ts_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_ts_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_ts_picksplit (internal, internal),
+	FUNCTION	7	gbt_ts_same (gbtreekey16, gbtreekey16, internal),
+	STORAGE		gbtreekey16;
+
+ALTER OPERATOR FAMILY gist_timestamp_ops USING gist ADD
+	OPERATOR	6	<> (timestamp, timestamp) ,
+	OPERATOR	15	<-> (timestamp, timestamp) FOR ORDER BY pg_catalog.interval_ops ,
+	FUNCTION	8 (timestamp, timestamp) gbt_ts_distance (internal, timestamp, int2, oid, internal) ,
+	FUNCTION	9 (timestamp, timestamp) gbt_ts_fetch (internal) ;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_timestamptz_ops
+DEFAULT FOR TYPE timestamptz USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_tstz_consistent (internal, timestamptz, int2, oid, internal),
+	FUNCTION	2	gbt_ts_union (internal, internal),
+	FUNCTION	3	gbt_tstz_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_ts_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_ts_picksplit (internal, internal),
+	FUNCTION	7	gbt_ts_same (gbtreekey16, gbtreekey16, internal),
+	STORAGE		gbtreekey16;
+
+ALTER OPERATOR FAMILY gist_timestamptz_ops USING gist ADD
+	OPERATOR	6	<> (timestamptz, timestamptz) ,
+	OPERATOR	15	<-> (timestamptz, timestamptz) FOR ORDER BY pg_catalog.interval_ops ,
+	FUNCTION	8 (timestamptz, timestamptz) gbt_tstz_distance (internal, timestamptz, int2, oid, internal) ,
+	FUNCTION	9 (timestamptz, timestamptz) gbt_ts_fetch (internal) ;
+
+--
+--
+--
+-- time ops
+--
+--
+--
+
+CREATE FUNCTION gbt_time_consistent(internal,time,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_time_distance(internal,time,int2,oid,internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_timetz_consistent(internal,timetz,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_time_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_timetz_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_time_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_time_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_time_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_time_union(internal, internal)
+RETURNS gbtreekey16
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_time_same(gbtreekey16, gbtreekey16, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_time_ops
+DEFAULT FOR TYPE time USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_time_consistent (internal, time, int2, oid, internal),
+	FUNCTION	2	gbt_time_union (internal, internal),
+	FUNCTION	3	gbt_time_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_time_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_time_picksplit (internal, internal),
+	FUNCTION	7	gbt_time_same (gbtreekey16, gbtreekey16, internal),
+	STORAGE		gbtreekey16;
+
+ALTER OPERATOR FAMILY gist_time_ops USING gist ADD
+	OPERATOR	6	<> (time, time) ,
+	OPERATOR	15	<-> (time, time) FOR ORDER BY pg_catalog.interval_ops ,
+	FUNCTION	8 (time, time) gbt_time_distance (internal, time, int2, oid, internal) ,
+	FUNCTION	9 (time, time) gbt_time_fetch (internal) ;
+
+
+CREATE OPERATOR CLASS gist_timetz_ops
+DEFAULT FOR TYPE timetz USING gist
+AS
+	OPERATOR	1	<   ,
+	OPERATOR	2	<=  ,
+	OPERATOR	3	=   ,
+	OPERATOR	4	>=  ,
+	OPERATOR	5	>   ,
+	FUNCTION	1	gbt_timetz_consistent (internal, timetz, int2, oid, internal),
+	FUNCTION	2	gbt_time_union (internal, internal),
+	FUNCTION	3	gbt_timetz_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_time_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_time_picksplit (internal, internal),
+	FUNCTION	7	gbt_time_same (gbtreekey16, gbtreekey16, internal),
+	STORAGE		gbtreekey16;
+
+ALTER OPERATOR FAMILY gist_timetz_ops USING gist ADD
+	OPERATOR	6	<> (timetz, timetz) ;
+	-- no 'fetch' function, as the compress function is lossy.
+
+
+--
+--
+--
+-- date ops
+--
+--
+--
+
+CREATE FUNCTION gbt_date_consistent(internal,date,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_date_distance(internal,date,int2,oid,internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_date_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_date_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_date_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_date_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_date_union(internal, internal)
+RETURNS gbtreekey8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_date_same(gbtreekey8, gbtreekey8, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_date_ops
+DEFAULT FOR TYPE date USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_date_consistent (internal, date, int2, oid, internal),
+	FUNCTION	2	gbt_date_union (internal, internal),
+	FUNCTION	3	gbt_date_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_date_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_date_picksplit (internal, internal),
+	FUNCTION	7	gbt_date_same (gbtreekey8, gbtreekey8, internal),
+	STORAGE		gbtreekey8;
+
+ALTER OPERATOR FAMILY gist_date_ops USING gist ADD
+	OPERATOR	6	<> (date, date) ,
+	OPERATOR	15	<-> (date, date) FOR ORDER BY pg_catalog.integer_ops ,
+	FUNCTION	8 (date, date) gbt_date_distance (internal, date, int2, oid, internal) ,
+	FUNCTION	9 (date, date) gbt_date_fetch (internal) ;
+
+
+--
+--
+--
+-- interval ops
+--
+--
+--
+
+CREATE FUNCTION gbt_intv_consistent(internal,interval,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_intv_distance(internal,interval,int2,oid,internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_intv_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_intv_decompress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_intv_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_intv_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_intv_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_intv_union(internal, internal)
+RETURNS gbtreekey32
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_intv_same(gbtreekey32, gbtreekey32, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_interval_ops
+DEFAULT FOR TYPE interval USING gist
+AS
+	OPERATOR	1	< ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	= ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	> ,
+	FUNCTION	1	gbt_intv_consistent (internal, interval, int2, oid, internal),
+	FUNCTION	2	gbt_intv_union (internal, internal),
+	FUNCTION	3	gbt_intv_compress (internal),
+	FUNCTION	4	gbt_intv_decompress (internal),
+	FUNCTION	5	gbt_intv_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_intv_picksplit (internal, internal),
+	FUNCTION	7	gbt_intv_same (gbtreekey32, gbtreekey32, internal),
+	STORAGE		gbtreekey32;
+
+ALTER OPERATOR FAMILY gist_interval_ops USING gist ADD
+	OPERATOR	6	<> (interval, interval) ,
+	OPERATOR	15	<-> (interval, interval) FOR ORDER BY pg_catalog.interval_ops ,
+	FUNCTION	8 (interval, interval) gbt_intv_distance (internal, interval, int2, oid, internal) ,
+	FUNCTION	9 (interval, interval) gbt_intv_fetch (internal) ;
+
+
+--
+--
+--
+-- cash ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_cash_consistent(internal,money,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_cash_distance(internal,money,int2,oid,internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_cash_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_cash_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_cash_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_cash_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_cash_union(internal, internal)
+RETURNS gbtreekey16
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_cash_same(gbtreekey16, gbtreekey16, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_cash_ops
+DEFAULT FOR TYPE money USING gist
+AS
+	OPERATOR	1	< ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	= ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	> ,
+	FUNCTION	1	gbt_cash_consistent (internal, money, int2, oid, internal),
+	FUNCTION	2	gbt_cash_union (internal, internal),
+	FUNCTION	3	gbt_cash_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_cash_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_cash_picksplit (internal, internal),
+	FUNCTION	7	gbt_cash_same (gbtreekey16, gbtreekey16, internal),
+	STORAGE		gbtreekey16;
+
+ALTER OPERATOR FAMILY gist_cash_ops USING gist ADD
+	OPERATOR	6	<> (money, money) ,
+	OPERATOR	15	<-> (money, money) FOR ORDER BY pg_catalog.money_ops ,
+	FUNCTION	8 (money, money) gbt_cash_distance (internal, money, int2, oid, internal) ,
+	FUNCTION	9 (money, money) gbt_cash_fetch (internal) ;
+
+
+--
+--
+--
+-- macaddr ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_macad_consistent(internal,macaddr,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_macad_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_macad_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_macad_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_macad_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_macad_union(internal, internal)
+RETURNS gbtreekey16
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_macad_same(gbtreekey16, gbtreekey16, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_macaddr_ops
+DEFAULT FOR TYPE macaddr USING gist
+AS
+	OPERATOR	1	< ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	= ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	> ,
+	FUNCTION	1	gbt_macad_consistent (internal, macaddr, int2, oid, internal),
+	FUNCTION	2	gbt_macad_union (internal, internal),
+	FUNCTION	3	gbt_macad_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_macad_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_macad_picksplit (internal, internal),
+	FUNCTION	7	gbt_macad_same (gbtreekey16, gbtreekey16, internal),
+	STORAGE		gbtreekey16;
+
+ALTER OPERATOR FAMILY gist_macaddr_ops USING gist ADD
+	OPERATOR	6	<> (macaddr, macaddr) ,
+	FUNCTION	9 (macaddr, macaddr) gbt_macad_fetch (internal);
+
+
+--
+--
+--
+-- text/ bpchar ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_text_consistent(internal,text,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bpchar_consistent(internal,bpchar,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_text_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bpchar_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_text_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_text_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_text_union(internal, internal)
+RETURNS gbtreekey_var
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_text_same(gbtreekey_var, gbtreekey_var, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_text_ops
+DEFAULT FOR TYPE text USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_text_consistent (internal, text, int2, oid, internal),
+	FUNCTION	2	gbt_text_union (internal, internal),
+	FUNCTION	3	gbt_text_compress (internal),
+	FUNCTION	4	gbt_var_decompress (internal),
+	FUNCTION	5	gbt_text_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_text_picksplit (internal, internal),
+	FUNCTION	7	gbt_text_same (gbtreekey_var, gbtreekey_var, internal),
+	STORAGE			gbtreekey_var;
+
+ALTER OPERATOR FAMILY gist_text_ops USING gist ADD
+	OPERATOR	6	<> (text, text) ,
+	FUNCTION	9 (text, text) gbt_var_fetch (internal) ;
+
+
+---- Create the operator class
+CREATE OPERATOR CLASS gist_bpchar_ops
+DEFAULT FOR TYPE bpchar USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_bpchar_consistent (internal, bpchar , int2, oid, internal),
+	FUNCTION	2	gbt_text_union (internal, internal),
+	FUNCTION	3	gbt_bpchar_compress (internal),
+	FUNCTION	4	gbt_var_decompress (internal),
+	FUNCTION	5	gbt_text_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_text_picksplit (internal, internal),
+	FUNCTION	7	gbt_text_same (gbtreekey_var, gbtreekey_var, internal),
+	STORAGE			gbtreekey_var;
+
+ALTER OPERATOR FAMILY gist_bpchar_ops USING gist ADD
+	OPERATOR	6	<> (bpchar, bpchar) ,
+	FUNCTION	9 (bpchar, bpchar) gbt_var_fetch (internal) ;
+
+--
+--
+-- bytea ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_bytea_consistent(internal,bytea,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bytea_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bytea_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bytea_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bytea_union(internal, internal)
+RETURNS gbtreekey_var
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bytea_same(gbtreekey_var, gbtreekey_var, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_bytea_ops
+DEFAULT FOR TYPE bytea USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_bytea_consistent (internal, bytea, int2, oid, internal),
+	FUNCTION	2	gbt_bytea_union (internal, internal),
+	FUNCTION	3	gbt_bytea_compress (internal),
+	FUNCTION	4	gbt_var_decompress (internal),
+	FUNCTION	5	gbt_bytea_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_bytea_picksplit (internal, internal),
+	FUNCTION	7	gbt_bytea_same (gbtreekey_var, gbtreekey_var, internal),
+	STORAGE			gbtreekey_var;
+
+ALTER OPERATOR FAMILY gist_bytea_ops USING gist ADD
+	OPERATOR	6	<> (bytea, bytea) ,
+	FUNCTION	9 (bytea, bytea) gbt_var_fetch (internal) ;
+
+
+--
+--
+--
+-- numeric ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_numeric_consistent(internal,numeric,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_numeric_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_numeric_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_numeric_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_numeric_union(internal, internal)
+RETURNS gbtreekey_var
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_numeric_same(gbtreekey_var, gbtreekey_var, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_numeric_ops
+DEFAULT FOR TYPE numeric USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_numeric_consistent (internal, numeric, int2, oid, internal),
+	FUNCTION	2	gbt_numeric_union (internal, internal),
+	FUNCTION	3	gbt_numeric_compress (internal),
+	FUNCTION	4	gbt_var_decompress (internal),
+	FUNCTION	5	gbt_numeric_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_numeric_picksplit (internal, internal),
+	FUNCTION	7	gbt_numeric_same (gbtreekey_var, gbtreekey_var, internal),
+	STORAGE			gbtreekey_var;
+
+ALTER OPERATOR FAMILY gist_numeric_ops USING gist ADD
+	OPERATOR	6	<> (numeric, numeric) ,
+	FUNCTION	9 (numeric, numeric) gbt_var_fetch (internal) ;
+
+
+--
+--
+-- bit ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_bit_consistent(internal,bit,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bit_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bit_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bit_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bit_union(internal, internal)
+RETURNS gbtreekey_var
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bit_same(gbtreekey_var, gbtreekey_var, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_bit_ops
+DEFAULT FOR TYPE bit USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_bit_consistent (internal, bit, int2, oid, internal),
+	FUNCTION	2	gbt_bit_union (internal, internal),
+	FUNCTION	3	gbt_bit_compress (internal),
+	FUNCTION	4	gbt_var_decompress (internal),
+	FUNCTION	5	gbt_bit_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_bit_picksplit (internal, internal),
+	FUNCTION	7	gbt_bit_same (gbtreekey_var, gbtreekey_var, internal),
+	STORAGE			gbtreekey_var;
+
+ALTER OPERATOR FAMILY gist_bit_ops USING gist ADD
+	OPERATOR	6	<> (bit, bit) ,
+	FUNCTION	9 (bit, bit) gbt_var_fetch (internal) ;
+
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_vbit_ops
+DEFAULT FOR TYPE varbit USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_bit_consistent (internal, bit, int2, oid, internal),
+	FUNCTION	2	gbt_bit_union (internal, internal),
+	FUNCTION	3	gbt_bit_compress (internal),
+	FUNCTION	4	gbt_var_decompress (internal),
+	FUNCTION	5	gbt_bit_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_bit_picksplit (internal, internal),
+	FUNCTION	7	gbt_bit_same (gbtreekey_var, gbtreekey_var, internal),
+	STORAGE			gbtreekey_var;
+
+ALTER OPERATOR FAMILY gist_vbit_ops USING gist ADD
+	OPERATOR	6	<> (varbit, varbit) ,
+	FUNCTION	9 (varbit, varbit) gbt_var_fetch (internal) ;
+
+
+--
+--
+--
+-- inet/cidr ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_inet_consistent(internal,inet,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_inet_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_inet_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_inet_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_inet_union(internal, internal)
+RETURNS gbtreekey16
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_inet_same(gbtreekey16, gbtreekey16, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_inet_ops
+DEFAULT FOR TYPE inet USING gist
+AS
+	OPERATOR	1	<   ,
+	OPERATOR	2	<=  ,
+	OPERATOR	3	=   ,
+	OPERATOR	4	>=  ,
+	OPERATOR	5	>   ,
+	FUNCTION	1	gbt_inet_consistent (internal, inet, int2, oid, internal),
+	FUNCTION	2	gbt_inet_union (internal, internal),
+	FUNCTION	3	gbt_inet_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_inet_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_inet_picksplit (internal, internal),
+	FUNCTION	7	gbt_inet_same (gbtreekey16, gbtreekey16, internal),
+	STORAGE		gbtreekey16;
+
+ALTER OPERATOR FAMILY gist_inet_ops USING gist ADD
+	OPERATOR	6	<>  (inet, inet) ;
+	-- no fetch support, the compress function is lossy
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_cidr_ops
+DEFAULT FOR TYPE cidr USING gist
+AS
+	OPERATOR	1	<  (inet, inet)  ,
+	OPERATOR	2	<= (inet, inet)  ,
+	OPERATOR	3	=  (inet, inet)  ,
+	OPERATOR	4	>= (inet, inet)  ,
+	OPERATOR	5	>  (inet, inet)  ,
+	FUNCTION	1	gbt_inet_consistent (internal, inet, int2, oid, internal),
+	FUNCTION	2	gbt_inet_union (internal, internal),
+	FUNCTION	3	gbt_inet_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_inet_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_inet_picksplit (internal, internal),
+	FUNCTION	7	gbt_inet_same (gbtreekey16, gbtreekey16, internal),
+	STORAGE		gbtreekey16;
+
+ALTER OPERATOR FAMILY gist_cidr_ops USING gist ADD
+	OPERATOR	6	<> (inet, inet) ;
+	-- no fetch support, the compress function is lossy
+
+--
+--
+--
+-- enum ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_enum_consistent(internal,anyenum,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_union(internal, internal)
+RETURNS gbtreekey4
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_same(gbtreekey8, gbtreekey8, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_enum_ops
+DEFAULT FOR TYPE anyenum USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_enum_consistent (internal, anyenum, int2, oid, internal),
+	FUNCTION	2	gbt_enum_union (internal, internal),
+	FUNCTION	3	gbt_enum_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_enum_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_enum_picksplit (internal, internal),
+	FUNCTION	7	gbt_enum_same (gbtreekey8, gbtreekey8, internal),
+	STORAGE		gbtreekey8;
+
+ALTER OPERATOR FAMILY gist_enum_ops USING gist ADD
+	OPERATOR	6	<> (anyenum, anyenum) ,
+	FUNCTION	9 (anyenum, anyenum) gbt_enum_fetch (internal) ;
diff --git a/contrib/btree_gist/btree_gist.control b/contrib/btree_gist/btree_gist.control
index 74d0e92..ddbf83d 100644
--- a/contrib/btree_gist/btree_gist.control
+++ b/contrib/btree_gist/btree_gist.control
@@ -1,5 +1,5 @@
 # btree_gist extension
 comment = 'support for indexing common datatypes in GiST'
-default_version = '1.2'
+default_version = '1.3'
 module_pathname = '$libdir/btree_gist'
 relocatable = true
diff --git a/contrib/btree_gist/btree_gist.h b/contrib/btree_gist/btree_gist.h
index 191202a..4850c51 100644
--- a/contrib/btree_gist/btree_gist.h
+++ b/contrib/btree_gist/btree_gist.h
@@ -31,7 +31,8 @@ enum gbtree_type
 	gbt_t_bpchar,
 	gbt_t_bytea,
 	gbt_t_bit,
-	gbt_t_inet
+	gbt_t_inet,
+	gbt_t_enum
 };
 
 #endif
diff --git a/contrib/btree_gist/btree_utils_num.c b/contrib/btree_gist/btree_utils_num.c
index 99cb41f..79f40a9 100644
--- a/contrib/btree_gist/btree_utils_num.c
+++ b/contrib/btree_gist/btree_utils_num.c
@@ -48,6 +48,7 @@ gbt_num_compress(GISTENTRY *entry, const gbtree_ninfo *tinfo)
 				leaf = &v.i8;
 				break;
 			case gbt_t_oid:
+			case gbt_t_enum:
 				v.i4 = DatumGetObjectId(entry->key);
 				leaf = &v.i4;
 				break;
@@ -122,6 +123,7 @@ gbt_num_fetch(GISTENTRY *entry, const gbtree_ninfo *tinfo)
 			datum = Int64GetDatum(*(int64 *) entry->key);
 			break;
 		case gbt_t_oid:
+		case gbt_t_enum:
 			datum = ObjectIdGetDatum(*(Oid *) entry->key);
 			break;
 		case gbt_t_float4:
diff --git a/contrib/btree_gist/data/enum.data b/contrib/btree_gist/data/enum.data
new file mode 100644
index 0000000..d03bfce
--- /dev/null
+++ b/contrib/btree_gist/data/enum.data
@@ -0,0 +1,595 @@
+r
+v
+i
+b
+r
+\N
+y
+v
+g
+o
+y
+b
+o
+o
+o
+o
+v
+r
+i
+o
+b
+r
+g
+b
+i
+o
+r
+r
+r
+\N
+o
+b
+v
+y
+o
+\N
+i
+o
+o
+g
+g
+b
+y
+v
+g
+g
+\N
+v
+g
+i
+i
+\N
+v
+y
+i
+r
+\N
+r
+\N
+g
+\N
+g
+\N
+v
+g
+y
+v
+r
+v
+r
+v
+y
+i
+i
+v
+y
+v
+i
+b
+i
+i
+r
+r
+\N
+\N
+y
+r
+g
+i
+y
+i
+i
+r
+g
+y
+\N
+i
+o
+r
+y
+y
+g
+o
+o
+g
+y
+r
+g
+v
+r
+i
+r
+i
+r
+y
+v
+b
+i
+o
+r
+\N
+o
+i
+v
+o
+b
+\N
+b
+g
+y
+o
+v
+b
+i
+v
+v
+o
+y
+i
+i
+i
+g
+b
+b
+g
+r
+i
+y
+o
+\N
+r
+\N
+i
+i
+g
+v
+o
+y
+y
+o
+i
+b
+r
+y
+y
+o
+g
+g
+g
+\N
+y
+o
+v
+g
+y
+g
+v
+\N
+i
+o
+v
+b
+b
+\N
+y
+v
+\N
+v
+\N
+i
+\N
+r
+b
+r
+o
+r
+b
+o
+g
+i
+r
+b
+g
+g
+y
+b
+b
+g
+y
+g
+v
+v
+b
+\N
+i
+v
+y
+b
+b
+o
+g
+b
+v
+g
+g
+b
+\N
+y
+r
+r
+b
+\N
+r
+g
+i
+o
+v
+\N
+o
+r
+b
+o
+b
+i
+\N
+\N
+y
+b
+y
+\N
+i
+i
+i
+o
+y
+o
+i
+b
+o
+g
+r
+\N
+b
+y
+\N
+g
+b
+y
+y
+o
+o
+b
+g
+i
+i
+v
+b
+o
+o
+v
+i
+g
+i
+o
+r
+o
+i
+i
+r
+b
+g
+o
+o
+y
+v
+g
+g
+g
+r
+o
+i
+i
+g
+\N
+o
+v
+b
+b
+v
+i
+g
+y
+i
+i
+g
+r
+y
+i
+b
+\N
+g
+y
+o
+\N
+i
+i
+b
+v
+o
+b
+v
+r
+g
+o
+v
+v
+y
+r
+v
+g
+\N
+v
+v
+b
+y
+o
+g
+i
+o
+b
+r
+y
+r
+v
+b
+b
+\N
+i
+v
+y
+r
+b
+i
+y
+g
+\N
+g
+r
+y
+y
+g
+b
+o
+v
+r
+i
+g
+r
+b
+b
+b
+\N
+y
+y
+y
+i
+o
+r
+g
+g
+i
+y
+g
+y
+v
+o
+o
+g
+\N
+b
+v
+o
+y
+r
+\N
+o
+i
+g
+\N
+i
+i
+i
+o
+b
+\N
+\N
+b
+\N
+v
+v
+r
+\N
+o
+b
+r
+o
+b
+o
+r
+y
+\N
+r
+i
+b
+b
+y
+v
+r
+g
+r
+r
+\N
+g
+\N
+v
+v
+y
+r
+o
+r
+o
+i
+o
+\N
+r
+\N
+i
+v
+b
+v
+\N
+b
+r
+v
+o
+\N
+i
+r
+b
+g
+o
+\N
+o
+g
+r
+v
+y
+g
+v
+r
+b
+r
+v
+o
+g
+i
+i
+g
+i
+y
+b
+i
+y
+r
+y
+o
+r
+b
+y
+y
+b
+y
+g
+b
+\N
+r
+g
+b
+o
+y
+o
+g
+r
+g
+b
+\N
+v
+v
+v
+g
+b
+y
+v
+o
+v
+g
+o
+g
+i
+b
+v
+i
+r
+r
+i
+b
+i
+b
+o
+\N
+\N
+y
+r
+g
+v
+o
+y
+\N
+g
+v
+o
+b
+v
+v
+\N
+r
+v
+y
+g
+b
+o
+v
+b
+v
+b
+r
+r
+i
+r
+v
+y
+v
+y
+o
+v
+g
+i
+r
+o
+o
+i
+y
+r
+\N
+y
+r
+b
+y
+y
+\N
+b
+\N
+\N
+i
+v
diff --git a/contrib/btree_gist/expected/enum.out b/contrib/btree_gist/expected/enum.out
new file mode 100644
index 0000000..c4b769d
--- /dev/null
+++ b/contrib/btree_gist/expected/enum.out
@@ -0,0 +1,91 @@
+-- enum check
+create type rainbow as enum ('r','o','y','g','b','i','v');
+CREATE TABLE enumtmp (a rainbow);
+\copy enumtmp from 'data/enum.data'
+SET enable_seqscan=on;
+select a, count(*) from enumtmp group by a order by 1;
+ a | count 
+---+-------
+ r |    76
+ o |    78
+ y |    73
+ g |    75
+ b |    77
+ i |    78
+ v |    75
+   |    63
+(8 rows)
+
+SELECT count(*) FROM enumtmp WHERE a <  'g'::rainbow;
+ count 
+-------
+   227
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a <= 'g'::rainbow;
+ count 
+-------
+   302
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a  = 'g'::rainbow;
+ count 
+-------
+    75
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a >= 'g'::rainbow;
+ count 
+-------
+   305
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a >  'g'::rainbow;
+ count 
+-------
+   230
+(1 row)
+
+CREATE INDEX enumidx ON enumtmp USING gist ( a );
+SET enable_seqscan=off;
+SELECT count(*) FROM enumtmp WHERE a <  'g'::rainbow;
+ count 
+-------
+   227
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a <= 'g'::rainbow;
+ count 
+-------
+   302
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a  = 'g'::rainbow;
+ count 
+-------
+    75
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a >= 'g'::rainbow;
+ count 
+-------
+   305
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a >  'g'::rainbow;
+ count 
+-------
+   230
+(1 row)
+
+EXPLAIN (COSTS OFF)
+SELECT count(*) FROM enumtmp WHERE a >= 'g'::rainbow;
+                  QUERY PLAN                   
+-----------------------------------------------
+ Aggregate
+   ->  Bitmap Heap Scan on enumtmp
+         Recheck Cond: (a >= 'g'::rainbow)
+         ->  Bitmap Index Scan on enumidx
+               Index Cond: (a >= 'g'::rainbow)
+(5 rows)
+
diff --git a/contrib/btree_gist/sql/enum.sql b/contrib/btree_gist/sql/enum.sql
new file mode 100644
index 0000000..476211e
--- /dev/null
+++ b/contrib/btree_gist/sql/enum.sql
@@ -0,0 +1,38 @@
+-- enum check
+
+create type rainbow as enum ('r','o','y','g','b','i','v');
+
+CREATE TABLE enumtmp (a rainbow);
+
+\copy enumtmp from 'data/enum.data'
+
+SET enable_seqscan=on;
+
+select a, count(*) from enumtmp group by a order by 1;
+
+SELECT count(*) FROM enumtmp WHERE a <  'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a <= 'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a  = 'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a >= 'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a >  'g'::rainbow;
+
+CREATE INDEX enumidx ON enumtmp USING gist ( a );
+
+SET enable_seqscan=off;
+
+SELECT count(*) FROM enumtmp WHERE a <  'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a <= 'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a  = 'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a >= 'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a >  'g'::rainbow;
+
+EXPLAIN (COSTS OFF)
+SELECT count(*) FROM enumtmp WHERE a >= 'g'::rainbow;
diff --git a/doc/src/sgml/btree-gin.sgml b/doc/src/sgml/btree-gin.sgml
index 2b081db..f407e92 100644
--- a/doc/src/sgml/btree-gin.sgml
+++ b/doc/src/sgml/btree-gin.sgml
@@ -16,7 +16,8 @@
   <type>time without time zone</>, <type>date</>, <type>interval</>,
   <type>oid</>, <type>money</>, <type>"char"</>,
   <type>varchar</>, <type>text</>, <type>bytea</>, <type>bit</>,
-  <type>varbit</>, <type>macaddr</>, <type>inet</>, and <type>cidr</>.
+  <type>varbit</>, <type>macaddr</>, <type>inet</>, <type>cidr</>,
+  and all <type>enum</> types.
  </para>
 
  <para>
diff --git a/doc/src/sgml/btree-gist.sgml b/doc/src/sgml/btree-gist.sgml
index e8a5622..7de480f 100644
--- a/doc/src/sgml/btree-gist.sgml
+++ b/doc/src/sgml/btree-gist.sgml
@@ -16,7 +16,8 @@
   <type>time without time zone</>, <type>date</>, <type>interval</>,
   <type>oid</>, <type>money</>, <type>char</>,
   <type>varchar</>, <type>text</>, <type>bytea</>, <type>bit</>,
-  <type>varbit</>, <type>macaddr</>, <type>inet</>, and <type>cidr</>.
+  <type>varbit</>, <type>macaddr</>, <type>inet</>, <type>cidr</>,
+  and all <type>enum</> types. 
  </para>
 
  <para>
#13Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andrew Dunstan (#12)
Re: btree_gin and btree_gist for enums

Andrew Dunstan <andrew@dunslane.net> writes:

On 11/05/2016 11:46 AM, Tom Lane wrote:

That may be a good fix for robustness purposes, but it seems pretty horrid
from an efficiency standpoint. Where is this call, and should we be
modifying it to provide a flinfo?

I thought of providing an flinfo, but I couldn't see a simple way to do
it that would provide something much longer lived than the function
call, in which case it seemed a bit pointless. That's why I asked for
assistance :-)

Hmm. The problem is that the intermediate layer in btree_gist (and
probably btree_gin too, didn't look) does not pass through the
FunctionCallInfo data structure that's provided by the GIST AM.
That wasn't needed up to now, because none of the supported data types
are complex enough that any cached state would be useful, but trying
to extend it to enums exposes the shortcoming.

We could fix this, but it would be pretty invasive since it would require
touching just about every function in btree_gist/gin. Not entirely sure
that it's worth it. On the other hand, the problem might well come up
again in future, perhaps for a datatype where the penalty for lack of
a cache is greater --- eg, it would be pretty painful to support
record_cmp without caching. And the changes ought to be relatively
mechanical, even if they are extensive.

BTW, this patch would be a great deal shorter if you made use of the
work done in 40b449ae8. That is, you no longer need to replace the
base extension script --- just add an update script and change the
default version in the .control file. See fd321a1df for an example.

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#14Andrew Dunstan
andrew@dunslane.net
In reply to: Tom Lane (#13)
Re: btree_gin and btree_gist for enums

On 11/05/2016 01:13 PM, Tom Lane wrote:

Andrew Dunstan <andrew@dunslane.net> writes:

On 11/05/2016 11:46 AM, Tom Lane wrote:

That may be a good fix for robustness purposes, but it seems pretty horrid
from an efficiency standpoint. Where is this call, and should we be
modifying it to provide a flinfo?

I thought of providing an flinfo, but I couldn't see a simple way to do
it that would provide something much longer lived than the function
call, in which case it seemed a bit pointless. That's why I asked for
assistance :-)

Hmm. The problem is that the intermediate layer in btree_gist (and
probably btree_gin too, didn't look) does not pass through the
FunctionCallInfo data structure that's provided by the GIST AM.
That wasn't needed up to now, because none of the supported data types
are complex enough that any cached state would be useful, but trying
to extend it to enums exposes the shortcoming.

We could fix this, but it would be pretty invasive since it would require
touching just about every function in btree_gist/gin. Not entirely sure
that it's worth it. On the other hand, the problem might well come up
again in future, perhaps for a datatype where the penalty for lack of
a cache is greater --- eg, it would be pretty painful to support
record_cmp without caching. And the changes ought to be relatively
mechanical, even if they are extensive.

Yeah. I think it's probably worth doing. btree_gin is probably a better
place to start because it's largely macro-ized.

I don't have time right now to do this. I'll try to get to it if nobody
else does over then next couple of months.

BTW, this patch would be a great deal shorter if you made use of the
work done in 40b449ae8. That is, you no longer need to replace the
base extension script --- just add an update script and change the
default version in the .control file. See fd321a1df for an example.

Oh, nice. My work was originally done in March, before this came in.

cheers

andrew

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#15Andrew Dunstan
adunstan@postgresql.org
In reply to: Andrew Dunstan (#14)
Re: btree_gin and btree_gist for enums

I won't have time to fix this before the end of the Commitfest
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#16Haribabu Kommi
kommi.haribabu@gmail.com
In reply to: Andrew Dunstan (#15)
Re: btree_gin and btree_gist for enums

On Wed, Nov 23, 2016 at 11:31 AM, Andrew Dunstan <adunstan@postgresql.org>
wrote:

I won't have time to fix this before the end of the Commitfest

The patch is marked as "returned with feedback" in 2016-11 commitfest.
Please free to submit an updated patch to the next commitfest.

Regards,
Hari Babu
Fujitsu Australia

#17Andrew Dunstan
andrew.dunstan@2ndquadrant.com
In reply to: Andrew Dunstan (#14)
Re: btree_gin and btree_gist for enums

On 11/05/2016 03:11 PM, Andrew Dunstan wrote:

On 11/05/2016 01:13 PM, Tom Lane wrote:

Andrew Dunstan <andrew@dunslane.net> writes:

On 11/05/2016 11:46 AM, Tom Lane wrote:

That may be a good fix for robustness purposes, but it seems pretty
horrid
from an efficiency standpoint. Where is this call, and should we be
modifying it to provide a flinfo?

I thought of providing an flinfo, but I couldn't see a simple way to do
it that would provide something much longer lived than the function
call, in which case it seemed a bit pointless. That's why I asked for
assistance :-)

Hmm. The problem is that the intermediate layer in btree_gist (and
probably btree_gin too, didn't look) does not pass through the
FunctionCallInfo data structure that's provided by the GIST AM.
That wasn't needed up to now, because none of the supported data types
are complex enough that any cached state would be useful, but trying
to extend it to enums exposes the shortcoming.

We could fix this, but it would be pretty invasive since it would
require
touching just about every function in btree_gist/gin. Not entirely sure
that it's worth it. On the other hand, the problem might well come up
again in future, perhaps for a datatype where the penalty for lack of
a cache is greater --- eg, it would be pretty painful to support
record_cmp without caching. And the changes ought to be relatively
mechanical, even if they are extensive.

Yeah. I think it's probably worth doing. btree_gin is probably a
better place to start because it's largely macro-ized.

So looking at this we have:

static Datum
gin_btree_compare_prefix(FunctionCallInfo fcinfo)
{
Datum a = PG_GETARG_DATUM(0);
Datum b = PG_GETARG_DATUM(1);
QueryInfo *data = (QueryInfo *) PG_GETARG_POINTER(3);
int32 res,
cmp;

cmp = DatumGetInt32(DirectFunctionCall2Coll(
data->typecmp,
PG_GET_COLLATION(),
(data->strategy ==
BTLessStrategyNumber ||
data->strategy ==
BTLessEqualStrategyNumber)
? data->datum : a,
b));

and then the referred to routine in the enum case looks like this:

Datum
gin_enum_cmp(PG_FUNCTION_ARGS)
{
Oid a = PG_GETARG_OID(0);
Oid b = PG_GETARG_OID(1);
int res = 0;

if (ENUM_IS_LEFTMOST(a))
{
res = (ENUM_IS_LEFTMOST(b)) ? 0 : -1;
}
else if (ENUM_IS_LEFTMOST(b))
{
res = 1;
}
else
{
res = DatumGetInt32(DirectFunctionCall2(enum_cmp,
ObjectIdGetDatum(a),
ObjectIdGetDatum(b)));
}

PG_RETURN_INT32(res);
}

I'm not entirely sure how I should replace those DirectFunctionCall2 calls.

cheers

andrew

--
Andrew Dunstan https://www.2ndQuadrant.com
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#18Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andrew Dunstan (#17)
Re: btree_gin and btree_gist for enums

Andrew Dunstan <andrew.dunstan@2ndquadrant.com> writes:

I'm not entirely sure how I should replace those DirectFunctionCall2 calls.

Basically what we want is for the called function to be able to use the
fcinfo->flinfo->fn_extra and fcinfo->flinfo->fn_mcxt fields of the
FmgrInfo struct that GIN has set up for the btree_gin support function.

The fast but somewhat scary way to do it would just be to pass through
the flinfo pointer as-is. Imagine that fmgr.c grows a set of functions
like

Datum
DontKnowWhatToCallThisFunctionCall2(PGFunction func,
FmgrInfo *flinfo, Oid collation,
Datum arg1, Datum arg2)
{
FunctionCallInfoData fcinfo;
Datum result;

InitFunctionCallInfoData(fcinfo, flinfo, 2, collation, NULL, NULL);

fcinfo.arg[0] = arg1;
fcinfo.arg[1] = arg2;
fcinfo.argnull[0] = false;
fcinfo.argnull[1] = false;

result = (*func) (&fcinfo);

/* Check for null result, since caller is clearly not expecting one */
if (fcinfo.isnull)
elog(ERROR, "function %p returned NULL", (void *) func);

return result;
}

and then you'd just pass through the fcinfo->flinfo you got.

The reason this is kind of scary is that it's just blithely assuming
that the function won't look at the *other* fields of the FmgrInfo.
If it did, it would likely get very confused, since those fields
would be describing the GIN support function, not the function we're
calling.

We could alternatively have this trampoline function set up a fresh, local
FmgrInfo struct that it zeroes except for copying fn_extra and fn_mcxt
from the caller's struct, and then it copies fn_extra back again on the
way out. That's a few more cycles but it would be safer, I think; if the
function tried to look at the other fields such as fn_oid it would see
obviously bogus data.

BTW, while I'm looking at this ... isn't gin_enum_cmp broken on its face?
It's using DirectFunctionCall2 to call enum_cmp, and that's wrong because
DirectFunctionCall2 does not pass through a flinfo but enum_cmp needs to
have one. I've not tested, but I'm certain that this would dump core if
asked to compare odd-numbered enum OIDs.

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#19Andrew Dunstan
andrew.dunstan@2ndquadrant.com
In reply to: Tom Lane (#18)
Re: btree_gin and btree_gist for enums

On 02/23/2017 04:41 PM, Tom Lane wrote:

BTW, while I'm looking at this ... isn't gin_enum_cmp broken on its face?
It's using DirectFunctionCall2 to call enum_cmp, and that's wrong because
DirectFunctionCall2 does not pass through a flinfo but enum_cmp needs to
have one. I've not tested, but I'm certain that this would dump core if
asked to compare odd-numbered enum OIDs.

Yes, that's what I'm trying to fix.

cheers

andrew

--
Andrew Dunstan https://www.2ndQuadrant.com
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#20Andrew Dunstan
andrew.dunstan@2ndquadrant.com
In reply to: Tom Lane (#18)
1 attachment(s)
Re: btree_gin and btree_gist for enums

On 02/23/2017 04:41 PM, Tom Lane wrote:

Andrew Dunstan <andrew.dunstan@2ndquadrant.com> writes:

I'm not entirely sure how I should replace those DirectFunctionCall2 calls.

Basically what we want is for the called function to be able to use the
fcinfo->flinfo->fn_extra and fcinfo->flinfo->fn_mcxt fields of the
FmgrInfo struct that GIN has set up for the btree_gin support function.

The fast but somewhat scary way to do it would just be to pass through
the flinfo pointer as-is. Imagine that fmgr.c grows a set of functions
like

[...]

Here's a POC for btree_gin based on my original patch. I just made your
function static in btree_gin.c at least for now. I stayed with the
DirectFunctionCall2 use in the type-specific routines where calling
context wasn't needed (i.e. everything except enums). But it looks more
than ugly and highly invasive for btree_gist, and sadly that's my main
use case, exclusion constraints with enum fields.

cheers

andrew

--
Andrew Dunstan https://www.2ndQuadrant.com
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

Attachments:

enum-btree-gin-2.patchtext/x-diff; name=enum-btree-gin-2.patchDownload
diff --git a/contrib/btree_gin/Makefile b/contrib/btree_gin/Makefile
index 0492091..c6aae26 100644
--- a/contrib/btree_gin/Makefile
+++ b/contrib/btree_gin/Makefile
@@ -4,13 +4,13 @@ MODULE_big = btree_gin
 OBJS = btree_gin.o $(WIN32RES)
 
 EXTENSION = btree_gin
-DATA = btree_gin--1.0.sql btree_gin--unpackaged--1.0.sql
+DATA = btree_gin--1.0.sql btree_gin--unpackaged--1.0.sql btree_gin--1.0--1.1.sql
 PGFILEDESC = "btree_gin - B-tree equivalent GIN operator classes"
 
 REGRESS = install_btree_gin int2 int4 int8 float4 float8 money oid \
 	timestamp timestamptz time timetz date interval \
 	macaddr inet cidr text varchar char bytea bit varbit \
-	numeric
+	numeric enum
 
 ifdef USE_PGXS
 PG_CONFIG = pg_config
diff --git a/contrib/btree_gin/btree_gin--1.0--1.1.sql b/contrib/btree_gin/btree_gin--1.0--1.1.sql
new file mode 100644
index 0000000..3c40ccd
--- /dev/null
+++ b/contrib/btree_gin/btree_gin--1.0--1.1.sql
@@ -0,0 +1,47 @@
+/* contrib/btree_gin/btree_gin--1.0--1.1.sql */
+
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "ALTER EXTENSION btree_gin UPDATE TO '1.1'" to load this file. \quit
+
+--
+--
+--
+-- enum ops
+--
+--
+
+
+CREATE FUNCTION gin_extract_value_anyenum(anyenum, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_anyenum(anyenum, anyenum, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_anyenum(anyenum, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_enum_cmp(anyenum, anyenum)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS enum_ops
+DEFAULT FOR TYPE anyenum USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       gin_enum_cmp(anyenum,anyenum),
+    FUNCTION        2       gin_extract_value_anyenum(anyenum, internal),
+    FUNCTION        3       gin_extract_query_anyenum(anyenum, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_anyenum(anyenum,anyenum,int2, internal),
+STORAGE         anyenum;
diff --git a/contrib/btree_gin/btree_gin.c b/contrib/btree_gin/btree_gin.c
index 030b610..4694275 100644
--- a/contrib/btree_gin/btree_gin.c
+++ b/contrib/btree_gin/btree_gin.c
@@ -25,6 +25,35 @@ typedef struct QueryInfo
 	Datum		(*typecmp) (FunctionCallInfo);
 } QueryInfo;
 
+/*
+ * Routine to provide context to a data type comparison call.
+ * Needed for enum support.
+ */
+
+static Datum
+CallerContextFunctionCall2(PGFunction func,
+						   FmgrInfo *flinfo, Oid collation,
+						   Datum arg1, Datum arg2)
+{
+	FunctionCallInfoData fcinfo;
+	Datum        result;
+
+	InitFunctionCallInfoData(fcinfo, flinfo, 2, collation, NULL, NULL);
+
+	fcinfo.arg[0] = arg1;
+	fcinfo.arg[1] = arg2;
+	fcinfo.argnull[0] = false;
+	fcinfo.argnull[1] = false;
+
+	result = (*func) (&fcinfo);
+
+	/* Check for null result, since caller is clearly not expecting one */
+	if (fcinfo.isnull)
+		elog(ERROR, "function %p returned NULL", (void *) func);
+
+	return result;
+}
+
 
 /*** GIN support functions shared by all datatypes ***/
 
@@ -112,13 +141,14 @@ gin_btree_compare_prefix(FunctionCallInfo fcinfo)
 	int32		res,
 				cmp;
 
-	cmp = DatumGetInt32(DirectFunctionCall2Coll(
-												data->typecmp,
-												PG_GET_COLLATION(),
-								   (data->strategy == BTLessStrategyNumber ||
-								 data->strategy == BTLessEqualStrategyNumber)
-												? data->datum : a,
-												b));
+	cmp = DatumGetInt32(CallerContextFunctionCall2(
+							data->typecmp,
+							fcinfo->flinfo,
+							PG_GET_COLLATION(),
+							(data->strategy == BTLessStrategyNumber ||
+							 data->strategy == BTLessEqualStrategyNumber)
+							? data->datum : a,
+							b));
 
 	switch (data->strategy)
 	{
@@ -416,3 +446,50 @@ leftmostvalue_numeric(void)
 }
 
 GIN_SUPPORT(numeric, true, leftmostvalue_numeric, gin_numeric_cmp)
+
+/*
+ * Use a similar trick to that used for numeric for enums, since we don't
+ * actually know the leftmost value of any enum without knowing the concrete
+ * type, so we use a dummy leftmost value of InvalidOid.
+ */
+
+
+#define ENUM_IS_LEFTMOST(x)	((x) == InvalidOid)
+
+PG_FUNCTION_INFO_V1(gin_enum_cmp);
+
+Datum
+gin_enum_cmp(PG_FUNCTION_ARGS)
+{
+	Oid		a = PG_GETARG_OID(0);
+	Oid		b = PG_GETARG_OID(1);
+	int		res = 0;
+
+	if (ENUM_IS_LEFTMOST(a))
+	{
+		res = (ENUM_IS_LEFTMOST(b)) ? 0 : -1;
+	}
+	else if (ENUM_IS_LEFTMOST(b))
+	{
+		res = 1;
+	}
+	else
+	{
+		res = DatumGetInt32(CallerContextFunctionCall2(
+								enum_cmp,
+								fcinfo->flinfo,
+								PG_GET_COLLATION(),
+								ObjectIdGetDatum(a),
+								ObjectIdGetDatum(b)));
+	}
+
+	PG_RETURN_INT32(res);
+}
+
+static Datum
+leftmostvalue_enum(void)
+{
+	return ObjectIdGetDatum(InvalidOid);
+}
+
+GIN_SUPPORT(anyenum, false, leftmostvalue_enum, gin_enum_cmp)
diff --git a/contrib/btree_gin/btree_gin.control b/contrib/btree_gin/btree_gin.control
index 3b2cb2d..d96436e 100644
--- a/contrib/btree_gin/btree_gin.control
+++ b/contrib/btree_gin/btree_gin.control
@@ -1,5 +1,5 @@
 # btree_gin extension
 comment = 'support for indexing common datatypes in GIN'
-default_version = '1.0'
+default_version = '1.1'
 module_pathname = '$libdir/btree_gin'
 relocatable = true
diff --git a/contrib/btree_gin/expected/enum.out b/contrib/btree_gin/expected/enum.out
new file mode 100644
index 0000000..bad1cc0
--- /dev/null
+++ b/contrib/btree_gin/expected/enum.out
@@ -0,0 +1,63 @@
+set enable_seqscan=off;
+CREATE TYPE rainbow AS ENUM ('r','o','y','g','b','i','v');
+CREATE TABLE test_enum (
+	i rainbow
+);
+INSERT INTO test_enum VALUES ('v'),('y'),('r'),('g'),('o'),('i'),('b');
+CREATE INDEX idx_enum ON test_enum USING gin (i);
+SELECT * FROM test_enum WHERE i<'g'::rainbow ORDER BY i;
+ i 
+---
+ r
+ o
+ y
+(3 rows)
+
+SELECT * FROM test_enum WHERE i<='g'::rainbow ORDER BY i;
+ i 
+---
+ r
+ o
+ y
+ g
+(4 rows)
+
+SELECT * FROM test_enum WHERE i='g'::rainbow ORDER BY i;
+ i 
+---
+ g
+(1 row)
+
+SELECT * FROM test_enum WHERE i>='g'::rainbow ORDER BY i;
+ i 
+---
+ g
+ b
+ i
+ v
+(4 rows)
+
+SELECT * FROM test_enum WHERE i>'g'::rainbow ORDER BY i;
+ i 
+---
+ b
+ i
+ v
+(3 rows)
+
+explain (costs off) SELECT * FROM test_enum WHERE i>='g'::rainbow ORDER BY i;
+                  QUERY PLAN                   
+-----------------------------------------------
+ Sort
+   Sort Key: i
+   ->  Bitmap Heap Scan on test_enum
+         Recheck Cond: (i >= 'g'::rainbow)
+         ->  Bitmap Index Scan on idx_enum
+               Index Cond: (i >= 'g'::rainbow)
+(6 rows)
+
+-- make sure we handle the non-evenly-numbered oid case for enums
+create type e as enum ('0', '2', '3');
+alter type e add value '1' after '0';
+create table t as select (i % 4)::text::e from generate_series(0, 100000) as i;
+create index on t using gin (e);
diff --git a/contrib/btree_gin/sql/enum.sql b/contrib/btree_gin/sql/enum.sql
new file mode 100644
index 0000000..6db2d76
--- /dev/null
+++ b/contrib/btree_gin/sql/enum.sql
@@ -0,0 +1,26 @@
+set enable_seqscan=off;
+
+CREATE TYPE rainbow AS ENUM ('r','o','y','g','b','i','v');
+
+CREATE TABLE test_enum (
+	i rainbow
+);
+
+INSERT INTO test_enum VALUES ('v'),('y'),('r'),('g'),('o'),('i'),('b');
+
+CREATE INDEX idx_enum ON test_enum USING gin (i);
+
+SELECT * FROM test_enum WHERE i<'g'::rainbow ORDER BY i;
+SELECT * FROM test_enum WHERE i<='g'::rainbow ORDER BY i;
+SELECT * FROM test_enum WHERE i='g'::rainbow ORDER BY i;
+SELECT * FROM test_enum WHERE i>='g'::rainbow ORDER BY i;
+SELECT * FROM test_enum WHERE i>'g'::rainbow ORDER BY i;
+
+explain (costs off) SELECT * FROM test_enum WHERE i>='g'::rainbow ORDER BY i;
+
+
+-- make sure we handle the non-evenly-numbered oid case for enums
+create type e as enum ('0', '2', '3');
+alter type e add value '1' after '0';
+create table t as select (i % 4)::text::e from generate_series(0, 100000) as i;
+create index on t using gin (e);
diff --git a/doc/src/sgml/btree-gin.sgml b/doc/src/sgml/btree-gin.sgml
index 2b081db..f407e92 100644
--- a/doc/src/sgml/btree-gin.sgml
+++ b/doc/src/sgml/btree-gin.sgml
@@ -16,7 +16,8 @@
   <type>time without time zone</>, <type>date</>, <type>interval</>,
   <type>oid</>, <type>money</>, <type>"char"</>,
   <type>varchar</>, <type>text</>, <type>bytea</>, <type>bit</>,
-  <type>varbit</>, <type>macaddr</>, <type>inet</>, and <type>cidr</>.
+  <type>varbit</>, <type>macaddr</>, <type>inet</>, <type>cidr</>,
+  and all <type>enum</> types.
  </para>
 
  <para>
#21Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andrew Dunstan (#19)
1 attachment(s)
Re: btree_gin and btree_gist for enums

Andrew Dunstan <andrew.dunstan@2ndquadrant.com> writes:

On 02/23/2017 04:41 PM, Tom Lane wrote:

BTW, while I'm looking at this ... isn't gin_enum_cmp broken on its face?

Yes, that's what I'm trying to fix.

I'd forgotten where this thread started. For a minute there I thought
we had a live bug, rather than a deficiency in code-under-development.

After thinking about that, I believe that enum_cmp_internal is a rather
considerable hazard. It might not be our only function that requires
fcinfo->flinfo cache space just some of the time not all the time, but
I don't recall anyplace else that could so easily undergo a reasonable
amount of testing without *ever* reaching the case where it requires
that cache space. So I'm now worried that it wouldn't be too hard for
such a bug to get past us.

I think we should address that by adding a non-bypassable Assert that
the caller did provide flinfo, as in the attached.

regards, tom lane

Attachments:

assert-that-enum-comparator-can-use-cache.patchtext/x-diff; charset=us-ascii; name=assert-that-enum-comparator-can-use-cache.patchDownload
diff --git a/src/backend/utils/adt/enum.c b/src/backend/utils/adt/enum.c
index 8110ee2..b1d2a6f 100644
*** a/src/backend/utils/adt/enum.c
--- b/src/backend/utils/adt/enum.c
*************** enum_cmp_internal(Oid arg1, Oid arg2, Fu
*** 263,268 ****
--- 263,277 ----
  {
  	TypeCacheEntry *tcache;
  
+ 	/*
+ 	 * We don't need the typcache except in the hopefully-uncommon case that
+ 	 * one or both Oids are odd.  This means that cursory testing of code that
+ 	 * fails to pass flinfo to an enum comparison function might not disclose
+ 	 * the oversight.  To make such errors more obvious, Assert that we have a
+ 	 * place to cache even when we take a fast-path exit.
+ 	 */
+ 	Assert(fcinfo->flinfo != NULL);
+ 
  	/* Equal OIDs are equal no matter what */
  	if (arg1 == arg2)
  		return 0;
*************** enum_cmp(PG_FUNCTION_ARGS)
*** 381,392 ****
  	Oid			a = PG_GETARG_OID(0);
  	Oid			b = PG_GETARG_OID(1);
  
! 	if (a == b)
! 		PG_RETURN_INT32(0);
! 	else if (enum_cmp_internal(a, b, fcinfo) > 0)
! 		PG_RETURN_INT32(1);
! 	else
! 		PG_RETURN_INT32(-1);
  }
  
  /* Enum programming support functions */
--- 390,396 ----
  	Oid			a = PG_GETARG_OID(0);
  	Oid			b = PG_GETARG_OID(1);
  
! 	PG_RETURN_INT32(enum_cmp_internal(a, b, fcinfo));
  }
  
  /* Enum programming support functions */
#22Andrew Dunstan
andrew.dunstan@2ndquadrant.com
In reply to: Tom Lane (#21)
Re: btree_gin and btree_gist for enums

On 02/23/2017 08:34 PM, Tom Lane wrote:

Andrew Dunstan <andrew.dunstan@2ndquadrant.com> writes:

On 02/23/2017 04:41 PM, Tom Lane wrote:

BTW, while I'm looking at this ... isn't gin_enum_cmp broken on its face?

Yes, that's what I'm trying to fix.

I'd forgotten where this thread started. For a minute there I thought
we had a live bug, rather than a deficiency in code-under-development.

After thinking about that, I believe that enum_cmp_internal is a rather
considerable hazard. It might not be our only function that requires
fcinfo->flinfo cache space just some of the time not all the time, but
I don't recall anyplace else that could so easily undergo a reasonable
amount of testing without *ever* reaching the case where it requires
that cache space. So I'm now worried that it wouldn't be too hard for
such a bug to get past us.

I think we should address that by adding a non-bypassable Assert that
the caller did provide flinfo, as in the attached.

Looks sane. I don't believe there is anywhere in the core code that
calls this without fcinfo->flinfo, But obviously I have tickled that
with my original patch for the extension.

cheers

andrew

--
Andrew Dunstan https://www.2ndQuadrant.com
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#23Andrew Dunstan
andrew.dunstan@2ndquadrant.com
In reply to: Tom Lane (#18)
Re: btree_gin and btree_gist for enums

On 02/23/2017 04:41 PM, Tom Lane wrote:

Andrew Dunstan <andrew.dunstan@2ndquadrant.com> writes:

I'm not entirely sure how I should replace those DirectFunctionCall2 calls.

Basically what we want is for the called function to be able to use the
fcinfo->flinfo->fn_extra and fcinfo->flinfo->fn_mcxt fields of the
FmgrInfo struct that GIN has set up for the btree_gin support function.

The fast but somewhat scary way to do it would just be to pass through
the flinfo pointer as-is. Imagine that fmgr.c grows a set of functions
like

Datum
DontKnowWhatToCallThisFunctionCall2(PGFunction func,
FmgrInfo *flinfo, Oid collation,
Datum arg1, Datum arg2)
{
FunctionCallInfoData fcinfo;
Datum result;

InitFunctionCallInfoData(fcinfo, flinfo, 2, collation, NULL, NULL);

fcinfo.arg[0] = arg1;
fcinfo.arg[1] = arg2;
fcinfo.argnull[0] = false;
fcinfo.argnull[1] = false;

result = (*func) (&fcinfo);

/* Check for null result, since caller is clearly not expecting one */
if (fcinfo.isnull)
elog(ERROR, "function %p returned NULL", (void *) func);

return result;
}

and then you'd just pass through the fcinfo->flinfo you got.

The reason this is kind of scary is that it's just blithely assuming
that the function won't look at the *other* fields of the FmgrInfo.
If it did, it would likely get very confused, since those fields
would be describing the GIN support function, not the function we're
calling.

We could alternatively have this trampoline function set up a fresh, local
FmgrInfo struct that it zeroes except for copying fn_extra and fn_mcxt
from the caller's struct, and then it copies fn_extra back again on the
way out. That's a few more cycles but it would be safer, I think; if the
function tried to look at the other fields such as fn_oid it would see
obviously bogus data.

Do we want one or both of these? I'm prepared to code up a patch to
fmgr.[ch] to provide them.

I don't know what to call it either. In my test I used
CallerContextFunctionCall2 - not sure if that's quite right, but should
be close.

The technique is somewhat similar to what we do in plperl.c where we
fake up a function call for handling DO blocks.

cheers

andrew

--
Andrew Dunstan https://www.2ndQuadrant.com
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#24Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andrew Dunstan (#23)
Re: btree_gin and btree_gist for enums

Andrew Dunstan <andrew.dunstan@2ndquadrant.com> writes:

On 02/23/2017 04:41 PM, Tom Lane wrote:

The reason this is kind of scary is that it's just blithely assuming
that the function won't look at the *other* fields of the FmgrInfo.
If it did, it would likely get very confused, since those fields
would be describing the GIN support function, not the function we're
calling.

We could alternatively have this trampoline function set up a fresh, local
FmgrInfo struct that it zeroes except for copying fn_extra and fn_mcxt
from the caller's struct, and then it copies fn_extra back again on the
way out. That's a few more cycles but it would be safer, I think; if the
function tried to look at the other fields such as fn_oid it would see
obviously bogus data.

Do we want one or both of these? I'm prepared to code up a patch to
fmgr.[ch] to provide them.

On reflection I'm not sure that the double-copy approach is all that much
safer than just passing down the caller's flinfo pointer. Most of the
time it would be better, but suppose that the callee updates fn_extra
and then throws elog(ERROR) --- the outcome would be different, probably
creating a leak in fn_mcxt. Maybe this would still be okay, because
perhaps that FmgrInfo is never used again, but I don't think we can assume
that for the case at hand.

At this point I'd be inclined to just document that the called function
should only use fn_extra/fn_mcxt.

I don't know what to call it either. In my test I used
CallerContextFunctionCall2 - not sure if that's quite right, but should
be close.

CallerInfo? CallerFInfo? Or we could spell out CallerFmgrInfo but
that seems a bit verbose.

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#25Andrew Dunstan
andrew.dunstan@2ndquadrant.com
In reply to: Tom Lane (#24)
Re: btree_gin and btree_gist for enums

On 02/24/2017 11:02 AM, Tom Lane wrote:

Andrew Dunstan <andrew.dunstan@2ndquadrant.com> writes:

On 02/23/2017 04:41 PM, Tom Lane wrote:

The reason this is kind of scary is that it's just blithely assuming
that the function won't look at the *other* fields of the FmgrInfo.
If it did, it would likely get very confused, since those fields
would be describing the GIN support function, not the function we're
calling.

We could alternatively have this trampoline function set up a fresh, local
FmgrInfo struct that it zeroes except for copying fn_extra and fn_mcxt
from the caller's struct, and then it copies fn_extra back again on the
way out. That's a few more cycles but it would be safer, I think; if the
function tried to look at the other fields such as fn_oid it would see
obviously bogus data.

Do we want one or both of these? I'm prepared to code up a patch to
fmgr.[ch] to provide them.

On reflection I'm not sure that the double-copy approach is all that much
safer than just passing down the caller's flinfo pointer. Most of the
time it would be better, but suppose that the callee updates fn_extra
and then throws elog(ERROR) --- the outcome would be different, probably
creating a leak in fn_mcxt. Maybe this would still be okay, because
perhaps that FmgrInfo is never used again, but I don't think we can assume
that for the case at hand.

At this point I'd be inclined to just document that the called function
should only use fn_extra/fn_mcxt.

fair enough. Will do it that way.

I don't know what to call it either. In my test I used
CallerContextFunctionCall2 - not sure if that's quite right, but should
be close.

CallerInfo? CallerFInfo? Or we could spell out CallerFmgrInfo but
that seems a bit verbose.

I'll go with CallerFInfoFunctionCall2 etc.

In the btree_gist system the calls to the routines like enum_cmp are
buried about three levels deep. I'm thinking I'll just pass the flinfo
down the stack and just call these routines at the bottom level.

cheers

andrew

--
Andrew Dunstan https://www.2ndQuadrant.com
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#26Andrew Dunstan
andrew.dunstan@2ndquadrant.com
In reply to: Andrew Dunstan (#25)
Re: btree_gin and btree_gist for enums

On 02/24/2017 02:55 PM, Andrew Dunstan wrote:

On 02/24/2017 11:02 AM, Tom Lane wrote:

I don't know what to call it either. In my test I used
CallerContextFunctionCall2 - not sure if that's quite right, but should
be close.

CallerInfo? CallerFInfo? Or we could spell out CallerFmgrInfo but
that seems a bit verbose.

I'll go with CallerFInfoFunctionCall2 etc.

In the btree_gist system the calls to the routines like enum_cmp are
buried about three levels deep. I'm thinking I'll just pass the flinfo
down the stack and just call these routines at the bottom level.

It's occurred to me that we could reduce the code clutter in fmgr.c a
bit by turning the DirectFunctionCall{n]Coll functions into macros
calling these functions and passing NULL as the flinfo param.

cheers

andrew

--
Andrew Dunstan https://www.2ndQuadrant.com
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#27Andrew Dunstan
andrew.dunstan@2ndquadrant.com
In reply to: Andrew Dunstan (#26)
1 attachment(s)
Re: btree_gin and btree_gist for enums

On 02/24/2017 05:34 PM, Andrew Dunstan wrote:

On 02/24/2017 02:55 PM, Andrew Dunstan wrote:

On 02/24/2017 11:02 AM, Tom Lane wrote:

I don't know what to call it either. In my test I used
CallerContextFunctionCall2 - not sure if that's quite right, but should
be close.

CallerInfo? CallerFInfo? Or we could spell out CallerFmgrInfo but
that seems a bit verbose.

I'll go with CallerFInfoFunctionCall2 etc.

In the btree_gist system the calls to the routines like enum_cmp are
buried about three levels deep. I'm thinking I'll just pass the flinfo
down the stack and just call these routines at the bottom level.

It's occurred to me that we could reduce the code clutter in fmgr.c a
bit by turning the DirectFunctionCall{n]Coll functions into macros
calling these functions and passing NULL as the flinfo param.

here's a patch along those lines. If there's agreement on this I can
finish up the work on btree_gist and btree_gin supoport for enums.

cheers

andrew

--
Andrew Dunstan https://www.2ndQuadrant.com
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

Attachments:

callfinfofunctioncall.patchtext/x-diff; name=callfinfofunctioncall.patchDownload
diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c
index 3976496..d565d3e 100644
--- a/src/backend/utils/fmgr/fmgr.c
+++ b/src/backend/utils/fmgr/fmgr.c
@@ -1006,19 +1006,30 @@ fmgr_security_definer(PG_FUNCTION_ARGS)
  *-------------------------------------------------------------------------
  */
 
-/*
- * These are for invocation of a specifically named function with a
+
+/* These are for invocation of a specifically named function with a
  * directly-computed parameter list.  Note that neither arguments nor result
- * are allowed to be NULL.  Also, the function cannot be one that needs to
- * look at FmgrInfo, since there won't be any.
+ * are allowed to be NULL.
+ *
+ * If the flinfo parameter is not NULL then this used to supply context
+ * to the called function. The callee should only use the passed in fn_mcxt
+ * and fn_extra. Anything else is likely to be bogus.
+ *
+ * But the fn_extra can be used for example for caching results
+ * (see enum_cmp for an example).
+ *
+ * No context is supplied if the parameter is NULL. See DirectFunctionCall
+ * macros. In this case the function must not try to look at FmgrInfo, since
+ * there won't be one and it is likely to result in an access violation.
  */
 Datum
-DirectFunctionCall1Coll(PGFunction func, Oid collation, Datum arg1)
+CallerFInfoFunctionCall1(PGFunction func, FmgrInfo *flinfo,
+						 Oid collation, Datum arg1)
 {
 	FunctionCallInfoData fcinfo;
 	Datum		result;
 
-	InitFunctionCallInfoData(fcinfo, NULL, 1, collation, NULL, NULL);
+	InitFunctionCallInfoData(fcinfo, flinfo, 1, collation, NULL, NULL);
 
 	fcinfo.arg[0] = arg1;
 	fcinfo.argnull[0] = false;
@@ -1033,12 +1044,13 @@ DirectFunctionCall1Coll(PGFunction func, Oid collation, Datum arg1)
 }
 
 Datum
-DirectFunctionCall2Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2)
+CallerFInfoFunctionCall2(PGFunction func, FmgrInfo *flinfo,
+						 Oid collation, Datum arg1, Datum arg2)
 {
 	FunctionCallInfoData fcinfo;
 	Datum		result;
 
-	InitFunctionCallInfoData(fcinfo, NULL, 2, collation, NULL, NULL);
+	InitFunctionCallInfoData(fcinfo, flinfo, 2, collation, NULL, NULL);
 
 	fcinfo.arg[0] = arg1;
 	fcinfo.arg[1] = arg2;
@@ -1055,13 +1067,14 @@ DirectFunctionCall2Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2)
 }
 
 Datum
-DirectFunctionCall3Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
-						Datum arg3)
+CallerFInfoFunctionCall3(PGFunction func, FmgrInfo *flinfo,
+						 Oid collation, Datum arg1, Datum arg2,
+						 Datum arg3)
 {
 	FunctionCallInfoData fcinfo;
 	Datum		result;
 
-	InitFunctionCallInfoData(fcinfo, NULL, 3, collation, NULL, NULL);
+	InitFunctionCallInfoData(fcinfo, flinfo, 3, collation, NULL, NULL);
 
 	fcinfo.arg[0] = arg1;
 	fcinfo.arg[1] = arg2;
@@ -1080,13 +1093,14 @@ DirectFunctionCall3Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
 }
 
 Datum
-DirectFunctionCall4Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
-						Datum arg3, Datum arg4)
+CallerFInfoFunctionCall4(PGFunction func, FmgrInfo *flinfo,
+						 Oid collation, Datum arg1, Datum arg2,
+						 Datum arg3, Datum arg4)
 {
 	FunctionCallInfoData fcinfo;
 	Datum		result;
 
-	InitFunctionCallInfoData(fcinfo, NULL, 4, collation, NULL, NULL);
+	InitFunctionCallInfoData(fcinfo, flinfo, 4, collation, NULL, NULL);
 
 	fcinfo.arg[0] = arg1;
 	fcinfo.arg[1] = arg2;
@@ -1107,13 +1121,14 @@ DirectFunctionCall4Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
 }
 
 Datum
-DirectFunctionCall5Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
-						Datum arg3, Datum arg4, Datum arg5)
+CallerFInfoFunctionCall5(PGFunction func, FmgrInfo *flinfo,
+						 Oid collation, Datum arg1, Datum arg2,
+						 Datum arg3, Datum arg4, Datum arg5)
 {
 	FunctionCallInfoData fcinfo;
 	Datum		result;
 
-	InitFunctionCallInfoData(fcinfo, NULL, 5, collation, NULL, NULL);
+	InitFunctionCallInfoData(fcinfo, flinfo, 5, collation, NULL, NULL);
 
 	fcinfo.arg[0] = arg1;
 	fcinfo.arg[1] = arg2;
@@ -1136,14 +1151,15 @@ DirectFunctionCall5Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
 }
 
 Datum
-DirectFunctionCall6Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
-						Datum arg3, Datum arg4, Datum arg5,
-						Datum arg6)
+CallerFInfoFunctionCall6(PGFunction func, FmgrInfo *flinfo,
+						 Oid collation, Datum arg1, Datum arg2,
+						 Datum arg3, Datum arg4, Datum arg5,
+						 Datum arg6)
 {
 	FunctionCallInfoData fcinfo;
 	Datum		result;
 
-	InitFunctionCallInfoData(fcinfo, NULL, 6, collation, NULL, NULL);
+	InitFunctionCallInfoData(fcinfo, flinfo, 6, collation, NULL, NULL);
 
 	fcinfo.arg[0] = arg1;
 	fcinfo.arg[1] = arg2;
@@ -1168,14 +1184,15 @@ DirectFunctionCall6Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
 }
 
 Datum
-DirectFunctionCall7Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
-						Datum arg3, Datum arg4, Datum arg5,
-						Datum arg6, Datum arg7)
+CallerFInfoFunctionCall7(PGFunction func, FmgrInfo *flinfo,
+						 Oid collation, Datum arg1, Datum arg2,
+						 Datum arg3, Datum arg4, Datum arg5,
+						 Datum arg6, Datum arg7)
 {
 	FunctionCallInfoData fcinfo;
 	Datum		result;
 
-	InitFunctionCallInfoData(fcinfo, NULL, 7, collation, NULL, NULL);
+	InitFunctionCallInfoData(fcinfo, flinfo, 7, collation, NULL, NULL);
 
 	fcinfo.arg[0] = arg1;
 	fcinfo.arg[1] = arg2;
@@ -1202,14 +1219,15 @@ DirectFunctionCall7Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
 }
 
 Datum
-DirectFunctionCall8Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
-						Datum arg3, Datum arg4, Datum arg5,
-						Datum arg6, Datum arg7, Datum arg8)
+CallerFInfoFunctionCall8(PGFunction func, FmgrInfo *flinfo,
+						 Oid collation, Datum arg1, Datum arg2,
+						 Datum arg3, Datum arg4, Datum arg5,
+						 Datum arg6, Datum arg7, Datum arg8)
 {
 	FunctionCallInfoData fcinfo;
 	Datum		result;
 
-	InitFunctionCallInfoData(fcinfo, NULL, 8, collation, NULL, NULL);
+	InitFunctionCallInfoData(fcinfo, flinfo, 8, collation, NULL, NULL);
 
 	fcinfo.arg[0] = arg1;
 	fcinfo.arg[1] = arg2;
@@ -1238,15 +1256,16 @@ DirectFunctionCall8Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
 }
 
 Datum
-DirectFunctionCall9Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
-						Datum arg3, Datum arg4, Datum arg5,
-						Datum arg6, Datum arg7, Datum arg8,
-						Datum arg9)
+CallerFInfoFunctionCall9(PGFunction func, FmgrInfo *flinfo,
+						 Oid collation, Datum arg1, Datum arg2,
+						 Datum arg3, Datum arg4, Datum arg5,
+						 Datum arg6, Datum arg7, Datum arg8,
+						 Datum arg9)
 {
 	FunctionCallInfoData fcinfo;
 	Datum		result;
 
-	InitFunctionCallInfoData(fcinfo, NULL, 9, collation, NULL, NULL);
+	InitFunctionCallInfoData(fcinfo, flinfo, 9, collation, NULL, NULL);
 
 	fcinfo.arg[0] = arg1;
 	fcinfo.arg[1] = arg2;
diff --git a/src/include/fmgr.h b/src/include/fmgr.h
index a671480..c186d01 100644
--- a/src/include/fmgr.h
+++ b/src/include/fmgr.h
@@ -443,37 +443,48 @@ extern int no_such_variable
 /* These are for invocation of a specifically named function with a
  * directly-computed parameter list.  Note that neither arguments nor result
  * are allowed to be NULL.
+ *
+ * If the flinfo parameter is not NULL then this used to supply context
+ * to the called function. The callee should only use the passed in fn_mcxt
+ * and fn_extra. Anything else is likely to be bogus.
+ *
+ * But the fn_extra can be used for example for caching results
+ * (see enum_cmp for an example).
+ *
+ * No context is supplied if the parameter is NULL. See DirectFunctionCall
+ * macros below. In this case the function must not try to look at FmgrInfo,
+ * since there won't be one and it is likely to result in an access violation.
  */
-extern Datum DirectFunctionCall1Coll(PGFunction func, Oid collation,
-						Datum arg1);
-extern Datum DirectFunctionCall2Coll(PGFunction func, Oid collation,
-						Datum arg1, Datum arg2);
-extern Datum DirectFunctionCall3Coll(PGFunction func, Oid collation,
-						Datum arg1, Datum arg2,
-						Datum arg3);
-extern Datum DirectFunctionCall4Coll(PGFunction func, Oid collation,
-						Datum arg1, Datum arg2,
-						Datum arg3, Datum arg4);
-extern Datum DirectFunctionCall5Coll(PGFunction func, Oid collation,
-						Datum arg1, Datum arg2,
-						Datum arg3, Datum arg4, Datum arg5);
-extern Datum DirectFunctionCall6Coll(PGFunction func, Oid collation,
-						Datum arg1, Datum arg2,
-						Datum arg3, Datum arg4, Datum arg5,
-						Datum arg6);
-extern Datum DirectFunctionCall7Coll(PGFunction func, Oid collation,
-						Datum arg1, Datum arg2,
-						Datum arg3, Datum arg4, Datum arg5,
-						Datum arg6, Datum arg7);
-extern Datum DirectFunctionCall8Coll(PGFunction func, Oid collation,
-						Datum arg1, Datum arg2,
-						Datum arg3, Datum arg4, Datum arg5,
-						Datum arg6, Datum arg7, Datum arg8);
-extern Datum DirectFunctionCall9Coll(PGFunction func, Oid collation,
-						Datum arg1, Datum arg2,
-						Datum arg3, Datum arg4, Datum arg5,
-						Datum arg6, Datum arg7, Datum arg8,
-						Datum arg9);
+extern Datum CallerFInfoFunctionCall1(PGFunction func, FmgrInfo *flinfo,
+						 Oid collation, Datum arg1);
+extern Datum CallerFInfoFunctionCall2(PGFunction func, FmgrInfo *flinfo,
+						 Oid collation, Datum arg1, Datum arg2);
+extern Datum CallerFInfoFunctionCall3(PGFunction func, FmgrInfo *flinfo,
+						 Oid collation, Datum arg1, Datum arg2,
+						 Datum arg3);
+extern Datum CallerFInfoFunctionCall4(PGFunction func, FmgrInfo *flinfo,
+						 Oid collation, Datum arg1, Datum arg2,
+						 Datum arg3, Datum arg4);
+extern Datum CallerFInfoFunctionCall5(PGFunction func, FmgrInfo *flinfo,
+						 Oid collation, Datum arg1, Datum arg2,
+						 Datum arg3, Datum arg4, Datum arg5);
+extern Datum CallerFInfoFunctionCall6(PGFunction func, FmgrInfo *flinfo,
+						 Oid collation, Datum arg1, Datum arg2,
+						 Datum arg3, Datum arg4, Datum arg5,
+						 Datum arg6);
+extern Datum CallerFInfoFunctionCall7(PGFunction func, FmgrInfo *flinfo,
+						 Oid collation, Datum arg1, Datum arg2,
+						 Datum arg3, Datum arg4, Datum arg5,
+						 Datum arg6, Datum arg7);
+extern Datum CallerFInfoFunctionCall8(PGFunction func, FmgrInfo *flinfo,
+						 Oid collation, Datum arg1, Datum arg2,
+						 Datum arg3, Datum arg4, Datum arg5,
+						 Datum arg6, Datum arg7, Datum arg8);
+extern Datum CallerFInfoFunctionCall9(PGFunction func, FmgrInfo *flinfo,
+						 Oid collation, Datum arg1, Datum arg2,
+						 Datum arg3, Datum arg4, Datum arg5,
+						 Datum arg6, Datum arg7, Datum arg8,
+						 Datum arg9);
 
 /* These are for invocation of a previously-looked-up function with a
  * directly-computed parameter list.  Note that neither arguments nor result
@@ -548,28 +559,55 @@ extern Datum OidFunctionCall9Coll(Oid functionId, Oid collation,
 					 Datum arg6, Datum arg7, Datum arg8,
 					 Datum arg9);
 
+/*
+ * These macros allow the flinfo argument to be omitted, so that no context is
+ * supplied to the called function.
+ */
+
+#define DirectFunctionCall1Coll(func, coll, arg1) \
+	CallerFInfoFunctionCall1(func, NULL, coll, arg1)
+#define DirectFunctionCall2Coll(func, coll, arg1, arg2) \
+	CallerFInfoFunctionCall2(func, NULL, coll, arg1, arg2)
+#define DirectFunctionCall3Coll(func, coll, arg1, arg2, arg3) \
+	CallerFInfoFunctionCall3(func, NULL, coll, arg1, arg2, arg3)
+#define DirectFunctionCall4Coll(func, coll, arg1, arg2, arg3, arg4) \
+	CallerFInfoFunctionCall4(func, NULL, coll, arg1, arg2, arg3, arg4)
+#define DirectFunctionCall5Coll(func, coll, arg1, arg2, arg3, arg4, arg5) \
+	CallerFInfoFunctionCall5(func, NULL, coll, arg1, arg2, arg3, arg4, arg5)
+#define DirectFunctionCall6Coll(func, coll, arg1, arg2, arg3, arg4, arg5, arg6) \
+	CallerFInfoFunctionCall6(func, NULL, coll, arg1, arg2, arg3, arg4, arg5, arg6)
+#define DirectFunctionCall7Coll(func, coll, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+	CallerFInfoFunctionCall7(func, NULL, coll, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+#define DirectFunctionCall8Coll(func, coll, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \
+	CallerFInfoFunctionCall8(func, NULL, coll, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
+#define DirectFunctionCall9Coll(func, coll, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) \
+	CallerFInfoFunctionCall9(func, NULL, coll, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
+
+
 /* These macros allow the collation argument to be omitted (with a default of
  * InvalidOid, ie, no collation).  They exist mostly for backwards
- * compatibility of source code.
+ * compatibility of source code. The flinfo argument is also set as NULL
+ * in the DirectFunctionCall cases, so that no context is supplied to the
+ * called function.
  */
 #define DirectFunctionCall1(func, arg1) \
-	DirectFunctionCall1Coll(func, InvalidOid, arg1)
+	CallerFInfoFunctionCall1(func, NULL, InvalidOid, arg1)
 #define DirectFunctionCall2(func, arg1, arg2) \
-	DirectFunctionCall2Coll(func, InvalidOid, arg1, arg2)
+	CallerFInfoFunctionCall2(func, NULL, InvalidOid, arg1, arg2)
 #define DirectFunctionCall3(func, arg1, arg2, arg3) \
-	DirectFunctionCall3Coll(func, InvalidOid, arg1, arg2, arg3)
+	CallerFInfoFunctionCall3(func, NULL, InvalidOid, arg1, arg2, arg3)
 #define DirectFunctionCall4(func, arg1, arg2, arg3, arg4) \
-	DirectFunctionCall4Coll(func, InvalidOid, arg1, arg2, arg3, arg4)
+	CallerFInfoFunctionCall4(func, NULL, InvalidOid, arg1, arg2, arg3, arg4)
 #define DirectFunctionCall5(func, arg1, arg2, arg3, arg4, arg5) \
-	DirectFunctionCall5Coll(func, InvalidOid, arg1, arg2, arg3, arg4, arg5)
+	CallerFInfoFunctionCall5(func, NULL, InvalidOid, arg1, arg2, arg3, arg4, arg5)
 #define DirectFunctionCall6(func, arg1, arg2, arg3, arg4, arg5, arg6) \
-	DirectFunctionCall6Coll(func, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6)
+	CallerFInfoFunctionCall6(func, NULL, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6)
 #define DirectFunctionCall7(func, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
-	DirectFunctionCall7Coll(func, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+	CallerFInfoFunctionCall7(func, NULL, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
 #define DirectFunctionCall8(func, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \
-	DirectFunctionCall8Coll(func, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
+	CallerFInfoFunctionCall8(func, NULL, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
 #define DirectFunctionCall9(func, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) \
-	DirectFunctionCall9Coll(func, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
+	CallerFInfoFunctionCall9(func, NULL, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
 #define FunctionCall1(flinfo, arg1) \
 	FunctionCall1Coll(flinfo, InvalidOid, arg1)
 #define FunctionCall2(flinfo, arg1, arg2) \
#28Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andrew Dunstan (#27)
Re: btree_gin and btree_gist for enums

Andrew Dunstan <andrew.dunstan@2ndquadrant.com> writes:

On 02/24/2017 05:34 PM, Andrew Dunstan wrote:

It's occurred to me that we could reduce the code clutter in fmgr.c a
bit by turning the DirectFunctionCall{n]Coll functions into macros
calling these functions and passing NULL as the flinfo param.

here's a patch along those lines. If there's agreement on this I can
finish up the work on btree_gist and btree_gin supoport for enums.

I'm not really thrilled with doing it like that, for two reasons:

1. This makes it look like CallerFInfoFunctionCallN is the more basic,
common interface, which it isn't and never will be. At best, that's
confusing. And I don't like having only one documentation block
covering both interfaces; that does nothing for clarity either.

2. By my count there are over 500 uses of DirectFunctionCallN in the
backend. This will add an additional hidden parameter to each one,
implying code bloat and some fractional speed cost.

I think it'd be better to leave DirectFunctionCallN alone and just invent
a small number of CallerFInfoFunctionCallN support functions (maybe N=1
and N=2 would be enough, at least for now).

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#29Emre Hasegeli
emre@hasegeli.com
In reply to: Tom Lane (#18)
Re: btree_gin and btree_gist for enums

The reason this is kind of scary is that it's just blithely assuming
that the function won't look at the *other* fields of the FmgrInfo.
If it did, it would likely get very confused, since those fields
would be describing the GIN support function, not the function we're
calling.

I am sorry if it doesn't make sense, but wouldn't the whole thing be
better, if we refactor enum.c to call only he internal functions with
TypeCacheEntry just like the rangetypes?

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#30Andrew Dunstan
andrew.dunstan@2ndquadrant.com
In reply to: Tom Lane (#28)
1 attachment(s)
Re: btree_gin and btree_gist for enums

On 02/25/2017 12:04 PM, Tom Lane wrote:

I think it'd be better to leave DirectFunctionCallN alone and just invent
a small number of CallerFInfoFunctionCallN support functions (maybe N=1
and N=2 would be enough, at least for now).

See attached.

cheers

andrew

--
Andrew Dunstan https://www.2ndQuadrant.com
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

Attachments:

callfinfofunctioncall2.patchtext/x-diff; name=callfinfofunctioncall2.patchDownload
diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c
index 3976496..66227e5 100644
--- a/src/backend/utils/fmgr/fmgr.c
+++ b/src/backend/utils/fmgr/fmgr.c
@@ -1276,6 +1276,54 @@ DirectFunctionCall9Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
 	return result;
 }
 
+/*
+ * These functions work like the DirectFunctionCall functions except that
+ * they use the flinfo parameter to initialise the fcinfo for the call.
+ * The callee should not look at anything except the fn_mcxt and fn_extra.
+ * Anything else is likely to be bogus.
+ */
+
+Datum
+CallerFInfoFunctionCall1(PGFunction func, FmgrInfo *flinfo, Oid collation, Datum arg1)
+{
+	FunctionCallInfoData fcinfo;
+	Datum		result;
+
+	InitFunctionCallInfoData(fcinfo, flinfo, 1, collation, NULL, NULL);
+
+	fcinfo.arg[0] = arg1;
+	fcinfo.argnull[0] = false;
+
+	result = (*func) (&fcinfo);
+
+	/* Check for null result, since caller is clearly not expecting one */
+	if (fcinfo.isnull)
+		elog(ERROR, "function %p returned NULL", (void *) func);
+
+	return result;
+}
+
+Datum
+CallerFInfoFunctionCall2(PGFunction func, FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
+{
+	FunctionCallInfoData fcinfo;
+	Datum		result;
+
+	InitFunctionCallInfoData(fcinfo, flinfo, 2, collation, NULL, NULL);
+
+	fcinfo.arg[0] = arg1;
+	fcinfo.arg[1] = arg2;
+	fcinfo.argnull[0] = false;
+	fcinfo.argnull[1] = false;
+
+	result = (*func) (&fcinfo);
+
+	/* Check for null result, since caller is clearly not expecting one */
+	if (fcinfo.isnull)
+		elog(ERROR, "function %p returned NULL", (void *) func);
+
+	return result;
+}
 
 /*
  * These are for invocation of a previously-looked-up function with a
diff --git a/src/include/fmgr.h b/src/include/fmgr.h
index a671480..739ce46 100644
--- a/src/include/fmgr.h
+++ b/src/include/fmgr.h
@@ -475,6 +475,19 @@ extern Datum DirectFunctionCall9Coll(PGFunction func, Oid collation,
 						Datum arg6, Datum arg7, Datum arg8,
 						Datum arg9);
 
+/*
+ * These functions work like the DirectFunctionCall functions except that
+ * they use the flinfo parameter to initialise the fcinfo for the call.
+ * The callee should not look at anything except the fn_mcxt and fn_extra.
+ * Anything else is likely to be bogus.
+ */
+
+extern Datum CallerFInfoFunctionCall1(PGFunction func, FmgrInfo *flinfo,
+						 Oid collation, Datum arg1);
+extern Datum CallerFInfoFunctionCall1(PGFunction func, FmgrInfo *flinfo,
+						 Oid collation, Datum arg1);
+
+
 /* These are for invocation of a previously-looked-up function with a
  * directly-computed parameter list.  Note that neither arguments nor result
  * are allowed to be NULL.
#31Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andrew Dunstan (#30)
Re: btree_gin and btree_gist for enums

Andrew Dunstan <andrew.dunstan@2ndquadrant.com> writes:

On 02/25/2017 12:04 PM, Tom Lane wrote:

I think it'd be better to leave DirectFunctionCallN alone and just invent
a small number of CallerFInfoFunctionCallN support functions (maybe N=1
and N=2 would be enough, at least for now).

See attached.

Yeah, I like this better, except that instead of

+ * The callee should not look at anything except the fn_mcxt and fn_extra.
+ * Anything else is likely to be bogus.

maybe

+ * It's recommended that the callee only use the fn_extra and fn_mcxt
+ * fields, as other fields will typically describe the calling function
+ * not the callee.  Conversely, the calling function should not have
+ * used fn_extra, unless its use is known compatible with the callee's.

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#32Andrew Dunstan
andrew.dunstan@2ndquadrant.com
In reply to: Tom Lane (#31)
Re: btree_gin and btree_gist for enums

On 02/25/2017 01:34 PM, Tom Lane wrote:

Andrew Dunstan <andrew.dunstan@2ndquadrant.com> writes:

On 02/25/2017 12:04 PM, Tom Lane wrote:

I think it'd be better to leave DirectFunctionCallN alone and just invent
a small number of CallerFInfoFunctionCallN support functions (maybe N=1
and N=2 would be enough, at least for now).

See attached.

Yeah, I like this better, except that instead of

+ * The callee should not look at anything except the fn_mcxt and fn_extra.
+ * Anything else is likely to be bogus.

maybe

+ * It's recommended that the callee only use the fn_extra and fn_mcxt
+ * fields, as other fields will typically describe the calling function
+ * not the callee.  Conversely, the calling function should not have
+ * used fn_extra, unless its use is known compatible with the callee's.

OK, Works for me. Thanks.

cheers

andrew

--
Andrew Dunstan https://www.2ndQuadrant.com
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#33Andrew Dunstan
andrew.dunstan@2ndquadrant.com
In reply to: Andrew Dunstan (#32)
Re: btree_gin and btree_gist for enums

On 02/25/2017 01:39 PM, Andrew Dunstan wrote:

On 02/25/2017 01:34 PM, Tom Lane wrote:

Andrew Dunstan <andrew.dunstan@2ndquadrant.com> writes:

On 02/25/2017 12:04 PM, Tom Lane wrote:

I think it'd be better to leave DirectFunctionCallN alone and just invent
a small number of CallerFInfoFunctionCallN support functions (maybe N=1
and N=2 would be enough, at least for now).

See attached.

Yeah, I like this better, except that instead of

+ * The callee should not look at anything except the fn_mcxt and fn_extra.
+ * Anything else is likely to be bogus.

maybe

+ * It's recommended that the callee only use the fn_extra and fn_mcxt
+ * fields, as other fields will typically describe the calling function
+ * not the callee.  Conversely, the calling function should not have
+ * used fn_extra, unless its use is known compatible with the callee's.

OK, Works for me. Thanks.

This works for the btree_gin case. However, there's a difficulty for
btree_gist - in the puicksplit routine the cmp function is passed to
qsort() so there is no chance to pass it an flinfo to set up the call to
the real comparison routine. Implementing a custom sort routine to work
around the problem seems a bridge too far. I can;t think of an
alternative off hand.

cheers

andrew

--
Andrew Dunstan https://www.2ndQuadrant.com
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#34Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andrew Dunstan (#33)
Re: btree_gin and btree_gist for enums

Andrew Dunstan <andrew.dunstan@2ndquadrant.com> writes:

This works for the btree_gin case. However, there's a difficulty for
btree_gist - in the puicksplit routine the cmp function is passed to
qsort() so there is no chance to pass it an flinfo to set up the call to
the real comparison routine. Implementing a custom sort routine to work
around the problem seems a bridge too far. I can;t think of an
alternative off hand.

We already have qsort_arg ... can't you change it to use that?

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#35Andrew Dunstan
andrew.dunstan@2ndquadrant.com
In reply to: Tom Lane (#34)
Re: btree_gin and btree_gist for enums

On 02/26/2017 03:26 PM, Tom Lane wrote:

Andrew Dunstan <andrew.dunstan@2ndquadrant.com> writes:

This works for the btree_gin case. However, there's a difficulty for
btree_gist - in the puicksplit routine the cmp function is passed to
qsort() so there is no chance to pass it an flinfo to set up the call to
the real comparison routine. Implementing a custom sort routine to work
around the problem seems a bridge too far. I can;t think of an
alternative off hand.

We already have qsort_arg ... can't you change it to use that?

Yes, wasn't aware of that, that looks like exactly what I need. thanks.

cheers

andrew

--
Andrew Dunstan https://www.2ndQuadrant.com
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#36Andrew Dunstan
andrew.dunstan@2ndquadrant.com
In reply to: Andrew Dunstan (#35)
5 attachment(s)
Re: btree_gin and btree_gist for enums

On 02/26/2017 04:09 PM, Andrew Dunstan wrote:

On 02/26/2017 03:26 PM, Tom Lane wrote:

Andrew Dunstan <andrew.dunstan@2ndquadrant.com> writes:

This works for the btree_gin case. However, there's a difficulty for
btree_gist - in the puicksplit routine the cmp function is passed to
qsort() so there is no chance to pass it an flinfo to set up the call to
the real comparison routine. Implementing a custom sort routine to work
around the problem seems a bridge too far. I can;t think of an
alternative off hand.

We already have qsort_arg ... can't you change it to use that?

Yes, wasn't aware of that, that looks like exactly what I need. thanks.

OK, here's the whole series of patches.

Patch 1 adds the CallerFInfoFunctionCall{1,2} functions.

Patch 2 adds btree_gist support for their use for non-varlena types

Patch 3 does the same for varlena types (Not required for patch 4, but
better to be consistent, I think.)

Patch 4 adds enum support to btree_gist

Patch 5 adds enum support to btree_gin

cheers

andrew

--
Andrew Dunstan https://www.2ndQuadrant.com
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

Attachments:

0004-Add-btree_gist-support-for-enum-types.patchtext/x-diff; name=0004-Add-btree_gist-support-for-enum-types.patchDownload
From 74ebe1490de916409458e3d1adf47dfa20b1fefb Mon Sep 17 00:00:00 2001
From: Andrew Dunstan <andrew@dunslane.net>
Date: Mon, 27 Feb 2017 15:41:03 -0500
Subject: [PATCH 4/4] Add btree_gist support for enum types.

This will alow enums to be used in exclusio n constraints.

The code uses the new CallerFInfoFunctionCall infrastructure in fmgr,
and the support for it added to btree_gist in a nearby patch.
---
 contrib/btree_gist/Makefile                 |   8 +-
 contrib/btree_gist/btree_enum.c             | 187 +++++++++
 contrib/btree_gist/btree_gist--1.3--1.4.sql |  69 ++++
 contrib/btree_gist/btree_gist.control       |   2 +-
 contrib/btree_gist/btree_gist.h             |   3 +-
 contrib/btree_gist/btree_utils_num.c        |   2 +
 contrib/btree_gist/data/enum.data           | 595 ++++++++++++++++++++++++++++
 contrib/btree_gist/expected/enum.out        |  91 +++++
 contrib/btree_gist/sql/enum.sql             |  38 ++
 doc/src/sgml/btree-gist.sgml                |   2 +-
 10 files changed, 991 insertions(+), 6 deletions(-)
 create mode 100644 contrib/btree_gist/btree_enum.c
 create mode 100644 contrib/btree_gist/btree_gist--1.3--1.4.sql
 create mode 100644 contrib/btree_gist/data/enum.data
 create mode 100644 contrib/btree_gist/expected/enum.out
 create mode 100644 contrib/btree_gist/sql/enum.sql

diff --git a/contrib/btree_gist/Makefile b/contrib/btree_gist/Makefile
index d36f517..beb2ed7 100644
--- a/contrib/btree_gist/Makefile
+++ b/contrib/btree_gist/Makefile
@@ -6,16 +6,18 @@ OBJS =  btree_gist.o btree_utils_num.o btree_utils_var.o btree_int2.o \
         btree_int4.o btree_int8.o btree_float4.o btree_float8.o btree_cash.o \
         btree_oid.o btree_ts.o btree_time.o btree_date.o btree_interval.o \
         btree_macaddr.o btree_inet.o btree_text.o btree_bytea.o btree_bit.o \
-        btree_numeric.o btree_uuid.o $(WIN32RES)
+        btree_numeric.o btree_uuid.o btree_enum.o $(WIN32RES)
 
 EXTENSION = btree_gist
 DATA = btree_gist--unpackaged--1.0.sql btree_gist--1.0--1.1.sql \
-       btree_gist--1.1--1.2.sql btree_gist--1.2.sql btree_gist--1.2--1.3.sql
+       btree_gist--1.1--1.2.sql btree_gist--1.2.sql btree_gist--1.2--1.3.sql \
+	   btree_gist--1.3--1.4.sql
+
 PGFILEDESC = "btree_gist - B-tree equivalent GiST operator classes"
 
 REGRESS = init int2 int4 int8 float4 float8 cash oid timestamp timestamptz \
         time timetz date interval macaddr inet cidr text varchar char bytea \
-        bit varbit numeric uuid not_equal
+        bit varbit numeric uuid enum not_equal
 
 SHLIB_LINK += $(filter -lm, $(LIBS))
 
diff --git a/contrib/btree_gist/btree_enum.c b/contrib/btree_gist/btree_enum.c
new file mode 100644
index 0000000..5e46e78
--- /dev/null
+++ b/contrib/btree_gist/btree_enum.c
@@ -0,0 +1,187 @@
+/*
+ * contrib/btree_gist/btree_enum.c
+ */
+#include "postgres.h"
+#include "fmgr.h"
+#include "utils/builtins.h"
+
+#include "btree_gist.h"
+#include "btree_utils_num.h"
+
+/* enums are really Oids, so we just use the same structure */
+
+typedef struct
+{
+	Oid			lower;
+	Oid			upper;
+} oidKEY;
+
+/*
+** enum ops
+*/
+PG_FUNCTION_INFO_V1(gbt_enum_compress);
+PG_FUNCTION_INFO_V1(gbt_enum_fetch);
+PG_FUNCTION_INFO_V1(gbt_enum_union);
+PG_FUNCTION_INFO_V1(gbt_enum_picksplit);
+PG_FUNCTION_INFO_V1(gbt_enum_consistent);
+PG_FUNCTION_INFO_V1(gbt_enum_penalty);
+PG_FUNCTION_INFO_V1(gbt_enum_same);
+
+
+static bool
+gbt_enumgt(const void *a, const void *b, FmgrInfo *flinfo)
+{
+	return DatumGetBool(
+		CallerFInfoFunctionCall2(enum_gt, flinfo, InvalidOid, ObjectIdGetDatum(*((const Oid *) a)), ObjectIdGetDatum(*((const Oid *) b)))
+		);
+}
+static bool
+gbt_enumge(const void *a, const void *b, FmgrInfo *flinfo)
+{
+	return DatumGetBool(
+		CallerFInfoFunctionCall2(enum_ge, flinfo, InvalidOid, ObjectIdGetDatum(*((const Oid *) a)), ObjectIdGetDatum(*((const Oid *) b)))
+		);
+}
+static bool
+gbt_enumeq(const void *a, const void *b, FmgrInfo *flinfo)
+{
+	return (*((const Oid *) a) == *((const Oid *) b));
+}
+static bool
+gbt_enumle(const void *a, const void *b, FmgrInfo *flinfo)
+{
+	return DatumGetBool(
+						CallerFInfoFunctionCall2(enum_le, flinfo, InvalidOid, ObjectIdGetDatum(*((const Oid *) a)), ObjectIdGetDatum(*((const Oid *) b)))
+		);
+}
+static bool
+gbt_enumlt(const void *a, const void *b, FmgrInfo *flinfo)
+{
+	return DatumGetBool(
+						CallerFInfoFunctionCall2(enum_lt, flinfo, InvalidOid, ObjectIdGetDatum(*((const Oid *) a)), ObjectIdGetDatum(*((const Oid *) b)))
+		);
+}
+
+static int
+gbt_enumkey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
+{
+	oidKEY	   *ia = (oidKEY *) (((const Nsrt *) a)->t);
+	oidKEY	   *ib = (oidKEY *) (((const Nsrt *) b)->t);
+
+	if (ia->lower == ib->lower)
+	{
+		if (ia->upper == ib->upper)
+			return 0;
+
+		return DatumGetInt32(
+			CallerFInfoFunctionCall2(enum_cmp, flinfo, InvalidOid, ObjectIdGetDatum(ia->upper), ObjectIdGetDatum(ib->upper))
+			);
+	}
+
+	return DatumGetInt32(
+		CallerFInfoFunctionCall2(enum_cmp, flinfo, InvalidOid, ObjectIdGetDatum(ia->lower), ObjectIdGetDatum(ib->lower))
+		);
+}
+
+static const gbtree_ninfo tinfo =
+{
+	gbt_t_enum,
+	sizeof(Oid),
+	8,							/* sizeof(gbtreekey8) */
+	gbt_enumgt,
+	gbt_enumge,
+	gbt_enumeq,
+	gbt_enumle,
+	gbt_enumlt,
+	gbt_enumkey_cmp,
+	NULL /* no KNN support at least for now */
+};
+
+
+/**************************************************
+ * Enum ops
+ **************************************************/
+
+
+Datum
+gbt_enum_compress(PG_FUNCTION_ARGS)
+{
+	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+
+	PG_RETURN_POINTER(gbt_num_compress(entry, &tinfo));
+}
+
+Datum
+gbt_enum_fetch(PG_FUNCTION_ARGS)
+{
+	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+
+	PG_RETURN_POINTER(gbt_num_fetch(entry, &tinfo));
+}
+
+Datum
+gbt_enum_consistent(PG_FUNCTION_ARGS)
+{
+	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+	Oid			query = PG_GETARG_OID(1);
+	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
+
+	/* Oid		subtype = PG_GETARG_OID(3); */
+	bool	   *recheck = (bool *) PG_GETARG_POINTER(4);
+	oidKEY	   *kkk = (oidKEY *) DatumGetPointer(entry->key);
+	GBT_NUMKEY_R key;
+
+	/* All cases served by this function are exact */
+	*recheck = false;
+
+	key.lower = (GBT_NUMKEY *) &kkk->lower;
+	key.upper = (GBT_NUMKEY *) &kkk->upper;
+
+	PG_RETURN_BOOL(
+				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
+		);
+}
+
+Datum
+gbt_enum_union(PG_FUNCTION_ARGS)
+{
+	GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
+	void	   *out = palloc(sizeof(oidKEY));
+
+	*(int *) PG_GETARG_POINTER(1) = sizeof(oidKEY);
+	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
+}
+
+
+Datum
+gbt_enum_penalty(PG_FUNCTION_ARGS)
+{
+	oidKEY	   *origentry = (oidKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
+	oidKEY	   *newentry = (oidKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
+	float	   *result = (float *) PG_GETARG_POINTER(2);
+
+	penalty_num(result, origentry->lower, origentry->upper, newentry->lower, newentry->upper);
+
+	PG_RETURN_POINTER(result);
+}
+
+Datum
+gbt_enum_picksplit(PG_FUNCTION_ARGS)
+{
+	PG_RETURN_POINTER(gbt_num_picksplit(
+									(GistEntryVector *) PG_GETARG_POINTER(0),
+									  (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
+										&tinfo, fcinfo->flinfo
+										));
+}
+
+Datum
+gbt_enum_same(PG_FUNCTION_ARGS)
+{
+	oidKEY	   *b1 = (oidKEY *) PG_GETARG_POINTER(0);
+	oidKEY	   *b2 = (oidKEY *) PG_GETARG_POINTER(1);
+	bool	   *result = (bool *) PG_GETARG_POINTER(2);
+
+	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
+	PG_RETURN_POINTER(result);
+}
diff --git a/contrib/btree_gist/btree_gist--1.3--1.4.sql b/contrib/btree_gist/btree_gist--1.3--1.4.sql
new file mode 100644
index 0000000..1233aec
--- /dev/null
+++ b/contrib/btree_gist/btree_gist--1.3--1.4.sql
@@ -0,0 +1,69 @@
+/* contrib/btree_gist/btree_gist--1.3--1.4.sql */
+
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "ALTER EXTENSION btree_gist UPDATE TO '1.4'" to load this file. \quit
+
+--
+--
+--
+-- enum ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_enum_consistent(internal,anyenum,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_union(internal, internal)
+RETURNS gbtreekey8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_same(gbtreekey8, gbtreekey8, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_enum_ops
+DEFAULT FOR TYPE anyenum USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_enum_consistent (internal, anyenum, int2, oid, internal),
+	FUNCTION	2	gbt_enum_union (internal, internal),
+	FUNCTION	3	gbt_enum_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_enum_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_enum_picksplit (internal, internal),
+	FUNCTION	7	gbt_enum_same (gbtreekey8, gbtreekey8, internal),
+	STORAGE		gbtreekey8;
+
+ALTER OPERATOR FAMILY gist_enum_ops USING gist ADD
+	OPERATOR	6	<> (anyenum, anyenum) ,
+	FUNCTION	9 (anyenum, anyenum) gbt_enum_fetch (internal) ;
diff --git a/contrib/btree_gist/btree_gist.control b/contrib/btree_gist/btree_gist.control
index ddbf83d..fdf0e6a 100644
--- a/contrib/btree_gist/btree_gist.control
+++ b/contrib/btree_gist/btree_gist.control
@@ -1,5 +1,5 @@
 # btree_gist extension
 comment = 'support for indexing common datatypes in GiST'
-default_version = '1.3'
+default_version = '1.4'
 module_pathname = '$libdir/btree_gist'
 relocatable = true
diff --git a/contrib/btree_gist/btree_gist.h b/contrib/btree_gist/btree_gist.h
index 9b3e22c..219ca89 100644
--- a/contrib/btree_gist/btree_gist.h
+++ b/contrib/btree_gist/btree_gist.h
@@ -32,7 +32,8 @@ enum gbtree_type
 	gbt_t_bytea,
 	gbt_t_bit,
 	gbt_t_inet,
-	gbt_t_uuid
+	gbt_t_uuid,
+	gbt_t_enum
 };
 
 #endif
diff --git a/contrib/btree_gist/btree_utils_num.c b/contrib/btree_gist/btree_utils_num.c
index e30924b..d4fee91 100644
--- a/contrib/btree_gist/btree_utils_num.c
+++ b/contrib/btree_gist/btree_utils_num.c
@@ -48,6 +48,7 @@ gbt_num_compress(GISTENTRY *entry, const gbtree_ninfo *tinfo)
 				leaf = &v.i8;
 				break;
 			case gbt_t_oid:
+			case gbt_t_enum:
 				v.i4 = DatumGetObjectId(entry->key);
 				leaf = &v.i4;
 				break;
@@ -122,6 +123,7 @@ gbt_num_fetch(GISTENTRY *entry, const gbtree_ninfo *tinfo)
 			datum = Int64GetDatum(*(int64 *) entry->key);
 			break;
 		case gbt_t_oid:
+		case gbt_t_enum:
 			datum = ObjectIdGetDatum(*(Oid *) entry->key);
 			break;
 		case gbt_t_float4:
diff --git a/contrib/btree_gist/data/enum.data b/contrib/btree_gist/data/enum.data
new file mode 100644
index 0000000..d03bfce
--- /dev/null
+++ b/contrib/btree_gist/data/enum.data
@@ -0,0 +1,595 @@
+r
+v
+i
+b
+r
+\N
+y
+v
+g
+o
+y
+b
+o
+o
+o
+o
+v
+r
+i
+o
+b
+r
+g
+b
+i
+o
+r
+r
+r
+\N
+o
+b
+v
+y
+o
+\N
+i
+o
+o
+g
+g
+b
+y
+v
+g
+g
+\N
+v
+g
+i
+i
+\N
+v
+y
+i
+r
+\N
+r
+\N
+g
+\N
+g
+\N
+v
+g
+y
+v
+r
+v
+r
+v
+y
+i
+i
+v
+y
+v
+i
+b
+i
+i
+r
+r
+\N
+\N
+y
+r
+g
+i
+y
+i
+i
+r
+g
+y
+\N
+i
+o
+r
+y
+y
+g
+o
+o
+g
+y
+r
+g
+v
+r
+i
+r
+i
+r
+y
+v
+b
+i
+o
+r
+\N
+o
+i
+v
+o
+b
+\N
+b
+g
+y
+o
+v
+b
+i
+v
+v
+o
+y
+i
+i
+i
+g
+b
+b
+g
+r
+i
+y
+o
+\N
+r
+\N
+i
+i
+g
+v
+o
+y
+y
+o
+i
+b
+r
+y
+y
+o
+g
+g
+g
+\N
+y
+o
+v
+g
+y
+g
+v
+\N
+i
+o
+v
+b
+b
+\N
+y
+v
+\N
+v
+\N
+i
+\N
+r
+b
+r
+o
+r
+b
+o
+g
+i
+r
+b
+g
+g
+y
+b
+b
+g
+y
+g
+v
+v
+b
+\N
+i
+v
+y
+b
+b
+o
+g
+b
+v
+g
+g
+b
+\N
+y
+r
+r
+b
+\N
+r
+g
+i
+o
+v
+\N
+o
+r
+b
+o
+b
+i
+\N
+\N
+y
+b
+y
+\N
+i
+i
+i
+o
+y
+o
+i
+b
+o
+g
+r
+\N
+b
+y
+\N
+g
+b
+y
+y
+o
+o
+b
+g
+i
+i
+v
+b
+o
+o
+v
+i
+g
+i
+o
+r
+o
+i
+i
+r
+b
+g
+o
+o
+y
+v
+g
+g
+g
+r
+o
+i
+i
+g
+\N
+o
+v
+b
+b
+v
+i
+g
+y
+i
+i
+g
+r
+y
+i
+b
+\N
+g
+y
+o
+\N
+i
+i
+b
+v
+o
+b
+v
+r
+g
+o
+v
+v
+y
+r
+v
+g
+\N
+v
+v
+b
+y
+o
+g
+i
+o
+b
+r
+y
+r
+v
+b
+b
+\N
+i
+v
+y
+r
+b
+i
+y
+g
+\N
+g
+r
+y
+y
+g
+b
+o
+v
+r
+i
+g
+r
+b
+b
+b
+\N
+y
+y
+y
+i
+o
+r
+g
+g
+i
+y
+g
+y
+v
+o
+o
+g
+\N
+b
+v
+o
+y
+r
+\N
+o
+i
+g
+\N
+i
+i
+i
+o
+b
+\N
+\N
+b
+\N
+v
+v
+r
+\N
+o
+b
+r
+o
+b
+o
+r
+y
+\N
+r
+i
+b
+b
+y
+v
+r
+g
+r
+r
+\N
+g
+\N
+v
+v
+y
+r
+o
+r
+o
+i
+o
+\N
+r
+\N
+i
+v
+b
+v
+\N
+b
+r
+v
+o
+\N
+i
+r
+b
+g
+o
+\N
+o
+g
+r
+v
+y
+g
+v
+r
+b
+r
+v
+o
+g
+i
+i
+g
+i
+y
+b
+i
+y
+r
+y
+o
+r
+b
+y
+y
+b
+y
+g
+b
+\N
+r
+g
+b
+o
+y
+o
+g
+r
+g
+b
+\N
+v
+v
+v
+g
+b
+y
+v
+o
+v
+g
+o
+g
+i
+b
+v
+i
+r
+r
+i
+b
+i
+b
+o
+\N
+\N
+y
+r
+g
+v
+o
+y
+\N
+g
+v
+o
+b
+v
+v
+\N
+r
+v
+y
+g
+b
+o
+v
+b
+v
+b
+r
+r
+i
+r
+v
+y
+v
+y
+o
+v
+g
+i
+r
+o
+o
+i
+y
+r
+\N
+y
+r
+b
+y
+y
+\N
+b
+\N
+\N
+i
+v
diff --git a/contrib/btree_gist/expected/enum.out b/contrib/btree_gist/expected/enum.out
new file mode 100644
index 0000000..c4b769d
--- /dev/null
+++ b/contrib/btree_gist/expected/enum.out
@@ -0,0 +1,91 @@
+-- enum check
+create type rainbow as enum ('r','o','y','g','b','i','v');
+CREATE TABLE enumtmp (a rainbow);
+\copy enumtmp from 'data/enum.data'
+SET enable_seqscan=on;
+select a, count(*) from enumtmp group by a order by 1;
+ a | count 
+---+-------
+ r |    76
+ o |    78
+ y |    73
+ g |    75
+ b |    77
+ i |    78
+ v |    75
+   |    63
+(8 rows)
+
+SELECT count(*) FROM enumtmp WHERE a <  'g'::rainbow;
+ count 
+-------
+   227
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a <= 'g'::rainbow;
+ count 
+-------
+   302
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a  = 'g'::rainbow;
+ count 
+-------
+    75
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a >= 'g'::rainbow;
+ count 
+-------
+   305
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a >  'g'::rainbow;
+ count 
+-------
+   230
+(1 row)
+
+CREATE INDEX enumidx ON enumtmp USING gist ( a );
+SET enable_seqscan=off;
+SELECT count(*) FROM enumtmp WHERE a <  'g'::rainbow;
+ count 
+-------
+   227
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a <= 'g'::rainbow;
+ count 
+-------
+   302
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a  = 'g'::rainbow;
+ count 
+-------
+    75
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a >= 'g'::rainbow;
+ count 
+-------
+   305
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a >  'g'::rainbow;
+ count 
+-------
+   230
+(1 row)
+
+EXPLAIN (COSTS OFF)
+SELECT count(*) FROM enumtmp WHERE a >= 'g'::rainbow;
+                  QUERY PLAN                   
+-----------------------------------------------
+ Aggregate
+   ->  Bitmap Heap Scan on enumtmp
+         Recheck Cond: (a >= 'g'::rainbow)
+         ->  Bitmap Index Scan on enumidx
+               Index Cond: (a >= 'g'::rainbow)
+(5 rows)
+
diff --git a/contrib/btree_gist/sql/enum.sql b/contrib/btree_gist/sql/enum.sql
new file mode 100644
index 0000000..476211e
--- /dev/null
+++ b/contrib/btree_gist/sql/enum.sql
@@ -0,0 +1,38 @@
+-- enum check
+
+create type rainbow as enum ('r','o','y','g','b','i','v');
+
+CREATE TABLE enumtmp (a rainbow);
+
+\copy enumtmp from 'data/enum.data'
+
+SET enable_seqscan=on;
+
+select a, count(*) from enumtmp group by a order by 1;
+
+SELECT count(*) FROM enumtmp WHERE a <  'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a <= 'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a  = 'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a >= 'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a >  'g'::rainbow;
+
+CREATE INDEX enumidx ON enumtmp USING gist ( a );
+
+SET enable_seqscan=off;
+
+SELECT count(*) FROM enumtmp WHERE a <  'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a <= 'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a  = 'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a >= 'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a >  'g'::rainbow;
+
+EXPLAIN (COSTS OFF)
+SELECT count(*) FROM enumtmp WHERE a >= 'g'::rainbow;
diff --git a/doc/src/sgml/btree-gist.sgml b/doc/src/sgml/btree-gist.sgml
index d08647c..358feb5 100644
--- a/doc/src/sgml/btree-gist.sgml
+++ b/doc/src/sgml/btree-gist.sgml
@@ -17,7 +17,7 @@
   <type>oid</>, <type>money</>, <type>char</>,
   <type>varchar</>, <type>text</>, <type>bytea</>, <type>bit</>,
   <type>varbit</>, <type>macaddr</>, <type>inet</>, <type>cidr</>,
-  and <type>uuid</>.
+  <type>uuid</> and all <type>enum</> types.
  </para>
 
  <para>
-- 
2.4.11

0003-CallerFInfoFunctionCall-support-for-btree_gist-varlena-types.patchtext/x-diff; name=0003-CallerFInfoFunctionCall-support-for-btree_gist-varlena-types.patchDownload
From 087e53c587ea26c3abd1ca1f377005892b356eb3 Mon Sep 17 00:00:00 2001
From: Andrew Dunstan <andrew@dunslane.net>
Date: Mon, 27 Feb 2017 14:26:51 -0500
Subject: [PATCH 3/4] Allow use of CallerFInfoFunctionCall with btree_gist for
 varlena types

---
 contrib/btree_gist/btree_bit.c       | 26 ++++++------
 contrib/btree_gist/btree_bytea.c     | 22 +++++------
 contrib/btree_gist/btree_numeric.c   | 22 +++++------
 contrib/btree_gist/btree_text.c      | 24 +++++------
 contrib/btree_gist/btree_utils_var.c | 77 +++++++++++++++++++-----------------
 contrib/btree_gist/btree_utils_var.h | 26 ++++++------
 6 files changed, 100 insertions(+), 97 deletions(-)

diff --git a/contrib/btree_gist/btree_bit.c b/contrib/btree_gist/btree_bit.c
index f34fa87..a57f45f 100644
--- a/contrib/btree_gist/btree_bit.c
+++ b/contrib/btree_gist/btree_bit.c
@@ -24,7 +24,7 @@ PG_FUNCTION_INFO_V1(gbt_bit_same);
 /* define for comparison */
 
 static bool
-gbt_bitgt(const void *a, const void *b, Oid collation)
+gbt_bitgt(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2(bitgt,
 											PointerGetDatum(a),
@@ -32,7 +32,7 @@ gbt_bitgt(const void *a, const void *b, Oid collation)
 }
 
 static bool
-gbt_bitge(const void *a, const void *b, Oid collation)
+gbt_bitge(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2(bitge,
 											PointerGetDatum(a),
@@ -40,7 +40,7 @@ gbt_bitge(const void *a, const void *b, Oid collation)
 }
 
 static bool
-gbt_biteq(const void *a, const void *b, Oid collation)
+gbt_biteq(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2(biteq,
 											PointerGetDatum(a),
@@ -48,7 +48,7 @@ gbt_biteq(const void *a, const void *b, Oid collation)
 }
 
 static bool
-gbt_bitle(const void *a, const void *b, Oid collation)
+gbt_bitle(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2(bitle,
 											PointerGetDatum(a),
@@ -56,7 +56,7 @@ gbt_bitle(const void *a, const void *b, Oid collation)
 }
 
 static bool
-gbt_bitlt(const void *a, const void *b, Oid collation)
+gbt_bitlt(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2(bitlt,
 											PointerGetDatum(a),
@@ -64,7 +64,7 @@ gbt_bitlt(const void *a, const void *b, Oid collation)
 }
 
 static int32
-gbt_bitcmp(const void *a, const void *b, Oid collation)
+gbt_bitcmp(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetInt32(DirectFunctionCall2(byteacmp,
 											 PointerGetDatum(a),
@@ -92,7 +92,7 @@ gbt_bit_xfrm(bytea *leaf)
 
 
 static GBT_VARKEY *
-gbt_bit_l2n(GBT_VARKEY *leaf)
+gbt_bit_l2n(GBT_VARKEY *leaf, FmgrInfo *flinfo)
 {
 	GBT_VARKEY *out = leaf;
 	GBT_VARKEY_R r = gbt_var_key_readable(leaf);
@@ -152,13 +152,13 @@ gbt_bit_consistent(PG_FUNCTION_ARGS)
 
 	if (GIST_LEAF(entry))
 		retval = gbt_var_consistent(&r, query, strategy, PG_GET_COLLATION(),
-									TRUE, &tinfo);
+									TRUE, &tinfo, fcinfo->flinfo);
 	else
 	{
 		bytea	   *q = gbt_bit_xfrm((bytea *) query);
 
 		retval = gbt_var_consistent(&r, q, strategy, PG_GET_COLLATION(),
-									FALSE, &tinfo);
+									FALSE, &tinfo, fcinfo->flinfo);
 	}
 	PG_RETURN_BOOL(retval);
 }
@@ -172,7 +172,7 @@ gbt_bit_union(PG_FUNCTION_ARGS)
 	int32	   *size = (int *) PG_GETARG_POINTER(1);
 
 	PG_RETURN_POINTER(gbt_var_union(entryvec, size, PG_GET_COLLATION(),
-									&tinfo));
+									&tinfo, fcinfo->flinfo));
 }
 
 
@@ -183,7 +183,7 @@ gbt_bit_picksplit(PG_FUNCTION_ARGS)
 	GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
 
 	gbt_var_picksplit(entryvec, v, PG_GET_COLLATION(),
-					  &tinfo);
+					  &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(v);
 }
 
@@ -194,7 +194,7 @@ gbt_bit_same(PG_FUNCTION_ARGS)
 	Datum		d2 = PG_GETARG_DATUM(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
 
-	*result = gbt_var_same(d1, d2, PG_GET_COLLATION(), &tinfo);
+	*result = gbt_var_same(d1, d2, PG_GET_COLLATION(), &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(result);
 }
 
@@ -207,5 +207,5 @@ gbt_bit_penalty(PG_FUNCTION_ARGS)
 	float	   *result = (float *) PG_GETARG_POINTER(2);
 
 	PG_RETURN_POINTER(gbt_var_penalty(result, o, n, PG_GET_COLLATION(),
-									  &tinfo));
+									  &tinfo, fcinfo->flinfo));
 }
diff --git a/contrib/btree_gist/btree_bytea.c b/contrib/btree_gist/btree_bytea.c
index df6c960..b9cd00f 100644
--- a/contrib/btree_gist/btree_bytea.c
+++ b/contrib/btree_gist/btree_bytea.c
@@ -23,7 +23,7 @@ PG_FUNCTION_INFO_V1(gbt_bytea_same);
 /* define for comparison */
 
 static bool
-gbt_byteagt(const void *a, const void *b, Oid collation)
+gbt_byteagt(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2(byteagt,
 											PointerGetDatum(a),
@@ -31,7 +31,7 @@ gbt_byteagt(const void *a, const void *b, Oid collation)
 }
 
 static bool
-gbt_byteage(const void *a, const void *b, Oid collation)
+gbt_byteage(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2(byteage,
 											PointerGetDatum(a),
@@ -39,7 +39,7 @@ gbt_byteage(const void *a, const void *b, Oid collation)
 }
 
 static bool
-gbt_byteaeq(const void *a, const void *b, Oid collation)
+gbt_byteaeq(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2(byteaeq,
 											PointerGetDatum(a),
@@ -47,7 +47,7 @@ gbt_byteaeq(const void *a, const void *b, Oid collation)
 }
 
 static bool
-gbt_byteale(const void *a, const void *b, Oid collation)
+gbt_byteale(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2(byteale,
 											PointerGetDatum(a),
@@ -55,7 +55,7 @@ gbt_byteale(const void *a, const void *b, Oid collation)
 }
 
 static bool
-gbt_bytealt(const void *a, const void *b, Oid collation)
+gbt_bytealt(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2(bytealt,
 											PointerGetDatum(a),
@@ -63,7 +63,7 @@ gbt_bytealt(const void *a, const void *b, Oid collation)
 }
 
 static int32
-gbt_byteacmp(const void *a, const void *b, Oid collation)
+gbt_byteacmp(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetInt32(DirectFunctionCall2(byteacmp,
 											 PointerGetDatum(a),
@@ -118,7 +118,7 @@ gbt_bytea_consistent(PG_FUNCTION_ARGS)
 	*recheck = false;
 
 	retval = gbt_var_consistent(&r, query, strategy, PG_GET_COLLATION(),
-								GIST_LEAF(entry), &tinfo);
+								GIST_LEAF(entry), &tinfo, fcinfo->flinfo);
 	PG_RETURN_BOOL(retval);
 }
 
@@ -131,7 +131,7 @@ gbt_bytea_union(PG_FUNCTION_ARGS)
 	int32	   *size = (int *) PG_GETARG_POINTER(1);
 
 	PG_RETURN_POINTER(gbt_var_union(entryvec, size, PG_GET_COLLATION(),
-									&tinfo));
+									&tinfo, fcinfo->flinfo));
 }
 
 
@@ -142,7 +142,7 @@ gbt_bytea_picksplit(PG_FUNCTION_ARGS)
 	GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
 
 	gbt_var_picksplit(entryvec, v, PG_GET_COLLATION(),
-					  &tinfo);
+					  &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(v);
 }
 
@@ -153,7 +153,7 @@ gbt_bytea_same(PG_FUNCTION_ARGS)
 	Datum		d2 = PG_GETARG_DATUM(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
 
-	*result = gbt_var_same(d1, d2, PG_GET_COLLATION(), &tinfo);
+	*result = gbt_var_same(d1, d2, PG_GET_COLLATION(), &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(result);
 }
 
@@ -166,5 +166,5 @@ gbt_bytea_penalty(PG_FUNCTION_ARGS)
 	float	   *result = (float *) PG_GETARG_POINTER(2);
 
 	PG_RETURN_POINTER(gbt_var_penalty(result, o, n, PG_GET_COLLATION(),
-									  &tinfo));
+									  &tinfo, fcinfo->flinfo));
 }
diff --git a/contrib/btree_gist/btree_numeric.c b/contrib/btree_gist/btree_numeric.c
index 47b0020..62e8f9d 100644
--- a/contrib/btree_gist/btree_numeric.c
+++ b/contrib/btree_gist/btree_numeric.c
@@ -27,7 +27,7 @@ PG_FUNCTION_INFO_V1(gbt_numeric_same);
 /* define for comparison */
 
 static bool
-gbt_numeric_gt(const void *a, const void *b, Oid collation)
+gbt_numeric_gt(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2(numeric_gt,
 											PointerGetDatum(a),
@@ -35,7 +35,7 @@ gbt_numeric_gt(const void *a, const void *b, Oid collation)
 }
 
 static bool
-gbt_numeric_ge(const void *a, const void *b, Oid collation)
+gbt_numeric_ge(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2(numeric_ge,
 											PointerGetDatum(a),
@@ -43,7 +43,7 @@ gbt_numeric_ge(const void *a, const void *b, Oid collation)
 }
 
 static bool
-gbt_numeric_eq(const void *a, const void *b, Oid collation)
+gbt_numeric_eq(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2(numeric_eq,
 											PointerGetDatum(a),
@@ -51,7 +51,7 @@ gbt_numeric_eq(const void *a, const void *b, Oid collation)
 }
 
 static bool
-gbt_numeric_le(const void *a, const void *b, Oid collation)
+gbt_numeric_le(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2(numeric_le,
 											PointerGetDatum(a),
@@ -59,7 +59,7 @@ gbt_numeric_le(const void *a, const void *b, Oid collation)
 }
 
 static bool
-gbt_numeric_lt(const void *a, const void *b, Oid collation)
+gbt_numeric_lt(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2(numeric_lt,
 											PointerGetDatum(a),
@@ -67,7 +67,7 @@ gbt_numeric_lt(const void *a, const void *b, Oid collation)
 }
 
 static int32
-gbt_numeric_cmp(const void *a, const void *b, Oid collation)
+gbt_numeric_cmp(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetInt32(DirectFunctionCall2(numeric_cmp,
 											 PointerGetDatum(a),
@@ -122,7 +122,7 @@ gbt_numeric_consistent(PG_FUNCTION_ARGS)
 	*recheck = false;
 
 	retval = gbt_var_consistent(&r, query, strategy, PG_GET_COLLATION(),
-								GIST_LEAF(entry), &tinfo);
+								GIST_LEAF(entry), &tinfo, fcinfo->flinfo);
 	PG_RETURN_BOOL(retval);
 }
 
@@ -135,7 +135,7 @@ gbt_numeric_union(PG_FUNCTION_ARGS)
 	int32	   *size = (int *) PG_GETARG_POINTER(1);
 
 	PG_RETURN_POINTER(gbt_var_union(entryvec, size, PG_GET_COLLATION(),
-									&tinfo));
+									&tinfo, fcinfo->flinfo));
 }
 
 
@@ -146,7 +146,7 @@ gbt_numeric_same(PG_FUNCTION_ARGS)
 	Datum		d2 = PG_GETARG_DATUM(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
 
-	*result = gbt_var_same(d1, d2, PG_GET_COLLATION(), &tinfo);
+	*result = gbt_var_same(d1, d2, PG_GET_COLLATION(), &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(result);
 }
 
@@ -171,7 +171,7 @@ gbt_numeric_penalty(PG_FUNCTION_ARGS)
 
 	rk = gbt_var_key_readable(org);
 	uni = PointerGetDatum(gbt_var_key_copy(&rk));
-	gbt_var_bin_union(&uni, newe, PG_GET_COLLATION(), &tinfo);
+	gbt_var_bin_union(&uni, newe, PG_GET_COLLATION(), &tinfo, fcinfo->flinfo);
 	ok = gbt_var_key_readable(org);
 	uk = gbt_var_key_readable((GBT_VARKEY *) DatumGetPointer(uni));
 
@@ -233,6 +233,6 @@ gbt_numeric_picksplit(PG_FUNCTION_ARGS)
 	GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
 
 	gbt_var_picksplit(entryvec, v, PG_GET_COLLATION(),
-					  &tinfo);
+					  &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(v);
 }
diff --git a/contrib/btree_gist/btree_text.c b/contrib/btree_gist/btree_text.c
index 2e00cb6..51fc310 100644
--- a/contrib/btree_gist/btree_text.c
+++ b/contrib/btree_gist/btree_text.c
@@ -23,7 +23,7 @@ PG_FUNCTION_INFO_V1(gbt_text_same);
 /* define for comparison */
 
 static bool
-gbt_textgt(const void *a, const void *b, Oid collation)
+gbt_textgt(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2Coll(text_gt,
 												collation,
@@ -32,7 +32,7 @@ gbt_textgt(const void *a, const void *b, Oid collation)
 }
 
 static bool
-gbt_textge(const void *a, const void *b, Oid collation)
+gbt_textge(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2Coll(text_ge,
 												collation,
@@ -41,7 +41,7 @@ gbt_textge(const void *a, const void *b, Oid collation)
 }
 
 static bool
-gbt_texteq(const void *a, const void *b, Oid collation)
+gbt_texteq(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2Coll(texteq,
 												collation,
@@ -50,7 +50,7 @@ gbt_texteq(const void *a, const void *b, Oid collation)
 }
 
 static bool
-gbt_textle(const void *a, const void *b, Oid collation)
+gbt_textle(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2Coll(text_le,
 												collation,
@@ -59,7 +59,7 @@ gbt_textle(const void *a, const void *b, Oid collation)
 }
 
 static bool
-gbt_textlt(const void *a, const void *b, Oid collation)
+gbt_textlt(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2Coll(text_lt,
 												collation,
@@ -68,7 +68,7 @@ gbt_textlt(const void *a, const void *b, Oid collation)
 }
 
 static int32
-gbt_textcmp(const void *a, const void *b, Oid collation)
+gbt_textcmp(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetInt32(DirectFunctionCall2Coll(bttextcmp,
 												 collation,
@@ -161,7 +161,7 @@ gbt_text_consistent(PG_FUNCTION_ARGS)
 	}
 
 	retval = gbt_var_consistent(&r, query, strategy, PG_GET_COLLATION(),
-								GIST_LEAF(entry), &tinfo);
+								GIST_LEAF(entry), &tinfo, fcinfo->flinfo);
 
 	PG_RETURN_BOOL(retval);
 }
@@ -190,7 +190,7 @@ gbt_bpchar_consistent(PG_FUNCTION_ARGS)
 	}
 
 	retval = gbt_var_consistent(&r, trim, strategy, PG_GET_COLLATION(),
-								GIST_LEAF(entry), &tinfo);
+								GIST_LEAF(entry), &tinfo, fcinfo->flinfo);
 	PG_RETURN_BOOL(retval);
 }
 
@@ -202,7 +202,7 @@ gbt_text_union(PG_FUNCTION_ARGS)
 	int32	   *size = (int *) PG_GETARG_POINTER(1);
 
 	PG_RETURN_POINTER(gbt_var_union(entryvec, size, PG_GET_COLLATION(),
-									&tinfo));
+									&tinfo, fcinfo->flinfo));
 }
 
 
@@ -213,7 +213,7 @@ gbt_text_picksplit(PG_FUNCTION_ARGS)
 	GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
 
 	gbt_var_picksplit(entryvec, v, PG_GET_COLLATION(),
-					  &tinfo);
+					  &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(v);
 }
 
@@ -224,7 +224,7 @@ gbt_text_same(PG_FUNCTION_ARGS)
 	Datum		d2 = PG_GETARG_DATUM(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
 
-	*result = gbt_var_same(d1, d2, PG_GET_COLLATION(), &tinfo);
+	*result = gbt_var_same(d1, d2, PG_GET_COLLATION(), &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(result);
 }
 
@@ -237,5 +237,5 @@ gbt_text_penalty(PG_FUNCTION_ARGS)
 	float	   *result = (float *) PG_GETARG_POINTER(2);
 
 	PG_RETURN_POINTER(gbt_var_penalty(result, o, n, PG_GET_COLLATION(),
-									  &tinfo));
+									  &tinfo, fcinfo->flinfo));
 }
diff --git a/contrib/btree_gist/btree_utils_var.c b/contrib/btree_gist/btree_utils_var.c
index 70b3794..16de893 100644
--- a/contrib/btree_gist/btree_utils_var.c
+++ b/contrib/btree_gist/btree_utils_var.c
@@ -25,6 +25,7 @@ typedef struct
 {
 	const gbtree_vinfo *tinfo;
 	Oid			collation;
+	FmgrInfo *flinfo;
 } gbt_vsrt_arg;
 
 
@@ -103,12 +104,12 @@ gbt_var_key_copy(const GBT_VARKEY_R *u)
 
 
 static GBT_VARKEY *
-gbt_var_leaf2node(GBT_VARKEY *leaf, const gbtree_vinfo *tinfo)
+gbt_var_leaf2node(GBT_VARKEY *leaf, const gbtree_vinfo *tinfo, FmgrInfo *flinfo)
 {
 	GBT_VARKEY *out = leaf;
 
 	if (tinfo->f_l2n)
-		out = (*tinfo->f_l2n) (leaf);
+		out = (*tinfo->f_l2n) (leaf, flinfo);
 
 	return out;
 }
@@ -232,7 +233,7 @@ gbt_var_node_truncate(const GBT_VARKEY *node, int32 cpf_length, const gbtree_vin
 
 void
 gbt_var_bin_union(Datum *u, GBT_VARKEY *e, Oid collation,
-				  const gbtree_vinfo *tinfo)
+				  const gbtree_vinfo *tinfo, FmgrInfo *flinfo)
 {
 	GBT_VARKEY_R eo = gbt_var_key_readable(e);
 	GBT_VARKEY_R nr;
@@ -241,7 +242,7 @@ gbt_var_bin_union(Datum *u, GBT_VARKEY *e, Oid collation,
 	{
 		GBT_VARKEY *tmp;
 
-		tmp = gbt_var_leaf2node(e, tinfo);
+		tmp = gbt_var_leaf2node(e, tinfo, flinfo);
 		if (tmp != e)
 			eo = gbt_var_key_readable(tmp);
 	}
@@ -254,13 +255,13 @@ gbt_var_bin_union(Datum *u, GBT_VARKEY *e, Oid collation,
 		nr.lower = ro.lower;
 		nr.upper = ro.upper;
 
-		if ((*tinfo->f_cmp) (ro.lower, eo.lower, collation) > 0)
+		if ((*tinfo->f_cmp) (ro.lower, eo.lower, flinfo, collation) > 0)
 		{
 			nr.lower = eo.lower;
 			update = true;
 		}
 
-		if ((*tinfo->f_cmp) (ro.upper, eo.upper, collation) < 0)
+		if ((*tinfo->f_cmp) (ro.upper, eo.upper, flinfo, collation) < 0)
 		{
 			nr.upper = eo.upper;
 			update = true;
@@ -321,7 +322,7 @@ gbt_var_fetch(PG_FUNCTION_ARGS)
 
 GBT_VARKEY *
 gbt_var_union(const GistEntryVector *entryvec, int32 *size, Oid collation,
-			  const gbtree_vinfo *tinfo)
+			  const gbtree_vinfo *tinfo, FmgrInfo *flinfo)
 {
 	int			i = 0,
 				numranges = entryvec->n;
@@ -338,7 +339,7 @@ gbt_var_union(const GistEntryVector *entryvec, int32 *size, Oid collation,
 	for (i = 1; i < numranges; i++)
 	{
 		cur = (GBT_VARKEY *) DatumGetPointer(entryvec->vector[i].key);
-		gbt_var_bin_union(&out, cur, collation, tinfo);
+		gbt_var_bin_union(&out, cur, collation, tinfo, flinfo);
 	}
 
 
@@ -360,7 +361,7 @@ gbt_var_union(const GistEntryVector *entryvec, int32 *size, Oid collation,
 
 bool
 gbt_var_same(Datum d1, Datum d2, Oid collation,
-			 const gbtree_vinfo *tinfo)
+			 const gbtree_vinfo *tinfo, FmgrInfo *flinfo)
 {
 	GBT_VARKEY *t1 = (GBT_VARKEY *) DatumGetPointer(d1);
 	GBT_VARKEY *t2 = (GBT_VARKEY *) DatumGetPointer(d2);
@@ -370,14 +371,14 @@ gbt_var_same(Datum d1, Datum d2, Oid collation,
 	r1 = gbt_var_key_readable(t1);
 	r2 = gbt_var_key_readable(t2);
 
-	return ((*tinfo->f_cmp) (r1.lower, r2.lower, collation) == 0 &&
-			(*tinfo->f_cmp) (r1.upper, r2.upper, collation) == 0);
+	return ((*tinfo->f_cmp) (r1.lower, r2.lower, flinfo, collation) == 0 &&
+			(*tinfo->f_cmp) (r1.upper, r2.upper, flinfo, collation) == 0);
 }
 
 
 float *
 gbt_var_penalty(float *res, const GISTENTRY *o, const GISTENTRY *n,
-				Oid collation, const gbtree_vinfo *tinfo)
+				Oid collation, const gbtree_vinfo *tinfo, FmgrInfo *flinfo)
 {
 	GBT_VARKEY *orge = (GBT_VARKEY *) DatumGetPointer(o->key);
 	GBT_VARKEY *newe = (GBT_VARKEY *) DatumGetPointer(n->key);
@@ -391,7 +392,7 @@ gbt_var_penalty(float *res, const GISTENTRY *o, const GISTENTRY *n,
 	{
 		GBT_VARKEY *tmp;
 
-		tmp = gbt_var_leaf2node(newe, tinfo);
+		tmp = gbt_var_leaf2node(newe, tinfo, flinfo);
 		if (tmp != newe)
 			nk = gbt_var_key_readable(tmp);
 	}
@@ -399,9 +400,9 @@ gbt_var_penalty(float *res, const GISTENTRY *o, const GISTENTRY *n,
 
 	if ((VARSIZE(ok.lower) - VARHDRSZ) == 0 && (VARSIZE(ok.upper) - VARHDRSZ) == 0)
 		*res = 0.0;
-	else if (!(((*tinfo->f_cmp) (nk.lower, ok.lower, collation) >= 0 ||
+	else if (!(((*tinfo->f_cmp) (nk.lower, ok.lower, flinfo, collation) >= 0 ||
 				gbt_bytea_pf_match(ok.lower, nk.lower, tinfo)) &&
-			   ((*tinfo->f_cmp) (nk.upper, ok.upper, collation) <= 0 ||
+			   ((*tinfo->f_cmp) (nk.upper, ok.upper, flinfo, collation) <= 0 ||
 				gbt_bytea_pf_match(ok.upper, nk.upper, tinfo))))
 	{
 		Datum		d = PointerGetDatum(0);
@@ -409,9 +410,9 @@ gbt_var_penalty(float *res, const GISTENTRY *o, const GISTENTRY *n,
 		int32		ol,
 					ul;
 
-		gbt_var_bin_union(&d, orge, collation, tinfo);
+		gbt_var_bin_union(&d, orge, collation, tinfo, flinfo);
 		ol = gbt_var_node_cp_len((GBT_VARKEY *) DatumGetPointer(d), tinfo);
-		gbt_var_bin_union(&d, newe, collation, tinfo);
+		gbt_var_bin_union(&d, newe, collation, tinfo, flinfo);
 		ul = gbt_var_node_cp_len((GBT_VARKEY *) DatumGetPointer(d), tinfo);
 
 		if (ul < ol)
@@ -448,16 +449,16 @@ gbt_vsrt_cmp(const void *a, const void *b, void *arg)
 	const gbt_vsrt_arg *varg = (const gbt_vsrt_arg *) arg;
 	int			res;
 
-	res = (*varg->tinfo->f_cmp) (ar.lower, br.lower, varg->collation);
+	res = (*varg->tinfo->f_cmp) (ar.lower, br.lower, varg->flinfo, varg->collation);
 	if (res == 0)
-		return (*varg->tinfo->f_cmp) (ar.upper, br.upper, varg->collation);
+		return (*varg->tinfo->f_cmp) (ar.upper, br.upper, varg->flinfo, varg->collation);
 
 	return res;
 }
 
 GIST_SPLITVEC *
 gbt_var_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v,
-				  Oid collation, const gbtree_vinfo *tinfo)
+				  Oid collation, const gbtree_vinfo *tinfo, FmgrInfo *flinfo)
 {
 	OffsetNumber i,
 				maxoff = entryvec->n - 1;
@@ -489,7 +490,7 @@ gbt_var_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v,
 		ro = gbt_var_key_readable((GBT_VARKEY *) cur);
 		if (ro.lower == ro.upper)		/* leaf */
 		{
-			sv[svcntr] = gbt_var_leaf2node((GBT_VARKEY *) cur, tinfo);
+			sv[svcntr] = gbt_var_leaf2node((GBT_VARKEY *) cur, tinfo, flinfo);
 			arr[i].t = sv[svcntr];
 			if (sv[svcntr] != (GBT_VARKEY *) cur)
 				svcntr++;
@@ -502,6 +503,7 @@ gbt_var_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v,
 	/* sort */
 	varg.tinfo = tinfo;
 	varg.collation = collation;
+	varg.flinfo = flinfo;
 	qsort_arg((void *) &arr[FirstOffsetNumber],
 			  maxoff - FirstOffsetNumber + 1,
 			  sizeof(Vsrt),
@@ -514,13 +516,13 @@ gbt_var_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v,
 	{
 		if (i <= (maxoff - FirstOffsetNumber + 1) / 2)
 		{
-			gbt_var_bin_union(&v->spl_ldatum, arr[i].t, collation, tinfo);
+			gbt_var_bin_union(&v->spl_ldatum, arr[i].t, collation, tinfo, flinfo);
 			v->spl_left[v->spl_nleft] = arr[i].i;
 			v->spl_nleft++;
 		}
 		else
 		{
-			gbt_var_bin_union(&v->spl_rdatum, arr[i].t, collation, tinfo);
+			gbt_var_bin_union(&v->spl_rdatum, arr[i].t, collation, tinfo, flinfo);
 			v->spl_right[v->spl_nright] = arr[i].i;
 			v->spl_nright++;
 		}
@@ -556,7 +558,8 @@ gbt_var_consistent(GBT_VARKEY_R *key,
 				   StrategyNumber strategy,
 				   Oid collation,
 				   bool is_leaf,
-				   const gbtree_vinfo *tinfo)
+				   const gbtree_vinfo *tinfo,
+				   FmgrInfo *flinfo)
 {
 	bool		retval = FALSE;
 
@@ -564,44 +567,44 @@ gbt_var_consistent(GBT_VARKEY_R *key,
 	{
 		case BTLessEqualStrategyNumber:
 			if (is_leaf)
-				retval = (*tinfo->f_ge) (query, key->lower, collation);
+				retval = (*tinfo->f_ge) (query, key->lower, flinfo, collation);
 			else
-				retval = (*tinfo->f_cmp) (query, key->lower, collation) >= 0
+				retval = (*tinfo->f_cmp) (query, key->lower, flinfo, collation) >= 0
 					|| gbt_var_node_pf_match(key, query, tinfo);
 			break;
 		case BTLessStrategyNumber:
 			if (is_leaf)
-				retval = (*tinfo->f_gt) (query, key->lower, collation);
+				retval = (*tinfo->f_gt) (query, key->lower, flinfo, collation);
 			else
-				retval = (*tinfo->f_cmp) (query, key->lower, collation) >= 0
+				retval = (*tinfo->f_cmp) (query, key->lower, flinfo, collation) >= 0
 					|| gbt_var_node_pf_match(key, query, tinfo);
 			break;
 		case BTEqualStrategyNumber:
 			if (is_leaf)
-				retval = (*tinfo->f_eq) (query, key->lower, collation);
+				retval = (*tinfo->f_eq) (query, key->lower, flinfo, collation);
 			else
 				retval =
-					((*tinfo->f_cmp) (key->lower, query, collation) <= 0 &&
-					 (*tinfo->f_cmp) (query, key->upper, collation) <= 0) ||
+					((*tinfo->f_cmp) (key->lower, query, flinfo, collation) <= 0 &&
+					 (*tinfo->f_cmp) (query, key->upper, flinfo, collation) <= 0) ||
 					gbt_var_node_pf_match(key, query, tinfo);
 			break;
 		case BTGreaterStrategyNumber:
 			if (is_leaf)
-				retval = (*tinfo->f_lt) (query, key->upper, collation);
+				retval = (*tinfo->f_lt) (query, key->upper, flinfo, collation);
 			else
-				retval = (*tinfo->f_cmp) (query, key->upper, collation) <= 0
+				retval = (*tinfo->f_cmp) (query, key->upper, flinfo, collation) <= 0
 					|| gbt_var_node_pf_match(key, query, tinfo);
 			break;
 		case BTGreaterEqualStrategyNumber:
 			if (is_leaf)
-				retval = (*tinfo->f_le) (query, key->upper, collation);
+				retval = (*tinfo->f_le) (query, key->upper, flinfo, collation);
 			else
-				retval = (*tinfo->f_cmp) (query, key->upper, collation) <= 0
+				retval = (*tinfo->f_cmp) (query, key->upper, flinfo, collation) <= 0
 					|| gbt_var_node_pf_match(key, query, tinfo);
 			break;
 		case BtreeGistNotEqualStrategyNumber:
-			retval = !((*tinfo->f_eq) (query, key->lower, collation) &&
-					   (*tinfo->f_eq) (query, key->upper, collation));
+			retval = !((*tinfo->f_eq) (query, key->lower, flinfo, collation) &&
+					   (*tinfo->f_eq) (query, key->upper, flinfo, collation));
 			break;
 		default:
 			retval = FALSE;
diff --git a/contrib/btree_gist/btree_utils_var.h b/contrib/btree_gist/btree_utils_var.h
index 9a7c4d1..7c9ffaf 100644
--- a/contrib/btree_gist/btree_utils_var.h
+++ b/contrib/btree_gist/btree_utils_var.h
@@ -34,13 +34,13 @@ typedef struct
 
 	/* Methods */
 
-	bool		(*f_gt) (const void *, const void *, Oid);		/* greater than */
-	bool		(*f_ge) (const void *, const void *, Oid);		/* greater equal */
-	bool		(*f_eq) (const void *, const void *, Oid);		/* equal */
-	bool		(*f_le) (const void *, const void *, Oid);		/* less equal */
-	bool		(*f_lt) (const void *, const void *, Oid);		/* less than */
-	int32		(*f_cmp) (const void *, const void *, Oid);		/* compare */
-	GBT_VARKEY *(*f_l2n) (GBT_VARKEY *);		/* convert leaf to node */
+	bool		(*f_gt) (const void *, const void *, FmgrInfo *flinfo, Oid);		/* greater than */
+	bool		(*f_ge) (const void *, const void *, FmgrInfo *flinfo, Oid);		/* greater equal */
+	bool		(*f_eq) (const void *, const void *, FmgrInfo *flinfo, Oid);		/* equal */
+	bool		(*f_le) (const void *, const void *, FmgrInfo *flinfo, Oid);		/* less equal */
+	bool		(*f_lt) (const void *, const void *, FmgrInfo *flinfo, Oid);		/* less than */
+	int32		(*f_cmp) (const void *, const void *, FmgrInfo *flinfo, Oid);		/* compare */
+	GBT_VARKEY *(*f_l2n) (GBT_VARKEY *, FmgrInfo *flinfo);		/* convert leaf to node */
 } gbtree_vinfo;
 
 
@@ -52,22 +52,22 @@ extern GBT_VARKEY *gbt_var_key_copy(const GBT_VARKEY_R *u);
 extern GISTENTRY *gbt_var_compress(GISTENTRY *entry, const gbtree_vinfo *tinfo);
 
 extern GBT_VARKEY *gbt_var_union(const GistEntryVector *entryvec, int32 *size,
-			  Oid collation, const gbtree_vinfo *tinfo);
+			  Oid collation, const gbtree_vinfo *tinfo, FmgrInfo *flinfo);
 
 extern bool gbt_var_same(Datum d1, Datum d2, Oid collation,
-			 const gbtree_vinfo *tinfo);
+			 const gbtree_vinfo *tinfo, FmgrInfo *flinfo);
 
 extern float *gbt_var_penalty(float *res, const GISTENTRY *o, const GISTENTRY *n,
-				Oid collation, const gbtree_vinfo *tinfo);
+				Oid collation, const gbtree_vinfo *tinfo, FmgrInfo *flinfo);
 
 extern bool gbt_var_consistent(GBT_VARKEY_R *key, const void *query,
 				   StrategyNumber strategy, Oid collation, bool is_leaf,
-				   const gbtree_vinfo *tinfo);
+				   const gbtree_vinfo *tinfo, FmgrInfo *flinfo);
 
 extern GIST_SPLITVEC *gbt_var_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v,
-				  Oid collation, const gbtree_vinfo *tinfo);
+				  Oid collation, const gbtree_vinfo *tinfo, FmgrInfo *flinfo);
 
 extern void gbt_var_bin_union(Datum *u, GBT_VARKEY *e, Oid collation,
-				  const gbtree_vinfo *tinfo);
+				  const gbtree_vinfo *tinfo, FmgrInfo *flinfo);
 
 #endif
-- 
2.4.11

0002-CallerFInfoFunctionCall-support-for-btree_gist-non-varlena-types.patchtext/x-diff; name=0002-CallerFInfoFunctionCall-support-for-btree_gist-non-varlena-types.patchDownload
From 0926e40bea4e6b5b4f07578f38f6c5026887f28f Mon Sep 17 00:00:00 2001
From: Andrew Dunstan <andrew@dunslane.net>
Date: Sun, 26 Feb 2017 16:58:01 -0500
Subject: [PATCH 2/4] Allow use of CallerFInfoFunctionCall with btree_gist for
 numeric types

None of the existing types actually need to use this mechanism, but this
will allow support for enum types which will need it. A separate patch
will adjust the varlena types support for consistency.
---
 contrib/btree_gist/btree_cash.c      | 24 +++++++--------
 contrib/btree_gist/btree_date.c      | 24 +++++++--------
 contrib/btree_gist/btree_float4.c    | 24 +++++++--------
 contrib/btree_gist/btree_float8.c    | 24 +++++++--------
 contrib/btree_gist/btree_inet.c      | 20 ++++++------
 contrib/btree_gist/btree_int2.c      | 24 +++++++--------
 contrib/btree_gist/btree_int4.c      | 24 +++++++--------
 contrib/btree_gist/btree_int8.c      | 24 +++++++--------
 contrib/btree_gist/btree_interval.c  | 24 +++++++--------
 contrib/btree_gist/btree_macaddr.c   | 20 ++++++------
 contrib/btree_gist/btree_oid.c       | 24 +++++++--------
 contrib/btree_gist/btree_time.c      | 26 ++++++++--------
 contrib/btree_gist/btree_ts.c        | 28 ++++++++---------
 contrib/btree_gist/btree_utils_num.c | 60 +++++++++++++++++++-----------------
 contrib/btree_gist/btree_utils_num.h | 26 ++++++++--------
 contrib/btree_gist/btree_uuid.c      | 20 ++++++------
 16 files changed, 209 insertions(+), 207 deletions(-)

diff --git a/contrib/btree_gist/btree_cash.c b/contrib/btree_gist/btree_cash.c
index aa14735..ca0c86b 100644
--- a/contrib/btree_gist/btree_cash.c
+++ b/contrib/btree_gist/btree_cash.c
@@ -26,33 +26,33 @@ PG_FUNCTION_INFO_V1(gbt_cash_penalty);
 PG_FUNCTION_INFO_V1(gbt_cash_same);
 
 static bool
-gbt_cashgt(const void *a, const void *b)
+gbt_cashgt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const Cash *) a) > *((const Cash *) b));
 }
 static bool
-gbt_cashge(const void *a, const void *b)
+gbt_cashge(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const Cash *) a) >= *((const Cash *) b));
 }
 static bool
-gbt_casheq(const void *a, const void *b)
+gbt_casheq(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const Cash *) a) == *((const Cash *) b));
 }
 static bool
-gbt_cashle(const void *a, const void *b)
+gbt_cashle(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const Cash *) a) <= *((const Cash *) b));
 }
 static bool
-gbt_cashlt(const void *a, const void *b)
+gbt_cashlt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const Cash *) a) < *((const Cash *) b));
 }
 
 static int
-gbt_cashkey_cmp(const void *a, const void *b)
+gbt_cashkey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	cashKEY    *ia = (cashKEY *) (((const Nsrt *) a)->t);
 	cashKEY    *ib = (cashKEY *) (((const Nsrt *) b)->t);
@@ -69,7 +69,7 @@ gbt_cashkey_cmp(const void *a, const void *b)
 }
 
 static float8
-gbt_cash_dist(const void *a, const void *b)
+gbt_cash_dist(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return GET_FLOAT_DISTANCE(Cash, a, b);
 }
@@ -151,7 +151,7 @@ gbt_cash_consistent(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_BOOL(
-				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo)
+				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -170,7 +170,7 @@ gbt_cash_distance(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_FLOAT8(
-			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo)
+			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -182,7 +182,7 @@ gbt_cash_union(PG_FUNCTION_ARGS)
 	void	   *out = palloc(sizeof(cashKEY));
 
 	*(int *) PG_GETARG_POINTER(1) = sizeof(cashKEY);
-	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
+	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
 }
 
 
@@ -205,7 +205,7 @@ gbt_cash_picksplit(PG_FUNCTION_ARGS)
 	PG_RETURN_POINTER(gbt_num_picksplit(
 									(GistEntryVector *) PG_GETARG_POINTER(0),
 									  (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
-										&tinfo
+										&tinfo, fcinfo->flinfo
 										));
 }
 
@@ -216,6 +216,6 @@ gbt_cash_same(PG_FUNCTION_ARGS)
 	cashKEY    *b2 = (cashKEY *) PG_GETARG_POINTER(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
 
-	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
+	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(result);
 }
diff --git a/contrib/btree_gist/btree_date.c b/contrib/btree_gist/btree_date.c
index 56031d4..c9daf34 100644
--- a/contrib/btree_gist/btree_date.c
+++ b/contrib/btree_gist/btree_date.c
@@ -27,7 +27,7 @@ PG_FUNCTION_INFO_V1(gbt_date_penalty);
 PG_FUNCTION_INFO_V1(gbt_date_same);
 
 static bool
-gbt_dategt(const void *a, const void *b)
+gbt_dategt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(
 						DirectFunctionCall2(date_gt, DateADTGetDatum(*((const DateADT *) a)), DateADTGetDatum(*((const DateADT *) b)))
@@ -35,7 +35,7 @@ gbt_dategt(const void *a, const void *b)
 }
 
 static bool
-gbt_datege(const void *a, const void *b)
+gbt_datege(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(
 						DirectFunctionCall2(date_ge, DateADTGetDatum(*((const DateADT *) a)), DateADTGetDatum(*((const DateADT *) b)))
@@ -43,7 +43,7 @@ gbt_datege(const void *a, const void *b)
 }
 
 static bool
-gbt_dateeq(const void *a, const void *b)
+gbt_dateeq(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(
 						DirectFunctionCall2(date_eq, DateADTGetDatum(*((const DateADT *) a)), DateADTGetDatum(*((const DateADT *) b)))
@@ -51,7 +51,7 @@ gbt_dateeq(const void *a, const void *b)
 }
 
 static bool
-gbt_datele(const void *a, const void *b)
+gbt_datele(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(
 						DirectFunctionCall2(date_le, DateADTGetDatum(*((const DateADT *) a)), DateADTGetDatum(*((const DateADT *) b)))
@@ -59,7 +59,7 @@ gbt_datele(const void *a, const void *b)
 }
 
 static bool
-gbt_datelt(const void *a, const void *b)
+gbt_datelt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(
 						DirectFunctionCall2(date_lt, DateADTGetDatum(*((const DateADT *) a)), DateADTGetDatum(*((const DateADT *) b)))
@@ -69,7 +69,7 @@ gbt_datelt(const void *a, const void *b)
 
 
 static int
-gbt_datekey_cmp(const void *a, const void *b)
+gbt_datekey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	dateKEY    *ia = (dateKEY *) (((const Nsrt *) a)->t);
 	dateKEY    *ib = (dateKEY *) (((const Nsrt *) b)->t);
@@ -83,7 +83,7 @@ gbt_datekey_cmp(const void *a, const void *b)
 }
 
 static float8
-gdb_date_dist(const void *a, const void *b)
+gdb_date_dist(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	/* we assume the difference can't overflow */
 	Datum		diff = DirectFunctionCall2(date_mi,
@@ -163,7 +163,7 @@ gbt_date_consistent(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_BOOL(
-				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo)
+				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -182,7 +182,7 @@ gbt_date_distance(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_FLOAT8(
-			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo)
+			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -194,7 +194,7 @@ gbt_date_union(PG_FUNCTION_ARGS)
 	void	   *out = palloc(sizeof(dateKEY));
 
 	*(int *) PG_GETARG_POINTER(1) = sizeof(dateKEY);
-	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
+	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
 }
 
 
@@ -244,7 +244,7 @@ gbt_date_picksplit(PG_FUNCTION_ARGS)
 	PG_RETURN_POINTER(gbt_num_picksplit(
 									(GistEntryVector *) PG_GETARG_POINTER(0),
 									  (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
-										&tinfo
+										&tinfo, fcinfo->flinfo
 										));
 }
 
@@ -255,6 +255,6 @@ gbt_date_same(PG_FUNCTION_ARGS)
 	dateKEY    *b2 = (dateKEY *) PG_GETARG_POINTER(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
 
-	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
+	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(result);
 }
diff --git a/contrib/btree_gist/btree_float4.c b/contrib/btree_gist/btree_float4.c
index 13dc4a5..46b3edb 100644
--- a/contrib/btree_gist/btree_float4.c
+++ b/contrib/btree_gist/btree_float4.c
@@ -25,33 +25,33 @@ PG_FUNCTION_INFO_V1(gbt_float4_penalty);
 PG_FUNCTION_INFO_V1(gbt_float4_same);
 
 static bool
-gbt_float4gt(const void *a, const void *b)
+gbt_float4gt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const float4 *) a) > *((const float4 *) b));
 }
 static bool
-gbt_float4ge(const void *a, const void *b)
+gbt_float4ge(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const float4 *) a) >= *((const float4 *) b));
 }
 static bool
-gbt_float4eq(const void *a, const void *b)
+gbt_float4eq(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const float4 *) a) == *((const float4 *) b));
 }
 static bool
-gbt_float4le(const void *a, const void *b)
+gbt_float4le(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const float4 *) a) <= *((const float4 *) b));
 }
 static bool
-gbt_float4lt(const void *a, const void *b)
+gbt_float4lt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const float4 *) a) < *((const float4 *) b));
 }
 
 static int
-gbt_float4key_cmp(const void *a, const void *b)
+gbt_float4key_cmp(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	float4KEY  *ia = (float4KEY *) (((const Nsrt *) a)->t);
 	float4KEY  *ib = (float4KEY *) (((const Nsrt *) b)->t);
@@ -68,7 +68,7 @@ gbt_float4key_cmp(const void *a, const void *b)
 }
 
 static float8
-gbt_float4_dist(const void *a, const void *b)
+gbt_float4_dist(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return GET_FLOAT_DISTANCE(float4, a, b);
 }
@@ -144,7 +144,7 @@ gbt_float4_consistent(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_BOOL(
-				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo)
+				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -163,7 +163,7 @@ gbt_float4_distance(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_FLOAT8(
-			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo)
+			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -175,7 +175,7 @@ gbt_float4_union(PG_FUNCTION_ARGS)
 	void	   *out = palloc(sizeof(float4KEY));
 
 	*(int *) PG_GETARG_POINTER(1) = sizeof(float4KEY);
-	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
+	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
 }
 
 
@@ -198,7 +198,7 @@ gbt_float4_picksplit(PG_FUNCTION_ARGS)
 	PG_RETURN_POINTER(gbt_num_picksplit(
 									(GistEntryVector *) PG_GETARG_POINTER(0),
 									  (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
-										&tinfo
+										&tinfo, fcinfo->flinfo
 										));
 }
 
@@ -209,6 +209,6 @@ gbt_float4_same(PG_FUNCTION_ARGS)
 	float4KEY  *b2 = (float4KEY *) PG_GETARG_POINTER(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
 
-	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
+	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(result);
 }
diff --git a/contrib/btree_gist/btree_float8.c b/contrib/btree_gist/btree_float8.c
index c3a2415..7d65307 100644
--- a/contrib/btree_gist/btree_float8.c
+++ b/contrib/btree_gist/btree_float8.c
@@ -26,33 +26,33 @@ PG_FUNCTION_INFO_V1(gbt_float8_same);
 
 
 static bool
-gbt_float8gt(const void *a, const void *b)
+gbt_float8gt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const float8 *) a) > *((const float8 *) b));
 }
 static bool
-gbt_float8ge(const void *a, const void *b)
+gbt_float8ge(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const float8 *) a) >= *((const float8 *) b));
 }
 static bool
-gbt_float8eq(const void *a, const void *b)
+gbt_float8eq(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const float8 *) a) == *((const float8 *) b));
 }
 static bool
-gbt_float8le(const void *a, const void *b)
+gbt_float8le(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const float8 *) a) <= *((const float8 *) b));
 }
 static bool
-gbt_float8lt(const void *a, const void *b)
+gbt_float8lt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const float8 *) a) < *((const float8 *) b));
 }
 
 static int
-gbt_float8key_cmp(const void *a, const void *b)
+gbt_float8key_cmp(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	float8KEY  *ia = (float8KEY *) (((const Nsrt *) a)->t);
 	float8KEY  *ib = (float8KEY *) (((const Nsrt *) b)->t);
@@ -69,7 +69,7 @@ gbt_float8key_cmp(const void *a, const void *b)
 }
 
 static float8
-gbt_float8_dist(const void *a, const void *b)
+gbt_float8_dist(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	float8		arg1 = *(const float8 *) a;
 	float8		arg2 = *(const float8 *) b;
@@ -151,7 +151,7 @@ gbt_float8_consistent(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_BOOL(
-				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo)
+				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -170,7 +170,7 @@ gbt_float8_distance(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_FLOAT8(
-			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo)
+			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -182,7 +182,7 @@ gbt_float8_union(PG_FUNCTION_ARGS)
 	void	   *out = palloc(sizeof(float8KEY));
 
 	*(int *) PG_GETARG_POINTER(1) = sizeof(float8KEY);
-	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
+	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
 }
 
 
@@ -205,7 +205,7 @@ gbt_float8_picksplit(PG_FUNCTION_ARGS)
 	PG_RETURN_POINTER(gbt_num_picksplit(
 									(GistEntryVector *) PG_GETARG_POINTER(0),
 									  (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
-										&tinfo
+										&tinfo, fcinfo->flinfo
 										));
 }
 
@@ -216,6 +216,6 @@ gbt_float8_same(PG_FUNCTION_ARGS)
 	float8KEY  *b2 = (float8KEY *) PG_GETARG_POINTER(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
 
-	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
+	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(result);
 }
diff --git a/contrib/btree_gist/btree_inet.c b/contrib/btree_gist/btree_inet.c
index 8227861..7c95ee6 100644
--- a/contrib/btree_gist/btree_inet.c
+++ b/contrib/btree_gist/btree_inet.c
@@ -27,33 +27,33 @@ PG_FUNCTION_INFO_V1(gbt_inet_same);
 
 
 static bool
-gbt_inetgt(const void *a, const void *b)
+gbt_inetgt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const double *) a) > *((const double *) b));
 }
 static bool
-gbt_inetge(const void *a, const void *b)
+gbt_inetge(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const double *) a) >= *((const double *) b));
 }
 static bool
-gbt_ineteq(const void *a, const void *b)
+gbt_ineteq(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const double *) a) == *((const double *) b));
 }
 static bool
-gbt_inetle(const void *a, const void *b)
+gbt_inetle(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const double *) a) <= *((const double *) b));
 }
 static bool
-gbt_inetlt(const void *a, const void *b)
+gbt_inetlt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const double *) a) < *((const double *) b));
 }
 
 static int
-gbt_inetkey_cmp(const void *a, const void *b)
+gbt_inetkey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	inetKEY    *ia = (inetKEY *) (((const Nsrt *) a)->t);
 	inetKEY    *ib = (inetKEY *) (((const Nsrt *) b)->t);
@@ -133,7 +133,7 @@ gbt_inet_consistent(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_BOOL(gbt_num_consistent(&key, (void *) &query,
-									  &strategy, GIST_LEAF(entry), &tinfo));
+									  &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo));
 }
 
 
@@ -144,7 +144,7 @@ gbt_inet_union(PG_FUNCTION_ARGS)
 	void	   *out = palloc(sizeof(inetKEY));
 
 	*(int *) PG_GETARG_POINTER(1) = sizeof(inetKEY);
-	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
+	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
 }
 
 
@@ -167,7 +167,7 @@ gbt_inet_picksplit(PG_FUNCTION_ARGS)
 	PG_RETURN_POINTER(gbt_num_picksplit(
 									(GistEntryVector *) PG_GETARG_POINTER(0),
 									  (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
-										&tinfo
+										&tinfo, fcinfo->flinfo
 										));
 }
 
@@ -178,6 +178,6 @@ gbt_inet_same(PG_FUNCTION_ARGS)
 	inetKEY    *b2 = (inetKEY *) PG_GETARG_POINTER(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
 
-	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
+	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(result);
 }
diff --git a/contrib/btree_gist/btree_int2.c b/contrib/btree_gist/btree_int2.c
index 54dc1cc..3dae5e7 100644
--- a/contrib/btree_gist/btree_int2.c
+++ b/contrib/btree_gist/btree_int2.c
@@ -25,33 +25,33 @@ PG_FUNCTION_INFO_V1(gbt_int2_penalty);
 PG_FUNCTION_INFO_V1(gbt_int2_same);
 
 static bool
-gbt_int2gt(const void *a, const void *b)
+gbt_int2gt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const int16 *) a) > *((const int16 *) b));
 }
 static bool
-gbt_int2ge(const void *a, const void *b)
+gbt_int2ge(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const int16 *) a) >= *((const int16 *) b));
 }
 static bool
-gbt_int2eq(const void *a, const void *b)
+gbt_int2eq(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const int16 *) a) == *((const int16 *) b));
 }
 static bool
-gbt_int2le(const void *a, const void *b)
+gbt_int2le(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const int16 *) a) <= *((const int16 *) b));
 }
 static bool
-gbt_int2lt(const void *a, const void *b)
+gbt_int2lt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const int16 *) a) < *((const int16 *) b));
 }
 
 static int
-gbt_int2key_cmp(const void *a, const void *b)
+gbt_int2key_cmp(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	int16KEY   *ia = (int16KEY *) (((const Nsrt *) a)->t);
 	int16KEY   *ib = (int16KEY *) (((const Nsrt *) b)->t);
@@ -68,7 +68,7 @@ gbt_int2key_cmp(const void *a, const void *b)
 }
 
 static float8
-gbt_int2_dist(const void *a, const void *b)
+gbt_int2_dist(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return GET_FLOAT_DISTANCE(int16, a, b);
 }
@@ -151,7 +151,7 @@ gbt_int2_consistent(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_BOOL(
-				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo)
+				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -170,7 +170,7 @@ gbt_int2_distance(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_FLOAT8(
-			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo)
+			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -182,7 +182,7 @@ gbt_int2_union(PG_FUNCTION_ARGS)
 	void	   *out = palloc(sizeof(int16KEY));
 
 	*(int *) PG_GETARG_POINTER(1) = sizeof(int16KEY);
-	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
+	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
 }
 
 
@@ -204,7 +204,7 @@ gbt_int2_picksplit(PG_FUNCTION_ARGS)
 	PG_RETURN_POINTER(gbt_num_picksplit(
 									(GistEntryVector *) PG_GETARG_POINTER(0),
 									  (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
-										&tinfo
+										&tinfo, fcinfo->flinfo
 										));
 }
 
@@ -215,6 +215,6 @@ gbt_int2_same(PG_FUNCTION_ARGS)
 	int16KEY   *b2 = (int16KEY *) PG_GETARG_POINTER(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
 
-	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
+	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(result);
 }
diff --git a/contrib/btree_gist/btree_int4.c b/contrib/btree_gist/btree_int4.c
index ddbcf52..213bfa3 100644
--- a/contrib/btree_gist/btree_int4.c
+++ b/contrib/btree_gist/btree_int4.c
@@ -26,33 +26,33 @@ PG_FUNCTION_INFO_V1(gbt_int4_same);
 
 
 static bool
-gbt_int4gt(const void *a, const void *b)
+gbt_int4gt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const int32 *) a) > *((const int32 *) b));
 }
 static bool
-gbt_int4ge(const void *a, const void *b)
+gbt_int4ge(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const int32 *) a) >= *((const int32 *) b));
 }
 static bool
-gbt_int4eq(const void *a, const void *b)
+gbt_int4eq(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const int32 *) a) == *((const int32 *) b));
 }
 static bool
-gbt_int4le(const void *a, const void *b)
+gbt_int4le(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const int32 *) a) <= *((const int32 *) b));
 }
 static bool
-gbt_int4lt(const void *a, const void *b)
+gbt_int4lt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const int32 *) a) < *((const int32 *) b));
 }
 
 static int
-gbt_int4key_cmp(const void *a, const void *b)
+gbt_int4key_cmp(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	int32KEY   *ia = (int32KEY *) (((const Nsrt *) a)->t);
 	int32KEY   *ib = (int32KEY *) (((const Nsrt *) b)->t);
@@ -69,7 +69,7 @@ gbt_int4key_cmp(const void *a, const void *b)
 }
 
 static float8
-gbt_int4_dist(const void *a, const void *b)
+gbt_int4_dist(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return GET_FLOAT_DISTANCE(int32, a, b);
 }
@@ -152,7 +152,7 @@ gbt_int4_consistent(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_BOOL(
-				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo)
+				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -171,7 +171,7 @@ gbt_int4_distance(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_FLOAT8(
-			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo)
+			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -183,7 +183,7 @@ gbt_int4_union(PG_FUNCTION_ARGS)
 	void	   *out = palloc(sizeof(int32KEY));
 
 	*(int *) PG_GETARG_POINTER(1) = sizeof(int32KEY);
-	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
+	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
 }
 
 
@@ -205,7 +205,7 @@ gbt_int4_picksplit(PG_FUNCTION_ARGS)
 	PG_RETURN_POINTER(gbt_num_picksplit(
 									(GistEntryVector *) PG_GETARG_POINTER(0),
 									  (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
-										&tinfo
+										&tinfo, fcinfo->flinfo
 										));
 }
 
@@ -216,6 +216,6 @@ gbt_int4_same(PG_FUNCTION_ARGS)
 	int32KEY   *b2 = (int32KEY *) PG_GETARG_POINTER(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
 
-	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
+	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(result);
 }
diff --git a/contrib/btree_gist/btree_int8.c b/contrib/btree_gist/btree_int8.c
index 44bf69a..62b079b 100644
--- a/contrib/btree_gist/btree_int8.c
+++ b/contrib/btree_gist/btree_int8.c
@@ -26,33 +26,33 @@ PG_FUNCTION_INFO_V1(gbt_int8_same);
 
 
 static bool
-gbt_int8gt(const void *a, const void *b)
+gbt_int8gt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const int64 *) a) > *((const int64 *) b));
 }
 static bool
-gbt_int8ge(const void *a, const void *b)
+gbt_int8ge(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const int64 *) a) >= *((const int64 *) b));
 }
 static bool
-gbt_int8eq(const void *a, const void *b)
+gbt_int8eq(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const int64 *) a) == *((const int64 *) b));
 }
 static bool
-gbt_int8le(const void *a, const void *b)
+gbt_int8le(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const int64 *) a) <= *((const int64 *) b));
 }
 static bool
-gbt_int8lt(const void *a, const void *b)
+gbt_int8lt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const int64 *) a) < *((const int64 *) b));
 }
 
 static int
-gbt_int8key_cmp(const void *a, const void *b)
+gbt_int8key_cmp(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	int64KEY   *ia = (int64KEY *) (((const Nsrt *) a)->t);
 	int64KEY   *ib = (int64KEY *) (((const Nsrt *) b)->t);
@@ -69,7 +69,7 @@ gbt_int8key_cmp(const void *a, const void *b)
 }
 
 static float8
-gbt_int8_dist(const void *a, const void *b)
+gbt_int8_dist(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return GET_FLOAT_DISTANCE(int64, a, b);
 }
@@ -152,7 +152,7 @@ gbt_int8_consistent(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_BOOL(
-				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo)
+				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -171,7 +171,7 @@ gbt_int8_distance(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_FLOAT8(
-			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo)
+			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -183,7 +183,7 @@ gbt_int8_union(PG_FUNCTION_ARGS)
 	void	   *out = palloc(sizeof(int64KEY));
 
 	*(int *) PG_GETARG_POINTER(1) = sizeof(int64KEY);
-	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
+	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
 }
 
 
@@ -205,7 +205,7 @@ gbt_int8_picksplit(PG_FUNCTION_ARGS)
 	PG_RETURN_POINTER(gbt_num_picksplit(
 									(GistEntryVector *) PG_GETARG_POINTER(0),
 									  (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
-										&tinfo
+										&tinfo, fcinfo->flinfo
 										));
 }
 
@@ -216,6 +216,6 @@ gbt_int8_same(PG_FUNCTION_ARGS)
 	int64KEY   *b2 = (int64KEY *) PG_GETARG_POINTER(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
 
-	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
+	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(result);
 }
diff --git a/contrib/btree_gist/btree_interval.c b/contrib/btree_gist/btree_interval.c
index e5cd0a2..f41f471 100644
--- a/contrib/btree_gist/btree_interval.c
+++ b/contrib/btree_gist/btree_interval.c
@@ -30,37 +30,37 @@ PG_FUNCTION_INFO_V1(gbt_intv_same);
 
 
 static bool
-gbt_intvgt(const void *a, const void *b)
+gbt_intvgt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(DirectFunctionCall2(interval_gt, IntervalPGetDatum(a), IntervalPGetDatum(b)));
 }
 
 static bool
-gbt_intvge(const void *a, const void *b)
+gbt_intvge(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(DirectFunctionCall2(interval_ge, IntervalPGetDatum(a), IntervalPGetDatum(b)));
 }
 
 static bool
-gbt_intveq(const void *a, const void *b)
+gbt_intveq(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(DirectFunctionCall2(interval_eq, IntervalPGetDatum(a), IntervalPGetDatum(b)));
 }
 
 static bool
-gbt_intvle(const void *a, const void *b)
+gbt_intvle(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(DirectFunctionCall2(interval_le, IntervalPGetDatum(a), IntervalPGetDatum(b)));
 }
 
 static bool
-gbt_intvlt(const void *a, const void *b)
+gbt_intvlt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(DirectFunctionCall2(interval_lt, IntervalPGetDatum(a), IntervalPGetDatum(b)));
 }
 
 static int
-gbt_intvkey_cmp(const void *a, const void *b)
+gbt_intvkey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	intvKEY    *ia = (intvKEY *) (((const Nsrt *) a)->t);
 	intvKEY    *ib = (intvKEY *) (((const Nsrt *) b)->t);
@@ -81,7 +81,7 @@ intr2num(const Interval *i)
 }
 
 static float8
-gbt_intv_dist(const void *a, const void *b)
+gbt_intv_dist(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (float8) Abs(intr2num((const Interval *) a) - intr2num((const Interval *) b));
 }
@@ -226,7 +226,7 @@ gbt_intv_consistent(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_BOOL(
-				   gbt_num_consistent(&key, (void *) query, &strategy, GIST_LEAF(entry), &tinfo)
+				   gbt_num_consistent(&key, (void *) query, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -245,7 +245,7 @@ gbt_intv_distance(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_FLOAT8(
-			 gbt_num_distance(&key, (void *) query, GIST_LEAF(entry), &tinfo)
+			 gbt_num_distance(&key, (void *) query, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -257,7 +257,7 @@ gbt_intv_union(PG_FUNCTION_ARGS)
 	void	   *out = palloc(sizeof(intvKEY));
 
 	*(int *) PG_GETARG_POINTER(1) = sizeof(intvKEY);
-	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
+	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
 }
 
 
@@ -287,7 +287,7 @@ gbt_intv_picksplit(PG_FUNCTION_ARGS)
 	PG_RETURN_POINTER(gbt_num_picksplit(
 									(GistEntryVector *) PG_GETARG_POINTER(0),
 									  (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
-										&tinfo
+										&tinfo, fcinfo->flinfo
 										));
 }
 
@@ -298,6 +298,6 @@ gbt_intv_same(PG_FUNCTION_ARGS)
 	intvKEY    *b2 = (intvKEY *) PG_GETARG_POINTER(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
 
-	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
+	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(result);
 }
diff --git a/contrib/btree_gist/btree_macaddr.c b/contrib/btree_gist/btree_macaddr.c
index 87d96c0..d530b4e 100644
--- a/contrib/btree_gist/btree_macaddr.c
+++ b/contrib/btree_gist/btree_macaddr.c
@@ -28,37 +28,37 @@ PG_FUNCTION_INFO_V1(gbt_macad_same);
 
 
 static bool
-gbt_macadgt(const void *a, const void *b)
+gbt_macadgt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(DirectFunctionCall2(macaddr_gt, PointerGetDatum(a), PointerGetDatum(b)));
 }
 static bool
-gbt_macadge(const void *a, const void *b)
+gbt_macadge(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(DirectFunctionCall2(macaddr_ge, PointerGetDatum(a), PointerGetDatum(b)));
 }
 
 static bool
-gbt_macadeq(const void *a, const void *b)
+gbt_macadeq(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(DirectFunctionCall2(macaddr_eq, PointerGetDatum(a), PointerGetDatum(b)));
 }
 
 static bool
-gbt_macadle(const void *a, const void *b)
+gbt_macadle(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(DirectFunctionCall2(macaddr_le, PointerGetDatum(a), PointerGetDatum(b)));
 }
 
 static bool
-gbt_macadlt(const void *a, const void *b)
+gbt_macadlt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(DirectFunctionCall2(macaddr_lt, PointerGetDatum(a), PointerGetDatum(b)));
 }
 
 
 static int
-gbt_macadkey_cmp(const void *a, const void *b)
+gbt_macadkey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	macKEY	   *ia = (macKEY *) (((const Nsrt *) a)->t);
 	macKEY	   *ib = (macKEY *) (((const Nsrt *) b)->t);
@@ -142,7 +142,7 @@ gbt_macad_consistent(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_BOOL(
-				   gbt_num_consistent(&key, (void *) query, &strategy, GIST_LEAF(entry), &tinfo)
+				   gbt_num_consistent(&key, (void *) query, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -154,7 +154,7 @@ gbt_macad_union(PG_FUNCTION_ARGS)
 	void	   *out = palloc0(sizeof(macKEY));
 
 	*(int *) PG_GETARG_POINTER(1) = sizeof(macKEY);
-	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
+	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
 }
 
 
@@ -184,7 +184,7 @@ gbt_macad_picksplit(PG_FUNCTION_ARGS)
 	PG_RETURN_POINTER(gbt_num_picksplit(
 									(GistEntryVector *) PG_GETARG_POINTER(0),
 									  (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
-										&tinfo
+										&tinfo, fcinfo->flinfo
 										));
 }
 
@@ -195,6 +195,6 @@ gbt_macad_same(PG_FUNCTION_ARGS)
 	macKEY	   *b2 = (macKEY *) PG_GETARG_POINTER(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
 
-	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
+	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(result);
 }
diff --git a/contrib/btree_gist/btree_oid.c b/contrib/btree_gist/btree_oid.c
index ac61a76..e588faa 100644
--- a/contrib/btree_gist/btree_oid.c
+++ b/contrib/btree_gist/btree_oid.c
@@ -26,33 +26,33 @@ PG_FUNCTION_INFO_V1(gbt_oid_same);
 
 
 static bool
-gbt_oidgt(const void *a, const void *b)
+gbt_oidgt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const Oid *) a) > *((const Oid *) b));
 }
 static bool
-gbt_oidge(const void *a, const void *b)
+gbt_oidge(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const Oid *) a) >= *((const Oid *) b));
 }
 static bool
-gbt_oideq(const void *a, const void *b)
+gbt_oideq(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const Oid *) a) == *((const Oid *) b));
 }
 static bool
-gbt_oidle(const void *a, const void *b)
+gbt_oidle(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const Oid *) a) <= *((const Oid *) b));
 }
 static bool
-gbt_oidlt(const void *a, const void *b)
+gbt_oidlt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const Oid *) a) < *((const Oid *) b));
 }
 
 static int
-gbt_oidkey_cmp(const void *a, const void *b)
+gbt_oidkey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	oidKEY	   *ia = (oidKEY *) (((const Nsrt *) a)->t);
 	oidKEY	   *ib = (oidKEY *) (((const Nsrt *) b)->t);
@@ -69,7 +69,7 @@ gbt_oidkey_cmp(const void *a, const void *b)
 }
 
 static float8
-gbt_oid_dist(const void *a, const void *b)
+gbt_oid_dist(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	Oid			aa = *(const Oid *) a;
 	Oid			bb = *(const Oid *) b;
@@ -152,7 +152,7 @@ gbt_oid_consistent(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_BOOL(
-				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo)
+				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -171,7 +171,7 @@ gbt_oid_distance(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_FLOAT8(
-			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo)
+			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -183,7 +183,7 @@ gbt_oid_union(PG_FUNCTION_ARGS)
 	void	   *out = palloc(sizeof(oidKEY));
 
 	*(int *) PG_GETARG_POINTER(1) = sizeof(oidKEY);
-	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
+	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
 }
 
 
@@ -205,7 +205,7 @@ gbt_oid_picksplit(PG_FUNCTION_ARGS)
 	PG_RETURN_POINTER(gbt_num_picksplit(
 									(GistEntryVector *) PG_GETARG_POINTER(0),
 									  (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
-										&tinfo
+										&tinfo, fcinfo->flinfo
 										));
 }
 
@@ -216,6 +216,6 @@ gbt_oid_same(PG_FUNCTION_ARGS)
 	oidKEY	   *b2 = (oidKEY *) PG_GETARG_POINTER(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
 
-	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
+	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(result);
 }
diff --git a/contrib/btree_gist/btree_time.c b/contrib/btree_gist/btree_time.c
index 959b282..a4a1ad5 100644
--- a/contrib/btree_gist/btree_time.c
+++ b/contrib/btree_gist/btree_time.c
@@ -38,7 +38,7 @@ PG_FUNCTION_INFO_V1(gbt_time_same);
 
 
 static bool
-gbt_timegt(const void *a, const void *b)
+gbt_timegt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	const TimeADT *aa = (const TimeADT *) a;
 	const TimeADT *bb = (const TimeADT *) b;
@@ -49,7 +49,7 @@ gbt_timegt(const void *a, const void *b)
 }
 
 static bool
-gbt_timege(const void *a, const void *b)
+gbt_timege(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	const TimeADT *aa = (const TimeADT *) a;
 	const TimeADT *bb = (const TimeADT *) b;
@@ -60,7 +60,7 @@ gbt_timege(const void *a, const void *b)
 }
 
 static bool
-gbt_timeeq(const void *a, const void *b)
+gbt_timeeq(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	const TimeADT *aa = (const TimeADT *) a;
 	const TimeADT *bb = (const TimeADT *) b;
@@ -71,7 +71,7 @@ gbt_timeeq(const void *a, const void *b)
 }
 
 static bool
-gbt_timele(const void *a, const void *b)
+gbt_timele(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	const TimeADT *aa = (const TimeADT *) a;
 	const TimeADT *bb = (const TimeADT *) b;
@@ -82,7 +82,7 @@ gbt_timele(const void *a, const void *b)
 }
 
 static bool
-gbt_timelt(const void *a, const void *b)
+gbt_timelt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	const TimeADT *aa = (const TimeADT *) a;
 	const TimeADT *bb = (const TimeADT *) b;
@@ -95,7 +95,7 @@ gbt_timelt(const void *a, const void *b)
 
 
 static int
-gbt_timekey_cmp(const void *a, const void *b)
+gbt_timekey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	timeKEY    *ia = (timeKEY *) (((const Nsrt *) a)->t);
 	timeKEY    *ib = (timeKEY *) (((const Nsrt *) b)->t);
@@ -109,7 +109,7 @@ gbt_timekey_cmp(const void *a, const void *b)
 }
 
 static float8
-gbt_time_dist(const void *a, const void *b)
+gbt_time_dist(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	const TimeADT *aa = (const TimeADT *) a;
 	const TimeADT *bb = (const TimeADT *) b;
@@ -217,7 +217,7 @@ gbt_time_consistent(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_BOOL(
-				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo)
+				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -235,7 +235,7 @@ gbt_time_distance(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_FLOAT8(
-			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo)
+			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -261,7 +261,7 @@ gbt_timetz_consistent(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_BOOL(
-				   gbt_num_consistent(&key, (void *) &qqq, &strategy, GIST_LEAF(entry), &tinfo)
+				   gbt_num_consistent(&key, (void *) &qqq, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -273,7 +273,7 @@ gbt_time_union(PG_FUNCTION_ARGS)
 	void	   *out = palloc(sizeof(timeKEY));
 
 	*(int *) PG_GETARG_POINTER(1) = sizeof(timeKEY);
-	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
+	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
 }
 
 
@@ -326,7 +326,7 @@ gbt_time_picksplit(PG_FUNCTION_ARGS)
 	PG_RETURN_POINTER(gbt_num_picksplit(
 									(GistEntryVector *) PG_GETARG_POINTER(0),
 									  (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
-										&tinfo
+										&tinfo, fcinfo->flinfo
 										));
 }
 
@@ -337,6 +337,6 @@ gbt_time_same(PG_FUNCTION_ARGS)
 	timeKEY    *b2 = (timeKEY *) PG_GETARG_POINTER(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
 
-	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
+	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(result);
 }
diff --git a/contrib/btree_gist/btree_ts.c b/contrib/btree_gist/btree_ts.c
index 97408f5..13bc394 100644
--- a/contrib/btree_gist/btree_ts.c
+++ b/contrib/btree_gist/btree_ts.c
@@ -40,7 +40,7 @@ PG_FUNCTION_INFO_V1(gbt_ts_same);
 
 
 static bool
-gbt_tsgt(const void *a, const void *b)
+gbt_tsgt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	const Timestamp *aa = (const Timestamp *) a;
 	const Timestamp *bb = (const Timestamp *) b;
@@ -51,7 +51,7 @@ gbt_tsgt(const void *a, const void *b)
 }
 
 static bool
-gbt_tsge(const void *a, const void *b)
+gbt_tsge(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	const Timestamp *aa = (const Timestamp *) a;
 	const Timestamp *bb = (const Timestamp *) b;
@@ -62,7 +62,7 @@ gbt_tsge(const void *a, const void *b)
 }
 
 static bool
-gbt_tseq(const void *a, const void *b)
+gbt_tseq(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	const Timestamp *aa = (const Timestamp *) a;
 	const Timestamp *bb = (const Timestamp *) b;
@@ -73,7 +73,7 @@ gbt_tseq(const void *a, const void *b)
 }
 
 static bool
-gbt_tsle(const void *a, const void *b)
+gbt_tsle(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	const Timestamp *aa = (const Timestamp *) a;
 	const Timestamp *bb = (const Timestamp *) b;
@@ -84,7 +84,7 @@ gbt_tsle(const void *a, const void *b)
 }
 
 static bool
-gbt_tslt(const void *a, const void *b)
+gbt_tslt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	const Timestamp *aa = (const Timestamp *) a;
 	const Timestamp *bb = (const Timestamp *) b;
@@ -96,7 +96,7 @@ gbt_tslt(const void *a, const void *b)
 
 
 static int
-gbt_tskey_cmp(const void *a, const void *b)
+gbt_tskey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	tsKEY	   *ia = (tsKEY *) (((const Nsrt *) a)->t);
 	tsKEY	   *ib = (tsKEY *) (((const Nsrt *) b)->t);
@@ -110,7 +110,7 @@ gbt_tskey_cmp(const void *a, const void *b)
 }
 
 static float8
-gbt_ts_dist(const void *a, const void *b)
+gbt_ts_dist(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	const Timestamp *aa = (const Timestamp *) a;
 	const Timestamp *bb = (const Timestamp *) b;
@@ -265,7 +265,7 @@ gbt_ts_consistent(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_BOOL(
-				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo)
+				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -283,7 +283,7 @@ gbt_ts_distance(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_FLOAT8(
-			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo)
+			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -308,7 +308,7 @@ gbt_tstz_consistent(PG_FUNCTION_ARGS)
 	qqq = tstz_to_ts_gmt(query);
 
 	PG_RETURN_BOOL(
-				   gbt_num_consistent(&key, (void *) &qqq, &strategy, GIST_LEAF(entry), &tinfo)
+				   gbt_num_consistent(&key, (void *) &qqq, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -328,7 +328,7 @@ gbt_tstz_distance(PG_FUNCTION_ARGS)
 	qqq = tstz_to_ts_gmt(query);
 
 	PG_RETURN_FLOAT8(
-			  gbt_num_distance(&key, (void *) &qqq, GIST_LEAF(entry), &tinfo)
+			  gbt_num_distance(&key, (void *) &qqq, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -340,7 +340,7 @@ gbt_ts_union(PG_FUNCTION_ARGS)
 	void	   *out = palloc(sizeof(tsKEY));
 
 	*(int *) PG_GETARG_POINTER(1) = sizeof(tsKEY);
-	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
+	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
 }
 
 
@@ -389,7 +389,7 @@ gbt_ts_picksplit(PG_FUNCTION_ARGS)
 	PG_RETURN_POINTER(gbt_num_picksplit(
 									(GistEntryVector *) PG_GETARG_POINTER(0),
 									  (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
-										&tinfo
+										&tinfo, fcinfo->flinfo
 										));
 }
 
@@ -400,6 +400,6 @@ gbt_ts_same(PG_FUNCTION_ARGS)
 	tsKEY	   *b2 = (tsKEY *) PG_GETARG_POINTER(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
 
-	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
+	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(result);
 }
diff --git a/contrib/btree_gist/btree_utils_num.c b/contrib/btree_gist/btree_utils_num.c
index 99cb41f..e30924b 100644
--- a/contrib/btree_gist/btree_utils_num.c
+++ b/contrib/btree_gist/btree_utils_num.c
@@ -159,7 +159,7 @@ gbt_num_fetch(GISTENTRY *entry, const gbtree_ninfo *tinfo)
 */
 
 void *
-gbt_num_union(GBT_NUMKEY *out, const GistEntryVector *entryvec, const gbtree_ninfo *tinfo)
+gbt_num_union(GBT_NUMKEY *out, const GistEntryVector *entryvec, const gbtree_ninfo *tinfo, FmgrInfo *flinfo)
 {
 	int			i,
 				numranges;
@@ -181,9 +181,9 @@ gbt_num_union(GBT_NUMKEY *out, const GistEntryVector *entryvec, const gbtree_nin
 		cur = (GBT_NUMKEY *) DatumGetPointer((entryvec->vector[i].key));
 		c.lower = &cur[0];
 		c.upper = &cur[tinfo->size];
-		if ((*tinfo->f_gt) (o.lower, c.lower))	/* out->lower > cur->lower */
+		if ((*tinfo->f_gt) (o.lower, c.lower, flinfo))	/* out->lower > cur->lower */
 			memcpy((void *) o.lower, (void *) c.lower, tinfo->size);
-		if ((*tinfo->f_lt) (o.upper, c.upper))	/* out->upper < cur->upper */
+		if ((*tinfo->f_lt) (o.upper, c.upper, flinfo))	/* out->upper < cur->upper */
 			memcpy((void *) o.upper, (void *) c.upper, tinfo->size);
 	}
 
@@ -197,7 +197,7 @@ gbt_num_union(GBT_NUMKEY *out, const GistEntryVector *entryvec, const gbtree_nin
 */
 
 bool
-gbt_num_same(const GBT_NUMKEY *a, const GBT_NUMKEY *b, const gbtree_ninfo *tinfo)
+gbt_num_same(const GBT_NUMKEY *a, const GBT_NUMKEY *b, const gbtree_ninfo *tinfo, FmgrInfo *flinfo)
 {
 	GBT_NUMKEY_R b1,
 				b2;
@@ -207,13 +207,13 @@ gbt_num_same(const GBT_NUMKEY *a, const GBT_NUMKEY *b, const gbtree_ninfo *tinfo
 	b2.lower = &(((GBT_NUMKEY *) b)[0]);
 	b2.upper = &(((GBT_NUMKEY *) b)[tinfo->size]);
 
-	return ((*tinfo->f_eq) (b1.lower, b2.lower) &&
-			(*tinfo->f_eq) (b1.upper, b2.upper));
+	return ((*tinfo->f_eq) (b1.lower, b2.lower, flinfo) &&
+			(*tinfo->f_eq) (b1.upper, b2.upper, flinfo));
 }
 
 
 void
-gbt_num_bin_union(Datum *u, GBT_NUMKEY *e, const gbtree_ninfo *tinfo)
+gbt_num_bin_union(Datum *u, GBT_NUMKEY *e, const gbtree_ninfo *tinfo, FmgrInfo *flinfo)
 {
 	GBT_NUMKEY_R rd;
 
@@ -232,9 +232,9 @@ gbt_num_bin_union(Datum *u, GBT_NUMKEY *e, const gbtree_ninfo *tinfo)
 
 		ur.lower = &(((GBT_NUMKEY *) DatumGetPointer(*u))[0]);
 		ur.upper = &(((GBT_NUMKEY *) DatumGetPointer(*u))[tinfo->size]);
-		if ((*tinfo->f_gt) ((void *) ur.lower, (void *) rd.lower))
+		if ((*tinfo->f_gt) ((void *) ur.lower, (void *) rd.lower, flinfo))
 			memcpy((void *) ur.lower, (void *) rd.lower, tinfo->size);
-		if ((*tinfo->f_lt) ((void *) ur.upper, (void *) rd.upper))
+		if ((*tinfo->f_lt) ((void *) ur.upper, (void *) rd.upper, flinfo))
 			memcpy((void *) ur.upper, (void *) rd.upper, tinfo->size);
 	}
 }
@@ -252,39 +252,40 @@ gbt_num_consistent(const GBT_NUMKEY_R *key,
 				   const void *query,
 				   const StrategyNumber *strategy,
 				   bool is_leaf,
-				   const gbtree_ninfo *tinfo)
+				   const gbtree_ninfo *tinfo,
+				   FmgrInfo *flinfo)
 {
 	bool		retval;
 
 	switch (*strategy)
 	{
 		case BTLessEqualStrategyNumber:
-			retval = (*tinfo->f_ge) (query, key->lower);
+			retval = (*tinfo->f_ge) (query, key->lower, flinfo);
 			break;
 		case BTLessStrategyNumber:
 			if (is_leaf)
-				retval = (*tinfo->f_gt) (query, key->lower);
+				retval = (*tinfo->f_gt) (query, key->lower, flinfo);
 			else
-				retval = (*tinfo->f_ge) (query, key->lower);
+				retval = (*tinfo->f_ge) (query, key->lower, flinfo);
 			break;
 		case BTEqualStrategyNumber:
 			if (is_leaf)
-				retval = (*tinfo->f_eq) (query, key->lower);
+				retval = (*tinfo->f_eq) (query, key->lower, flinfo);
 			else
-				retval = ((*tinfo->f_le) (key->lower, query) && (*tinfo->f_le) (query, key->upper)) ? true : false;
+				retval = ((*tinfo->f_le) (key->lower, query, flinfo) && (*tinfo->f_le) (query, key->upper, flinfo)) ? true : false;
 			break;
 		case BTGreaterStrategyNumber:
 			if (is_leaf)
-				retval = (*tinfo->f_lt) (query, key->upper);
+				retval = (*tinfo->f_lt) (query, key->upper, flinfo);
 			else
-				retval = (*tinfo->f_le) (query, key->upper);
+				retval = (*tinfo->f_le) (query, key->upper, flinfo);
 			break;
 		case BTGreaterEqualStrategyNumber:
-			retval = (*tinfo->f_le) (query, key->upper);
+			retval = (*tinfo->f_le) (query, key->upper, flinfo);
 			break;
 		case BtreeGistNotEqualStrategyNumber:
-			retval = (!((*tinfo->f_eq) (query, key->lower) &&
-						(*tinfo->f_eq) (query, key->upper))) ? true : false;
+			retval = (!((*tinfo->f_eq) (query, key->lower, flinfo) &&
+						(*tinfo->f_eq) (query, key->upper, flinfo))) ? true : false;
 			break;
 		default:
 			retval = false;
@@ -302,17 +303,18 @@ float8
 gbt_num_distance(const GBT_NUMKEY_R *key,
 				 const void *query,
 				 bool is_leaf,
-				 const gbtree_ninfo *tinfo)
+				 const gbtree_ninfo *tinfo,
+				 FmgrInfo *flinfo)
 {
 	float8		retval;
 
 	if (tinfo->f_dist == NULL)
 		elog(ERROR, "KNN search is not supported for btree_gist type %d",
 			 (int) tinfo->t);
-	if (tinfo->f_le(query, key->lower))
-		retval = tinfo->f_dist(query, key->lower);
-	else if (tinfo->f_ge(query, key->upper))
-		retval = tinfo->f_dist(query, key->upper);
+	if (tinfo->f_le(query, key->lower, flinfo))
+		retval = tinfo->f_dist(query, key->lower, flinfo);
+	else if (tinfo->f_ge(query, key->upper, flinfo))
+		retval = tinfo->f_dist(query, key->upper, flinfo);
 	else
 		retval = 0.0;
 
@@ -322,7 +324,7 @@ gbt_num_distance(const GBT_NUMKEY_R *key,
 
 GIST_SPLITVEC *
 gbt_num_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v,
-				  const gbtree_ninfo *tinfo)
+				  const gbtree_ninfo *tinfo, FmgrInfo *flinfo)
 {
 	OffsetNumber i,
 				maxoff = entryvec->n - 1;
@@ -345,7 +347,7 @@ gbt_num_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v,
 		arr[i].t = (GBT_NUMKEY *) DatumGetPointer((entryvec->vector[i].key));
 		arr[i].i = i;
 	}
-	qsort((void *) &arr[FirstOffsetNumber], maxoff - FirstOffsetNumber + 1, sizeof(Nsrt), tinfo->f_cmp);
+	qsort_arg((void *) &arr[FirstOffsetNumber], maxoff - FirstOffsetNumber + 1, sizeof(Nsrt), (qsort_arg_comparator) tinfo->f_cmp, (void *) flinfo);
 
 	/* We do simply create two parts */
 
@@ -353,13 +355,13 @@ gbt_num_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v,
 	{
 		if (i <= (maxoff - FirstOffsetNumber + 1) / 2)
 		{
-			gbt_num_bin_union(&v->spl_ldatum, arr[i].t, tinfo);
+			gbt_num_bin_union(&v->spl_ldatum, arr[i].t, tinfo, flinfo);
 			v->spl_left[v->spl_nleft] = arr[i].i;
 			v->spl_nleft++;
 		}
 		else
 		{
-			gbt_num_bin_union(&v->spl_rdatum, arr[i].t, tinfo);
+			gbt_num_bin_union(&v->spl_rdatum, arr[i].t, tinfo, flinfo);
 			v->spl_right[v->spl_nright] = arr[i].i;
 			v->spl_nright++;
 		}
diff --git a/contrib/btree_gist/btree_utils_num.h b/contrib/btree_gist/btree_utils_num.h
index 67d4968..17561fa 100644
--- a/contrib/btree_gist/btree_utils_num.h
+++ b/contrib/btree_gist/btree_utils_num.h
@@ -42,13 +42,13 @@ typedef struct
 
 	/* Methods */
 
-	bool		(*f_gt) (const void *, const void *);	/* greater than */
-	bool		(*f_ge) (const void *, const void *);	/* greater or equal */
-	bool		(*f_eq) (const void *, const void *);	/* equal */
-	bool		(*f_le) (const void *, const void *);	/* less or equal */
-	bool		(*f_lt) (const void *, const void *);	/* less than */
-	int			(*f_cmp) (const void *, const void *);	/* key compare function */
-	float8		(*f_dist) (const void *, const void *); /* key distance function */
+	bool		(*f_gt) (const void *, const void *, FmgrInfo *);	/* greater than */
+	bool		(*f_ge) (const void *, const void *, FmgrInfo *);	/* greater or equal */
+	bool		(*f_eq) (const void *, const void *, FmgrInfo *);	/* equal */
+	bool		(*f_le) (const void *, const void *, FmgrInfo *);	/* less or equal */
+	bool		(*f_lt) (const void *, const void *, FmgrInfo *);	/* less than */
+	int			(*f_cmp) (const void *, const void *, FmgrInfo *);	/* key compare function */
+	float8		(*f_dist) (const void *, const void *, FmgrInfo *); /* key distance function */
 } gbtree_ninfo;
 
 
@@ -113,25 +113,25 @@ extern Interval *abs_interval(Interval *a);
 
 extern bool gbt_num_consistent(const GBT_NUMKEY_R *key, const void *query,
 				   const StrategyNumber *strategy, bool is_leaf,
-				   const gbtree_ninfo *tinfo);
+				   const gbtree_ninfo *tinfo, FmgrInfo *flinfo);
 
 extern float8 gbt_num_distance(const GBT_NUMKEY_R *key, const void *query,
-				 bool is_leaf, const gbtree_ninfo *tinfo);
+				 bool is_leaf, const gbtree_ninfo *tinfo, FmgrInfo *flinfo);
 
 extern GIST_SPLITVEC *gbt_num_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v,
-				  const gbtree_ninfo *tinfo);
+				  const gbtree_ninfo *tinfo, FmgrInfo *flinfo);
 
 extern GISTENTRY *gbt_num_compress(GISTENTRY *entry, const gbtree_ninfo *tinfo);
 
 extern GISTENTRY *gbt_num_fetch(GISTENTRY *entry, const gbtree_ninfo *tinfo);
 
 extern void *gbt_num_union(GBT_NUMKEY *out, const GistEntryVector *entryvec,
-			  const gbtree_ninfo *tinfo);
+			  const gbtree_ninfo *tinfo, FmgrInfo *flinfo);
 
 extern bool gbt_num_same(const GBT_NUMKEY *a, const GBT_NUMKEY *b,
-			 const gbtree_ninfo *tinfo);
+			 const gbtree_ninfo *tinfo, FmgrInfo *flinfo);
 
 extern void gbt_num_bin_union(Datum *u, GBT_NUMKEY *e,
-				  const gbtree_ninfo *tinfo);
+				  const gbtree_ninfo *tinfo, FmgrInfo *flinfo);
 
 #endif
diff --git a/contrib/btree_gist/btree_uuid.c b/contrib/btree_gist/btree_uuid.c
index 44cef64..5ed8092 100644
--- a/contrib/btree_gist/btree_uuid.c
+++ b/contrib/btree_gist/btree_uuid.c
@@ -34,37 +34,37 @@ uuid_internal_cmp(const pg_uuid_t *arg1, const pg_uuid_t *arg2)
 }
 
 static bool
-gbt_uuidgt(const void *a, const void *b)
+gbt_uuidgt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return uuid_internal_cmp((const pg_uuid_t *) a, (const pg_uuid_t *) b) > 0;
 }
 
 static bool
-gbt_uuidge(const void *a, const void *b)
+gbt_uuidge(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return uuid_internal_cmp((const pg_uuid_t *) a, (const pg_uuid_t *) b) >= 0;
 }
 
 static bool
-gbt_uuideq(const void *a, const void *b)
+gbt_uuideq(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return uuid_internal_cmp((const pg_uuid_t *) a, (const pg_uuid_t *) b) == 0;
 }
 
 static bool
-gbt_uuidle(const void *a, const void *b)
+gbt_uuidle(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return uuid_internal_cmp((const pg_uuid_t *) a, (const pg_uuid_t *) b) <= 0;
 }
 
 static bool
-gbt_uuidlt(const void *a, const void *b)
+gbt_uuidlt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return uuid_internal_cmp((const pg_uuid_t *) a, (const pg_uuid_t *) b) < 0;
 }
 
 static int
-gbt_uuidkey_cmp(const void *a, const void *b)
+gbt_uuidkey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	uuidKEY    *ia = (uuidKEY *) (((const Nsrt *) a)->t);
 	uuidKEY    *ib = (uuidKEY *) (((const Nsrt *) b)->t);
@@ -150,7 +150,7 @@ gbt_uuid_consistent(PG_FUNCTION_ARGS)
 
 	PG_RETURN_BOOL(
 				   gbt_num_consistent(&key, (void *) query, &strategy,
-									  GIST_LEAF(entry), &tinfo)
+									  GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -161,7 +161,7 @@ gbt_uuid_union(PG_FUNCTION_ARGS)
 	void	   *out = palloc(sizeof(uuidKEY));
 
 	*(int *) PG_GETARG_POINTER(1) = sizeof(uuidKEY);
-	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
+	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
 }
 
 /*
@@ -222,7 +222,7 @@ gbt_uuid_picksplit(PG_FUNCTION_ARGS)
 	PG_RETURN_POINTER(gbt_num_picksplit(
 									(GistEntryVector *) PG_GETARG_POINTER(0),
 									  (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
-										&tinfo
+										&tinfo, fcinfo->flinfo
 										));
 }
 
@@ -233,6 +233,6 @@ gbt_uuid_same(PG_FUNCTION_ARGS)
 	uuidKEY    *b2 = (uuidKEY *) PG_GETARG_POINTER(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
 
-	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
+	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(result);
 }
-- 
2.4.11

0001-Provide-a-direct-function-call-mechanism-that-uses-t.patchtext/x-diff; name=0001-Provide-a-direct-function-call-mechanism-that-uses-t.patchDownload
From 4f13d88c2b14d736360830eab865e17b62e29d8f Mon Sep 17 00:00:00 2001
From: Andrew Dunstan <andrew@dunslane.net>
Date: Sun, 26 Feb 2017 09:38:07 -0500
Subject: [PATCH 1/4] Provide a direct function call mechanism that uses the
 caller's context.

The current DirectFunctionCall functions use NULL as the flinfo in
initializing the FunctionCallInfoData for the call. That means the
called function has no fn_mcxt or fn_extra to work with, and attempting
to do so will result in an access violation. These functions instead use
the provided flinfo, which will usually be the caller's own flinfo. The
caller needs to ensure that it doesn't use the fn_extra in way that is
incompatible with the way the called function will use it. The called
function should not rely on anything else in the provided context, as it
will be relevant to the caller, not the callee.

Original code from Tom Lane.

Discussion: https://postgr.es/m/db2b70a4-78d7-294a-a315-8e7f506c5978@2ndQuadrant.com
---
 src/backend/utils/fmgr/fmgr.c | 50 +++++++++++++++++++++++++++++++++++++++++++
 src/include/fmgr.h            | 15 +++++++++++++
 2 files changed, 65 insertions(+)

diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c
index 3976496..93dc229 100644
--- a/src/backend/utils/fmgr/fmgr.c
+++ b/src/backend/utils/fmgr/fmgr.c
@@ -1276,6 +1276,56 @@ DirectFunctionCall9Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
 	return result;
 }
 
+/*
+ * These functions work like the DirectFunctionCall functions except that
+ * they use the flinfo parameter to initialise the fcinfo for the call.
+ * It's recommended that the callee only use the fn_extra and fn_mcxt
+ * fields, as other fields will typically describe the calling function
+ * not the callee.  Conversely, the calling function should not have
+ * used fn_extra, unless its use is known to be compatible with the callee's.
+ */
+
+Datum
+CallerFInfoFunctionCall1(PGFunction func, FmgrInfo *flinfo, Oid collation, Datum arg1)
+{
+	FunctionCallInfoData fcinfo;
+	Datum		result;
+
+	InitFunctionCallInfoData(fcinfo, flinfo, 1, collation, NULL, NULL);
+
+	fcinfo.arg[0] = arg1;
+	fcinfo.argnull[0] = false;
+
+	result = (*func) (&fcinfo);
+
+	/* Check for null result, since caller is clearly not expecting one */
+	if (fcinfo.isnull)
+		elog(ERROR, "function %p returned NULL", (void *) func);
+
+	return result;
+}
+
+Datum
+CallerFInfoFunctionCall2(PGFunction func, FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
+{
+	FunctionCallInfoData fcinfo;
+	Datum		result;
+
+	InitFunctionCallInfoData(fcinfo, flinfo, 2, collation, NULL, NULL);
+
+	fcinfo.arg[0] = arg1;
+	fcinfo.arg[1] = arg2;
+	fcinfo.argnull[0] = false;
+	fcinfo.argnull[1] = false;
+
+	result = (*func) (&fcinfo);
+
+	/* Check for null result, since caller is clearly not expecting one */
+	if (fcinfo.isnull)
+		elog(ERROR, "function %p returned NULL", (void *) func);
+
+	return result;
+}
 
 /*
  * These are for invocation of a previously-looked-up function with a
diff --git a/src/include/fmgr.h b/src/include/fmgr.h
index a671480..0bac91a 100644
--- a/src/include/fmgr.h
+++ b/src/include/fmgr.h
@@ -475,7 +475,21 @@ extern Datum DirectFunctionCall9Coll(PGFunction func, Oid collation,
 						Datum arg6, Datum arg7, Datum arg8,
 						Datum arg9);
 
+/*
+ * These functions work like the DirectFunctionCall functions except that
+ * they use the flinfo parameter to initialise the fcinfo for the call.
+ * It's recommended that the callee only use the fn_extra and fn_mcxt
+ * fields, as other fields will typically describe the calling function
+ * not the callee.  Conversely, the calling function should not have
+ * used fn_extra, unless its use is known to be compatible with the callee's.
+ */
+
+extern Datum CallerFInfoFunctionCall1(PGFunction func, FmgrInfo *flinfo,
+						 Oid collation, Datum arg1);
+extern Datum CallerFInfoFunctionCall2(PGFunction func, FmgrInfo *flinfo,
+						 Oid collation, Datum arg1, Datum arg2);
+
+
 /* These are for invocation of a previously-looked-up function with a
  * directly-computed parameter list.  Note that neither arguments nor result
  * are allowed to be NULL.
-- 
2.4.11

0005-Add-btree_gin-support-for-enum-types.patchtext/x-diff; name=0005-Add-btree_gin-support-for-enum-types.patchDownload
From dcf73b5f94c2729167c2659dcab2fe5e1e292792 Mon Sep 17 00:00:00 2001
From: Andrew Dunstan <andrew@dunslane.net>
Date: Mon, 27 Feb 2017 16:10:41 -0500
Subject: [PATCH] Add btree_gin support for enum types

---
 contrib/btree_gin/Makefile                |  4 +-
 contrib/btree_gin/btree_gin--1.0--1.1.sql | 47 ++++++++++++++++++++++
 contrib/btree_gin/btree_gin.c             | 67 +++++++++++++++++++++++++++----
 contrib/btree_gin/btree_gin.control       |  2 +-
 contrib/btree_gin/expected/enum.out       | 63 +++++++++++++++++++++++++++++
 doc/src/sgml/btree-gin.sgml               |  3 +-
 6 files changed, 174 insertions(+), 12 deletions(-)
 create mode 100644 contrib/btree_gin/btree_gin--1.0--1.1.sql
 create mode 100644 contrib/btree_gin/expected/enum.out

diff --git a/contrib/btree_gin/Makefile b/contrib/btree_gin/Makefile
index 0492091..c6aae26 100644
--- a/contrib/btree_gin/Makefile
+++ b/contrib/btree_gin/Makefile
@@ -4,13 +4,13 @@ MODULE_big = btree_gin
 OBJS = btree_gin.o $(WIN32RES)
 
 EXTENSION = btree_gin
-DATA = btree_gin--1.0.sql btree_gin--unpackaged--1.0.sql
+DATA = btree_gin--1.0.sql btree_gin--unpackaged--1.0.sql btree_gin--1.0--1.1.sql
 PGFILEDESC = "btree_gin - B-tree equivalent GIN operator classes"
 
 REGRESS = install_btree_gin int2 int4 int8 float4 float8 money oid \
 	timestamp timestamptz time timetz date interval \
 	macaddr inet cidr text varchar char bytea bit varbit \
-	numeric
+	numeric enum
 
 ifdef USE_PGXS
 PG_CONFIG = pg_config
diff --git a/contrib/btree_gin/btree_gin--1.0--1.1.sql b/contrib/btree_gin/btree_gin--1.0--1.1.sql
new file mode 100644
index 0000000..3c40ccd
--- /dev/null
+++ b/contrib/btree_gin/btree_gin--1.0--1.1.sql
@@ -0,0 +1,47 @@
+/* contrib/btree_gin/btree_gin--1.0--1.1.sql */
+
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "ALTER EXTENSION btree_gin UPDATE TO '1.1'" to load this file. \quit
+
+--
+--
+--
+-- enum ops
+--
+--
+
+
+CREATE FUNCTION gin_extract_value_anyenum(anyenum, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_anyenum(anyenum, anyenum, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_anyenum(anyenum, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_enum_cmp(anyenum, anyenum)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS enum_ops
+DEFAULT FOR TYPE anyenum USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       gin_enum_cmp(anyenum,anyenum),
+    FUNCTION        2       gin_extract_value_anyenum(anyenum, internal),
+    FUNCTION        3       gin_extract_query_anyenum(anyenum, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_anyenum(anyenum,anyenum,int2, internal),
+STORAGE         anyenum;
diff --git a/contrib/btree_gin/btree_gin.c b/contrib/btree_gin/btree_gin.c
index 030b610..840b8e2 100644
--- a/contrib/btree_gin/btree_gin.c
+++ b/contrib/btree_gin/btree_gin.c
@@ -25,7 +25,6 @@ typedef struct QueryInfo
 	Datum		(*typecmp) (FunctionCallInfo);
 } QueryInfo;
 
-
 /*** GIN support functions shared by all datatypes ***/
 
 static Datum
@@ -112,13 +111,14 @@ gin_btree_compare_prefix(FunctionCallInfo fcinfo)
 	int32		res,
 				cmp;
 
-	cmp = DatumGetInt32(DirectFunctionCall2Coll(
-												data->typecmp,
-												PG_GET_COLLATION(),
-								   (data->strategy == BTLessStrategyNumber ||
-								 data->strategy == BTLessEqualStrategyNumber)
-												? data->datum : a,
-												b));
+	cmp = DatumGetInt32(CallerFInfoFunctionCall2(
+							data->typecmp,
+							fcinfo->flinfo,
+							PG_GET_COLLATION(),
+							(data->strategy == BTLessStrategyNumber ||
+							 data->strategy == BTLessEqualStrategyNumber)
+							? data->datum : a,
+							b));
 
 	switch (data->strategy)
 	{
@@ -416,3 +416,54 @@ leftmostvalue_numeric(void)
 }
 
 GIN_SUPPORT(numeric, true, leftmostvalue_numeric, gin_numeric_cmp)
+
+/*
+ * Use a similar trick to that used for numeric for enums, since we don't
+ * actually know the leftmost value of any enum without knowing the concrete
+ * type, so we use a dummy leftmost value of InvalidOid.
+ *
+ * Note that we use CallerFInfoFunctionCall2 here so that enum_cmp
+ * gets a valid fn_extra to work with. Unlike most other type comparison
+ * routines it needs it, so we can't use DirectFunctionCall2.
+ */
+
+
+#define ENUM_IS_LEFTMOST(x)	((x) == InvalidOid)
+
+PG_FUNCTION_INFO_V1(gin_enum_cmp);
+
+Datum
+gin_enum_cmp(PG_FUNCTION_ARGS)
+{
+	Oid		a = PG_GETARG_OID(0);
+	Oid		b = PG_GETARG_OID(1);
+	int		res = 0;
+
+	if (ENUM_IS_LEFTMOST(a))
+	{
+		res = (ENUM_IS_LEFTMOST(b)) ? 0 : -1;
+	}
+	else if (ENUM_IS_LEFTMOST(b))
+	{
+		res = 1;
+	}
+	else
+	{
+		res = DatumGetInt32(CallerFInfoFunctionCall2(
+								enum_cmp,
+								fcinfo->flinfo,
+								PG_GET_COLLATION(),
+								ObjectIdGetDatum(a),
+								ObjectIdGetDatum(b)));
+	}
+
+	PG_RETURN_INT32(res);
+}
+
+static Datum
+leftmostvalue_enum(void)
+{
+	return ObjectIdGetDatum(InvalidOid);
+}
+
+GIN_SUPPORT(anyenum, false, leftmostvalue_enum, gin_enum_cmp)
diff --git a/contrib/btree_gin/btree_gin.control b/contrib/btree_gin/btree_gin.control
index 3b2cb2d..d96436e 100644
--- a/contrib/btree_gin/btree_gin.control
+++ b/contrib/btree_gin/btree_gin.control
@@ -1,5 +1,5 @@
 # btree_gin extension
 comment = 'support for indexing common datatypes in GIN'
-default_version = '1.0'
+default_version = '1.1'
 module_pathname = '$libdir/btree_gin'
 relocatable = true
diff --git a/contrib/btree_gin/expected/enum.out b/contrib/btree_gin/expected/enum.out
new file mode 100644
index 0000000..bad1cc0
--- /dev/null
+++ b/contrib/btree_gin/expected/enum.out
@@ -0,0 +1,63 @@
+set enable_seqscan=off;
+CREATE TYPE rainbow AS ENUM ('r','o','y','g','b','i','v');
+CREATE TABLE test_enum (
+	i rainbow
+);
+INSERT INTO test_enum VALUES ('v'),('y'),('r'),('g'),('o'),('i'),('b');
+CREATE INDEX idx_enum ON test_enum USING gin (i);
+SELECT * FROM test_enum WHERE i<'g'::rainbow ORDER BY i;
+ i 
+---
+ r
+ o
+ y
+(3 rows)
+
+SELECT * FROM test_enum WHERE i<='g'::rainbow ORDER BY i;
+ i 
+---
+ r
+ o
+ y
+ g
+(4 rows)
+
+SELECT * FROM test_enum WHERE i='g'::rainbow ORDER BY i;
+ i 
+---
+ g
+(1 row)
+
+SELECT * FROM test_enum WHERE i>='g'::rainbow ORDER BY i;
+ i 
+---
+ g
+ b
+ i
+ v
+(4 rows)
+
+SELECT * FROM test_enum WHERE i>'g'::rainbow ORDER BY i;
+ i 
+---
+ b
+ i
+ v
+(3 rows)
+
+explain (costs off) SELECT * FROM test_enum WHERE i>='g'::rainbow ORDER BY i;
+                  QUERY PLAN                   
+-----------------------------------------------
+ Sort
+   Sort Key: i
+   ->  Bitmap Heap Scan on test_enum
+         Recheck Cond: (i >= 'g'::rainbow)
+         ->  Bitmap Index Scan on idx_enum
+               Index Cond: (i >= 'g'::rainbow)
+(6 rows)
+
+-- make sure we handle the non-evenly-numbered oid case for enums
+create type e as enum ('0', '2', '3');
+alter type e add value '1' after '0';
+create table t as select (i % 4)::text::e from generate_series(0, 100000) as i;
+create index on t using gin (e);
diff --git a/doc/src/sgml/btree-gin.sgml b/doc/src/sgml/btree-gin.sgml
index 2b081db..f407e92 100644
--- a/doc/src/sgml/btree-gin.sgml
+++ b/doc/src/sgml/btree-gin.sgml
@@ -16,7 +16,8 @@
   <type>time without time zone</>, <type>date</>, <type>interval</>,
   <type>oid</>, <type>money</>, <type>"char"</>,
   <type>varchar</>, <type>text</>, <type>bytea</>, <type>bit</>,
-  <type>varbit</>, <type>macaddr</>, <type>inet</>, and <type>cidr</>.
+  <type>varbit</>, <type>macaddr</>, <type>inet</>, <type>cidr</>,
+  and all <type>enum</> types.
  </para>
 
  <para>
-- 
2.4.11

#37Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andrew Dunstan (#36)
Re: btree_gin and btree_gist for enums

Andrew Dunstan <andrew.dunstan@2ndquadrant.com> writes:

OK, here's the whole series of patches.

I've not tested it at all, but this looks generally sane in a quick
once-over.

A minor quibble is that in 0003, you weren't terribly consistent about
argument order --- in some places you have the FmgrInfo argument added
before the collation argument, and in some places after. I'd suggest
trying to make the argument orders consistent with the fmgr.c support
functions. (I'm generally -1 on blindly adding stuff at the end.)

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#38Andrew Dunstan
andrew.dunstan@2ndquadrant.com
In reply to: Tom Lane (#37)
Re: btree_gin and btree_gist for enums

On 02/27/2017 04:41 PM, Tom Lane wrote:

Andrew Dunstan <andrew.dunstan@2ndquadrant.com> writes:

OK, here's the whole series of patches.

I've not tested it at all, but this looks generally sane in a quick
once-over.

A minor quibble is that in 0003, you weren't terribly consistent about
argument order --- in some places you have the FmgrInfo argument added
before the collation argument, and in some places after. I'd suggest
trying to make the argument orders consistent with the fmgr.c support
functions. (I'm generally -1 on blindly adding stuff at the end.)

Thanks for reviewing.

I don't mind changing it, but if I do I'm inclined to make it as
consistent as possible with the 0002 patch, which did put all the
FmgrInfo arguments at the end - there's not any other more obvious place
for them in that case, as there is no collation argument.

cheers

andrew

--
Andrew Dunstan https://www.2ndQuadrant.com
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#39Anastasia Lubennikova
a.lubennikova@postgrespro.ru
In reply to: Andrew Dunstan (#36)
2 attachment(s)
Re: btree_gin and btree_gist for enums

28.02.2017 00:22, Andrew Dunstan:

OK, here's the whole series of patches.

Patch 1 adds the CallerFInfoFunctionCall{1,2} functions.

Patch 2 adds btree_gist support for their use for non-varlena types

Patch 3 does the same for varlena types (Not required for patch 4, but
better to be consistent, I think.)

Patch 4 adds enum support to btree_gist

Patch 5 adds enum support to btree_gin

cheers

andrew

Thank you for implementing the feature!
These patches seem to have some merge conflicts with recent commit:

commit c7a9fa399d557c6366222e90b35db31e45d25678
Author: Stephen Frost <sfrost@snowman.net>
Date: Wed Mar 15 11:16:25 2017 -0400

Add support for EUI-64 MAC addresses as macaddr8

And also, it's needed to update patch 0002 to consider macaddr8, I
attached the diff.
Complete patch (including 0002_addition fix) rebased to the current
master is attached as well.
It works as expected, code itself looks clear and well documented.

The only issue I've found is a make check failure in contrib/btree_gin
subdirectory:

test numeric ... ok
test enum ... /bin/sh: 1: cannot open
/home/anastasia/newprojects/original_repo/postgres/contrib/btree_gin/sql/enum.sql:
No such file
diff:
/home/anastasia/newprojects/original_repo/postgres/contrib/btree_gin/results/enum.out:
No such file or directory
diff command failed with status 512: diff
"/home/anastasia/newprojects/original_repo/postgres/contrib/btree_gin/expected/enum.out"
"/home/anastasia/newprojects/original_repo/postgres/contrib/btree_gin/results/enum.out"

"/home/anastasia/newprojects/original_repo/postgres/contrib/btree_gin/results/enum.out.diff"

Please, add regression test for btree_gin, and this patch can be
considered "Ready for committer".

--
Anastasia Lubennikova
Postgres Professional: http://www.postgrespro.com
The Russian Postgres Company

Attachments:

0002_addition.patchtext/x-diff; name=0002_addition.patchDownload
diff --git a/contrib/btree_gist/btree_macaddr8.c b/contrib/btree_gist/btree_macaddr8.c
index 13238ef..96afbcd 100644
--- a/contrib/btree_gist/btree_macaddr8.c
+++ b/contrib/btree_gist/btree_macaddr8.c
@@ -28,37 +28,37 @@ PG_FUNCTION_INFO_V1(gbt_macad8_same);
 
 
 static bool
-gbt_macad8gt(const void *a, const void *b)
+gbt_macad8gt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(DirectFunctionCall2(macaddr8_gt, PointerGetDatum(a), PointerGetDatum(b)));
 }
 static bool
-gbt_macad8ge(const void *a, const void *b)
+gbt_macad8ge(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(DirectFunctionCall2(macaddr8_ge, PointerGetDatum(a), PointerGetDatum(b)));
 }
 
 static bool
-gbt_macad8eq(const void *a, const void *b)
+gbt_macad8eq(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(DirectFunctionCall2(macaddr8_eq, PointerGetDatum(a), PointerGetDatum(b)));
 }
 
 static bool
-gbt_macad8le(const void *a, const void *b)
+gbt_macad8le(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(DirectFunctionCall2(macaddr8_le, PointerGetDatum(a), PointerGetDatum(b)));
 }
 
 static bool
-gbt_macad8lt(const void *a, const void *b)
+gbt_macad8lt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(DirectFunctionCall2(macaddr8_lt, PointerGetDatum(a), PointerGetDatum(b)));
 }
 
 
 static int
-gbt_macad8key_cmp(const void *a, const void *b)
+gbt_macad8key_cmp(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	mac8KEY    *ia = (mac8KEY *) (((const Nsrt *) a)->t);
 	mac8KEY    *ib = (mac8KEY *) (((const Nsrt *) b)->t);
@@ -142,7 +142,7 @@ gbt_macad8_consistent(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_BOOL(
-				   gbt_num_consistent(&key, (void *) query, &strategy, GIST_LEAF(entry), &tinfo)
+				   gbt_num_consistent(&key, (void *) query, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -154,7 +154,7 @@ gbt_macad8_union(PG_FUNCTION_ARGS)
 	void	   *out = palloc0(sizeof(mac8KEY));
 
 	*(int *) PG_GETARG_POINTER(1) = sizeof(mac8KEY);
-	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
+	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
 }
 
 
@@ -184,7 +184,7 @@ gbt_macad8_picksplit(PG_FUNCTION_ARGS)
 	PG_RETURN_POINTER(gbt_num_picksplit(
 									(GistEntryVector *) PG_GETARG_POINTER(0),
 									  (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
-										&tinfo
+										&tinfo, fcinfo->flinfo
 										));
 }
 
@@ -195,6 +195,6 @@ gbt_macad8_same(PG_FUNCTION_ARGS)
 	mac8KEY    *b2 = (mac8KEY *) PG_GETARG_POINTER(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
 
-	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
+	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(result);
 }
complete_btree_gin_gist_enums_v0.patchtext/x-diff; name=complete_btree_gin_gist_enums_v0.patchDownload
commit 50f4a4efcb9ed3ae5e0378676459c6d1ce455bd2
Author: Anastasia <a.lubennikova@postgrespro.ru>
Date:   Tue Mar 21 10:11:37 2017 +0300

    complete btree_gin_gist_enum patch

diff --git a/contrib/btree_gin/Makefile b/contrib/btree_gin/Makefile
index f22e4af..589755f 100644
--- a/contrib/btree_gin/Makefile
+++ b/contrib/btree_gin/Makefile
@@ -10,7 +10,7 @@ PGFILEDESC = "btree_gin - B-tree equivalent GIN operator classes"
 REGRESS = install_btree_gin int2 int4 int8 float4 float8 money oid \
 	timestamp timestamptz time timetz date interval \
 	macaddr macaddr8 inet cidr text varchar char bytea bit varbit \
-	numeric
+	numeric enum
 
 ifdef USE_PGXS
 PG_CONFIG = pg_config
diff --git a/contrib/btree_gin/btree_gin--1.0--1.1.sql b/contrib/btree_gin/btree_gin--1.0--1.1.sql
index dd81d27..006af59 100644
--- a/contrib/btree_gin/btree_gin--1.0--1.1.sql
+++ b/contrib/btree_gin/btree_gin--1.0--1.1.sql
@@ -33,3 +33,47 @@ AS
     FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
     FUNCTION        5       gin_compare_prefix_macaddr8(macaddr8, macaddr8, int2, internal),
 STORAGE         macaddr8;
+
+
+--
+--
+--
+-- enum ops
+--
+--
+
+
+CREATE FUNCTION gin_extract_value_anyenum(anyenum, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_compare_prefix_anyenum(anyenum, anyenum, int2, internal)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_extract_query_anyenum(anyenum, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION gin_enum_cmp(anyenum, anyenum)
+RETURNS int4
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OPERATOR CLASS enum_ops
+DEFAULT FOR TYPE anyenum USING gin
+AS
+    OPERATOR        1       <,
+    OPERATOR        2       <=,
+    OPERATOR        3       =,
+    OPERATOR        4       >=,
+    OPERATOR        5       >,
+    FUNCTION        1       gin_enum_cmp(anyenum,anyenum),
+    FUNCTION        2       gin_extract_value_anyenum(anyenum, internal),
+    FUNCTION        3       gin_extract_query_anyenum(anyenum, internal, int2, internal, internal),
+    FUNCTION        4       gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+    FUNCTION        5       gin_compare_prefix_anyenum(anyenum,anyenum,int2, internal),
+STORAGE         anyenum;
diff --git a/contrib/btree_gin/btree_gin.c b/contrib/btree_gin/btree_gin.c
index 725456e..7191fbf 100644
--- a/contrib/btree_gin/btree_gin.c
+++ b/contrib/btree_gin/btree_gin.c
@@ -25,7 +25,6 @@ typedef struct QueryInfo
 	Datum		(*typecmp) (FunctionCallInfo);
 } QueryInfo;
 
-
 /*** GIN support functions shared by all datatypes ***/
 
 static Datum
@@ -112,13 +111,14 @@ gin_btree_compare_prefix(FunctionCallInfo fcinfo)
 	int32		res,
 				cmp;
 
-	cmp = DatumGetInt32(DirectFunctionCall2Coll(
-												data->typecmp,
-												PG_GET_COLLATION(),
-								   (data->strategy == BTLessStrategyNumber ||
-								 data->strategy == BTLessEqualStrategyNumber)
-												? data->datum : a,
-												b));
+	cmp = DatumGetInt32(CallerFInfoFunctionCall2(
+							data->typecmp,
+							fcinfo->flinfo,
+							PG_GET_COLLATION(),
+							(data->strategy == BTLessStrategyNumber ||
+							 data->strategy == BTLessEqualStrategyNumber)
+							? data->datum : a,
+							b));
 
 	switch (data->strategy)
 	{
@@ -426,3 +426,54 @@ leftmostvalue_numeric(void)
 }
 
 GIN_SUPPORT(numeric, true, leftmostvalue_numeric, gin_numeric_cmp)
+
+/*
+ * Use a similar trick to that used for numeric for enums, since we don't
+ * actually know the leftmost value of any enum without knowing the concrete
+ * type, so we use a dummy leftmost value of InvalidOid.
+ *
+ * Note that we use CallerFInfoFunctionCall2 here so that enum_cmp
+ * gets a valid fn_extra to work with. Unlike most other type comparison
+ * routines it needs it, so we can't use DirectFunctionCall2.
+ */
+
+
+#define ENUM_IS_LEFTMOST(x)	((x) == InvalidOid)
+
+PG_FUNCTION_INFO_V1(gin_enum_cmp);
+
+Datum
+gin_enum_cmp(PG_FUNCTION_ARGS)
+{
+	Oid		a = PG_GETARG_OID(0);
+	Oid		b = PG_GETARG_OID(1);
+	int		res = 0;
+
+	if (ENUM_IS_LEFTMOST(a))
+	{
+		res = (ENUM_IS_LEFTMOST(b)) ? 0 : -1;
+	}
+	else if (ENUM_IS_LEFTMOST(b))
+	{
+		res = 1;
+	}
+	else
+	{
+		res = DatumGetInt32(CallerFInfoFunctionCall2(
+								enum_cmp,
+								fcinfo->flinfo,
+								PG_GET_COLLATION(),
+								ObjectIdGetDatum(a),
+								ObjectIdGetDatum(b)));
+	}
+
+	PG_RETURN_INT32(res);
+}
+
+static Datum
+leftmostvalue_enum(void)
+{
+	return ObjectIdGetDatum(InvalidOid);
+}
+
+GIN_SUPPORT(anyenum, false, leftmostvalue_enum, gin_enum_cmp)
diff --git a/contrib/btree_gin/expected/enum.out b/contrib/btree_gin/expected/enum.out
new file mode 100644
index 0000000..bad1cc0
--- /dev/null
+++ b/contrib/btree_gin/expected/enum.out
@@ -0,0 +1,63 @@
+set enable_seqscan=off;
+CREATE TYPE rainbow AS ENUM ('r','o','y','g','b','i','v');
+CREATE TABLE test_enum (
+	i rainbow
+);
+INSERT INTO test_enum VALUES ('v'),('y'),('r'),('g'),('o'),('i'),('b');
+CREATE INDEX idx_enum ON test_enum USING gin (i);
+SELECT * FROM test_enum WHERE i<'g'::rainbow ORDER BY i;
+ i 
+---
+ r
+ o
+ y
+(3 rows)
+
+SELECT * FROM test_enum WHERE i<='g'::rainbow ORDER BY i;
+ i 
+---
+ r
+ o
+ y
+ g
+(4 rows)
+
+SELECT * FROM test_enum WHERE i='g'::rainbow ORDER BY i;
+ i 
+---
+ g
+(1 row)
+
+SELECT * FROM test_enum WHERE i>='g'::rainbow ORDER BY i;
+ i 
+---
+ g
+ b
+ i
+ v
+(4 rows)
+
+SELECT * FROM test_enum WHERE i>'g'::rainbow ORDER BY i;
+ i 
+---
+ b
+ i
+ v
+(3 rows)
+
+explain (costs off) SELECT * FROM test_enum WHERE i>='g'::rainbow ORDER BY i;
+                  QUERY PLAN                   
+-----------------------------------------------
+ Sort
+   Sort Key: i
+   ->  Bitmap Heap Scan on test_enum
+         Recheck Cond: (i >= 'g'::rainbow)
+         ->  Bitmap Index Scan on idx_enum
+               Index Cond: (i >= 'g'::rainbow)
+(6 rows)
+
+-- make sure we handle the non-evenly-numbered oid case for enums
+create type e as enum ('0', '2', '3');
+alter type e add value '1' after '0';
+create table t as select (i % 4)::text::e from generate_series(0, 100000) as i;
+create index on t using gin (e);
diff --git a/contrib/btree_gist/Makefile b/contrib/btree_gist/Makefile
index c70f178..5d6ab63 100644
--- a/contrib/btree_gist/Makefile
+++ b/contrib/btree_gist/Makefile
@@ -6,7 +6,7 @@ OBJS =  btree_gist.o btree_utils_num.o btree_utils_var.o btree_int2.o \
         btree_int4.o btree_int8.o btree_float4.o btree_float8.o btree_cash.o \
         btree_oid.o btree_ts.o btree_time.o btree_date.o btree_interval.o \
         btree_macaddr.o btree_macaddr8.o btree_inet.o btree_text.o btree_bytea.o \
-        btree_bit.o btree_numeric.o btree_uuid.o $(WIN32RES)
+        btree_bit.o btree_numeric.o btree_uuid.o btree_enum.o $(WIN32RES)
 
 EXTENSION = btree_gist
 DATA = btree_gist--unpackaged--1.0.sql btree_gist--1.0--1.1.sql \
@@ -16,7 +16,7 @@ PGFILEDESC = "btree_gist - B-tree equivalent GiST operator classes"
 
 REGRESS = init int2 int4 int8 float4 float8 cash oid timestamp timestamptz \
         time timetz date interval macaddr macaddr8 inet cidr text varchar char \
-        bytea bit varbit numeric uuid not_equal
+        bytea bit varbit numeric uuid enum not_equal
 
 SHLIB_LINK += $(filter -lm, $(LIBS))
 
diff --git a/contrib/btree_gist/btree_bit.c b/contrib/btree_gist/btree_bit.c
index f34fa87..a57f45f 100644
--- a/contrib/btree_gist/btree_bit.c
+++ b/contrib/btree_gist/btree_bit.c
@@ -24,7 +24,7 @@ PG_FUNCTION_INFO_V1(gbt_bit_same);
 /* define for comparison */
 
 static bool
-gbt_bitgt(const void *a, const void *b, Oid collation)
+gbt_bitgt(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2(bitgt,
 											PointerGetDatum(a),
@@ -32,7 +32,7 @@ gbt_bitgt(const void *a, const void *b, Oid collation)
 }
 
 static bool
-gbt_bitge(const void *a, const void *b, Oid collation)
+gbt_bitge(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2(bitge,
 											PointerGetDatum(a),
@@ -40,7 +40,7 @@ gbt_bitge(const void *a, const void *b, Oid collation)
 }
 
 static bool
-gbt_biteq(const void *a, const void *b, Oid collation)
+gbt_biteq(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2(biteq,
 											PointerGetDatum(a),
@@ -48,7 +48,7 @@ gbt_biteq(const void *a, const void *b, Oid collation)
 }
 
 static bool
-gbt_bitle(const void *a, const void *b, Oid collation)
+gbt_bitle(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2(bitle,
 											PointerGetDatum(a),
@@ -56,7 +56,7 @@ gbt_bitle(const void *a, const void *b, Oid collation)
 }
 
 static bool
-gbt_bitlt(const void *a, const void *b, Oid collation)
+gbt_bitlt(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2(bitlt,
 											PointerGetDatum(a),
@@ -64,7 +64,7 @@ gbt_bitlt(const void *a, const void *b, Oid collation)
 }
 
 static int32
-gbt_bitcmp(const void *a, const void *b, Oid collation)
+gbt_bitcmp(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetInt32(DirectFunctionCall2(byteacmp,
 											 PointerGetDatum(a),
@@ -92,7 +92,7 @@ gbt_bit_xfrm(bytea *leaf)
 
 
 static GBT_VARKEY *
-gbt_bit_l2n(GBT_VARKEY *leaf)
+gbt_bit_l2n(GBT_VARKEY *leaf, FmgrInfo *flinfo)
 {
 	GBT_VARKEY *out = leaf;
 	GBT_VARKEY_R r = gbt_var_key_readable(leaf);
@@ -152,13 +152,13 @@ gbt_bit_consistent(PG_FUNCTION_ARGS)
 
 	if (GIST_LEAF(entry))
 		retval = gbt_var_consistent(&r, query, strategy, PG_GET_COLLATION(),
-									TRUE, &tinfo);
+									TRUE, &tinfo, fcinfo->flinfo);
 	else
 	{
 		bytea	   *q = gbt_bit_xfrm((bytea *) query);
 
 		retval = gbt_var_consistent(&r, q, strategy, PG_GET_COLLATION(),
-									FALSE, &tinfo);
+									FALSE, &tinfo, fcinfo->flinfo);
 	}
 	PG_RETURN_BOOL(retval);
 }
@@ -172,7 +172,7 @@ gbt_bit_union(PG_FUNCTION_ARGS)
 	int32	   *size = (int *) PG_GETARG_POINTER(1);
 
 	PG_RETURN_POINTER(gbt_var_union(entryvec, size, PG_GET_COLLATION(),
-									&tinfo));
+									&tinfo, fcinfo->flinfo));
 }
 
 
@@ -183,7 +183,7 @@ gbt_bit_picksplit(PG_FUNCTION_ARGS)
 	GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
 
 	gbt_var_picksplit(entryvec, v, PG_GET_COLLATION(),
-					  &tinfo);
+					  &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(v);
 }
 
@@ -194,7 +194,7 @@ gbt_bit_same(PG_FUNCTION_ARGS)
 	Datum		d2 = PG_GETARG_DATUM(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
 
-	*result = gbt_var_same(d1, d2, PG_GET_COLLATION(), &tinfo);
+	*result = gbt_var_same(d1, d2, PG_GET_COLLATION(), &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(result);
 }
 
@@ -207,5 +207,5 @@ gbt_bit_penalty(PG_FUNCTION_ARGS)
 	float	   *result = (float *) PG_GETARG_POINTER(2);
 
 	PG_RETURN_POINTER(gbt_var_penalty(result, o, n, PG_GET_COLLATION(),
-									  &tinfo));
+									  &tinfo, fcinfo->flinfo));
 }
diff --git a/contrib/btree_gist/btree_bytea.c b/contrib/btree_gist/btree_bytea.c
index df6c960..b9cd00f 100644
--- a/contrib/btree_gist/btree_bytea.c
+++ b/contrib/btree_gist/btree_bytea.c
@@ -23,7 +23,7 @@ PG_FUNCTION_INFO_V1(gbt_bytea_same);
 /* define for comparison */
 
 static bool
-gbt_byteagt(const void *a, const void *b, Oid collation)
+gbt_byteagt(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2(byteagt,
 											PointerGetDatum(a),
@@ -31,7 +31,7 @@ gbt_byteagt(const void *a, const void *b, Oid collation)
 }
 
 static bool
-gbt_byteage(const void *a, const void *b, Oid collation)
+gbt_byteage(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2(byteage,
 											PointerGetDatum(a),
@@ -39,7 +39,7 @@ gbt_byteage(const void *a, const void *b, Oid collation)
 }
 
 static bool
-gbt_byteaeq(const void *a, const void *b, Oid collation)
+gbt_byteaeq(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2(byteaeq,
 											PointerGetDatum(a),
@@ -47,7 +47,7 @@ gbt_byteaeq(const void *a, const void *b, Oid collation)
 }
 
 static bool
-gbt_byteale(const void *a, const void *b, Oid collation)
+gbt_byteale(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2(byteale,
 											PointerGetDatum(a),
@@ -55,7 +55,7 @@ gbt_byteale(const void *a, const void *b, Oid collation)
 }
 
 static bool
-gbt_bytealt(const void *a, const void *b, Oid collation)
+gbt_bytealt(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2(bytealt,
 											PointerGetDatum(a),
@@ -63,7 +63,7 @@ gbt_bytealt(const void *a, const void *b, Oid collation)
 }
 
 static int32
-gbt_byteacmp(const void *a, const void *b, Oid collation)
+gbt_byteacmp(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetInt32(DirectFunctionCall2(byteacmp,
 											 PointerGetDatum(a),
@@ -118,7 +118,7 @@ gbt_bytea_consistent(PG_FUNCTION_ARGS)
 	*recheck = false;
 
 	retval = gbt_var_consistent(&r, query, strategy, PG_GET_COLLATION(),
-								GIST_LEAF(entry), &tinfo);
+								GIST_LEAF(entry), &tinfo, fcinfo->flinfo);
 	PG_RETURN_BOOL(retval);
 }
 
@@ -131,7 +131,7 @@ gbt_bytea_union(PG_FUNCTION_ARGS)
 	int32	   *size = (int *) PG_GETARG_POINTER(1);
 
 	PG_RETURN_POINTER(gbt_var_union(entryvec, size, PG_GET_COLLATION(),
-									&tinfo));
+									&tinfo, fcinfo->flinfo));
 }
 
 
@@ -142,7 +142,7 @@ gbt_bytea_picksplit(PG_FUNCTION_ARGS)
 	GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
 
 	gbt_var_picksplit(entryvec, v, PG_GET_COLLATION(),
-					  &tinfo);
+					  &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(v);
 }
 
@@ -153,7 +153,7 @@ gbt_bytea_same(PG_FUNCTION_ARGS)
 	Datum		d2 = PG_GETARG_DATUM(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
 
-	*result = gbt_var_same(d1, d2, PG_GET_COLLATION(), &tinfo);
+	*result = gbt_var_same(d1, d2, PG_GET_COLLATION(), &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(result);
 }
 
@@ -166,5 +166,5 @@ gbt_bytea_penalty(PG_FUNCTION_ARGS)
 	float	   *result = (float *) PG_GETARG_POINTER(2);
 
 	PG_RETURN_POINTER(gbt_var_penalty(result, o, n, PG_GET_COLLATION(),
-									  &tinfo));
+									  &tinfo, fcinfo->flinfo));
 }
diff --git a/contrib/btree_gist/btree_cash.c b/contrib/btree_gist/btree_cash.c
index aa14735..ca0c86b 100644
--- a/contrib/btree_gist/btree_cash.c
+++ b/contrib/btree_gist/btree_cash.c
@@ -26,33 +26,33 @@ PG_FUNCTION_INFO_V1(gbt_cash_penalty);
 PG_FUNCTION_INFO_V1(gbt_cash_same);
 
 static bool
-gbt_cashgt(const void *a, const void *b)
+gbt_cashgt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const Cash *) a) > *((const Cash *) b));
 }
 static bool
-gbt_cashge(const void *a, const void *b)
+gbt_cashge(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const Cash *) a) >= *((const Cash *) b));
 }
 static bool
-gbt_casheq(const void *a, const void *b)
+gbt_casheq(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const Cash *) a) == *((const Cash *) b));
 }
 static bool
-gbt_cashle(const void *a, const void *b)
+gbt_cashle(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const Cash *) a) <= *((const Cash *) b));
 }
 static bool
-gbt_cashlt(const void *a, const void *b)
+gbt_cashlt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const Cash *) a) < *((const Cash *) b));
 }
 
 static int
-gbt_cashkey_cmp(const void *a, const void *b)
+gbt_cashkey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	cashKEY    *ia = (cashKEY *) (((const Nsrt *) a)->t);
 	cashKEY    *ib = (cashKEY *) (((const Nsrt *) b)->t);
@@ -69,7 +69,7 @@ gbt_cashkey_cmp(const void *a, const void *b)
 }
 
 static float8
-gbt_cash_dist(const void *a, const void *b)
+gbt_cash_dist(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return GET_FLOAT_DISTANCE(Cash, a, b);
 }
@@ -151,7 +151,7 @@ gbt_cash_consistent(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_BOOL(
-				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo)
+				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -170,7 +170,7 @@ gbt_cash_distance(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_FLOAT8(
-			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo)
+			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -182,7 +182,7 @@ gbt_cash_union(PG_FUNCTION_ARGS)
 	void	   *out = palloc(sizeof(cashKEY));
 
 	*(int *) PG_GETARG_POINTER(1) = sizeof(cashKEY);
-	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
+	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
 }
 
 
@@ -205,7 +205,7 @@ gbt_cash_picksplit(PG_FUNCTION_ARGS)
 	PG_RETURN_POINTER(gbt_num_picksplit(
 									(GistEntryVector *) PG_GETARG_POINTER(0),
 									  (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
-										&tinfo
+										&tinfo, fcinfo->flinfo
 										));
 }
 
@@ -216,6 +216,6 @@ gbt_cash_same(PG_FUNCTION_ARGS)
 	cashKEY    *b2 = (cashKEY *) PG_GETARG_POINTER(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
 
-	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
+	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(result);
 }
diff --git a/contrib/btree_gist/btree_date.c b/contrib/btree_gist/btree_date.c
index 56031d4..c9daf34 100644
--- a/contrib/btree_gist/btree_date.c
+++ b/contrib/btree_gist/btree_date.c
@@ -27,7 +27,7 @@ PG_FUNCTION_INFO_V1(gbt_date_penalty);
 PG_FUNCTION_INFO_V1(gbt_date_same);
 
 static bool
-gbt_dategt(const void *a, const void *b)
+gbt_dategt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(
 						DirectFunctionCall2(date_gt, DateADTGetDatum(*((const DateADT *) a)), DateADTGetDatum(*((const DateADT *) b)))
@@ -35,7 +35,7 @@ gbt_dategt(const void *a, const void *b)
 }
 
 static bool
-gbt_datege(const void *a, const void *b)
+gbt_datege(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(
 						DirectFunctionCall2(date_ge, DateADTGetDatum(*((const DateADT *) a)), DateADTGetDatum(*((const DateADT *) b)))
@@ -43,7 +43,7 @@ gbt_datege(const void *a, const void *b)
 }
 
 static bool
-gbt_dateeq(const void *a, const void *b)
+gbt_dateeq(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(
 						DirectFunctionCall2(date_eq, DateADTGetDatum(*((const DateADT *) a)), DateADTGetDatum(*((const DateADT *) b)))
@@ -51,7 +51,7 @@ gbt_dateeq(const void *a, const void *b)
 }
 
 static bool
-gbt_datele(const void *a, const void *b)
+gbt_datele(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(
 						DirectFunctionCall2(date_le, DateADTGetDatum(*((const DateADT *) a)), DateADTGetDatum(*((const DateADT *) b)))
@@ -59,7 +59,7 @@ gbt_datele(const void *a, const void *b)
 }
 
 static bool
-gbt_datelt(const void *a, const void *b)
+gbt_datelt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(
 						DirectFunctionCall2(date_lt, DateADTGetDatum(*((const DateADT *) a)), DateADTGetDatum(*((const DateADT *) b)))
@@ -69,7 +69,7 @@ gbt_datelt(const void *a, const void *b)
 
 
 static int
-gbt_datekey_cmp(const void *a, const void *b)
+gbt_datekey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	dateKEY    *ia = (dateKEY *) (((const Nsrt *) a)->t);
 	dateKEY    *ib = (dateKEY *) (((const Nsrt *) b)->t);
@@ -83,7 +83,7 @@ gbt_datekey_cmp(const void *a, const void *b)
 }
 
 static float8
-gdb_date_dist(const void *a, const void *b)
+gdb_date_dist(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	/* we assume the difference can't overflow */
 	Datum		diff = DirectFunctionCall2(date_mi,
@@ -163,7 +163,7 @@ gbt_date_consistent(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_BOOL(
-				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo)
+				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -182,7 +182,7 @@ gbt_date_distance(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_FLOAT8(
-			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo)
+			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -194,7 +194,7 @@ gbt_date_union(PG_FUNCTION_ARGS)
 	void	   *out = palloc(sizeof(dateKEY));
 
 	*(int *) PG_GETARG_POINTER(1) = sizeof(dateKEY);
-	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
+	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
 }
 
 
@@ -244,7 +244,7 @@ gbt_date_picksplit(PG_FUNCTION_ARGS)
 	PG_RETURN_POINTER(gbt_num_picksplit(
 									(GistEntryVector *) PG_GETARG_POINTER(0),
 									  (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
-										&tinfo
+										&tinfo, fcinfo->flinfo
 										));
 }
 
@@ -255,6 +255,6 @@ gbt_date_same(PG_FUNCTION_ARGS)
 	dateKEY    *b2 = (dateKEY *) PG_GETARG_POINTER(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
 
-	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
+	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(result);
 }
diff --git a/contrib/btree_gist/btree_enum.c b/contrib/btree_gist/btree_enum.c
new file mode 100644
index 0000000..5e46e78
--- /dev/null
+++ b/contrib/btree_gist/btree_enum.c
@@ -0,0 +1,187 @@
+/*
+ * contrib/btree_gist/btree_enum.c
+ */
+#include "postgres.h"
+#include "fmgr.h"
+#include "utils/builtins.h"
+
+#include "btree_gist.h"
+#include "btree_utils_num.h"
+
+/* enums are really Oids, so we just use the same structure */
+
+typedef struct
+{
+	Oid			lower;
+	Oid			upper;
+} oidKEY;
+
+/*
+** enum ops
+*/
+PG_FUNCTION_INFO_V1(gbt_enum_compress);
+PG_FUNCTION_INFO_V1(gbt_enum_fetch);
+PG_FUNCTION_INFO_V1(gbt_enum_union);
+PG_FUNCTION_INFO_V1(gbt_enum_picksplit);
+PG_FUNCTION_INFO_V1(gbt_enum_consistent);
+PG_FUNCTION_INFO_V1(gbt_enum_penalty);
+PG_FUNCTION_INFO_V1(gbt_enum_same);
+
+
+static bool
+gbt_enumgt(const void *a, const void *b, FmgrInfo *flinfo)
+{
+	return DatumGetBool(
+		CallerFInfoFunctionCall2(enum_gt, flinfo, InvalidOid, ObjectIdGetDatum(*((const Oid *) a)), ObjectIdGetDatum(*((const Oid *) b)))
+		);
+}
+static bool
+gbt_enumge(const void *a, const void *b, FmgrInfo *flinfo)
+{
+	return DatumGetBool(
+		CallerFInfoFunctionCall2(enum_ge, flinfo, InvalidOid, ObjectIdGetDatum(*((const Oid *) a)), ObjectIdGetDatum(*((const Oid *) b)))
+		);
+}
+static bool
+gbt_enumeq(const void *a, const void *b, FmgrInfo *flinfo)
+{
+	return (*((const Oid *) a) == *((const Oid *) b));
+}
+static bool
+gbt_enumle(const void *a, const void *b, FmgrInfo *flinfo)
+{
+	return DatumGetBool(
+						CallerFInfoFunctionCall2(enum_le, flinfo, InvalidOid, ObjectIdGetDatum(*((const Oid *) a)), ObjectIdGetDatum(*((const Oid *) b)))
+		);
+}
+static bool
+gbt_enumlt(const void *a, const void *b, FmgrInfo *flinfo)
+{
+	return DatumGetBool(
+						CallerFInfoFunctionCall2(enum_lt, flinfo, InvalidOid, ObjectIdGetDatum(*((const Oid *) a)), ObjectIdGetDatum(*((const Oid *) b)))
+		);
+}
+
+static int
+gbt_enumkey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
+{
+	oidKEY	   *ia = (oidKEY *) (((const Nsrt *) a)->t);
+	oidKEY	   *ib = (oidKEY *) (((const Nsrt *) b)->t);
+
+	if (ia->lower == ib->lower)
+	{
+		if (ia->upper == ib->upper)
+			return 0;
+
+		return DatumGetInt32(
+			CallerFInfoFunctionCall2(enum_cmp, flinfo, InvalidOid, ObjectIdGetDatum(ia->upper), ObjectIdGetDatum(ib->upper))
+			);
+	}
+
+	return DatumGetInt32(
+		CallerFInfoFunctionCall2(enum_cmp, flinfo, InvalidOid, ObjectIdGetDatum(ia->lower), ObjectIdGetDatum(ib->lower))
+		);
+}
+
+static const gbtree_ninfo tinfo =
+{
+	gbt_t_enum,
+	sizeof(Oid),
+	8,							/* sizeof(gbtreekey8) */
+	gbt_enumgt,
+	gbt_enumge,
+	gbt_enumeq,
+	gbt_enumle,
+	gbt_enumlt,
+	gbt_enumkey_cmp,
+	NULL /* no KNN support at least for now */
+};
+
+
+/**************************************************
+ * Enum ops
+ **************************************************/
+
+
+Datum
+gbt_enum_compress(PG_FUNCTION_ARGS)
+{
+	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+
+	PG_RETURN_POINTER(gbt_num_compress(entry, &tinfo));
+}
+
+Datum
+gbt_enum_fetch(PG_FUNCTION_ARGS)
+{
+	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+
+	PG_RETURN_POINTER(gbt_num_fetch(entry, &tinfo));
+}
+
+Datum
+gbt_enum_consistent(PG_FUNCTION_ARGS)
+{
+	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+	Oid			query = PG_GETARG_OID(1);
+	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
+
+	/* Oid		subtype = PG_GETARG_OID(3); */
+	bool	   *recheck = (bool *) PG_GETARG_POINTER(4);
+	oidKEY	   *kkk = (oidKEY *) DatumGetPointer(entry->key);
+	GBT_NUMKEY_R key;
+
+	/* All cases served by this function are exact */
+	*recheck = false;
+
+	key.lower = (GBT_NUMKEY *) &kkk->lower;
+	key.upper = (GBT_NUMKEY *) &kkk->upper;
+
+	PG_RETURN_BOOL(
+				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
+		);
+}
+
+Datum
+gbt_enum_union(PG_FUNCTION_ARGS)
+{
+	GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
+	void	   *out = palloc(sizeof(oidKEY));
+
+	*(int *) PG_GETARG_POINTER(1) = sizeof(oidKEY);
+	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
+}
+
+
+Datum
+gbt_enum_penalty(PG_FUNCTION_ARGS)
+{
+	oidKEY	   *origentry = (oidKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
+	oidKEY	   *newentry = (oidKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
+	float	   *result = (float *) PG_GETARG_POINTER(2);
+
+	penalty_num(result, origentry->lower, origentry->upper, newentry->lower, newentry->upper);
+
+	PG_RETURN_POINTER(result);
+}
+
+Datum
+gbt_enum_picksplit(PG_FUNCTION_ARGS)
+{
+	PG_RETURN_POINTER(gbt_num_picksplit(
+									(GistEntryVector *) PG_GETARG_POINTER(0),
+									  (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
+										&tinfo, fcinfo->flinfo
+										));
+}
+
+Datum
+gbt_enum_same(PG_FUNCTION_ARGS)
+{
+	oidKEY	   *b1 = (oidKEY *) PG_GETARG_POINTER(0);
+	oidKEY	   *b2 = (oidKEY *) PG_GETARG_POINTER(1);
+	bool	   *result = (bool *) PG_GETARG_POINTER(2);
+
+	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
+	PG_RETURN_POINTER(result);
+}
diff --git a/contrib/btree_gist/btree_float4.c b/contrib/btree_gist/btree_float4.c
index 13dc4a5..46b3edb 100644
--- a/contrib/btree_gist/btree_float4.c
+++ b/contrib/btree_gist/btree_float4.c
@@ -25,33 +25,33 @@ PG_FUNCTION_INFO_V1(gbt_float4_penalty);
 PG_FUNCTION_INFO_V1(gbt_float4_same);
 
 static bool
-gbt_float4gt(const void *a, const void *b)
+gbt_float4gt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const float4 *) a) > *((const float4 *) b));
 }
 static bool
-gbt_float4ge(const void *a, const void *b)
+gbt_float4ge(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const float4 *) a) >= *((const float4 *) b));
 }
 static bool
-gbt_float4eq(const void *a, const void *b)
+gbt_float4eq(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const float4 *) a) == *((const float4 *) b));
 }
 static bool
-gbt_float4le(const void *a, const void *b)
+gbt_float4le(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const float4 *) a) <= *((const float4 *) b));
 }
 static bool
-gbt_float4lt(const void *a, const void *b)
+gbt_float4lt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const float4 *) a) < *((const float4 *) b));
 }
 
 static int
-gbt_float4key_cmp(const void *a, const void *b)
+gbt_float4key_cmp(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	float4KEY  *ia = (float4KEY *) (((const Nsrt *) a)->t);
 	float4KEY  *ib = (float4KEY *) (((const Nsrt *) b)->t);
@@ -68,7 +68,7 @@ gbt_float4key_cmp(const void *a, const void *b)
 }
 
 static float8
-gbt_float4_dist(const void *a, const void *b)
+gbt_float4_dist(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return GET_FLOAT_DISTANCE(float4, a, b);
 }
@@ -144,7 +144,7 @@ gbt_float4_consistent(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_BOOL(
-				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo)
+				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -163,7 +163,7 @@ gbt_float4_distance(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_FLOAT8(
-			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo)
+			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -175,7 +175,7 @@ gbt_float4_union(PG_FUNCTION_ARGS)
 	void	   *out = palloc(sizeof(float4KEY));
 
 	*(int *) PG_GETARG_POINTER(1) = sizeof(float4KEY);
-	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
+	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
 }
 
 
@@ -198,7 +198,7 @@ gbt_float4_picksplit(PG_FUNCTION_ARGS)
 	PG_RETURN_POINTER(gbt_num_picksplit(
 									(GistEntryVector *) PG_GETARG_POINTER(0),
 									  (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
-										&tinfo
+										&tinfo, fcinfo->flinfo
 										));
 }
 
@@ -209,6 +209,6 @@ gbt_float4_same(PG_FUNCTION_ARGS)
 	float4KEY  *b2 = (float4KEY *) PG_GETARG_POINTER(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
 
-	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
+	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(result);
 }
diff --git a/contrib/btree_gist/btree_float8.c b/contrib/btree_gist/btree_float8.c
index c3a2415..7d65307 100644
--- a/contrib/btree_gist/btree_float8.c
+++ b/contrib/btree_gist/btree_float8.c
@@ -26,33 +26,33 @@ PG_FUNCTION_INFO_V1(gbt_float8_same);
 
 
 static bool
-gbt_float8gt(const void *a, const void *b)
+gbt_float8gt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const float8 *) a) > *((const float8 *) b));
 }
 static bool
-gbt_float8ge(const void *a, const void *b)
+gbt_float8ge(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const float8 *) a) >= *((const float8 *) b));
 }
 static bool
-gbt_float8eq(const void *a, const void *b)
+gbt_float8eq(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const float8 *) a) == *((const float8 *) b));
 }
 static bool
-gbt_float8le(const void *a, const void *b)
+gbt_float8le(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const float8 *) a) <= *((const float8 *) b));
 }
 static bool
-gbt_float8lt(const void *a, const void *b)
+gbt_float8lt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const float8 *) a) < *((const float8 *) b));
 }
 
 static int
-gbt_float8key_cmp(const void *a, const void *b)
+gbt_float8key_cmp(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	float8KEY  *ia = (float8KEY *) (((const Nsrt *) a)->t);
 	float8KEY  *ib = (float8KEY *) (((const Nsrt *) b)->t);
@@ -69,7 +69,7 @@ gbt_float8key_cmp(const void *a, const void *b)
 }
 
 static float8
-gbt_float8_dist(const void *a, const void *b)
+gbt_float8_dist(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	float8		arg1 = *(const float8 *) a;
 	float8		arg2 = *(const float8 *) b;
@@ -151,7 +151,7 @@ gbt_float8_consistent(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_BOOL(
-				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo)
+				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -170,7 +170,7 @@ gbt_float8_distance(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_FLOAT8(
-			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo)
+			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -182,7 +182,7 @@ gbt_float8_union(PG_FUNCTION_ARGS)
 	void	   *out = palloc(sizeof(float8KEY));
 
 	*(int *) PG_GETARG_POINTER(1) = sizeof(float8KEY);
-	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
+	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
 }
 
 
@@ -205,7 +205,7 @@ gbt_float8_picksplit(PG_FUNCTION_ARGS)
 	PG_RETURN_POINTER(gbt_num_picksplit(
 									(GistEntryVector *) PG_GETARG_POINTER(0),
 									  (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
-										&tinfo
+										&tinfo, fcinfo->flinfo
 										));
 }
 
@@ -216,6 +216,6 @@ gbt_float8_same(PG_FUNCTION_ARGS)
 	float8KEY  *b2 = (float8KEY *) PG_GETARG_POINTER(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
 
-	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
+	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(result);
 }
diff --git a/contrib/btree_gist/btree_gist--1.3--1.4.sql b/contrib/btree_gist/btree_gist--1.3--1.4.sql
index f77f6c8..e8dabe1 100644
--- a/contrib/btree_gist/btree_gist--1.3--1.4.sql
+++ b/contrib/btree_gist/btree_gist--1.3--1.4.sql
@@ -62,3 +62,69 @@ AS
 ALTER OPERATOR FAMILY gist_macaddr8_ops USING gist ADD
 	OPERATOR	6	<> (macaddr8, macaddr8) ,
 	FUNCTION	9 (macaddr8, macaddr8) gbt_macad8_fetch (internal);
+
+
+--
+--
+--
+-- enum ops
+--
+--
+--
+-- define the GiST support methods
+CREATE FUNCTION gbt_enum_consistent(internal,anyenum,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_union(internal, internal)
+RETURNS gbtreekey8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_enum_same(gbtreekey8, gbtreekey8, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_enum_ops
+DEFAULT FOR TYPE anyenum USING gist
+AS
+	OPERATOR	1	<  ,
+	OPERATOR	2	<= ,
+	OPERATOR	3	=  ,
+	OPERATOR	4	>= ,
+	OPERATOR	5	>  ,
+	FUNCTION	1	gbt_enum_consistent (internal, anyenum, int2, oid, internal),
+	FUNCTION	2	gbt_enum_union (internal, internal),
+	FUNCTION	3	gbt_enum_compress (internal),
+	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	5	gbt_enum_penalty (internal, internal, internal),
+	FUNCTION	6	gbt_enum_picksplit (internal, internal),
+	FUNCTION	7	gbt_enum_same (gbtreekey8, gbtreekey8, internal),
+	STORAGE		gbtreekey8;
+
+ALTER OPERATOR FAMILY gist_enum_ops USING gist ADD
+	OPERATOR	6	<> (anyenum, anyenum) ,
+	FUNCTION	9 (anyenum, anyenum) gbt_enum_fetch (internal) ;
diff --git a/contrib/btree_gist/btree_gist.h b/contrib/btree_gist/btree_gist.h
index f759299..011285a 100644
--- a/contrib/btree_gist/btree_gist.h
+++ b/contrib/btree_gist/btree_gist.h
@@ -33,7 +33,8 @@ enum gbtree_type
 	gbt_t_bytea,
 	gbt_t_bit,
 	gbt_t_inet,
-	gbt_t_uuid
+	gbt_t_uuid,
+	gbt_t_enum
 };
 
 #endif
diff --git a/contrib/btree_gist/btree_inet.c b/contrib/btree_gist/btree_inet.c
index 8227861..7c95ee6 100644
--- a/contrib/btree_gist/btree_inet.c
+++ b/contrib/btree_gist/btree_inet.c
@@ -27,33 +27,33 @@ PG_FUNCTION_INFO_V1(gbt_inet_same);
 
 
 static bool
-gbt_inetgt(const void *a, const void *b)
+gbt_inetgt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const double *) a) > *((const double *) b));
 }
 static bool
-gbt_inetge(const void *a, const void *b)
+gbt_inetge(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const double *) a) >= *((const double *) b));
 }
 static bool
-gbt_ineteq(const void *a, const void *b)
+gbt_ineteq(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const double *) a) == *((const double *) b));
 }
 static bool
-gbt_inetle(const void *a, const void *b)
+gbt_inetle(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const double *) a) <= *((const double *) b));
 }
 static bool
-gbt_inetlt(const void *a, const void *b)
+gbt_inetlt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const double *) a) < *((const double *) b));
 }
 
 static int
-gbt_inetkey_cmp(const void *a, const void *b)
+gbt_inetkey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	inetKEY    *ia = (inetKEY *) (((const Nsrt *) a)->t);
 	inetKEY    *ib = (inetKEY *) (((const Nsrt *) b)->t);
@@ -133,7 +133,7 @@ gbt_inet_consistent(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_BOOL(gbt_num_consistent(&key, (void *) &query,
-									  &strategy, GIST_LEAF(entry), &tinfo));
+									  &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo));
 }
 
 
@@ -144,7 +144,7 @@ gbt_inet_union(PG_FUNCTION_ARGS)
 	void	   *out = palloc(sizeof(inetKEY));
 
 	*(int *) PG_GETARG_POINTER(1) = sizeof(inetKEY);
-	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
+	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
 }
 
 
@@ -167,7 +167,7 @@ gbt_inet_picksplit(PG_FUNCTION_ARGS)
 	PG_RETURN_POINTER(gbt_num_picksplit(
 									(GistEntryVector *) PG_GETARG_POINTER(0),
 									  (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
-										&tinfo
+										&tinfo, fcinfo->flinfo
 										));
 }
 
@@ -178,6 +178,6 @@ gbt_inet_same(PG_FUNCTION_ARGS)
 	inetKEY    *b2 = (inetKEY *) PG_GETARG_POINTER(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
 
-	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
+	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(result);
 }
diff --git a/contrib/btree_gist/btree_int2.c b/contrib/btree_gist/btree_int2.c
index 54dc1cc..3dae5e7 100644
--- a/contrib/btree_gist/btree_int2.c
+++ b/contrib/btree_gist/btree_int2.c
@@ -25,33 +25,33 @@ PG_FUNCTION_INFO_V1(gbt_int2_penalty);
 PG_FUNCTION_INFO_V1(gbt_int2_same);
 
 static bool
-gbt_int2gt(const void *a, const void *b)
+gbt_int2gt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const int16 *) a) > *((const int16 *) b));
 }
 static bool
-gbt_int2ge(const void *a, const void *b)
+gbt_int2ge(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const int16 *) a) >= *((const int16 *) b));
 }
 static bool
-gbt_int2eq(const void *a, const void *b)
+gbt_int2eq(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const int16 *) a) == *((const int16 *) b));
 }
 static bool
-gbt_int2le(const void *a, const void *b)
+gbt_int2le(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const int16 *) a) <= *((const int16 *) b));
 }
 static bool
-gbt_int2lt(const void *a, const void *b)
+gbt_int2lt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const int16 *) a) < *((const int16 *) b));
 }
 
 static int
-gbt_int2key_cmp(const void *a, const void *b)
+gbt_int2key_cmp(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	int16KEY   *ia = (int16KEY *) (((const Nsrt *) a)->t);
 	int16KEY   *ib = (int16KEY *) (((const Nsrt *) b)->t);
@@ -68,7 +68,7 @@ gbt_int2key_cmp(const void *a, const void *b)
 }
 
 static float8
-gbt_int2_dist(const void *a, const void *b)
+gbt_int2_dist(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return GET_FLOAT_DISTANCE(int16, a, b);
 }
@@ -151,7 +151,7 @@ gbt_int2_consistent(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_BOOL(
-				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo)
+				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -170,7 +170,7 @@ gbt_int2_distance(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_FLOAT8(
-			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo)
+			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -182,7 +182,7 @@ gbt_int2_union(PG_FUNCTION_ARGS)
 	void	   *out = palloc(sizeof(int16KEY));
 
 	*(int *) PG_GETARG_POINTER(1) = sizeof(int16KEY);
-	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
+	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
 }
 
 
@@ -204,7 +204,7 @@ gbt_int2_picksplit(PG_FUNCTION_ARGS)
 	PG_RETURN_POINTER(gbt_num_picksplit(
 									(GistEntryVector *) PG_GETARG_POINTER(0),
 									  (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
-										&tinfo
+										&tinfo, fcinfo->flinfo
 										));
 }
 
@@ -215,6 +215,6 @@ gbt_int2_same(PG_FUNCTION_ARGS)
 	int16KEY   *b2 = (int16KEY *) PG_GETARG_POINTER(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
 
-	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
+	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(result);
 }
diff --git a/contrib/btree_gist/btree_int4.c b/contrib/btree_gist/btree_int4.c
index ddbcf52..213bfa3 100644
--- a/contrib/btree_gist/btree_int4.c
+++ b/contrib/btree_gist/btree_int4.c
@@ -26,33 +26,33 @@ PG_FUNCTION_INFO_V1(gbt_int4_same);
 
 
 static bool
-gbt_int4gt(const void *a, const void *b)
+gbt_int4gt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const int32 *) a) > *((const int32 *) b));
 }
 static bool
-gbt_int4ge(const void *a, const void *b)
+gbt_int4ge(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const int32 *) a) >= *((const int32 *) b));
 }
 static bool
-gbt_int4eq(const void *a, const void *b)
+gbt_int4eq(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const int32 *) a) == *((const int32 *) b));
 }
 static bool
-gbt_int4le(const void *a, const void *b)
+gbt_int4le(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const int32 *) a) <= *((const int32 *) b));
 }
 static bool
-gbt_int4lt(const void *a, const void *b)
+gbt_int4lt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const int32 *) a) < *((const int32 *) b));
 }
 
 static int
-gbt_int4key_cmp(const void *a, const void *b)
+gbt_int4key_cmp(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	int32KEY   *ia = (int32KEY *) (((const Nsrt *) a)->t);
 	int32KEY   *ib = (int32KEY *) (((const Nsrt *) b)->t);
@@ -69,7 +69,7 @@ gbt_int4key_cmp(const void *a, const void *b)
 }
 
 static float8
-gbt_int4_dist(const void *a, const void *b)
+gbt_int4_dist(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return GET_FLOAT_DISTANCE(int32, a, b);
 }
@@ -152,7 +152,7 @@ gbt_int4_consistent(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_BOOL(
-				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo)
+				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -171,7 +171,7 @@ gbt_int4_distance(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_FLOAT8(
-			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo)
+			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -183,7 +183,7 @@ gbt_int4_union(PG_FUNCTION_ARGS)
 	void	   *out = palloc(sizeof(int32KEY));
 
 	*(int *) PG_GETARG_POINTER(1) = sizeof(int32KEY);
-	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
+	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
 }
 
 
@@ -205,7 +205,7 @@ gbt_int4_picksplit(PG_FUNCTION_ARGS)
 	PG_RETURN_POINTER(gbt_num_picksplit(
 									(GistEntryVector *) PG_GETARG_POINTER(0),
 									  (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
-										&tinfo
+										&tinfo, fcinfo->flinfo
 										));
 }
 
@@ -216,6 +216,6 @@ gbt_int4_same(PG_FUNCTION_ARGS)
 	int32KEY   *b2 = (int32KEY *) PG_GETARG_POINTER(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
 
-	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
+	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(result);
 }
diff --git a/contrib/btree_gist/btree_int8.c b/contrib/btree_gist/btree_int8.c
index 44bf69a..62b079b 100644
--- a/contrib/btree_gist/btree_int8.c
+++ b/contrib/btree_gist/btree_int8.c
@@ -26,33 +26,33 @@ PG_FUNCTION_INFO_V1(gbt_int8_same);
 
 
 static bool
-gbt_int8gt(const void *a, const void *b)
+gbt_int8gt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const int64 *) a) > *((const int64 *) b));
 }
 static bool
-gbt_int8ge(const void *a, const void *b)
+gbt_int8ge(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const int64 *) a) >= *((const int64 *) b));
 }
 static bool
-gbt_int8eq(const void *a, const void *b)
+gbt_int8eq(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const int64 *) a) == *((const int64 *) b));
 }
 static bool
-gbt_int8le(const void *a, const void *b)
+gbt_int8le(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const int64 *) a) <= *((const int64 *) b));
 }
 static bool
-gbt_int8lt(const void *a, const void *b)
+gbt_int8lt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const int64 *) a) < *((const int64 *) b));
 }
 
 static int
-gbt_int8key_cmp(const void *a, const void *b)
+gbt_int8key_cmp(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	int64KEY   *ia = (int64KEY *) (((const Nsrt *) a)->t);
 	int64KEY   *ib = (int64KEY *) (((const Nsrt *) b)->t);
@@ -69,7 +69,7 @@ gbt_int8key_cmp(const void *a, const void *b)
 }
 
 static float8
-gbt_int8_dist(const void *a, const void *b)
+gbt_int8_dist(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return GET_FLOAT_DISTANCE(int64, a, b);
 }
@@ -152,7 +152,7 @@ gbt_int8_consistent(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_BOOL(
-				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo)
+				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -171,7 +171,7 @@ gbt_int8_distance(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_FLOAT8(
-			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo)
+			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -183,7 +183,7 @@ gbt_int8_union(PG_FUNCTION_ARGS)
 	void	   *out = palloc(sizeof(int64KEY));
 
 	*(int *) PG_GETARG_POINTER(1) = sizeof(int64KEY);
-	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
+	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
 }
 
 
@@ -205,7 +205,7 @@ gbt_int8_picksplit(PG_FUNCTION_ARGS)
 	PG_RETURN_POINTER(gbt_num_picksplit(
 									(GistEntryVector *) PG_GETARG_POINTER(0),
 									  (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
-										&tinfo
+										&tinfo, fcinfo->flinfo
 										));
 }
 
@@ -216,6 +216,6 @@ gbt_int8_same(PG_FUNCTION_ARGS)
 	int64KEY   *b2 = (int64KEY *) PG_GETARG_POINTER(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
 
-	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
+	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(result);
 }
diff --git a/contrib/btree_gist/btree_interval.c b/contrib/btree_gist/btree_interval.c
index e5cd0a2..f41f471 100644
--- a/contrib/btree_gist/btree_interval.c
+++ b/contrib/btree_gist/btree_interval.c
@@ -30,37 +30,37 @@ PG_FUNCTION_INFO_V1(gbt_intv_same);
 
 
 static bool
-gbt_intvgt(const void *a, const void *b)
+gbt_intvgt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(DirectFunctionCall2(interval_gt, IntervalPGetDatum(a), IntervalPGetDatum(b)));
 }
 
 static bool
-gbt_intvge(const void *a, const void *b)
+gbt_intvge(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(DirectFunctionCall2(interval_ge, IntervalPGetDatum(a), IntervalPGetDatum(b)));
 }
 
 static bool
-gbt_intveq(const void *a, const void *b)
+gbt_intveq(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(DirectFunctionCall2(interval_eq, IntervalPGetDatum(a), IntervalPGetDatum(b)));
 }
 
 static bool
-gbt_intvle(const void *a, const void *b)
+gbt_intvle(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(DirectFunctionCall2(interval_le, IntervalPGetDatum(a), IntervalPGetDatum(b)));
 }
 
 static bool
-gbt_intvlt(const void *a, const void *b)
+gbt_intvlt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(DirectFunctionCall2(interval_lt, IntervalPGetDatum(a), IntervalPGetDatum(b)));
 }
 
 static int
-gbt_intvkey_cmp(const void *a, const void *b)
+gbt_intvkey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	intvKEY    *ia = (intvKEY *) (((const Nsrt *) a)->t);
 	intvKEY    *ib = (intvKEY *) (((const Nsrt *) b)->t);
@@ -81,7 +81,7 @@ intr2num(const Interval *i)
 }
 
 static float8
-gbt_intv_dist(const void *a, const void *b)
+gbt_intv_dist(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (float8) Abs(intr2num((const Interval *) a) - intr2num((const Interval *) b));
 }
@@ -226,7 +226,7 @@ gbt_intv_consistent(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_BOOL(
-				   gbt_num_consistent(&key, (void *) query, &strategy, GIST_LEAF(entry), &tinfo)
+				   gbt_num_consistent(&key, (void *) query, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -245,7 +245,7 @@ gbt_intv_distance(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_FLOAT8(
-			 gbt_num_distance(&key, (void *) query, GIST_LEAF(entry), &tinfo)
+			 gbt_num_distance(&key, (void *) query, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -257,7 +257,7 @@ gbt_intv_union(PG_FUNCTION_ARGS)
 	void	   *out = palloc(sizeof(intvKEY));
 
 	*(int *) PG_GETARG_POINTER(1) = sizeof(intvKEY);
-	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
+	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
 }
 
 
@@ -287,7 +287,7 @@ gbt_intv_picksplit(PG_FUNCTION_ARGS)
 	PG_RETURN_POINTER(gbt_num_picksplit(
 									(GistEntryVector *) PG_GETARG_POINTER(0),
 									  (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
-										&tinfo
+										&tinfo, fcinfo->flinfo
 										));
 }
 
@@ -298,6 +298,6 @@ gbt_intv_same(PG_FUNCTION_ARGS)
 	intvKEY    *b2 = (intvKEY *) PG_GETARG_POINTER(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
 
-	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
+	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(result);
 }
diff --git a/contrib/btree_gist/btree_macaddr.c b/contrib/btree_gist/btree_macaddr.c
index 87d96c0..d530b4e 100644
--- a/contrib/btree_gist/btree_macaddr.c
+++ b/contrib/btree_gist/btree_macaddr.c
@@ -28,37 +28,37 @@ PG_FUNCTION_INFO_V1(gbt_macad_same);
 
 
 static bool
-gbt_macadgt(const void *a, const void *b)
+gbt_macadgt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(DirectFunctionCall2(macaddr_gt, PointerGetDatum(a), PointerGetDatum(b)));
 }
 static bool
-gbt_macadge(const void *a, const void *b)
+gbt_macadge(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(DirectFunctionCall2(macaddr_ge, PointerGetDatum(a), PointerGetDatum(b)));
 }
 
 static bool
-gbt_macadeq(const void *a, const void *b)
+gbt_macadeq(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(DirectFunctionCall2(macaddr_eq, PointerGetDatum(a), PointerGetDatum(b)));
 }
 
 static bool
-gbt_macadle(const void *a, const void *b)
+gbt_macadle(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(DirectFunctionCall2(macaddr_le, PointerGetDatum(a), PointerGetDatum(b)));
 }
 
 static bool
-gbt_macadlt(const void *a, const void *b)
+gbt_macadlt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(DirectFunctionCall2(macaddr_lt, PointerGetDatum(a), PointerGetDatum(b)));
 }
 
 
 static int
-gbt_macadkey_cmp(const void *a, const void *b)
+gbt_macadkey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	macKEY	   *ia = (macKEY *) (((const Nsrt *) a)->t);
 	macKEY	   *ib = (macKEY *) (((const Nsrt *) b)->t);
@@ -142,7 +142,7 @@ gbt_macad_consistent(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_BOOL(
-				   gbt_num_consistent(&key, (void *) query, &strategy, GIST_LEAF(entry), &tinfo)
+				   gbt_num_consistent(&key, (void *) query, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -154,7 +154,7 @@ gbt_macad_union(PG_FUNCTION_ARGS)
 	void	   *out = palloc0(sizeof(macKEY));
 
 	*(int *) PG_GETARG_POINTER(1) = sizeof(macKEY);
-	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
+	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
 }
 
 
@@ -184,7 +184,7 @@ gbt_macad_picksplit(PG_FUNCTION_ARGS)
 	PG_RETURN_POINTER(gbt_num_picksplit(
 									(GistEntryVector *) PG_GETARG_POINTER(0),
 									  (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
-										&tinfo
+										&tinfo, fcinfo->flinfo
 										));
 }
 
@@ -195,6 +195,6 @@ gbt_macad_same(PG_FUNCTION_ARGS)
 	macKEY	   *b2 = (macKEY *) PG_GETARG_POINTER(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
 
-	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
+	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(result);
 }
diff --git a/contrib/btree_gist/btree_macaddr8.c b/contrib/btree_gist/btree_macaddr8.c
index 13238ef..96afbcd 100644
--- a/contrib/btree_gist/btree_macaddr8.c
+++ b/contrib/btree_gist/btree_macaddr8.c
@@ -28,37 +28,37 @@ PG_FUNCTION_INFO_V1(gbt_macad8_same);
 
 
 static bool
-gbt_macad8gt(const void *a, const void *b)
+gbt_macad8gt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(DirectFunctionCall2(macaddr8_gt, PointerGetDatum(a), PointerGetDatum(b)));
 }
 static bool
-gbt_macad8ge(const void *a, const void *b)
+gbt_macad8ge(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(DirectFunctionCall2(macaddr8_ge, PointerGetDatum(a), PointerGetDatum(b)));
 }
 
 static bool
-gbt_macad8eq(const void *a, const void *b)
+gbt_macad8eq(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(DirectFunctionCall2(macaddr8_eq, PointerGetDatum(a), PointerGetDatum(b)));
 }
 
 static bool
-gbt_macad8le(const void *a, const void *b)
+gbt_macad8le(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(DirectFunctionCall2(macaddr8_le, PointerGetDatum(a), PointerGetDatum(b)));
 }
 
 static bool
-gbt_macad8lt(const void *a, const void *b)
+gbt_macad8lt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return DatumGetBool(DirectFunctionCall2(macaddr8_lt, PointerGetDatum(a), PointerGetDatum(b)));
 }
 
 
 static int
-gbt_macad8key_cmp(const void *a, const void *b)
+gbt_macad8key_cmp(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	mac8KEY    *ia = (mac8KEY *) (((const Nsrt *) a)->t);
 	mac8KEY    *ib = (mac8KEY *) (((const Nsrt *) b)->t);
@@ -142,7 +142,7 @@ gbt_macad8_consistent(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_BOOL(
-				   gbt_num_consistent(&key, (void *) query, &strategy, GIST_LEAF(entry), &tinfo)
+				   gbt_num_consistent(&key, (void *) query, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -154,7 +154,7 @@ gbt_macad8_union(PG_FUNCTION_ARGS)
 	void	   *out = palloc0(sizeof(mac8KEY));
 
 	*(int *) PG_GETARG_POINTER(1) = sizeof(mac8KEY);
-	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
+	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
 }
 
 
@@ -184,7 +184,7 @@ gbt_macad8_picksplit(PG_FUNCTION_ARGS)
 	PG_RETURN_POINTER(gbt_num_picksplit(
 									(GistEntryVector *) PG_GETARG_POINTER(0),
 									  (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
-										&tinfo
+										&tinfo, fcinfo->flinfo
 										));
 }
 
@@ -195,6 +195,6 @@ gbt_macad8_same(PG_FUNCTION_ARGS)
 	mac8KEY    *b2 = (mac8KEY *) PG_GETARG_POINTER(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
 
-	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
+	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(result);
 }
diff --git a/contrib/btree_gist/btree_numeric.c b/contrib/btree_gist/btree_numeric.c
index 47b0020..62e8f9d 100644
--- a/contrib/btree_gist/btree_numeric.c
+++ b/contrib/btree_gist/btree_numeric.c
@@ -27,7 +27,7 @@ PG_FUNCTION_INFO_V1(gbt_numeric_same);
 /* define for comparison */
 
 static bool
-gbt_numeric_gt(const void *a, const void *b, Oid collation)
+gbt_numeric_gt(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2(numeric_gt,
 											PointerGetDatum(a),
@@ -35,7 +35,7 @@ gbt_numeric_gt(const void *a, const void *b, Oid collation)
 }
 
 static bool
-gbt_numeric_ge(const void *a, const void *b, Oid collation)
+gbt_numeric_ge(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2(numeric_ge,
 											PointerGetDatum(a),
@@ -43,7 +43,7 @@ gbt_numeric_ge(const void *a, const void *b, Oid collation)
 }
 
 static bool
-gbt_numeric_eq(const void *a, const void *b, Oid collation)
+gbt_numeric_eq(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2(numeric_eq,
 											PointerGetDatum(a),
@@ -51,7 +51,7 @@ gbt_numeric_eq(const void *a, const void *b, Oid collation)
 }
 
 static bool
-gbt_numeric_le(const void *a, const void *b, Oid collation)
+gbt_numeric_le(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2(numeric_le,
 											PointerGetDatum(a),
@@ -59,7 +59,7 @@ gbt_numeric_le(const void *a, const void *b, Oid collation)
 }
 
 static bool
-gbt_numeric_lt(const void *a, const void *b, Oid collation)
+gbt_numeric_lt(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2(numeric_lt,
 											PointerGetDatum(a),
@@ -67,7 +67,7 @@ gbt_numeric_lt(const void *a, const void *b, Oid collation)
 }
 
 static int32
-gbt_numeric_cmp(const void *a, const void *b, Oid collation)
+gbt_numeric_cmp(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetInt32(DirectFunctionCall2(numeric_cmp,
 											 PointerGetDatum(a),
@@ -122,7 +122,7 @@ gbt_numeric_consistent(PG_FUNCTION_ARGS)
 	*recheck = false;
 
 	retval = gbt_var_consistent(&r, query, strategy, PG_GET_COLLATION(),
-								GIST_LEAF(entry), &tinfo);
+								GIST_LEAF(entry), &tinfo, fcinfo->flinfo);
 	PG_RETURN_BOOL(retval);
 }
 
@@ -135,7 +135,7 @@ gbt_numeric_union(PG_FUNCTION_ARGS)
 	int32	   *size = (int *) PG_GETARG_POINTER(1);
 
 	PG_RETURN_POINTER(gbt_var_union(entryvec, size, PG_GET_COLLATION(),
-									&tinfo));
+									&tinfo, fcinfo->flinfo));
 }
 
 
@@ -146,7 +146,7 @@ gbt_numeric_same(PG_FUNCTION_ARGS)
 	Datum		d2 = PG_GETARG_DATUM(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
 
-	*result = gbt_var_same(d1, d2, PG_GET_COLLATION(), &tinfo);
+	*result = gbt_var_same(d1, d2, PG_GET_COLLATION(), &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(result);
 }
 
@@ -171,7 +171,7 @@ gbt_numeric_penalty(PG_FUNCTION_ARGS)
 
 	rk = gbt_var_key_readable(org);
 	uni = PointerGetDatum(gbt_var_key_copy(&rk));
-	gbt_var_bin_union(&uni, newe, PG_GET_COLLATION(), &tinfo);
+	gbt_var_bin_union(&uni, newe, PG_GET_COLLATION(), &tinfo, fcinfo->flinfo);
 	ok = gbt_var_key_readable(org);
 	uk = gbt_var_key_readable((GBT_VARKEY *) DatumGetPointer(uni));
 
@@ -233,6 +233,6 @@ gbt_numeric_picksplit(PG_FUNCTION_ARGS)
 	GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
 
 	gbt_var_picksplit(entryvec, v, PG_GET_COLLATION(),
-					  &tinfo);
+					  &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(v);
 }
diff --git a/contrib/btree_gist/btree_oid.c b/contrib/btree_gist/btree_oid.c
index ac61a76..e588faa 100644
--- a/contrib/btree_gist/btree_oid.c
+++ b/contrib/btree_gist/btree_oid.c
@@ -26,33 +26,33 @@ PG_FUNCTION_INFO_V1(gbt_oid_same);
 
 
 static bool
-gbt_oidgt(const void *a, const void *b)
+gbt_oidgt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const Oid *) a) > *((const Oid *) b));
 }
 static bool
-gbt_oidge(const void *a, const void *b)
+gbt_oidge(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const Oid *) a) >= *((const Oid *) b));
 }
 static bool
-gbt_oideq(const void *a, const void *b)
+gbt_oideq(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const Oid *) a) == *((const Oid *) b));
 }
 static bool
-gbt_oidle(const void *a, const void *b)
+gbt_oidle(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const Oid *) a) <= *((const Oid *) b));
 }
 static bool
-gbt_oidlt(const void *a, const void *b)
+gbt_oidlt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return (*((const Oid *) a) < *((const Oid *) b));
 }
 
 static int
-gbt_oidkey_cmp(const void *a, const void *b)
+gbt_oidkey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	oidKEY	   *ia = (oidKEY *) (((const Nsrt *) a)->t);
 	oidKEY	   *ib = (oidKEY *) (((const Nsrt *) b)->t);
@@ -69,7 +69,7 @@ gbt_oidkey_cmp(const void *a, const void *b)
 }
 
 static float8
-gbt_oid_dist(const void *a, const void *b)
+gbt_oid_dist(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	Oid			aa = *(const Oid *) a;
 	Oid			bb = *(const Oid *) b;
@@ -152,7 +152,7 @@ gbt_oid_consistent(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_BOOL(
-				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo)
+				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -171,7 +171,7 @@ gbt_oid_distance(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_FLOAT8(
-			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo)
+			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -183,7 +183,7 @@ gbt_oid_union(PG_FUNCTION_ARGS)
 	void	   *out = palloc(sizeof(oidKEY));
 
 	*(int *) PG_GETARG_POINTER(1) = sizeof(oidKEY);
-	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
+	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
 }
 
 
@@ -205,7 +205,7 @@ gbt_oid_picksplit(PG_FUNCTION_ARGS)
 	PG_RETURN_POINTER(gbt_num_picksplit(
 									(GistEntryVector *) PG_GETARG_POINTER(0),
 									  (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
-										&tinfo
+										&tinfo, fcinfo->flinfo
 										));
 }
 
@@ -216,6 +216,6 @@ gbt_oid_same(PG_FUNCTION_ARGS)
 	oidKEY	   *b2 = (oidKEY *) PG_GETARG_POINTER(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
 
-	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
+	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(result);
 }
diff --git a/contrib/btree_gist/btree_text.c b/contrib/btree_gist/btree_text.c
index 2e00cb6..51fc310 100644
--- a/contrib/btree_gist/btree_text.c
+++ b/contrib/btree_gist/btree_text.c
@@ -23,7 +23,7 @@ PG_FUNCTION_INFO_V1(gbt_text_same);
 /* define for comparison */
 
 static bool
-gbt_textgt(const void *a, const void *b, Oid collation)
+gbt_textgt(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2Coll(text_gt,
 												collation,
@@ -32,7 +32,7 @@ gbt_textgt(const void *a, const void *b, Oid collation)
 }
 
 static bool
-gbt_textge(const void *a, const void *b, Oid collation)
+gbt_textge(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2Coll(text_ge,
 												collation,
@@ -41,7 +41,7 @@ gbt_textge(const void *a, const void *b, Oid collation)
 }
 
 static bool
-gbt_texteq(const void *a, const void *b, Oid collation)
+gbt_texteq(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2Coll(texteq,
 												collation,
@@ -50,7 +50,7 @@ gbt_texteq(const void *a, const void *b, Oid collation)
 }
 
 static bool
-gbt_textle(const void *a, const void *b, Oid collation)
+gbt_textle(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2Coll(text_le,
 												collation,
@@ -59,7 +59,7 @@ gbt_textle(const void *a, const void *b, Oid collation)
 }
 
 static bool
-gbt_textlt(const void *a, const void *b, Oid collation)
+gbt_textlt(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetBool(DirectFunctionCall2Coll(text_lt,
 												collation,
@@ -68,7 +68,7 @@ gbt_textlt(const void *a, const void *b, Oid collation)
 }
 
 static int32
-gbt_textcmp(const void *a, const void *b, Oid collation)
+gbt_textcmp(const void *a, const void *b, FmgrInfo *flinfo, Oid collation)
 {
 	return DatumGetInt32(DirectFunctionCall2Coll(bttextcmp,
 												 collation,
@@ -161,7 +161,7 @@ gbt_text_consistent(PG_FUNCTION_ARGS)
 	}
 
 	retval = gbt_var_consistent(&r, query, strategy, PG_GET_COLLATION(),
-								GIST_LEAF(entry), &tinfo);
+								GIST_LEAF(entry), &tinfo, fcinfo->flinfo);
 
 	PG_RETURN_BOOL(retval);
 }
@@ -190,7 +190,7 @@ gbt_bpchar_consistent(PG_FUNCTION_ARGS)
 	}
 
 	retval = gbt_var_consistent(&r, trim, strategy, PG_GET_COLLATION(),
-								GIST_LEAF(entry), &tinfo);
+								GIST_LEAF(entry), &tinfo, fcinfo->flinfo);
 	PG_RETURN_BOOL(retval);
 }
 
@@ -202,7 +202,7 @@ gbt_text_union(PG_FUNCTION_ARGS)
 	int32	   *size = (int *) PG_GETARG_POINTER(1);
 
 	PG_RETURN_POINTER(gbt_var_union(entryvec, size, PG_GET_COLLATION(),
-									&tinfo));
+									&tinfo, fcinfo->flinfo));
 }
 
 
@@ -213,7 +213,7 @@ gbt_text_picksplit(PG_FUNCTION_ARGS)
 	GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
 
 	gbt_var_picksplit(entryvec, v, PG_GET_COLLATION(),
-					  &tinfo);
+					  &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(v);
 }
 
@@ -224,7 +224,7 @@ gbt_text_same(PG_FUNCTION_ARGS)
 	Datum		d2 = PG_GETARG_DATUM(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
 
-	*result = gbt_var_same(d1, d2, PG_GET_COLLATION(), &tinfo);
+	*result = gbt_var_same(d1, d2, PG_GET_COLLATION(), &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(result);
 }
 
@@ -237,5 +237,5 @@ gbt_text_penalty(PG_FUNCTION_ARGS)
 	float	   *result = (float *) PG_GETARG_POINTER(2);
 
 	PG_RETURN_POINTER(gbt_var_penalty(result, o, n, PG_GET_COLLATION(),
-									  &tinfo));
+									  &tinfo, fcinfo->flinfo));
 }
diff --git a/contrib/btree_gist/btree_time.c b/contrib/btree_gist/btree_time.c
index 959b282..a4a1ad5 100644
--- a/contrib/btree_gist/btree_time.c
+++ b/contrib/btree_gist/btree_time.c
@@ -38,7 +38,7 @@ PG_FUNCTION_INFO_V1(gbt_time_same);
 
 
 static bool
-gbt_timegt(const void *a, const void *b)
+gbt_timegt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	const TimeADT *aa = (const TimeADT *) a;
 	const TimeADT *bb = (const TimeADT *) b;
@@ -49,7 +49,7 @@ gbt_timegt(const void *a, const void *b)
 }
 
 static bool
-gbt_timege(const void *a, const void *b)
+gbt_timege(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	const TimeADT *aa = (const TimeADT *) a;
 	const TimeADT *bb = (const TimeADT *) b;
@@ -60,7 +60,7 @@ gbt_timege(const void *a, const void *b)
 }
 
 static bool
-gbt_timeeq(const void *a, const void *b)
+gbt_timeeq(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	const TimeADT *aa = (const TimeADT *) a;
 	const TimeADT *bb = (const TimeADT *) b;
@@ -71,7 +71,7 @@ gbt_timeeq(const void *a, const void *b)
 }
 
 static bool
-gbt_timele(const void *a, const void *b)
+gbt_timele(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	const TimeADT *aa = (const TimeADT *) a;
 	const TimeADT *bb = (const TimeADT *) b;
@@ -82,7 +82,7 @@ gbt_timele(const void *a, const void *b)
 }
 
 static bool
-gbt_timelt(const void *a, const void *b)
+gbt_timelt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	const TimeADT *aa = (const TimeADT *) a;
 	const TimeADT *bb = (const TimeADT *) b;
@@ -95,7 +95,7 @@ gbt_timelt(const void *a, const void *b)
 
 
 static int
-gbt_timekey_cmp(const void *a, const void *b)
+gbt_timekey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	timeKEY    *ia = (timeKEY *) (((const Nsrt *) a)->t);
 	timeKEY    *ib = (timeKEY *) (((const Nsrt *) b)->t);
@@ -109,7 +109,7 @@ gbt_timekey_cmp(const void *a, const void *b)
 }
 
 static float8
-gbt_time_dist(const void *a, const void *b)
+gbt_time_dist(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	const TimeADT *aa = (const TimeADT *) a;
 	const TimeADT *bb = (const TimeADT *) b;
@@ -217,7 +217,7 @@ gbt_time_consistent(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_BOOL(
-				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo)
+				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -235,7 +235,7 @@ gbt_time_distance(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_FLOAT8(
-			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo)
+			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -261,7 +261,7 @@ gbt_timetz_consistent(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_BOOL(
-				   gbt_num_consistent(&key, (void *) &qqq, &strategy, GIST_LEAF(entry), &tinfo)
+				   gbt_num_consistent(&key, (void *) &qqq, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -273,7 +273,7 @@ gbt_time_union(PG_FUNCTION_ARGS)
 	void	   *out = palloc(sizeof(timeKEY));
 
 	*(int *) PG_GETARG_POINTER(1) = sizeof(timeKEY);
-	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
+	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
 }
 
 
@@ -326,7 +326,7 @@ gbt_time_picksplit(PG_FUNCTION_ARGS)
 	PG_RETURN_POINTER(gbt_num_picksplit(
 									(GistEntryVector *) PG_GETARG_POINTER(0),
 									  (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
-										&tinfo
+										&tinfo, fcinfo->flinfo
 										));
 }
 
@@ -337,6 +337,6 @@ gbt_time_same(PG_FUNCTION_ARGS)
 	timeKEY    *b2 = (timeKEY *) PG_GETARG_POINTER(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
 
-	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
+	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(result);
 }
diff --git a/contrib/btree_gist/btree_ts.c b/contrib/btree_gist/btree_ts.c
index 97408f5..13bc394 100644
--- a/contrib/btree_gist/btree_ts.c
+++ b/contrib/btree_gist/btree_ts.c
@@ -40,7 +40,7 @@ PG_FUNCTION_INFO_V1(gbt_ts_same);
 
 
 static bool
-gbt_tsgt(const void *a, const void *b)
+gbt_tsgt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	const Timestamp *aa = (const Timestamp *) a;
 	const Timestamp *bb = (const Timestamp *) b;
@@ -51,7 +51,7 @@ gbt_tsgt(const void *a, const void *b)
 }
 
 static bool
-gbt_tsge(const void *a, const void *b)
+gbt_tsge(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	const Timestamp *aa = (const Timestamp *) a;
 	const Timestamp *bb = (const Timestamp *) b;
@@ -62,7 +62,7 @@ gbt_tsge(const void *a, const void *b)
 }
 
 static bool
-gbt_tseq(const void *a, const void *b)
+gbt_tseq(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	const Timestamp *aa = (const Timestamp *) a;
 	const Timestamp *bb = (const Timestamp *) b;
@@ -73,7 +73,7 @@ gbt_tseq(const void *a, const void *b)
 }
 
 static bool
-gbt_tsle(const void *a, const void *b)
+gbt_tsle(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	const Timestamp *aa = (const Timestamp *) a;
 	const Timestamp *bb = (const Timestamp *) b;
@@ -84,7 +84,7 @@ gbt_tsle(const void *a, const void *b)
 }
 
 static bool
-gbt_tslt(const void *a, const void *b)
+gbt_tslt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	const Timestamp *aa = (const Timestamp *) a;
 	const Timestamp *bb = (const Timestamp *) b;
@@ -96,7 +96,7 @@ gbt_tslt(const void *a, const void *b)
 
 
 static int
-gbt_tskey_cmp(const void *a, const void *b)
+gbt_tskey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	tsKEY	   *ia = (tsKEY *) (((const Nsrt *) a)->t);
 	tsKEY	   *ib = (tsKEY *) (((const Nsrt *) b)->t);
@@ -110,7 +110,7 @@ gbt_tskey_cmp(const void *a, const void *b)
 }
 
 static float8
-gbt_ts_dist(const void *a, const void *b)
+gbt_ts_dist(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	const Timestamp *aa = (const Timestamp *) a;
 	const Timestamp *bb = (const Timestamp *) b;
@@ -265,7 +265,7 @@ gbt_ts_consistent(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_BOOL(
-				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo)
+				   gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -283,7 +283,7 @@ gbt_ts_distance(PG_FUNCTION_ARGS)
 	key.upper = (GBT_NUMKEY *) &kkk->upper;
 
 	PG_RETURN_FLOAT8(
-			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo)
+			gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -308,7 +308,7 @@ gbt_tstz_consistent(PG_FUNCTION_ARGS)
 	qqq = tstz_to_ts_gmt(query);
 
 	PG_RETURN_BOOL(
-				   gbt_num_consistent(&key, (void *) &qqq, &strategy, GIST_LEAF(entry), &tinfo)
+				   gbt_num_consistent(&key, (void *) &qqq, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -328,7 +328,7 @@ gbt_tstz_distance(PG_FUNCTION_ARGS)
 	qqq = tstz_to_ts_gmt(query);
 
 	PG_RETURN_FLOAT8(
-			  gbt_num_distance(&key, (void *) &qqq, GIST_LEAF(entry), &tinfo)
+			  gbt_num_distance(&key, (void *) &qqq, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -340,7 +340,7 @@ gbt_ts_union(PG_FUNCTION_ARGS)
 	void	   *out = palloc(sizeof(tsKEY));
 
 	*(int *) PG_GETARG_POINTER(1) = sizeof(tsKEY);
-	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
+	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
 }
 
 
@@ -389,7 +389,7 @@ gbt_ts_picksplit(PG_FUNCTION_ARGS)
 	PG_RETURN_POINTER(gbt_num_picksplit(
 									(GistEntryVector *) PG_GETARG_POINTER(0),
 									  (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
-										&tinfo
+										&tinfo, fcinfo->flinfo
 										));
 }
 
@@ -400,6 +400,6 @@ gbt_ts_same(PG_FUNCTION_ARGS)
 	tsKEY	   *b2 = (tsKEY *) PG_GETARG_POINTER(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
 
-	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
+	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(result);
 }
diff --git a/contrib/btree_gist/btree_utils_num.c b/contrib/btree_gist/btree_utils_num.c
index 99cb41f..d4fee91 100644
--- a/contrib/btree_gist/btree_utils_num.c
+++ b/contrib/btree_gist/btree_utils_num.c
@@ -48,6 +48,7 @@ gbt_num_compress(GISTENTRY *entry, const gbtree_ninfo *tinfo)
 				leaf = &v.i8;
 				break;
 			case gbt_t_oid:
+			case gbt_t_enum:
 				v.i4 = DatumGetObjectId(entry->key);
 				leaf = &v.i4;
 				break;
@@ -122,6 +123,7 @@ gbt_num_fetch(GISTENTRY *entry, const gbtree_ninfo *tinfo)
 			datum = Int64GetDatum(*(int64 *) entry->key);
 			break;
 		case gbt_t_oid:
+		case gbt_t_enum:
 			datum = ObjectIdGetDatum(*(Oid *) entry->key);
 			break;
 		case gbt_t_float4:
@@ -159,7 +161,7 @@ gbt_num_fetch(GISTENTRY *entry, const gbtree_ninfo *tinfo)
 */
 
 void *
-gbt_num_union(GBT_NUMKEY *out, const GistEntryVector *entryvec, const gbtree_ninfo *tinfo)
+gbt_num_union(GBT_NUMKEY *out, const GistEntryVector *entryvec, const gbtree_ninfo *tinfo, FmgrInfo *flinfo)
 {
 	int			i,
 				numranges;
@@ -181,9 +183,9 @@ gbt_num_union(GBT_NUMKEY *out, const GistEntryVector *entryvec, const gbtree_nin
 		cur = (GBT_NUMKEY *) DatumGetPointer((entryvec->vector[i].key));
 		c.lower = &cur[0];
 		c.upper = &cur[tinfo->size];
-		if ((*tinfo->f_gt) (o.lower, c.lower))	/* out->lower > cur->lower */
+		if ((*tinfo->f_gt) (o.lower, c.lower, flinfo))	/* out->lower > cur->lower */
 			memcpy((void *) o.lower, (void *) c.lower, tinfo->size);
-		if ((*tinfo->f_lt) (o.upper, c.upper))	/* out->upper < cur->upper */
+		if ((*tinfo->f_lt) (o.upper, c.upper, flinfo))	/* out->upper < cur->upper */
 			memcpy((void *) o.upper, (void *) c.upper, tinfo->size);
 	}
 
@@ -197,7 +199,7 @@ gbt_num_union(GBT_NUMKEY *out, const GistEntryVector *entryvec, const gbtree_nin
 */
 
 bool
-gbt_num_same(const GBT_NUMKEY *a, const GBT_NUMKEY *b, const gbtree_ninfo *tinfo)
+gbt_num_same(const GBT_NUMKEY *a, const GBT_NUMKEY *b, const gbtree_ninfo *tinfo, FmgrInfo *flinfo)
 {
 	GBT_NUMKEY_R b1,
 				b2;
@@ -207,13 +209,13 @@ gbt_num_same(const GBT_NUMKEY *a, const GBT_NUMKEY *b, const gbtree_ninfo *tinfo
 	b2.lower = &(((GBT_NUMKEY *) b)[0]);
 	b2.upper = &(((GBT_NUMKEY *) b)[tinfo->size]);
 
-	return ((*tinfo->f_eq) (b1.lower, b2.lower) &&
-			(*tinfo->f_eq) (b1.upper, b2.upper));
+	return ((*tinfo->f_eq) (b1.lower, b2.lower, flinfo) &&
+			(*tinfo->f_eq) (b1.upper, b2.upper, flinfo));
 }
 
 
 void
-gbt_num_bin_union(Datum *u, GBT_NUMKEY *e, const gbtree_ninfo *tinfo)
+gbt_num_bin_union(Datum *u, GBT_NUMKEY *e, const gbtree_ninfo *tinfo, FmgrInfo *flinfo)
 {
 	GBT_NUMKEY_R rd;
 
@@ -232,9 +234,9 @@ gbt_num_bin_union(Datum *u, GBT_NUMKEY *e, const gbtree_ninfo *tinfo)
 
 		ur.lower = &(((GBT_NUMKEY *) DatumGetPointer(*u))[0]);
 		ur.upper = &(((GBT_NUMKEY *) DatumGetPointer(*u))[tinfo->size]);
-		if ((*tinfo->f_gt) ((void *) ur.lower, (void *) rd.lower))
+		if ((*tinfo->f_gt) ((void *) ur.lower, (void *) rd.lower, flinfo))
 			memcpy((void *) ur.lower, (void *) rd.lower, tinfo->size);
-		if ((*tinfo->f_lt) ((void *) ur.upper, (void *) rd.upper))
+		if ((*tinfo->f_lt) ((void *) ur.upper, (void *) rd.upper, flinfo))
 			memcpy((void *) ur.upper, (void *) rd.upper, tinfo->size);
 	}
 }
@@ -252,39 +254,40 @@ gbt_num_consistent(const GBT_NUMKEY_R *key,
 				   const void *query,
 				   const StrategyNumber *strategy,
 				   bool is_leaf,
-				   const gbtree_ninfo *tinfo)
+				   const gbtree_ninfo *tinfo,
+				   FmgrInfo *flinfo)
 {
 	bool		retval;
 
 	switch (*strategy)
 	{
 		case BTLessEqualStrategyNumber:
-			retval = (*tinfo->f_ge) (query, key->lower);
+			retval = (*tinfo->f_ge) (query, key->lower, flinfo);
 			break;
 		case BTLessStrategyNumber:
 			if (is_leaf)
-				retval = (*tinfo->f_gt) (query, key->lower);
+				retval = (*tinfo->f_gt) (query, key->lower, flinfo);
 			else
-				retval = (*tinfo->f_ge) (query, key->lower);
+				retval = (*tinfo->f_ge) (query, key->lower, flinfo);
 			break;
 		case BTEqualStrategyNumber:
 			if (is_leaf)
-				retval = (*tinfo->f_eq) (query, key->lower);
+				retval = (*tinfo->f_eq) (query, key->lower, flinfo);
 			else
-				retval = ((*tinfo->f_le) (key->lower, query) && (*tinfo->f_le) (query, key->upper)) ? true : false;
+				retval = ((*tinfo->f_le) (key->lower, query, flinfo) && (*tinfo->f_le) (query, key->upper, flinfo)) ? true : false;
 			break;
 		case BTGreaterStrategyNumber:
 			if (is_leaf)
-				retval = (*tinfo->f_lt) (query, key->upper);
+				retval = (*tinfo->f_lt) (query, key->upper, flinfo);
 			else
-				retval = (*tinfo->f_le) (query, key->upper);
+				retval = (*tinfo->f_le) (query, key->upper, flinfo);
 			break;
 		case BTGreaterEqualStrategyNumber:
-			retval = (*tinfo->f_le) (query, key->upper);
+			retval = (*tinfo->f_le) (query, key->upper, flinfo);
 			break;
 		case BtreeGistNotEqualStrategyNumber:
-			retval = (!((*tinfo->f_eq) (query, key->lower) &&
-						(*tinfo->f_eq) (query, key->upper))) ? true : false;
+			retval = (!((*tinfo->f_eq) (query, key->lower, flinfo) &&
+						(*tinfo->f_eq) (query, key->upper, flinfo))) ? true : false;
 			break;
 		default:
 			retval = false;
@@ -302,17 +305,18 @@ float8
 gbt_num_distance(const GBT_NUMKEY_R *key,
 				 const void *query,
 				 bool is_leaf,
-				 const gbtree_ninfo *tinfo)
+				 const gbtree_ninfo *tinfo,
+				 FmgrInfo *flinfo)
 {
 	float8		retval;
 
 	if (tinfo->f_dist == NULL)
 		elog(ERROR, "KNN search is not supported for btree_gist type %d",
 			 (int) tinfo->t);
-	if (tinfo->f_le(query, key->lower))
-		retval = tinfo->f_dist(query, key->lower);
-	else if (tinfo->f_ge(query, key->upper))
-		retval = tinfo->f_dist(query, key->upper);
+	if (tinfo->f_le(query, key->lower, flinfo))
+		retval = tinfo->f_dist(query, key->lower, flinfo);
+	else if (tinfo->f_ge(query, key->upper, flinfo))
+		retval = tinfo->f_dist(query, key->upper, flinfo);
 	else
 		retval = 0.0;
 
@@ -322,7 +326,7 @@ gbt_num_distance(const GBT_NUMKEY_R *key,
 
 GIST_SPLITVEC *
 gbt_num_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v,
-				  const gbtree_ninfo *tinfo)
+				  const gbtree_ninfo *tinfo, FmgrInfo *flinfo)
 {
 	OffsetNumber i,
 				maxoff = entryvec->n - 1;
@@ -345,7 +349,7 @@ gbt_num_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v,
 		arr[i].t = (GBT_NUMKEY *) DatumGetPointer((entryvec->vector[i].key));
 		arr[i].i = i;
 	}
-	qsort((void *) &arr[FirstOffsetNumber], maxoff - FirstOffsetNumber + 1, sizeof(Nsrt), tinfo->f_cmp);
+	qsort_arg((void *) &arr[FirstOffsetNumber], maxoff - FirstOffsetNumber + 1, sizeof(Nsrt), (qsort_arg_comparator) tinfo->f_cmp, (void *) flinfo);
 
 	/* We do simply create two parts */
 
@@ -353,13 +357,13 @@ gbt_num_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v,
 	{
 		if (i <= (maxoff - FirstOffsetNumber + 1) / 2)
 		{
-			gbt_num_bin_union(&v->spl_ldatum, arr[i].t, tinfo);
+			gbt_num_bin_union(&v->spl_ldatum, arr[i].t, tinfo, flinfo);
 			v->spl_left[v->spl_nleft] = arr[i].i;
 			v->spl_nleft++;
 		}
 		else
 		{
-			gbt_num_bin_union(&v->spl_rdatum, arr[i].t, tinfo);
+			gbt_num_bin_union(&v->spl_rdatum, arr[i].t, tinfo, flinfo);
 			v->spl_right[v->spl_nright] = arr[i].i;
 			v->spl_nright++;
 		}
diff --git a/contrib/btree_gist/btree_utils_num.h b/contrib/btree_gist/btree_utils_num.h
index 67d4968..17561fa 100644
--- a/contrib/btree_gist/btree_utils_num.h
+++ b/contrib/btree_gist/btree_utils_num.h
@@ -42,13 +42,13 @@ typedef struct
 
 	/* Methods */
 
-	bool		(*f_gt) (const void *, const void *);	/* greater than */
-	bool		(*f_ge) (const void *, const void *);	/* greater or equal */
-	bool		(*f_eq) (const void *, const void *);	/* equal */
-	bool		(*f_le) (const void *, const void *);	/* less or equal */
-	bool		(*f_lt) (const void *, const void *);	/* less than */
-	int			(*f_cmp) (const void *, const void *);	/* key compare function */
-	float8		(*f_dist) (const void *, const void *); /* key distance function */
+	bool		(*f_gt) (const void *, const void *, FmgrInfo *);	/* greater than */
+	bool		(*f_ge) (const void *, const void *, FmgrInfo *);	/* greater or equal */
+	bool		(*f_eq) (const void *, const void *, FmgrInfo *);	/* equal */
+	bool		(*f_le) (const void *, const void *, FmgrInfo *);	/* less or equal */
+	bool		(*f_lt) (const void *, const void *, FmgrInfo *);	/* less than */
+	int			(*f_cmp) (const void *, const void *, FmgrInfo *);	/* key compare function */
+	float8		(*f_dist) (const void *, const void *, FmgrInfo *); /* key distance function */
 } gbtree_ninfo;
 
 
@@ -113,25 +113,25 @@ extern Interval *abs_interval(Interval *a);
 
 extern bool gbt_num_consistent(const GBT_NUMKEY_R *key, const void *query,
 				   const StrategyNumber *strategy, bool is_leaf,
-				   const gbtree_ninfo *tinfo);
+				   const gbtree_ninfo *tinfo, FmgrInfo *flinfo);
 
 extern float8 gbt_num_distance(const GBT_NUMKEY_R *key, const void *query,
-				 bool is_leaf, const gbtree_ninfo *tinfo);
+				 bool is_leaf, const gbtree_ninfo *tinfo, FmgrInfo *flinfo);
 
 extern GIST_SPLITVEC *gbt_num_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v,
-				  const gbtree_ninfo *tinfo);
+				  const gbtree_ninfo *tinfo, FmgrInfo *flinfo);
 
 extern GISTENTRY *gbt_num_compress(GISTENTRY *entry, const gbtree_ninfo *tinfo);
 
 extern GISTENTRY *gbt_num_fetch(GISTENTRY *entry, const gbtree_ninfo *tinfo);
 
 extern void *gbt_num_union(GBT_NUMKEY *out, const GistEntryVector *entryvec,
-			  const gbtree_ninfo *tinfo);
+			  const gbtree_ninfo *tinfo, FmgrInfo *flinfo);
 
 extern bool gbt_num_same(const GBT_NUMKEY *a, const GBT_NUMKEY *b,
-			 const gbtree_ninfo *tinfo);
+			 const gbtree_ninfo *tinfo, FmgrInfo *flinfo);
 
 extern void gbt_num_bin_union(Datum *u, GBT_NUMKEY *e,
-				  const gbtree_ninfo *tinfo);
+				  const gbtree_ninfo *tinfo, FmgrInfo *flinfo);
 
 #endif
diff --git a/contrib/btree_gist/btree_utils_var.c b/contrib/btree_gist/btree_utils_var.c
index 70b3794..16de893 100644
--- a/contrib/btree_gist/btree_utils_var.c
+++ b/contrib/btree_gist/btree_utils_var.c
@@ -25,6 +25,7 @@ typedef struct
 {
 	const gbtree_vinfo *tinfo;
 	Oid			collation;
+	FmgrInfo *flinfo;
 } gbt_vsrt_arg;
 
 
@@ -103,12 +104,12 @@ gbt_var_key_copy(const GBT_VARKEY_R *u)
 
 
 static GBT_VARKEY *
-gbt_var_leaf2node(GBT_VARKEY *leaf, const gbtree_vinfo *tinfo)
+gbt_var_leaf2node(GBT_VARKEY *leaf, const gbtree_vinfo *tinfo, FmgrInfo *flinfo)
 {
 	GBT_VARKEY *out = leaf;
 
 	if (tinfo->f_l2n)
-		out = (*tinfo->f_l2n) (leaf);
+		out = (*tinfo->f_l2n) (leaf, flinfo);
 
 	return out;
 }
@@ -232,7 +233,7 @@ gbt_var_node_truncate(const GBT_VARKEY *node, int32 cpf_length, const gbtree_vin
 
 void
 gbt_var_bin_union(Datum *u, GBT_VARKEY *e, Oid collation,
-				  const gbtree_vinfo *tinfo)
+				  const gbtree_vinfo *tinfo, FmgrInfo *flinfo)
 {
 	GBT_VARKEY_R eo = gbt_var_key_readable(e);
 	GBT_VARKEY_R nr;
@@ -241,7 +242,7 @@ gbt_var_bin_union(Datum *u, GBT_VARKEY *e, Oid collation,
 	{
 		GBT_VARKEY *tmp;
 
-		tmp = gbt_var_leaf2node(e, tinfo);
+		tmp = gbt_var_leaf2node(e, tinfo, flinfo);
 		if (tmp != e)
 			eo = gbt_var_key_readable(tmp);
 	}
@@ -254,13 +255,13 @@ gbt_var_bin_union(Datum *u, GBT_VARKEY *e, Oid collation,
 		nr.lower = ro.lower;
 		nr.upper = ro.upper;
 
-		if ((*tinfo->f_cmp) (ro.lower, eo.lower, collation) > 0)
+		if ((*tinfo->f_cmp) (ro.lower, eo.lower, flinfo, collation) > 0)
 		{
 			nr.lower = eo.lower;
 			update = true;
 		}
 
-		if ((*tinfo->f_cmp) (ro.upper, eo.upper, collation) < 0)
+		if ((*tinfo->f_cmp) (ro.upper, eo.upper, flinfo, collation) < 0)
 		{
 			nr.upper = eo.upper;
 			update = true;
@@ -321,7 +322,7 @@ gbt_var_fetch(PG_FUNCTION_ARGS)
 
 GBT_VARKEY *
 gbt_var_union(const GistEntryVector *entryvec, int32 *size, Oid collation,
-			  const gbtree_vinfo *tinfo)
+			  const gbtree_vinfo *tinfo, FmgrInfo *flinfo)
 {
 	int			i = 0,
 				numranges = entryvec->n;
@@ -338,7 +339,7 @@ gbt_var_union(const GistEntryVector *entryvec, int32 *size, Oid collation,
 	for (i = 1; i < numranges; i++)
 	{
 		cur = (GBT_VARKEY *) DatumGetPointer(entryvec->vector[i].key);
-		gbt_var_bin_union(&out, cur, collation, tinfo);
+		gbt_var_bin_union(&out, cur, collation, tinfo, flinfo);
 	}
 
 
@@ -360,7 +361,7 @@ gbt_var_union(const GistEntryVector *entryvec, int32 *size, Oid collation,
 
 bool
 gbt_var_same(Datum d1, Datum d2, Oid collation,
-			 const gbtree_vinfo *tinfo)
+			 const gbtree_vinfo *tinfo, FmgrInfo *flinfo)
 {
 	GBT_VARKEY *t1 = (GBT_VARKEY *) DatumGetPointer(d1);
 	GBT_VARKEY *t2 = (GBT_VARKEY *) DatumGetPointer(d2);
@@ -370,14 +371,14 @@ gbt_var_same(Datum d1, Datum d2, Oid collation,
 	r1 = gbt_var_key_readable(t1);
 	r2 = gbt_var_key_readable(t2);
 
-	return ((*tinfo->f_cmp) (r1.lower, r2.lower, collation) == 0 &&
-			(*tinfo->f_cmp) (r1.upper, r2.upper, collation) == 0);
+	return ((*tinfo->f_cmp) (r1.lower, r2.lower, flinfo, collation) == 0 &&
+			(*tinfo->f_cmp) (r1.upper, r2.upper, flinfo, collation) == 0);
 }
 
 
 float *
 gbt_var_penalty(float *res, const GISTENTRY *o, const GISTENTRY *n,
-				Oid collation, const gbtree_vinfo *tinfo)
+				Oid collation, const gbtree_vinfo *tinfo, FmgrInfo *flinfo)
 {
 	GBT_VARKEY *orge = (GBT_VARKEY *) DatumGetPointer(o->key);
 	GBT_VARKEY *newe = (GBT_VARKEY *) DatumGetPointer(n->key);
@@ -391,7 +392,7 @@ gbt_var_penalty(float *res, const GISTENTRY *o, const GISTENTRY *n,
 	{
 		GBT_VARKEY *tmp;
 
-		tmp = gbt_var_leaf2node(newe, tinfo);
+		tmp = gbt_var_leaf2node(newe, tinfo, flinfo);
 		if (tmp != newe)
 			nk = gbt_var_key_readable(tmp);
 	}
@@ -399,9 +400,9 @@ gbt_var_penalty(float *res, const GISTENTRY *o, const GISTENTRY *n,
 
 	if ((VARSIZE(ok.lower) - VARHDRSZ) == 0 && (VARSIZE(ok.upper) - VARHDRSZ) == 0)
 		*res = 0.0;
-	else if (!(((*tinfo->f_cmp) (nk.lower, ok.lower, collation) >= 0 ||
+	else if (!(((*tinfo->f_cmp) (nk.lower, ok.lower, flinfo, collation) >= 0 ||
 				gbt_bytea_pf_match(ok.lower, nk.lower, tinfo)) &&
-			   ((*tinfo->f_cmp) (nk.upper, ok.upper, collation) <= 0 ||
+			   ((*tinfo->f_cmp) (nk.upper, ok.upper, flinfo, collation) <= 0 ||
 				gbt_bytea_pf_match(ok.upper, nk.upper, tinfo))))
 	{
 		Datum		d = PointerGetDatum(0);
@@ -409,9 +410,9 @@ gbt_var_penalty(float *res, const GISTENTRY *o, const GISTENTRY *n,
 		int32		ol,
 					ul;
 
-		gbt_var_bin_union(&d, orge, collation, tinfo);
+		gbt_var_bin_union(&d, orge, collation, tinfo, flinfo);
 		ol = gbt_var_node_cp_len((GBT_VARKEY *) DatumGetPointer(d), tinfo);
-		gbt_var_bin_union(&d, newe, collation, tinfo);
+		gbt_var_bin_union(&d, newe, collation, tinfo, flinfo);
 		ul = gbt_var_node_cp_len((GBT_VARKEY *) DatumGetPointer(d), tinfo);
 
 		if (ul < ol)
@@ -448,16 +449,16 @@ gbt_vsrt_cmp(const void *a, const void *b, void *arg)
 	const gbt_vsrt_arg *varg = (const gbt_vsrt_arg *) arg;
 	int			res;
 
-	res = (*varg->tinfo->f_cmp) (ar.lower, br.lower, varg->collation);
+	res = (*varg->tinfo->f_cmp) (ar.lower, br.lower, varg->flinfo, varg->collation);
 	if (res == 0)
-		return (*varg->tinfo->f_cmp) (ar.upper, br.upper, varg->collation);
+		return (*varg->tinfo->f_cmp) (ar.upper, br.upper, varg->flinfo, varg->collation);
 
 	return res;
 }
 
 GIST_SPLITVEC *
 gbt_var_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v,
-				  Oid collation, const gbtree_vinfo *tinfo)
+				  Oid collation, const gbtree_vinfo *tinfo, FmgrInfo *flinfo)
 {
 	OffsetNumber i,
 				maxoff = entryvec->n - 1;
@@ -489,7 +490,7 @@ gbt_var_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v,
 		ro = gbt_var_key_readable((GBT_VARKEY *) cur);
 		if (ro.lower == ro.upper)		/* leaf */
 		{
-			sv[svcntr] = gbt_var_leaf2node((GBT_VARKEY *) cur, tinfo);
+			sv[svcntr] = gbt_var_leaf2node((GBT_VARKEY *) cur, tinfo, flinfo);
 			arr[i].t = sv[svcntr];
 			if (sv[svcntr] != (GBT_VARKEY *) cur)
 				svcntr++;
@@ -502,6 +503,7 @@ gbt_var_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v,
 	/* sort */
 	varg.tinfo = tinfo;
 	varg.collation = collation;
+	varg.flinfo = flinfo;
 	qsort_arg((void *) &arr[FirstOffsetNumber],
 			  maxoff - FirstOffsetNumber + 1,
 			  sizeof(Vsrt),
@@ -514,13 +516,13 @@ gbt_var_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v,
 	{
 		if (i <= (maxoff - FirstOffsetNumber + 1) / 2)
 		{
-			gbt_var_bin_union(&v->spl_ldatum, arr[i].t, collation, tinfo);
+			gbt_var_bin_union(&v->spl_ldatum, arr[i].t, collation, tinfo, flinfo);
 			v->spl_left[v->spl_nleft] = arr[i].i;
 			v->spl_nleft++;
 		}
 		else
 		{
-			gbt_var_bin_union(&v->spl_rdatum, arr[i].t, collation, tinfo);
+			gbt_var_bin_union(&v->spl_rdatum, arr[i].t, collation, tinfo, flinfo);
 			v->spl_right[v->spl_nright] = arr[i].i;
 			v->spl_nright++;
 		}
@@ -556,7 +558,8 @@ gbt_var_consistent(GBT_VARKEY_R *key,
 				   StrategyNumber strategy,
 				   Oid collation,
 				   bool is_leaf,
-				   const gbtree_vinfo *tinfo)
+				   const gbtree_vinfo *tinfo,
+				   FmgrInfo *flinfo)
 {
 	bool		retval = FALSE;
 
@@ -564,44 +567,44 @@ gbt_var_consistent(GBT_VARKEY_R *key,
 	{
 		case BTLessEqualStrategyNumber:
 			if (is_leaf)
-				retval = (*tinfo->f_ge) (query, key->lower, collation);
+				retval = (*tinfo->f_ge) (query, key->lower, flinfo, collation);
 			else
-				retval = (*tinfo->f_cmp) (query, key->lower, collation) >= 0
+				retval = (*tinfo->f_cmp) (query, key->lower, flinfo, collation) >= 0
 					|| gbt_var_node_pf_match(key, query, tinfo);
 			break;
 		case BTLessStrategyNumber:
 			if (is_leaf)
-				retval = (*tinfo->f_gt) (query, key->lower, collation);
+				retval = (*tinfo->f_gt) (query, key->lower, flinfo, collation);
 			else
-				retval = (*tinfo->f_cmp) (query, key->lower, collation) >= 0
+				retval = (*tinfo->f_cmp) (query, key->lower, flinfo, collation) >= 0
 					|| gbt_var_node_pf_match(key, query, tinfo);
 			break;
 		case BTEqualStrategyNumber:
 			if (is_leaf)
-				retval = (*tinfo->f_eq) (query, key->lower, collation);
+				retval = (*tinfo->f_eq) (query, key->lower, flinfo, collation);
 			else
 				retval =
-					((*tinfo->f_cmp) (key->lower, query, collation) <= 0 &&
-					 (*tinfo->f_cmp) (query, key->upper, collation) <= 0) ||
+					((*tinfo->f_cmp) (key->lower, query, flinfo, collation) <= 0 &&
+					 (*tinfo->f_cmp) (query, key->upper, flinfo, collation) <= 0) ||
 					gbt_var_node_pf_match(key, query, tinfo);
 			break;
 		case BTGreaterStrategyNumber:
 			if (is_leaf)
-				retval = (*tinfo->f_lt) (query, key->upper, collation);
+				retval = (*tinfo->f_lt) (query, key->upper, flinfo, collation);
 			else
-				retval = (*tinfo->f_cmp) (query, key->upper, collation) <= 0
+				retval = (*tinfo->f_cmp) (query, key->upper, flinfo, collation) <= 0
 					|| gbt_var_node_pf_match(key, query, tinfo);
 			break;
 		case BTGreaterEqualStrategyNumber:
 			if (is_leaf)
-				retval = (*tinfo->f_le) (query, key->upper, collation);
+				retval = (*tinfo->f_le) (query, key->upper, flinfo, collation);
 			else
-				retval = (*tinfo->f_cmp) (query, key->upper, collation) <= 0
+				retval = (*tinfo->f_cmp) (query, key->upper, flinfo, collation) <= 0
 					|| gbt_var_node_pf_match(key, query, tinfo);
 			break;
 		case BtreeGistNotEqualStrategyNumber:
-			retval = !((*tinfo->f_eq) (query, key->lower, collation) &&
-					   (*tinfo->f_eq) (query, key->upper, collation));
+			retval = !((*tinfo->f_eq) (query, key->lower, flinfo, collation) &&
+					   (*tinfo->f_eq) (query, key->upper, flinfo, collation));
 			break;
 		default:
 			retval = FALSE;
diff --git a/contrib/btree_gist/btree_utils_var.h b/contrib/btree_gist/btree_utils_var.h
index 9a7c4d1..7c9ffaf 100644
--- a/contrib/btree_gist/btree_utils_var.h
+++ b/contrib/btree_gist/btree_utils_var.h
@@ -34,13 +34,13 @@ typedef struct
 
 	/* Methods */
 
-	bool		(*f_gt) (const void *, const void *, Oid);		/* greater than */
-	bool		(*f_ge) (const void *, const void *, Oid);		/* greater equal */
-	bool		(*f_eq) (const void *, const void *, Oid);		/* equal */
-	bool		(*f_le) (const void *, const void *, Oid);		/* less equal */
-	bool		(*f_lt) (const void *, const void *, Oid);		/* less than */
-	int32		(*f_cmp) (const void *, const void *, Oid);		/* compare */
-	GBT_VARKEY *(*f_l2n) (GBT_VARKEY *);		/* convert leaf to node */
+	bool		(*f_gt) (const void *, const void *, FmgrInfo *flinfo, Oid);		/* greater than */
+	bool		(*f_ge) (const void *, const void *, FmgrInfo *flinfo, Oid);		/* greater equal */
+	bool		(*f_eq) (const void *, const void *, FmgrInfo *flinfo, Oid);		/* equal */
+	bool		(*f_le) (const void *, const void *, FmgrInfo *flinfo, Oid);		/* less equal */
+	bool		(*f_lt) (const void *, const void *, FmgrInfo *flinfo, Oid);		/* less than */
+	int32		(*f_cmp) (const void *, const void *, FmgrInfo *flinfo, Oid);		/* compare */
+	GBT_VARKEY *(*f_l2n) (GBT_VARKEY *, FmgrInfo *flinfo);		/* convert leaf to node */
 } gbtree_vinfo;
 
 
@@ -52,22 +52,22 @@ extern GBT_VARKEY *gbt_var_key_copy(const GBT_VARKEY_R *u);
 extern GISTENTRY *gbt_var_compress(GISTENTRY *entry, const gbtree_vinfo *tinfo);
 
 extern GBT_VARKEY *gbt_var_union(const GistEntryVector *entryvec, int32 *size,
-			  Oid collation, const gbtree_vinfo *tinfo);
+			  Oid collation, const gbtree_vinfo *tinfo, FmgrInfo *flinfo);
 
 extern bool gbt_var_same(Datum d1, Datum d2, Oid collation,
-			 const gbtree_vinfo *tinfo);
+			 const gbtree_vinfo *tinfo, FmgrInfo *flinfo);
 
 extern float *gbt_var_penalty(float *res, const GISTENTRY *o, const GISTENTRY *n,
-				Oid collation, const gbtree_vinfo *tinfo);
+				Oid collation, const gbtree_vinfo *tinfo, FmgrInfo *flinfo);
 
 extern bool gbt_var_consistent(GBT_VARKEY_R *key, const void *query,
 				   StrategyNumber strategy, Oid collation, bool is_leaf,
-				   const gbtree_vinfo *tinfo);
+				   const gbtree_vinfo *tinfo, FmgrInfo *flinfo);
 
 extern GIST_SPLITVEC *gbt_var_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v,
-				  Oid collation, const gbtree_vinfo *tinfo);
+				  Oid collation, const gbtree_vinfo *tinfo, FmgrInfo *flinfo);
 
 extern void gbt_var_bin_union(Datum *u, GBT_VARKEY *e, Oid collation,
-				  const gbtree_vinfo *tinfo);
+				  const gbtree_vinfo *tinfo, FmgrInfo *flinfo);
 
 #endif
diff --git a/contrib/btree_gist/btree_uuid.c b/contrib/btree_gist/btree_uuid.c
index 44cef64..5ed8092 100644
--- a/contrib/btree_gist/btree_uuid.c
+++ b/contrib/btree_gist/btree_uuid.c
@@ -34,37 +34,37 @@ uuid_internal_cmp(const pg_uuid_t *arg1, const pg_uuid_t *arg2)
 }
 
 static bool
-gbt_uuidgt(const void *a, const void *b)
+gbt_uuidgt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return uuid_internal_cmp((const pg_uuid_t *) a, (const pg_uuid_t *) b) > 0;
 }
 
 static bool
-gbt_uuidge(const void *a, const void *b)
+gbt_uuidge(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return uuid_internal_cmp((const pg_uuid_t *) a, (const pg_uuid_t *) b) >= 0;
 }
 
 static bool
-gbt_uuideq(const void *a, const void *b)
+gbt_uuideq(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return uuid_internal_cmp((const pg_uuid_t *) a, (const pg_uuid_t *) b) == 0;
 }
 
 static bool
-gbt_uuidle(const void *a, const void *b)
+gbt_uuidle(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return uuid_internal_cmp((const pg_uuid_t *) a, (const pg_uuid_t *) b) <= 0;
 }
 
 static bool
-gbt_uuidlt(const void *a, const void *b)
+gbt_uuidlt(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	return uuid_internal_cmp((const pg_uuid_t *) a, (const pg_uuid_t *) b) < 0;
 }
 
 static int
-gbt_uuidkey_cmp(const void *a, const void *b)
+gbt_uuidkey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
 {
 	uuidKEY    *ia = (uuidKEY *) (((const Nsrt *) a)->t);
 	uuidKEY    *ib = (uuidKEY *) (((const Nsrt *) b)->t);
@@ -150,7 +150,7 @@ gbt_uuid_consistent(PG_FUNCTION_ARGS)
 
 	PG_RETURN_BOOL(
 				   gbt_num_consistent(&key, (void *) query, &strategy,
-									  GIST_LEAF(entry), &tinfo)
+									  GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
 		);
 }
 
@@ -161,7 +161,7 @@ gbt_uuid_union(PG_FUNCTION_ARGS)
 	void	   *out = palloc(sizeof(uuidKEY));
 
 	*(int *) PG_GETARG_POINTER(1) = sizeof(uuidKEY);
-	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
+	PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
 }
 
 /*
@@ -222,7 +222,7 @@ gbt_uuid_picksplit(PG_FUNCTION_ARGS)
 	PG_RETURN_POINTER(gbt_num_picksplit(
 									(GistEntryVector *) PG_GETARG_POINTER(0),
 									  (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
-										&tinfo
+										&tinfo, fcinfo->flinfo
 										));
 }
 
@@ -233,6 +233,6 @@ gbt_uuid_same(PG_FUNCTION_ARGS)
 	uuidKEY    *b2 = (uuidKEY *) PG_GETARG_POINTER(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
 
-	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
+	*result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
 	PG_RETURN_POINTER(result);
 }
diff --git a/contrib/btree_gist/data/enum.data b/contrib/btree_gist/data/enum.data
new file mode 100644
index 0000000..d03bfce
--- /dev/null
+++ b/contrib/btree_gist/data/enum.data
@@ -0,0 +1,595 @@
+r
+v
+i
+b
+r
+\N
+y
+v
+g
+o
+y
+b
+o
+o
+o
+o
+v
+r
+i
+o
+b
+r
+g
+b
+i
+o
+r
+r
+r
+\N
+o
+b
+v
+y
+o
+\N
+i
+o
+o
+g
+g
+b
+y
+v
+g
+g
+\N
+v
+g
+i
+i
+\N
+v
+y
+i
+r
+\N
+r
+\N
+g
+\N
+g
+\N
+v
+g
+y
+v
+r
+v
+r
+v
+y
+i
+i
+v
+y
+v
+i
+b
+i
+i
+r
+r
+\N
+\N
+y
+r
+g
+i
+y
+i
+i
+r
+g
+y
+\N
+i
+o
+r
+y
+y
+g
+o
+o
+g
+y
+r
+g
+v
+r
+i
+r
+i
+r
+y
+v
+b
+i
+o
+r
+\N
+o
+i
+v
+o
+b
+\N
+b
+g
+y
+o
+v
+b
+i
+v
+v
+o
+y
+i
+i
+i
+g
+b
+b
+g
+r
+i
+y
+o
+\N
+r
+\N
+i
+i
+g
+v
+o
+y
+y
+o
+i
+b
+r
+y
+y
+o
+g
+g
+g
+\N
+y
+o
+v
+g
+y
+g
+v
+\N
+i
+o
+v
+b
+b
+\N
+y
+v
+\N
+v
+\N
+i
+\N
+r
+b
+r
+o
+r
+b
+o
+g
+i
+r
+b
+g
+g
+y
+b
+b
+g
+y
+g
+v
+v
+b
+\N
+i
+v
+y
+b
+b
+o
+g
+b
+v
+g
+g
+b
+\N
+y
+r
+r
+b
+\N
+r
+g
+i
+o
+v
+\N
+o
+r
+b
+o
+b
+i
+\N
+\N
+y
+b
+y
+\N
+i
+i
+i
+o
+y
+o
+i
+b
+o
+g
+r
+\N
+b
+y
+\N
+g
+b
+y
+y
+o
+o
+b
+g
+i
+i
+v
+b
+o
+o
+v
+i
+g
+i
+o
+r
+o
+i
+i
+r
+b
+g
+o
+o
+y
+v
+g
+g
+g
+r
+o
+i
+i
+g
+\N
+o
+v
+b
+b
+v
+i
+g
+y
+i
+i
+g
+r
+y
+i
+b
+\N
+g
+y
+o
+\N
+i
+i
+b
+v
+o
+b
+v
+r
+g
+o
+v
+v
+y
+r
+v
+g
+\N
+v
+v
+b
+y
+o
+g
+i
+o
+b
+r
+y
+r
+v
+b
+b
+\N
+i
+v
+y
+r
+b
+i
+y
+g
+\N
+g
+r
+y
+y
+g
+b
+o
+v
+r
+i
+g
+r
+b
+b
+b
+\N
+y
+y
+y
+i
+o
+r
+g
+g
+i
+y
+g
+y
+v
+o
+o
+g
+\N
+b
+v
+o
+y
+r
+\N
+o
+i
+g
+\N
+i
+i
+i
+o
+b
+\N
+\N
+b
+\N
+v
+v
+r
+\N
+o
+b
+r
+o
+b
+o
+r
+y
+\N
+r
+i
+b
+b
+y
+v
+r
+g
+r
+r
+\N
+g
+\N
+v
+v
+y
+r
+o
+r
+o
+i
+o
+\N
+r
+\N
+i
+v
+b
+v
+\N
+b
+r
+v
+o
+\N
+i
+r
+b
+g
+o
+\N
+o
+g
+r
+v
+y
+g
+v
+r
+b
+r
+v
+o
+g
+i
+i
+g
+i
+y
+b
+i
+y
+r
+y
+o
+r
+b
+y
+y
+b
+y
+g
+b
+\N
+r
+g
+b
+o
+y
+o
+g
+r
+g
+b
+\N
+v
+v
+v
+g
+b
+y
+v
+o
+v
+g
+o
+g
+i
+b
+v
+i
+r
+r
+i
+b
+i
+b
+o
+\N
+\N
+y
+r
+g
+v
+o
+y
+\N
+g
+v
+o
+b
+v
+v
+\N
+r
+v
+y
+g
+b
+o
+v
+b
+v
+b
+r
+r
+i
+r
+v
+y
+v
+y
+o
+v
+g
+i
+r
+o
+o
+i
+y
+r
+\N
+y
+r
+b
+y
+y
+\N
+b
+\N
+\N
+i
+v
diff --git a/contrib/btree_gist/expected/enum.out b/contrib/btree_gist/expected/enum.out
new file mode 100644
index 0000000..c4b769d
--- /dev/null
+++ b/contrib/btree_gist/expected/enum.out
@@ -0,0 +1,91 @@
+-- enum check
+create type rainbow as enum ('r','o','y','g','b','i','v');
+CREATE TABLE enumtmp (a rainbow);
+\copy enumtmp from 'data/enum.data'
+SET enable_seqscan=on;
+select a, count(*) from enumtmp group by a order by 1;
+ a | count 
+---+-------
+ r |    76
+ o |    78
+ y |    73
+ g |    75
+ b |    77
+ i |    78
+ v |    75
+   |    63
+(8 rows)
+
+SELECT count(*) FROM enumtmp WHERE a <  'g'::rainbow;
+ count 
+-------
+   227
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a <= 'g'::rainbow;
+ count 
+-------
+   302
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a  = 'g'::rainbow;
+ count 
+-------
+    75
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a >= 'g'::rainbow;
+ count 
+-------
+   305
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a >  'g'::rainbow;
+ count 
+-------
+   230
+(1 row)
+
+CREATE INDEX enumidx ON enumtmp USING gist ( a );
+SET enable_seqscan=off;
+SELECT count(*) FROM enumtmp WHERE a <  'g'::rainbow;
+ count 
+-------
+   227
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a <= 'g'::rainbow;
+ count 
+-------
+   302
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a  = 'g'::rainbow;
+ count 
+-------
+    75
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a >= 'g'::rainbow;
+ count 
+-------
+   305
+(1 row)
+
+SELECT count(*) FROM enumtmp WHERE a >  'g'::rainbow;
+ count 
+-------
+   230
+(1 row)
+
+EXPLAIN (COSTS OFF)
+SELECT count(*) FROM enumtmp WHERE a >= 'g'::rainbow;
+                  QUERY PLAN                   
+-----------------------------------------------
+ Aggregate
+   ->  Bitmap Heap Scan on enumtmp
+         Recheck Cond: (a >= 'g'::rainbow)
+         ->  Bitmap Index Scan on enumidx
+               Index Cond: (a >= 'g'::rainbow)
+(5 rows)
+
diff --git a/contrib/btree_gist/sql/enum.sql b/contrib/btree_gist/sql/enum.sql
new file mode 100644
index 0000000..476211e
--- /dev/null
+++ b/contrib/btree_gist/sql/enum.sql
@@ -0,0 +1,38 @@
+-- enum check
+
+create type rainbow as enum ('r','o','y','g','b','i','v');
+
+CREATE TABLE enumtmp (a rainbow);
+
+\copy enumtmp from 'data/enum.data'
+
+SET enable_seqscan=on;
+
+select a, count(*) from enumtmp group by a order by 1;
+
+SELECT count(*) FROM enumtmp WHERE a <  'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a <= 'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a  = 'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a >= 'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a >  'g'::rainbow;
+
+CREATE INDEX enumidx ON enumtmp USING gist ( a );
+
+SET enable_seqscan=off;
+
+SELECT count(*) FROM enumtmp WHERE a <  'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a <= 'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a  = 'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a >= 'g'::rainbow;
+
+SELECT count(*) FROM enumtmp WHERE a >  'g'::rainbow;
+
+EXPLAIN (COSTS OFF)
+SELECT count(*) FROM enumtmp WHERE a >= 'g'::rainbow;
diff --git a/doc/src/sgml/btree-gin.sgml b/doc/src/sgml/btree-gin.sgml
index 0de8eb5..375e7ec 100644
--- a/doc/src/sgml/btree-gin.sgml
+++ b/doc/src/sgml/btree-gin.sgml
@@ -17,7 +17,7 @@
   <type>oid</>, <type>money</>, <type>"char"</>,
   <type>varchar</>, <type>text</>, <type>bytea</>, <type>bit</>,
   <type>varbit</>, <type>macaddr</>, <type>macaddr8</>, <type>inet</>,
-  and <type>cidr</>.
+  <type>cidr</>, and all <type>enum</> types.
  </para>
 
  <para>
diff --git a/doc/src/sgml/btree-gist.sgml b/doc/src/sgml/btree-gist.sgml
index cfdd5be..c05f527 100644
--- a/doc/src/sgml/btree-gist.sgml
+++ b/doc/src/sgml/btree-gist.sgml
@@ -17,7 +17,8 @@
   <type>oid</>, <type>money</>, <type>char</>,
   <type>varchar</>, <type>text</>, <type>bytea</>, <type>bit</>,
   <type>varbit</>, <type>macaddr</>, <type>macaddr8</>, <type>inet</>,
-  <type>cidr</> and <type>uuid</>.
+  <type>cidr</>, <type>uuid</> and all <type>enum</> types.
+
  </para>
 
  <para>
diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c
index 8c00da6..9fb6952 100644
--- a/src/backend/utils/fmgr/fmgr.c
+++ b/src/backend/utils/fmgr/fmgr.c
@@ -1276,6 +1276,56 @@ DirectFunctionCall9Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
 	return result;
 }
 
+/*
+ * These functions work like the DirectFunctionCall functions except that
+ * they use the flinfo parameter to initialise the fcinfo for the call.
+ * It's recommended that the callee only use the fn_extra and fn_mcxt
+ * fields, as other fields will typically describe the calling function
+ * not the callee.  Conversely, the calling function should not have
+ * used fn_extra, unless its use is known to be compatible with the callee's.
+ */
+
+Datum
+CallerFInfoFunctionCall1(PGFunction func, FmgrInfo *flinfo, Oid collation, Datum arg1)
+{
+	FunctionCallInfoData fcinfo;
+	Datum		result;
+
+	InitFunctionCallInfoData(fcinfo, flinfo, 1, collation, NULL, NULL);
+
+	fcinfo.arg[0] = arg1;
+	fcinfo.argnull[0] = false;
+
+	result = (*func) (&fcinfo);
+
+	/* Check for null result, since caller is clearly not expecting one */
+	if (fcinfo.isnull)
+		elog(ERROR, "function %p returned NULL", (void *) func);
+
+	return result;
+}
+
+Datum
+CallerFInfoFunctionCall2(PGFunction func, FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
+{
+	FunctionCallInfoData fcinfo;
+	Datum		result;
+
+	InitFunctionCallInfoData(fcinfo, flinfo, 2, collation, NULL, NULL);
+
+	fcinfo.arg[0] = arg1;
+	fcinfo.arg[1] = arg2;
+	fcinfo.argnull[0] = false;
+	fcinfo.argnull[1] = false;
+
+	result = (*func) (&fcinfo);
+
+	/* Check for null result, since caller is clearly not expecting one */
+	if (fcinfo.isnull)
+		elog(ERROR, "function %p returned NULL", (void *) func);
+
+	return result;
+}
 
 /*
  * These are for invocation of a previously-looked-up function with a
diff --git a/src/include/fmgr.h b/src/include/fmgr.h
index 4d400d2..d0b3edb 100644
--- a/src/include/fmgr.h
+++ b/src/include/fmgr.h
@@ -482,6 +482,18 @@ extern Datum DirectFunctionCall9Coll(PGFunction func, Oid collation,
 						Datum arg3, Datum arg4, Datum arg5,
 						Datum arg6, Datum arg7, Datum arg8,
 						Datum arg9);
+/*
+ * These functions work like the DirectFunctionCall functions except that
+ * they use the flinfo parameter to initialise the fcinfo for the call.
+ * It's recommended that the callee only use the fn_extra and fn_mcxt
+ * fields, as other fields will typically describe the calling function
+ * not the callee.  Conversely, the calling function should not have
+ * used fn_extra, unless its use is known to be compatible with the callee's.
+ */
+extern Datum CallerFInfoFunctionCall1(PGFunction func, FmgrInfo *flinfo,
+						 Oid collation, Datum arg1);
+extern Datum CallerFInfoFunctionCall2(PGFunction func, FmgrInfo *flinfo,
+						 Oid collation, Datum arg1, Datum arg2);
 
 /* These are for invocation of a previously-looked-up function with a
  * directly-computed parameter list.  Note that neither arguments nor result