On Thu, Apr 5, 2018 at 8:16 AM, Teodor Sigaev <[email protected]> wrote:
> somehow you missed some parts in 0001 patch, at least regression tests
> fail:
>
> CREATE EXTENSION btree_gin;
> + ERROR: could not find function "gin_extract_value_uuid" in file
> "/usr/local/pgsql/lib/btree_gin.so"
>
>
Ouch... My fault, filterdiff is acting weird for some reason...
Here is the corrected versions... I tested here applying on a clean master
just to be sure, all looks good.
Very sorry about that mess. I hope it can get in v11, it is a patch so
simple, but so useful for many people.
Best regards,
--
Matheus de Oliveira
diff --git a/contrib/btree_gin/Makefile b/contrib/btree_gin/Makefile
new file mode 100644
index 690e1d7..a9e9925
*** a/contrib/btree_gin/Makefile
--- b/contrib/btree_gin/Makefile
*************** OBJS = btree_gin.o $(WIN32RES)
*** 5,17 ****
EXTENSION = btree_gin
DATA = btree_gin--1.0.sql btree_gin--1.0--1.1.sql btree_gin--1.1--1.2.sql \
! btree_gin--unpackaged--1.0.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 macaddr8 inet cidr text varchar char bytea bit varbit \
! numeric enum
ifdef USE_PGXS
PG_CONFIG = pg_config
--- 5,17 ----
EXTENSION = btree_gin
DATA = btree_gin--1.0.sql btree_gin--1.0--1.1.sql btree_gin--1.1--1.2.sql \
! btree_gin--1.2--1.3.sql btree_gin--unpackaged--1.0.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 macaddr8 inet cidr text varchar char bytea bit varbit \
! numeric enum uuid name bool bpchar
ifdef USE_PGXS
PG_CONFIG = pg_config
diff --git a/contrib/btree_gin/btree_gin--1.2--1.3.sql b/contrib/btree_gin/btree_gin--1.2--1.3.sql
new file mode 100644
index ...db675b7
*** a/contrib/btree_gin/btree_gin--1.2--1.3.sql
--- b/contrib/btree_gin/btree_gin--1.2--1.3.sql
***************
*** 0 ****
--- 1,128 ----
+ /* contrib/btree_gin/btree_gin--1.2--1.3.sql */
+
+ -- complain if script is sourced in psql, rather than via CREATE EXTENSION
+ \echo Use "ALTER EXTENSION btree_gin UPDATE TO '1.3'" to load this file. \quit
+
+ -- uuid datatype support new in 1.3.
+ CREATE FUNCTION gin_extract_value_uuid(uuid, internal)
+ RETURNS internal
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE FUNCTION gin_compare_prefix_uuid(uuid, uuid, int2, internal)
+ RETURNS int4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE FUNCTION gin_extract_query_uuid(uuid, internal, int2, internal, internal)
+ RETURNS internal
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE OPERATOR CLASS uuid_ops
+ DEFAULT FOR TYPE uuid USING gin
+ AS
+ OPERATOR 1 <,
+ OPERATOR 2 <=,
+ OPERATOR 3 =,
+ OPERATOR 4 >=,
+ OPERATOR 5 >,
+ FUNCTION 1 uuid_cmp(uuid,uuid),
+ FUNCTION 2 gin_extract_value_uuid(uuid, internal),
+ FUNCTION 3 gin_extract_query_uuid(uuid, internal, int2, internal, internal),
+ FUNCTION 4 gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+ FUNCTION 5 gin_compare_prefix_uuid(uuid,uuid,int2, internal),
+ STORAGE uuid;
+
+ -- name datatype support new in 1.3.
+ CREATE FUNCTION gin_extract_value_name(name, internal)
+ RETURNS internal
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE FUNCTION gin_compare_prefix_name(name, name, int2, internal)
+ RETURNS int4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE FUNCTION gin_extract_query_name(name, internal, int2, internal, internal)
+ RETURNS internal
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE OPERATOR CLASS name_ops
+ DEFAULT FOR TYPE name USING gin
+ AS
+ OPERATOR 1 <,
+ OPERATOR 2 <=,
+ OPERATOR 3 =,
+ OPERATOR 4 >=,
+ OPERATOR 5 >,
+ FUNCTION 1 btnamecmp(name,name),
+ FUNCTION 2 gin_extract_value_name(name, internal),
+ FUNCTION 3 gin_extract_query_name(name, internal, int2, internal, internal),
+ FUNCTION 4 gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+ FUNCTION 5 gin_compare_prefix_name(name,name,int2, internal),
+ STORAGE name;
+
+ -- bool datatype support new in 1.3.
+ CREATE FUNCTION gin_extract_value_bool(bool, internal)
+ RETURNS internal
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE FUNCTION gin_compare_prefix_bool(bool, bool, int2, internal)
+ RETURNS int4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE FUNCTION gin_extract_query_bool(bool, internal, int2, internal, internal)
+ RETURNS internal
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE OPERATOR CLASS bool_ops
+ DEFAULT FOR TYPE bool USING gin
+ AS
+ OPERATOR 1 <,
+ OPERATOR 2 <=,
+ OPERATOR 3 =,
+ OPERATOR 4 >=,
+ OPERATOR 5 >,
+ FUNCTION 1 btboolcmp(bool,bool),
+ FUNCTION 2 gin_extract_value_bool(bool, internal),
+ FUNCTION 3 gin_extract_query_bool(bool, internal, int2, internal, internal),
+ FUNCTION 4 gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+ FUNCTION 5 gin_compare_prefix_bool(bool,bool,int2, internal),
+ STORAGE bool;
+
+ -- bpchar datatype support new in 1.3.
+ CREATE FUNCTION gin_extract_value_bpchar(bpchar, internal)
+ RETURNS internal
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE FUNCTION gin_compare_prefix_bpchar(bpchar, bpchar, int2, internal)
+ RETURNS int4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE FUNCTION gin_extract_query_bpchar(bpchar, internal, int2, internal, internal)
+ RETURNS internal
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE OPERATOR CLASS bpchar_ops
+ DEFAULT FOR TYPE bpchar USING gin
+ AS
+ OPERATOR 1 <,
+ OPERATOR 2 <=,
+ OPERATOR 3 =,
+ OPERATOR 4 >=,
+ OPERATOR 5 >,
+ FUNCTION 1 bpcharcmp(bpchar, bpchar),
+ FUNCTION 2 gin_extract_value_bpchar(bpchar, internal),
+ FUNCTION 3 gin_extract_query_bpchar(bpchar, internal, int2, internal, internal),
+ FUNCTION 4 gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+ FUNCTION 5 gin_compare_prefix_bpchar(bpchar,bpchar,int2, internal),
+ STORAGE bpchar;
diff --git a/contrib/btree_gin/btree_gin.c b/contrib/btree_gin/btree_gin.c
new file mode 100644
index 2473f79..a660681
*** a/contrib/btree_gin/btree_gin.c
--- b/contrib/btree_gin/btree_gin.c
***************
*** 14,19 ****
--- 14,20 ----
#include "utils/numeric.h"
#include "utils/timestamp.h"
#include "utils/varbit.h"
+ #include "utils/uuid.h"
PG_MODULE_MAGIC;
*************** leftmostvalue_text(void)
*** 350,355 ****
--- 351,358 ----
GIN_SUPPORT(text, true, leftmostvalue_text, bttextcmp)
+ GIN_SUPPORT(bpchar, true, leftmostvalue_text, bpcharcmp)
+
static Datum
leftmostvalue_char(void)
{
*************** GIN_SUPPORT(numeric, true, leftmostvalue
*** 437,443 ****
* routines it needs it, so we can't use DirectFunctionCall2.
*/
-
#define ENUM_IS_LEFTMOST(x) ((x) == InvalidOid)
PG_FUNCTION_INFO_V1(gin_enum_cmp);
--- 440,445 ----
*************** leftmostvalue_enum(void)
*** 477,479 ****
--- 479,508 ----
}
GIN_SUPPORT(anyenum, false, leftmostvalue_enum, gin_enum_cmp)
+
+ static Datum
+ leftmostvalue_uuid(void)
+ {
+ /* palloc0 will create the UUID with all zeroes: "00000000-0000-0000-0000-000000000000" */
+ pg_uuid_t *retval = (pg_uuid_t *) palloc0(sizeof(pg_uuid_t));
+ return UUIDPGetDatum(retval);
+ }
+
+ GIN_SUPPORT(uuid, false, leftmostvalue_uuid, uuid_cmp)
+
+ static Datum
+ leftmostvalue_name(void)
+ {
+ NameData* result = (NameData *) palloc0(NAMEDATALEN);
+ return NameGetDatum(result);
+ }
+
+ GIN_SUPPORT(name, false, leftmostvalue_name, btnamecmp)
+
+ static Datum
+ leftmostvalue_bool(void)
+ {
+ return BoolGetDatum(false);
+ }
+
+ GIN_SUPPORT(bool, false, leftmostvalue_bool, btboolcmp)
diff --git a/contrib/btree_gin/btree_gin.control b/contrib/btree_gin/btree_gin.control
new file mode 100644
index 3acc5af..d576da7
*** a/contrib/btree_gin/btree_gin.control
--- b/contrib/btree_gin/btree_gin.control
***************
*** 1,5 ****
# btree_gin extension
comment = 'support for indexing common datatypes in GIN'
! default_version = '1.2'
module_pathname = '$libdir/btree_gin'
relocatable = true
--- 1,5 ----
# btree_gin extension
comment = 'support for indexing common datatypes in GIN'
! default_version = '1.3'
module_pathname = '$libdir/btree_gin'
relocatable = true
diff --git a/contrib/btree_gin/expected/bool.out b/contrib/btree_gin/expected/bool.out
new file mode 100644
index ...efb3e1e
*** a/contrib/btree_gin/expected/bool.out
--- b/contrib/btree_gin/expected/bool.out
***************
*** 0 ****
--- 1,119 ----
+ set enable_seqscan=off;
+ CREATE TABLE test_bool (
+ i boolean
+ );
+ INSERT INTO test_bool VALUES (false),(true),(null);
+ CREATE INDEX idx_bool ON test_bool USING gin (i);
+ SELECT * FROM test_bool WHERE i<true ORDER BY i;
+ i
+ ---
+ f
+ (1 row)
+
+ SELECT * FROM test_bool WHERE i<=true ORDER BY i;
+ i
+ ---
+ f
+ t
+ (2 rows)
+
+ SELECT * FROM test_bool WHERE i=true ORDER BY i;
+ i
+ ---
+ t
+ (1 row)
+
+ SELECT * FROM test_bool WHERE i>=true ORDER BY i;
+ i
+ ---
+ t
+ (1 row)
+
+ SELECT * FROM test_bool WHERE i>true ORDER BY i;
+ i
+ ---
+ (0 rows)
+
+ SELECT * FROM test_bool WHERE i<false ORDER BY i;
+ i
+ ---
+ (0 rows)
+
+ SELECT * FROM test_bool WHERE i<=false ORDER BY i;
+ i
+ ---
+ f
+ (1 row)
+
+ SELECT * FROM test_bool WHERE i=false ORDER BY i;
+ i
+ ---
+ f
+ (1 row)
+
+ SELECT * FROM test_bool WHERE i>=false ORDER BY i;
+ i
+ ---
+ f
+ t
+ (2 rows)
+
+ SELECT * FROM test_bool WHERE i>false ORDER BY i;
+ i
+ ---
+ t
+ (1 row)
+
+ EXPLAIN (COSTS OFF) SELECT * FROM test_bool WHERE i<true ORDER BY i;
+ QUERY PLAN
+ -------------------------------------------
+ Sort
+ Sort Key: i
+ -> Bitmap Heap Scan on test_bool
+ Recheck Cond: (i < true)
+ -> Bitmap Index Scan on idx_bool
+ Index Cond: (i < true)
+ (6 rows)
+
+ EXPLAIN (COSTS OFF) SELECT * FROM test_bool WHERE i<=true ORDER BY i;
+ QUERY PLAN
+ -------------------------------------------
+ Sort
+ Sort Key: i
+ -> Bitmap Heap Scan on test_bool
+ Recheck Cond: (i <= true)
+ -> Bitmap Index Scan on idx_bool
+ Index Cond: (i <= true)
+ (6 rows)
+
+ EXPLAIN (COSTS OFF) SELECT * FROM test_bool WHERE i=true ORDER BY i;
+ QUERY PLAN
+ -----------------------------
+ Sort
+ Sort Key: i
+ -> Seq Scan on test_bool
+ Filter: i
+ (4 rows)
+
+ EXPLAIN (COSTS OFF) SELECT * FROM test_bool WHERE i>=true ORDER BY i;
+ QUERY PLAN
+ -------------------------------------------
+ Sort
+ Sort Key: i
+ -> Bitmap Heap Scan on test_bool
+ Recheck Cond: (i >= true)
+ -> Bitmap Index Scan on idx_bool
+ Index Cond: (i >= true)
+ (6 rows)
+
+ EXPLAIN (COSTS OFF) SELECT * FROM test_bool WHERE i>true ORDER BY i;
+ QUERY PLAN
+ -------------------------------------------
+ Sort
+ Sort Key: i
+ -> Bitmap Heap Scan on test_bool
+ Recheck Cond: (i > true)
+ -> Bitmap Index Scan on idx_bool
+ Index Cond: (i > true)
+ (6 rows)
+
diff --git a/contrib/btree_gin/expected/bpchar.out b/contrib/btree_gin/expected/bpchar.out
new file mode 100644
index ...2eb8855
*** a/contrib/btree_gin/expected/bpchar.out
--- b/contrib/btree_gin/expected/bpchar.out
***************
*** 0 ****
--- 1,109 ----
+ set enable_seqscan=off;
+ CREATE TABLE test_bpchar (
+ i char(10)
+ );
+ INSERT INTO test_bpchar VALUES ('a'),('ab'),('abc'),('abc '),('abb'),('axy'),('xyz'),('xyz ');
+ CREATE INDEX idx_bpchar ON test_bpchar USING gin (i);
+ SELECT * FROM test_bpchar WHERE i<'abc' ORDER BY i;
+ i
+ ------------
+ a
+ ab
+ abb
+ (3 rows)
+
+ SELECT * FROM test_bpchar WHERE i<='abc' ORDER BY i;
+ i
+ ------------
+ a
+ ab
+ abb
+ abc
+ abc
+ (5 rows)
+
+ SELECT * FROM test_bpchar WHERE i='abc' ORDER BY i;
+ i
+ ------------
+ abc
+ abc
+ (2 rows)
+
+ SELECT * FROM test_bpchar WHERE i='abc ' ORDER BY i;
+ i
+ ------------
+ abc
+ abc
+ (2 rows)
+
+ SELECT * FROM test_bpchar WHERE i>='abc' ORDER BY i;
+ i
+ ------------
+ abc
+ abc
+ axy
+ xyz
+ xyz
+ (5 rows)
+
+ SELECT * FROM test_bpchar WHERE i>'abc' ORDER BY i;
+ i
+ ------------
+ axy
+ xyz
+ xyz
+ (3 rows)
+
+ EXPLAIN (COSTS OFF) SELECT * FROM test_bpchar WHERE i<'abc' ORDER BY i;
+ QUERY PLAN
+ -----------------------------------------------
+ Sort
+ Sort Key: i
+ -> Bitmap Heap Scan on test_bpchar
+ Recheck Cond: (i < 'abc'::bpchar)
+ -> Bitmap Index Scan on idx_bpchar
+ Index Cond: (i < 'abc'::bpchar)
+ (6 rows)
+
+ EXPLAIN (COSTS OFF) SELECT * FROM test_bpchar WHERE i<='abc' ORDER BY i;
+ QUERY PLAN
+ ------------------------------------------------
+ Sort
+ Sort Key: i
+ -> Bitmap Heap Scan on test_bpchar
+ Recheck Cond: (i <= 'abc'::bpchar)
+ -> Bitmap Index Scan on idx_bpchar
+ Index Cond: (i <= 'abc'::bpchar)
+ (6 rows)
+
+ EXPLAIN (COSTS OFF) SELECT * FROM test_bpchar WHERE i='abc' ORDER BY i;
+ QUERY PLAN
+ -----------------------------------------
+ Bitmap Heap Scan on test_bpchar
+ Recheck Cond: (i = 'abc'::bpchar)
+ -> Bitmap Index Scan on idx_bpchar
+ Index Cond: (i = 'abc'::bpchar)
+ (4 rows)
+
+ EXPLAIN (COSTS OFF) SELECT * FROM test_bpchar WHERE i>='abc' ORDER BY i;
+ QUERY PLAN
+ ------------------------------------------------
+ Sort
+ Sort Key: i
+ -> Bitmap Heap Scan on test_bpchar
+ Recheck Cond: (i >= 'abc'::bpchar)
+ -> Bitmap Index Scan on idx_bpchar
+ Index Cond: (i >= 'abc'::bpchar)
+ (6 rows)
+
+ EXPLAIN (COSTS OFF) SELECT * FROM test_bpchar WHERE i>'abc' ORDER BY i;
+ QUERY PLAN
+ -----------------------------------------------
+ Sort
+ Sort Key: i
+ -> Bitmap Heap Scan on test_bpchar
+ Recheck Cond: (i > 'abc'::bpchar)
+ -> Bitmap Index Scan on idx_bpchar
+ Index Cond: (i > 'abc'::bpchar)
+ (6 rows)
+
diff --git a/contrib/btree_gin/expected/name.out b/contrib/btree_gin/expected/name.out
new file mode 100644
index ...174de65
*** a/contrib/btree_gin/expected/name.out
--- b/contrib/btree_gin/expected/name.out
***************
*** 0 ****
--- 1,97 ----
+ set enable_seqscan=off;
+ CREATE TABLE test_name (
+ i name
+ );
+ INSERT INTO test_name VALUES ('a'),('ab'),('abc'),('abb'),('axy'),('xyz');
+ CREATE INDEX idx_name ON test_name USING gin (i);
+ SELECT * FROM test_name WHERE i<'abc' ORDER BY i;
+ i
+ -----
+ a
+ ab
+ abb
+ (3 rows)
+
+ SELECT * FROM test_name WHERE i<='abc' ORDER BY i;
+ i
+ -----
+ a
+ ab
+ abb
+ abc
+ (4 rows)
+
+ SELECT * FROM test_name WHERE i='abc' ORDER BY i;
+ i
+ -----
+ abc
+ (1 row)
+
+ SELECT * FROM test_name WHERE i>='abc' ORDER BY i;
+ i
+ -----
+ abc
+ axy
+ xyz
+ (3 rows)
+
+ SELECT * FROM test_name WHERE i>'abc' ORDER BY i;
+ i
+ -----
+ axy
+ xyz
+ (2 rows)
+
+ EXPLAIN (COSTS OFF) SELECT * FROM test_name WHERE i<'abc' ORDER BY i;
+ QUERY PLAN
+ ---------------------------------------------
+ Sort
+ Sort Key: i
+ -> Bitmap Heap Scan on test_name
+ Recheck Cond: (i < 'abc'::name)
+ -> Bitmap Index Scan on idx_name
+ Index Cond: (i < 'abc'::name)
+ (6 rows)
+
+ EXPLAIN (COSTS OFF) SELECT * FROM test_name WHERE i<='abc' ORDER BY i;
+ QUERY PLAN
+ ----------------------------------------------
+ Sort
+ Sort Key: i
+ -> Bitmap Heap Scan on test_name
+ Recheck Cond: (i <= 'abc'::name)
+ -> Bitmap Index Scan on idx_name
+ Index Cond: (i <= 'abc'::name)
+ (6 rows)
+
+ EXPLAIN (COSTS OFF) SELECT * FROM test_name WHERE i='abc' ORDER BY i;
+ QUERY PLAN
+ ---------------------------------------
+ Bitmap Heap Scan on test_name
+ Recheck Cond: (i = 'abc'::name)
+ -> Bitmap Index Scan on idx_name
+ Index Cond: (i = 'abc'::name)
+ (4 rows)
+
+ EXPLAIN (COSTS OFF) SELECT * FROM test_name WHERE i>='abc' ORDER BY i;
+ QUERY PLAN
+ ----------------------------------------------
+ Sort
+ Sort Key: i
+ -> Bitmap Heap Scan on test_name
+ Recheck Cond: (i >= 'abc'::name)
+ -> Bitmap Index Scan on idx_name
+ Index Cond: (i >= 'abc'::name)
+ (6 rows)
+
+ EXPLAIN (COSTS OFF) SELECT * FROM test_name WHERE i>'abc' ORDER BY i;
+ QUERY PLAN
+ ---------------------------------------------
+ Sort
+ Sort Key: i
+ -> Bitmap Heap Scan on test_name
+ Recheck Cond: (i > 'abc'::name)
+ -> Bitmap Index Scan on idx_name
+ Index Cond: (i > 'abc'::name)
+ (6 rows)
+
diff --git a/contrib/btree_gin/expected/uuid.out b/contrib/btree_gin/expected/uuid.out
new file mode 100644
index ...60fd8d6
*** a/contrib/btree_gin/expected/uuid.out
--- b/contrib/btree_gin/expected/uuid.out
***************
*** 0 ****
--- 1,104 ----
+ set enable_seqscan=off;
+ CREATE TABLE test_uuid (
+ i uuid
+ );
+ INSERT INTO test_uuid VALUES
+ ( '00000000-0000-0000-0000-000000000000' ),
+ ( '299bc99f-2f79-4e3e-bfea-2cbfd62a7c27' ),
+ ( '6264af33-0d43-4337-bf4e-43509b8a4be8' ),
+ ( 'ce41c936-6acb-4feb-8c91-852a673e5a5c' ),
+ ( 'd2ce731f-f2a8-4a2b-be37-8f0ba637427f' ),
+ ( 'ffffffff-ffff-ffff-ffff-ffffffffffff' )
+ ;
+ CREATE INDEX idx_uuid ON test_uuid USING gin (i);
+ SELECT * FROM test_uuid WHERE i<'ce41c936-6acb-4feb-8c91-852a673e5a5c'::uuid ORDER BY i;
+ i
+ --------------------------------------
+ 00000000-0000-0000-0000-000000000000
+ 299bc99f-2f79-4e3e-bfea-2cbfd62a7c27
+ 6264af33-0d43-4337-bf4e-43509b8a4be8
+ (3 rows)
+
+ SELECT * FROM test_uuid WHERE i<='ce41c936-6acb-4feb-8c91-852a673e5a5c'::uuid ORDER BY i;
+ i
+ --------------------------------------
+ 00000000-0000-0000-0000-000000000000
+ 299bc99f-2f79-4e3e-bfea-2cbfd62a7c27
+ 6264af33-0d43-4337-bf4e-43509b8a4be8
+ ce41c936-6acb-4feb-8c91-852a673e5a5c
+ (4 rows)
+
+ SELECT * FROM test_uuid WHERE i='ce41c936-6acb-4feb-8c91-852a673e5a5c'::uuid ORDER BY i;
+ i
+ --------------------------------------
+ ce41c936-6acb-4feb-8c91-852a673e5a5c
+ (1 row)
+
+ SELECT * FROM test_uuid WHERE i>='ce41c936-6acb-4feb-8c91-852a673e5a5c'::uuid ORDER BY i;
+ i
+ --------------------------------------
+ ce41c936-6acb-4feb-8c91-852a673e5a5c
+ d2ce731f-f2a8-4a2b-be37-8f0ba637427f
+ ffffffff-ffff-ffff-ffff-ffffffffffff
+ (3 rows)
+
+ SELECT * FROM test_uuid WHERE i>'ce41c936-6acb-4feb-8c91-852a673e5a5c'::uuid ORDER BY i;
+ i
+ --------------------------------------
+ d2ce731f-f2a8-4a2b-be37-8f0ba637427f
+ ffffffff-ffff-ffff-ffff-ffffffffffff
+ (2 rows)
+
+ EXPLAIN (COSTS OFF) SELECT * FROM test_uuid WHERE i<'ce41c936-6acb-4feb-8c91-852a673e5a5c'::uuid ORDER BY i;
+ QUERY PLAN
+ ------------------------------------------------------------------------------
+ Sort
+ Sort Key: i
+ -> Bitmap Heap Scan on test_uuid
+ Recheck Cond: (i < 'ce41c936-6acb-4feb-8c91-852a673e5a5c'::uuid)
+ -> Bitmap Index Scan on idx_uuid
+ Index Cond: (i < 'ce41c936-6acb-4feb-8c91-852a673e5a5c'::uuid)
+ (6 rows)
+
+ EXPLAIN (COSTS OFF) SELECT * FROM test_uuid WHERE i<='ce41c936-6acb-4feb-8c91-852a673e5a5c'::uuid ORDER BY i;
+ QUERY PLAN
+ -------------------------------------------------------------------------------
+ Sort
+ Sort Key: i
+ -> Bitmap Heap Scan on test_uuid
+ Recheck Cond: (i <= 'ce41c936-6acb-4feb-8c91-852a673e5a5c'::uuid)
+ -> Bitmap Index Scan on idx_uuid
+ Index Cond: (i <= 'ce41c936-6acb-4feb-8c91-852a673e5a5c'::uuid)
+ (6 rows)
+
+ EXPLAIN (COSTS OFF) SELECT * FROM test_uuid WHERE i='ce41c936-6acb-4feb-8c91-852a673e5a5c'::uuid ORDER BY i;
+ QUERY PLAN
+ ------------------------------------------------------------------------
+ Bitmap Heap Scan on test_uuid
+ Recheck Cond: (i = 'ce41c936-6acb-4feb-8c91-852a673e5a5c'::uuid)
+ -> Bitmap Index Scan on idx_uuid
+ Index Cond: (i = 'ce41c936-6acb-4feb-8c91-852a673e5a5c'::uuid)
+ (4 rows)
+
+ EXPLAIN (COSTS OFF) SELECT * FROM test_uuid WHERE i>='ce41c936-6acb-4feb-8c91-852a673e5a5c'::uuid ORDER BY i;
+ QUERY PLAN
+ -------------------------------------------------------------------------------
+ Sort
+ Sort Key: i
+ -> Bitmap Heap Scan on test_uuid
+ Recheck Cond: (i >= 'ce41c936-6acb-4feb-8c91-852a673e5a5c'::uuid)
+ -> Bitmap Index Scan on idx_uuid
+ Index Cond: (i >= 'ce41c936-6acb-4feb-8c91-852a673e5a5c'::uuid)
+ (6 rows)
+
+ EXPLAIN (COSTS OFF) SELECT * FROM test_uuid WHERE i>'ce41c936-6acb-4feb-8c91-852a673e5a5c'::uuid ORDER BY i;
+ QUERY PLAN
+ ------------------------------------------------------------------------------
+ Sort
+ Sort Key: i
+ -> Bitmap Heap Scan on test_uuid
+ Recheck Cond: (i > 'ce41c936-6acb-4feb-8c91-852a673e5a5c'::uuid)
+ -> Bitmap Index Scan on idx_uuid
+ Index Cond: (i > 'ce41c936-6acb-4feb-8c91-852a673e5a5c'::uuid)
+ (6 rows)
+
diff --git a/contrib/btree_gin/sql/bool.sql b/contrib/btree_gin/sql/bool.sql
new file mode 100644
index ...dad2ff3
*** a/contrib/btree_gin/sql/bool.sql
--- b/contrib/btree_gin/sql/bool.sql
***************
*** 0 ****
--- 1,27 ----
+ set enable_seqscan=off;
+
+ CREATE TABLE test_bool (
+ i boolean
+ );
+
+ INSERT INTO test_bool VALUES (false),(true),(null);
+
+ CREATE INDEX idx_bool ON test_bool USING gin (i);
+
+ SELECT * FROM test_bool WHERE i<true ORDER BY i;
+ SELECT * FROM test_bool WHERE i<=true ORDER BY i;
+ SELECT * FROM test_bool WHERE i=true ORDER BY i;
+ SELECT * FROM test_bool WHERE i>=true ORDER BY i;
+ SELECT * FROM test_bool WHERE i>true ORDER BY i;
+
+ SELECT * FROM test_bool WHERE i<false ORDER BY i;
+ SELECT * FROM test_bool WHERE i<=false ORDER BY i;
+ SELECT * FROM test_bool WHERE i=false ORDER BY i;
+ SELECT * FROM test_bool WHERE i>=false ORDER BY i;
+ SELECT * FROM test_bool WHERE i>false ORDER BY i;
+
+ EXPLAIN (COSTS OFF) SELECT * FROM test_bool WHERE i<true ORDER BY i;
+ EXPLAIN (COSTS OFF) SELECT * FROM test_bool WHERE i<=true ORDER BY i;
+ EXPLAIN (COSTS OFF) SELECT * FROM test_bool WHERE i=true ORDER BY i;
+ EXPLAIN (COSTS OFF) SELECT * FROM test_bool WHERE i>=true ORDER BY i;
+ EXPLAIN (COSTS OFF) SELECT * FROM test_bool WHERE i>true ORDER BY i;
diff --git a/contrib/btree_gin/sql/bpchar.sql b/contrib/btree_gin/sql/bpchar.sql
new file mode 100644
index ...4c951e3
*** a/contrib/btree_gin/sql/bpchar.sql
--- b/contrib/btree_gin/sql/bpchar.sql
***************
*** 0 ****
--- 1,22 ----
+ set enable_seqscan=off;
+
+ CREATE TABLE test_bpchar (
+ i char(10)
+ );
+
+ INSERT INTO test_bpchar VALUES ('a'),('ab'),('abc'),('abc '),('abb'),('axy'),('xyz'),('xyz ');
+
+ CREATE INDEX idx_bpchar ON test_bpchar USING gin (i);
+
+ SELECT * FROM test_bpchar WHERE i<'abc' ORDER BY i;
+ SELECT * FROM test_bpchar WHERE i<='abc' ORDER BY i;
+ SELECT * FROM test_bpchar WHERE i='abc' ORDER BY i;
+ SELECT * FROM test_bpchar WHERE i='abc ' ORDER BY i;
+ SELECT * FROM test_bpchar WHERE i>='abc' ORDER BY i;
+ SELECT * FROM test_bpchar WHERE i>'abc' ORDER BY i;
+
+ EXPLAIN (COSTS OFF) SELECT * FROM test_bpchar WHERE i<'abc' ORDER BY i;
+ EXPLAIN (COSTS OFF) SELECT * FROM test_bpchar WHERE i<='abc' ORDER BY i;
+ EXPLAIN (COSTS OFF) SELECT * FROM test_bpchar WHERE i='abc' ORDER BY i;
+ EXPLAIN (COSTS OFF) SELECT * FROM test_bpchar WHERE i>='abc' ORDER BY i;
+ EXPLAIN (COSTS OFF) SELECT * FROM test_bpchar WHERE i>'abc' ORDER BY i;
diff --git a/contrib/btree_gin/sql/name.sql b/contrib/btree_gin/sql/name.sql
new file mode 100644
index ...c11580c
*** a/contrib/btree_gin/sql/name.sql
--- b/contrib/btree_gin/sql/name.sql
***************
*** 0 ****
--- 1,21 ----
+ set enable_seqscan=off;
+
+ CREATE TABLE test_name (
+ i name
+ );
+
+ INSERT INTO test_name VALUES ('a'),('ab'),('abc'),('abb'),('axy'),('xyz');
+
+ CREATE INDEX idx_name ON test_name USING gin (i);
+
+ SELECT * FROM test_name WHERE i<'abc' ORDER BY i;
+ SELECT * FROM test_name WHERE i<='abc' ORDER BY i;
+ SELECT * FROM test_name WHERE i='abc' ORDER BY i;
+ SELECT * FROM test_name WHERE i>='abc' ORDER BY i;
+ SELECT * FROM test_name WHERE i>'abc' ORDER BY i;
+
+ EXPLAIN (COSTS OFF) SELECT * FROM test_name WHERE i<'abc' ORDER BY i;
+ EXPLAIN (COSTS OFF) SELECT * FROM test_name WHERE i<='abc' ORDER BY i;
+ EXPLAIN (COSTS OFF) SELECT * FROM test_name WHERE i='abc' ORDER BY i;
+ EXPLAIN (COSTS OFF) SELECT * FROM test_name WHERE i>='abc' ORDER BY i;
+ EXPLAIN (COSTS OFF) SELECT * FROM test_name WHERE i>'abc' ORDER BY i;
diff --git a/contrib/btree_gin/sql/uuid.sql b/contrib/btree_gin/sql/uuid.sql
new file mode 100644
index ...3c141bd
*** a/contrib/btree_gin/sql/uuid.sql
--- b/contrib/btree_gin/sql/uuid.sql
***************
*** 0 ****
--- 1,28 ----
+ set enable_seqscan=off;
+
+ CREATE TABLE test_uuid (
+ i uuid
+ );
+
+ INSERT INTO test_uuid VALUES
+ ( '00000000-0000-0000-0000-000000000000' ),
+ ( '299bc99f-2f79-4e3e-bfea-2cbfd62a7c27' ),
+ ( '6264af33-0d43-4337-bf4e-43509b8a4be8' ),
+ ( 'ce41c936-6acb-4feb-8c91-852a673e5a5c' ),
+ ( 'd2ce731f-f2a8-4a2b-be37-8f0ba637427f' ),
+ ( 'ffffffff-ffff-ffff-ffff-ffffffffffff' )
+ ;
+
+ CREATE INDEX idx_uuid ON test_uuid USING gin (i);
+
+ SELECT * FROM test_uuid WHERE i<'ce41c936-6acb-4feb-8c91-852a673e5a5c'::uuid ORDER BY i;
+ SELECT * FROM test_uuid WHERE i<='ce41c936-6acb-4feb-8c91-852a673e5a5c'::uuid ORDER BY i;
+ SELECT * FROM test_uuid WHERE i='ce41c936-6acb-4feb-8c91-852a673e5a5c'::uuid ORDER BY i;
+ SELECT * FROM test_uuid WHERE i>='ce41c936-6acb-4feb-8c91-852a673e5a5c'::uuid ORDER BY i;
+ SELECT * FROM test_uuid WHERE i>'ce41c936-6acb-4feb-8c91-852a673e5a5c'::uuid ORDER BY i;
+
+ EXPLAIN (COSTS OFF) SELECT * FROM test_uuid WHERE i<'ce41c936-6acb-4feb-8c91-852a673e5a5c'::uuid ORDER BY i;
+ EXPLAIN (COSTS OFF) SELECT * FROM test_uuid WHERE i<='ce41c936-6acb-4feb-8c91-852a673e5a5c'::uuid ORDER BY i;
+ EXPLAIN (COSTS OFF) SELECT * FROM test_uuid WHERE i='ce41c936-6acb-4feb-8c91-852a673e5a5c'::uuid ORDER BY i;
+ EXPLAIN (COSTS OFF) SELECT * FROM test_uuid WHERE i>='ce41c936-6acb-4feb-8c91-852a673e5a5c'::uuid ORDER BY i;
+ EXPLAIN (COSTS OFF) SELECT * FROM test_uuid WHERE i>'ce41c936-6acb-4feb-8c91-852a673e5a5c'::uuid ORDER BY i;
diff --git a/doc/src/sgml/btree-gin.sgml b/doc/src/sgml/btree-gin.sgml
new file mode 100644
index e491fa7..314e001
*** a/doc/src/sgml/btree-gin.sgml
--- b/doc/src/sgml/btree-gin.sgml
***************
*** 17,23 ****
<type>oid</type>, <type>money</type>, <type>"char"</type>,
<type>varchar</type>, <type>text</type>, <type>bytea</type>, <type>bit</type>,
<type>varbit</type>, <type>macaddr</type>, <type>macaddr8</type>, <type>inet</type>,
! <type>cidr</type>, and all <type>enum</type> types.
</para>
<para>
--- 17,24 ----
<type>oid</type>, <type>money</type>, <type>"char"</type>,
<type>varchar</type>, <type>text</type>, <type>bytea</type>, <type>bit</type>,
<type>varbit</type>, <type>macaddr</type>, <type>macaddr8</type>, <type>inet</type>,
! <type>cidr</type>, <type>uuid</type>, <type>name</type>, <type>bool</type>,
! <type>bpchar</type>, and all <type>enum</type> types.
</para>
<para>
diff --git a/contrib/btree_gin/Makefile b/contrib/btree_gin/Makefile
new file mode 100644
index a9e9925..d36f5ad
*** a/contrib/btree_gin/Makefile
--- b/contrib/btree_gin/Makefile
*************** PGFILEDESC = "btree_gin - B-tree equival
*** 11,17 ****
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 enum uuid name bool bpchar
ifdef USE_PGXS
PG_CONFIG = pg_config
--- 11,17 ----
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 enum uuid name bool anyrange bpchar
ifdef USE_PGXS
PG_CONFIG = pg_config
diff --git a/contrib/btree_gin/btree_gin--1.2--1.3.sql b/contrib/btree_gin/btree_gin--1.2--1.3.sql
new file mode 100644
index db675b7..f7523a3
*** a/contrib/btree_gin/btree_gin--1.2--1.3.sql
--- b/contrib/btree_gin/btree_gin--1.2--1.3.sql
*************** AS
*** 96,101 ****
--- 96,137 ----
FUNCTION 5 gin_compare_prefix_bool(bool,bool,int2, internal),
STORAGE bool;
+ -- anyrange datatype support new in 1.3.
+ CREATE FUNCTION gin_anyrange_cmp(anyrange, anyrange)
+ RETURNS int4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE FUNCTION gin_extract_value_anyrange(anyrange, internal)
+ RETURNS internal
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE FUNCTION gin_compare_prefix_anyrange(anyrange, anyrange, int2, internal)
+ RETURNS int4
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE FUNCTION gin_extract_query_anyrange(anyrange, internal, int2, internal, internal)
+ RETURNS internal
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE OPERATOR CLASS anyrange_ops
+ DEFAULT FOR TYPE anyrange USING gin
+ AS
+ OPERATOR 1 <,
+ OPERATOR 2 <=,
+ OPERATOR 3 =,
+ OPERATOR 4 >=,
+ OPERATOR 5 >,
+ FUNCTION 1 gin_anyrange_cmp(anyrange,anyrange),
+ FUNCTION 2 gin_extract_value_anyrange(anyrange, internal),
+ FUNCTION 3 gin_extract_query_anyrange(anyrange, internal, int2, internal, internal),
+ FUNCTION 4 gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
+ FUNCTION 5 gin_compare_prefix_anyrange(anyrange,anyrange,int2, internal),
+ STORAGE anyrange;
+
-- bpchar datatype support new in 1.3.
CREATE FUNCTION gin_extract_value_bpchar(bpchar, internal)
RETURNS internal
diff --git a/contrib/btree_gin/btree_gin.c b/contrib/btree_gin/btree_gin.c
new file mode 100644
index a660681..37e0740
*** a/contrib/btree_gin/btree_gin.c
--- b/contrib/btree_gin/btree_gin.c
***************
*** 15,20 ****
--- 15,21 ----
#include "utils/timestamp.h"
#include "utils/varbit.h"
#include "utils/uuid.h"
+ #include "utils/rangetypes.h"
PG_MODULE_MAGIC;
*************** leftmostvalue_bool(void)
*** 506,508 ****
--- 507,560 ----
}
GIN_SUPPORT(bool, false, leftmostvalue_bool, btboolcmp)
+
+ /*
+ * Similarly to Numeric, we don't know the left-most value, although for
+ * different reasons (numeric does not have one, while for anyarray we
+ * don't even know the concrete type). We could try to build a fake empty
+ * range, but we simply use PointerGetDatum(NULL) just like for Numeric.
+ */
+ #define ANYRANGE_IS_LEFTMOST(x) ((x) == NULL)
+
+ PG_FUNCTION_INFO_V1(gin_anyrange_cmp);
+
+ /*
+ * Note that we use CallerFInfoFunctionCall2 here so that range_cmp
+ * gets a valid fn_extra to work with. Unlike most other type comparison
+ * routines it needs it, so we can't use DirectFunctionCall2.
+ */
+ Datum
+ gin_anyrange_cmp(PG_FUNCTION_ARGS)
+ {
+ RangeType *a = (RangeType *) PG_GETARG_POINTER(0);
+ RangeType *b = (RangeType *) PG_GETARG_POINTER(1);
+ int res = 0;
+
+ if (ANYRANGE_IS_LEFTMOST(a))
+ {
+ res = (ANYRANGE_IS_LEFTMOST(b)) ? 0 : -1;
+ }
+ else if (ANYRANGE_IS_LEFTMOST(b))
+ {
+ res = 1;
+ }
+ else
+ {
+ res = DatumGetInt32(CallerFInfoFunctionCall2(
+ range_cmp,
+ fcinfo->flinfo,
+ PG_GET_COLLATION(),
+ RangeTypePGetDatum(a),
+ RangeTypePGetDatum(b)));
+ }
+
+ PG_RETURN_INT32(res);
+ }
+
+ static Datum
+ leftmostvalue_anyrange(void)
+ {
+ return PointerGetDatum(NULL);
+ }
+
+ GIN_SUPPORT(anyrange, false, leftmostvalue_anyrange, gin_anyrange_cmp)
diff --git a/contrib/btree_gin/expected/anyrange.out b/contrib/btree_gin/expected/anyrange.out
new file mode 100644
index ...93b24f4
*** a/contrib/btree_gin/expected/anyrange.out
--- b/contrib/btree_gin/expected/anyrange.out
***************
*** 0 ****
--- 1,113 ----
+ set enable_seqscan=off;
+ CREATE TABLE test_tsrange (
+ i tsrange
+ );
+ INSERT INTO test_tsrange VALUES
+ ( 'empty' ),
+ ( '(,)' ),
+ ( '[2018-02-02 03:55:08,2018-04-02 03:55:08)' ),
+ ( '[2018-02-02 04:55:08,2018-04-02 04:55:08)' ),
+ ( '[2018-02-02 05:55:08,2018-04-02 05:55:08)' ),
+ ( '[2018-02-02 08:55:08,2018-04-02 08:55:08)' ),
+ ( '[2018-02-02 09:55:08,2018-04-02 09:55:08)' ),
+ ( '[2018-02-02 10:55:08,2018-04-02 10:55:08)' ),
+ ( '[infinity,infinity]' )
+ ;
+ CREATE INDEX idx_tsrange ON test_tsrange USING gin (i);
+ SELECT * FROM test_tsrange WHERE i<'[2018-02-02 08:55:08,2018-04-02 08:55:08)'::tsrange ORDER BY i;
+ i
+ ---------------------------------------------------------
+ empty
+ (,)
+ ["Fri Feb 02 03:55:08 2018","Mon Apr 02 03:55:08 2018")
+ ["Fri Feb 02 04:55:08 2018","Mon Apr 02 04:55:08 2018")
+ ["Fri Feb 02 05:55:08 2018","Mon Apr 02 05:55:08 2018")
+ (5 rows)
+
+ SELECT * FROM test_tsrange WHERE i<='[2018-02-02 08:55:08,2018-04-02 08:55:08)'::tsrange ORDER BY i;
+ i
+ ---------------------------------------------------------
+ empty
+ (,)
+ ["Fri Feb 02 03:55:08 2018","Mon Apr 02 03:55:08 2018")
+ ["Fri Feb 02 04:55:08 2018","Mon Apr 02 04:55:08 2018")
+ ["Fri Feb 02 05:55:08 2018","Mon Apr 02 05:55:08 2018")
+ ["Fri Feb 02 08:55:08 2018","Mon Apr 02 08:55:08 2018")
+ (6 rows)
+
+ SELECT * FROM test_tsrange WHERE i='[2018-02-02 08:55:08,2018-04-02 08:55:08)'::tsrange ORDER BY i;
+ i
+ ---------------------------------------------------------
+ ["Fri Feb 02 08:55:08 2018","Mon Apr 02 08:55:08 2018")
+ (1 row)
+
+ SELECT * FROM test_tsrange WHERE i>='[2018-02-02 08:55:08,2018-04-02 08:55:08)'::tsrange ORDER BY i;
+ i
+ ---------------------------------------------------------
+ ["Fri Feb 02 08:55:08 2018","Mon Apr 02 08:55:08 2018")
+ ["Fri Feb 02 09:55:08 2018","Mon Apr 02 09:55:08 2018")
+ ["Fri Feb 02 10:55:08 2018","Mon Apr 02 10:55:08 2018")
+ [infinity,infinity]
+ (4 rows)
+
+ SELECT * FROM test_tsrange WHERE i>'[2018-02-02 08:55:08,2018-04-02 08:55:08)'::tsrange ORDER BY i;
+ i
+ ---------------------------------------------------------
+ ["Fri Feb 02 09:55:08 2018","Mon Apr 02 09:55:08 2018")
+ ["Fri Feb 02 10:55:08 2018","Mon Apr 02 10:55:08 2018")
+ [infinity,infinity]
+ (3 rows)
+
+ EXPLAIN (COSTS OFF) SELECT * FROM test_tsrange WHERE i<'[2018-02-02 08:55:08,2018-04-02 08:55:08)'::tsrange ORDER BY i;
+ QUERY PLAN
+ ----------------------------------------------------------------------------------------------------
+ Sort
+ Sort Key: i
+ -> Bitmap Heap Scan on test_tsrange
+ Recheck Cond: (i < '["Fri Feb 02 08:55:08 2018","Mon Apr 02 08:55:08 2018")'::tsrange)
+ -> Bitmap Index Scan on idx_tsrange
+ Index Cond: (i < '["Fri Feb 02 08:55:08 2018","Mon Apr 02 08:55:08 2018")'::tsrange)
+ (6 rows)
+
+ EXPLAIN (COSTS OFF) SELECT * FROM test_tsrange WHERE i<='[2018-02-02 08:55:08,2018-04-02 08:55:08)'::tsrange ORDER BY i;
+ QUERY PLAN
+ -----------------------------------------------------------------------------------------------------
+ Sort
+ Sort Key: i
+ -> Bitmap Heap Scan on test_tsrange
+ Recheck Cond: (i <= '["Fri Feb 02 08:55:08 2018","Mon Apr 02 08:55:08 2018")'::tsrange)
+ -> Bitmap Index Scan on idx_tsrange
+ Index Cond: (i <= '["Fri Feb 02 08:55:08 2018","Mon Apr 02 08:55:08 2018")'::tsrange)
+ (6 rows)
+
+ EXPLAIN (COSTS OFF) SELECT * FROM test_tsrange WHERE i='[2018-02-02 08:55:08,2018-04-02 08:55:08)'::tsrange ORDER BY i;
+ QUERY PLAN
+ ----------------------------------------------------------------------------------------------
+ Bitmap Heap Scan on test_tsrange
+ Recheck Cond: (i = '["Fri Feb 02 08:55:08 2018","Mon Apr 02 08:55:08 2018")'::tsrange)
+ -> Bitmap Index Scan on idx_tsrange
+ Index Cond: (i = '["Fri Feb 02 08:55:08 2018","Mon Apr 02 08:55:08 2018")'::tsrange)
+ (4 rows)
+
+ EXPLAIN (COSTS OFF) SELECT * FROM test_tsrange WHERE i>='[2018-02-02 08:55:08,2018-04-02 08:55:08)'::tsrange ORDER BY i;
+ QUERY PLAN
+ -----------------------------------------------------------------------------------------------------
+ Sort
+ Sort Key: i
+ -> Bitmap Heap Scan on test_tsrange
+ Recheck Cond: (i >= '["Fri Feb 02 08:55:08 2018","Mon Apr 02 08:55:08 2018")'::tsrange)
+ -> Bitmap Index Scan on idx_tsrange
+ Index Cond: (i >= '["Fri Feb 02 08:55:08 2018","Mon Apr 02 08:55:08 2018")'::tsrange)
+ (6 rows)
+
+ EXPLAIN (COSTS OFF) SELECT * FROM test_tsrange WHERE i>'[2018-02-02 08:55:08,2018-04-02 08:55:08)'::tsrange ORDER BY i;
+ QUERY PLAN
+ ----------------------------------------------------------------------------------------------------
+ Sort
+ Sort Key: i
+ -> Bitmap Heap Scan on test_tsrange
+ Recheck Cond: (i > '["Fri Feb 02 08:55:08 2018","Mon Apr 02 08:55:08 2018")'::tsrange)
+ -> Bitmap Index Scan on idx_tsrange
+ Index Cond: (i > '["Fri Feb 02 08:55:08 2018","Mon Apr 02 08:55:08 2018")'::tsrange)
+ (6 rows)
+
diff --git a/contrib/btree_gin/sql/anyrange.sql b/contrib/btree_gin/sql/anyrange.sql
new file mode 100644
index ...97157ad
*** a/contrib/btree_gin/sql/anyrange.sql
--- b/contrib/btree_gin/sql/anyrange.sql
***************
*** 0 ****
--- 1,31 ----
+ set enable_seqscan=off;
+
+ CREATE TABLE test_tsrange (
+ i tsrange
+ );
+
+ INSERT INTO test_tsrange VALUES
+ ( 'empty' ),
+ ( '(,)' ),
+ ( '[2018-02-02 03:55:08,2018-04-02 03:55:08)' ),
+ ( '[2018-02-02 04:55:08,2018-04-02 04:55:08)' ),
+ ( '[2018-02-02 05:55:08,2018-04-02 05:55:08)' ),
+ ( '[2018-02-02 08:55:08,2018-04-02 08:55:08)' ),
+ ( '[2018-02-02 09:55:08,2018-04-02 09:55:08)' ),
+ ( '[2018-02-02 10:55:08,2018-04-02 10:55:08)' ),
+ ( '[infinity,infinity]' )
+ ;
+
+ CREATE INDEX idx_tsrange ON test_tsrange USING gin (i);
+
+ SELECT * FROM test_tsrange WHERE i<'[2018-02-02 08:55:08,2018-04-02 08:55:08)'::tsrange ORDER BY i;
+ SELECT * FROM test_tsrange WHERE i<='[2018-02-02 08:55:08,2018-04-02 08:55:08)'::tsrange ORDER BY i;
+ SELECT * FROM test_tsrange WHERE i='[2018-02-02 08:55:08,2018-04-02 08:55:08)'::tsrange ORDER BY i;
+ SELECT * FROM test_tsrange WHERE i>='[2018-02-02 08:55:08,2018-04-02 08:55:08)'::tsrange ORDER BY i;
+ SELECT * FROM test_tsrange WHERE i>'[2018-02-02 08:55:08,2018-04-02 08:55:08)'::tsrange ORDER BY i;
+
+ EXPLAIN (COSTS OFF) SELECT * FROM test_tsrange WHERE i<'[2018-02-02 08:55:08,2018-04-02 08:55:08)'::tsrange ORDER BY i;
+ EXPLAIN (COSTS OFF) SELECT * FROM test_tsrange WHERE i<='[2018-02-02 08:55:08,2018-04-02 08:55:08)'::tsrange ORDER BY i;
+ EXPLAIN (COSTS OFF) SELECT * FROM test_tsrange WHERE i='[2018-02-02 08:55:08,2018-04-02 08:55:08)'::tsrange ORDER BY i;
+ EXPLAIN (COSTS OFF) SELECT * FROM test_tsrange WHERE i>='[2018-02-02 08:55:08,2018-04-02 08:55:08)'::tsrange ORDER BY i;
+ EXPLAIN (COSTS OFF) SELECT * FROM test_tsrange WHERE i>'[2018-02-02 08:55:08,2018-04-02 08:55:08)'::tsrange ORDER BY i;
diff --git a/doc/src/sgml/btree-gin.sgml b/doc/src/sgml/btree-gin.sgml
new file mode 100644
index 314e001..e1315da
*** a/doc/src/sgml/btree-gin.sgml
--- b/doc/src/sgml/btree-gin.sgml
***************
*** 18,24 ****
<type>varchar</type>, <type>text</type>, <type>bytea</type>, <type>bit</type>,
<type>varbit</type>, <type>macaddr</type>, <type>macaddr8</type>, <type>inet</type>,
<type>cidr</type>, <type>uuid</type>, <type>name</type>, <type>bool</type>,
! <type>bpchar</type>, and all <type>enum</type> types.
</para>
<para>
--- 18,24 ----
<type>varchar</type>, <type>text</type>, <type>bytea</type>, <type>bit</type>,
<type>varbit</type>, <type>macaddr</type>, <type>macaddr8</type>, <type>inet</type>,
<type>cidr</type>, <type>uuid</type>, <type>name</type>, <type>bool</type>,
! <type>bpchar</type>, and all <type>enum</type> and <type>anyrange</type> types.
</para>
<para>