Add btree_gist support for searching on "not equals".
authorRobert Haas <rhaas@postgresql.org>
Mon, 2 Aug 2010 16:26:48 +0000 (16:26 +0000)
committerRobert Haas <rhaas@postgresql.org>
Mon, 2 Aug 2010 16:26:48 +0000 (16:26 +0000)
Jeff Davis, with slight editorialization by me.

contrib/btree_gist/btree_gist.h
contrib/btree_gist/btree_gist.sql.in
contrib/btree_gist/btree_utils_num.c
contrib/btree_gist/btree_utils_var.c
doc/src/sgml/btree-gist.sgml

index 425ce8cff4c3ee8423847dfe7dbe2580790231d2..db5c5713b5b1d00182471f9e74b35cfea24acb0f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $PostgreSQL: pgsql/contrib/btree_gist/btree_gist.h,v 1.9 2009/06/11 14:48:50 momjian Exp $
+ * $PostgreSQL: pgsql/contrib/btree_gist/btree_gist.h,v 1.10 2010/08/02 16:26:48 rhaas Exp $
  */
 #ifndef __BTREE_GIST_H__
 #define __BTREE_GIST_H__
@@ -9,6 +9,8 @@
 #include "access/itup.h"
 #include "access/nbtree.h"
 
+#define BtreeGistNotEqualStrategyNumber 6
+
 /* indexed types */
 
 enum gbtree_type
index e78c83cdc286e55f8ab3e3d01f7dc34f3ceb5dde..0a285a71c1d44f578690d8236e12495b7f48b6e8 100644 (file)
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/contrib/btree_gist/btree_gist.sql.in,v 1.21 2009/06/11 18:30:03 tgl Exp $ */
+/* $PostgreSQL: pgsql/contrib/btree_gist/btree_gist.sql.in,v 1.22 2010/08/02 16:26:48 rhaas Exp $ */
 
 -- Adjust this setting to control where the objects get created.
 SET search_path = public;
@@ -143,6 +143,7 @@ AS
    OPERATOR    3   =  ,
    OPERATOR    4   >= ,
    OPERATOR    5   >  ,
+   OPERATOR    6   <> ,
    FUNCTION    1   gbt_oid_consistent (internal, oid, int2, oid, internal),
    FUNCTION    2   gbt_oid_union (bytea, internal),
    FUNCTION    3   gbt_oid_compress (internal),
@@ -200,6 +201,7 @@ AS
    OPERATOR    3   =  ,
    OPERATOR    4   >= ,
    OPERATOR    5   >  ,
+   OPERATOR    6   <> ,
    FUNCTION    1   gbt_int2_consistent (internal, int2, int2, oid, internal),
    FUNCTION    2   gbt_int2_union (bytea, internal),
    FUNCTION    3   gbt_int2_compress (internal),
@@ -256,6 +258,7 @@ AS
    OPERATOR    3   =  ,
    OPERATOR    4   >= ,
    OPERATOR    5   >  ,
+   OPERATOR    6   <> ,
    FUNCTION    1   gbt_int4_consistent (internal, int4, int2, oid, internal),
    FUNCTION    2   gbt_int4_union (bytea, internal),
    FUNCTION    3   gbt_int4_compress (internal),
@@ -312,6 +315,7 @@ AS
    OPERATOR    3   =  ,
    OPERATOR    4   >= ,
    OPERATOR    5   >  ,
+   OPERATOR    6   <> ,
    FUNCTION    1   gbt_int8_consistent (internal, int8, int2, oid, internal),
    FUNCTION    2   gbt_int8_union (bytea, internal),
    FUNCTION    3   gbt_int8_compress (internal),
@@ -369,6 +373,7 @@ AS
    OPERATOR    3   =  ,
    OPERATOR    4   >= ,
    OPERATOR    5   >  ,
+   OPERATOR    6   <> ,
    FUNCTION    1   gbt_float4_consistent (internal, float4, int2, oid, internal),
    FUNCTION    2   gbt_float4_union (bytea, internal),
    FUNCTION    3   gbt_float4_compress (internal),
@@ -428,6 +433,7 @@ AS
    OPERATOR    3   =  ,
    OPERATOR    4   >= ,
    OPERATOR    5   >  ,
+   OPERATOR    6   <> ,
    FUNCTION    1   gbt_float8_consistent (internal, float8, int2, oid, internal),
    FUNCTION    2   gbt_float8_union (bytea, internal),
    FUNCTION    3   gbt_float8_compress (internal),
@@ -495,6 +501,7 @@ AS
    OPERATOR    3   =  ,
    OPERATOR    4   >= ,
    OPERATOR    5   >  ,
+   OPERATOR    6   <> ,
    FUNCTION    1   gbt_ts_consistent (internal, timestamp, int2, oid, internal),
    FUNCTION    2   gbt_ts_union (bytea, internal),
    FUNCTION    3   gbt_ts_compress (internal),
@@ -514,6 +521,7 @@ AS
    OPERATOR    3   =  ,
    OPERATOR    4   >= ,
    OPERATOR    5   >  ,
+   OPERATOR    6   <> ,
    FUNCTION    1   gbt_tstz_consistent (internal, timestamptz, int2, oid, internal),
    FUNCTION    2   gbt_ts_union (bytea, internal),
    FUNCTION    3   gbt_tstz_compress (internal),
@@ -581,6 +589,7 @@ AS
    OPERATOR    3   =  ,
    OPERATOR    4   >= ,
    OPERATOR    5   >  ,
+   OPERATOR    6   <> ,
    FUNCTION    1   gbt_time_consistent (internal, time, int2, oid, internal),
    FUNCTION    2   gbt_time_union (bytea, internal),
    FUNCTION    3   gbt_time_compress (internal),
@@ -598,6 +607,7 @@ AS
    OPERATOR    3   =   ,
    OPERATOR    4   >=  ,
    OPERATOR    5   >   ,
+   OPERATOR    6   <> ,
    FUNCTION    1   gbt_timetz_consistent (internal, timetz, int2, oid, internal),
    FUNCTION    2   gbt_time_union (bytea, internal),
    FUNCTION    3   gbt_timetz_compress (internal),
@@ -655,6 +665,7 @@ AS
    OPERATOR    3   =  ,
    OPERATOR    4   >= ,
    OPERATOR    5   >  ,
+   OPERATOR    6   <> ,
    FUNCTION    1   gbt_date_consistent (internal, date, int2, oid, internal),
    FUNCTION    2   gbt_date_union (bytea, internal),
    FUNCTION    3   gbt_date_compress (internal),
@@ -717,6 +728,7 @@ AS
    OPERATOR    3   = ,
    OPERATOR    4   >= ,
    OPERATOR    5   > ,
+   OPERATOR    6   <> ,
    FUNCTION    1   gbt_intv_consistent (internal, interval, int2, oid, internal),
    FUNCTION    2   gbt_intv_union (bytea, internal),
    FUNCTION    3   gbt_intv_compress (internal),
@@ -773,6 +785,7 @@ AS
    OPERATOR    3   = ,
    OPERATOR    4   >= ,
    OPERATOR    5   > ,
+   OPERATOR    6   <> ,
    FUNCTION    1   gbt_cash_consistent (internal, money, int2, oid, internal),
    FUNCTION    2   gbt_cash_union (bytea, internal),
    FUNCTION    3   gbt_cash_compress (internal),
@@ -829,6 +842,7 @@ AS
    OPERATOR    3   = ,
    OPERATOR    4   >= ,
    OPERATOR    5   > ,
+   OPERATOR    6   <> ,
    FUNCTION    1   gbt_macad_consistent (internal, macaddr, int2, oid, internal),
    FUNCTION    2   gbt_macad_union (bytea, internal),
    FUNCTION    3   gbt_macad_compress (internal),
@@ -897,6 +911,7 @@ AS
    OPERATOR    3   =  ,
    OPERATOR    4   >= ,
    OPERATOR    5   >  ,
+   OPERATOR    6   <> ,
    FUNCTION    1   gbt_text_consistent (internal, text, int2, oid, internal),
    FUNCTION    2   gbt_text_union (bytea, internal),
    FUNCTION    3   gbt_text_compress (internal),
@@ -916,6 +931,7 @@ AS
    OPERATOR    3   =  ,
    OPERATOR    4   >= ,
    OPERATOR    5   >  ,
+   OPERATOR    6   <> ,
    FUNCTION    1   gbt_bpchar_consistent (internal, bpchar , int2, oid, internal),
    FUNCTION    2   gbt_text_union (bytea, internal),
    FUNCTION    3   gbt_bpchar_compress (internal),
@@ -973,6 +989,7 @@ AS
    OPERATOR    3   =  ,
    OPERATOR    4   >= ,
    OPERATOR    5   >  ,
+   OPERATOR    6   <> ,
    FUNCTION    1   gbt_bytea_consistent (internal, bytea, int2, oid, internal),
    FUNCTION    2   gbt_bytea_union (bytea, internal),
    FUNCTION    3   gbt_bytea_compress (internal),
@@ -1030,6 +1047,7 @@ AS
    OPERATOR    3   =  ,
    OPERATOR    4   >= ,
    OPERATOR    5   >  ,
+   OPERATOR    6   <> ,
    FUNCTION    1   gbt_numeric_consistent (internal, numeric, int2, oid, internal),
    FUNCTION    2   gbt_numeric_union (bytea, internal),
    FUNCTION    3   gbt_numeric_compress (internal),
@@ -1085,6 +1103,7 @@ AS
    OPERATOR    3   =  ,
    OPERATOR    4   >= ,
    OPERATOR    5   >  ,
+   OPERATOR    6   <> ,
    FUNCTION    1   gbt_bit_consistent (internal, bit, int2, oid, internal),
    FUNCTION    2   gbt_bit_union (bytea, internal),
    FUNCTION    3   gbt_bit_compress (internal),
@@ -1104,6 +1123,7 @@ AS
    OPERATOR    3   =  ,
    OPERATOR    4   >= ,
    OPERATOR    5   >  ,
+   OPERATOR    6   <> ,
    FUNCTION    1   gbt_bit_consistent (internal, bit, int2, oid, internal),
    FUNCTION    2   gbt_bit_union (bytea, internal),
    FUNCTION    3   gbt_bit_compress (internal),
@@ -1162,6 +1182,7 @@ AS
    OPERATOR    3   =   ,
    OPERATOR    4   >=  ,
    OPERATOR    5   >   ,
+   OPERATOR    6   <>  ,
    FUNCTION    1   gbt_inet_consistent (internal, inet, int2, oid, internal),
    FUNCTION    2   gbt_inet_union (bytea, internal),
    FUNCTION    3   gbt_inet_compress (internal),
@@ -1180,6 +1201,7 @@ AS
    OPERATOR    3   =  (inet, inet)  ,
    OPERATOR    4   >= (inet, inet)  ,
    OPERATOR    5   >  (inet, inet)  ,
+   OPERATOR    6   <> (inet, inet)  ,
    FUNCTION    1   gbt_inet_consistent (internal, inet, int2, oid, internal),
    FUNCTION    2   gbt_inet_union (bytea, internal),
    FUNCTION    3   gbt_inet_compress (internal),
index ff206dcda8288615e8810aef7c4083e382a63114..e4b4824769f8787f759aa6ba25b7adbd772b1f2a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $PostgreSQL: pgsql/contrib/btree_gist/btree_utils_num.c,v 1.12 2009/06/11 14:48:50 momjian Exp $
+ * $PostgreSQL: pgsql/contrib/btree_gist/btree_utils_num.c,v 1.13 2010/08/02 16:26:48 rhaas Exp $
  */
 #include "btree_gist.h"
 #include "btree_utils_num.h"
@@ -225,6 +225,10 @@ gbt_num_consistent(
        case BTGreaterEqualStrategyNumber:
            retval = (*tinfo->f_le) (query, key->upper);
            break;
+       case BtreeGistNotEqualStrategyNumber:
+           retval = ! ((*tinfo->f_eq) (query, key->lower) &&
+               (*tinfo->f_eq) (query, key->upper));
+           break;
        default:
            retval = FALSE;
    }
index 916706d8a479650532d16963639c179dd43260b8..447ba59efbd034d8a0914d19a7f2522cabc8a432 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $PostgreSQL: pgsql/contrib/btree_gist/btree_utils_var.c,v 1.23 2010/02/26 02:00:32 momjian Exp $
+ * $PostgreSQL: pgsql/contrib/btree_gist/btree_utils_var.c,v 1.24 2010/08/02 16:26:48 rhaas Exp $
  */
 #include "btree_gist.h"
 
@@ -596,6 +596,9 @@ gbt_var_consistent(
                retval = (*tinfo->f_cmp) ((bytea *) query, key->upper) <= 0
                    || gbt_var_node_pf_match(key, query, tinfo);
            break;
+       case BtreeGistNotEqualStrategyNumber:
+           retval = ! ((*tinfo->f_eq) (query, key->lower) && (*tinfo->f_eq) (query, key->upper));
+           break;
        default:
            retval = FALSE;
    }
index 8264d5a219c3947bcf4214fe2fde4936b7bf775e..d477f23a2e46abc047fdd74ccdd952efef4ed56a 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/btree-gist.sgml,v 1.5 2010/03/17 17:12:31 petere Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/btree-gist.sgml,v 1.6 2010/08/02 16:26:48 rhaas Exp $ -->
 
 <sect1 id="btree-gist">
  <title>btree_gist</title>
   GiST operator classes.
  </para>
 
+ <para>
+  In addition to the typical btree search operators, btree_gist also
+  provides search operators for <literal>&lt;&gt;</literal> ("not
+  equals"). This may be useful in combination with an
+  <link linkend="SQL-CREATETABLE-EXCLUDE">Exclusion Constraint</link>,
+  as descibed below.
+ </para>
+
  <sect2>
   <title>Example usage</title>
 
+  <para>
+   Simple example using btree_gist instead of btree:
+  </para>
+
 <programlisting>
 CREATE TABLE test (a int4);
 -- create index
 CREATE INDEX testidx ON test USING gist (a);
 -- query
 SELECT * FROM test WHERE a &lt; 10;
+</programlisting>
+
+  <para>
+   Example using an <link linkend="SQL-CREATETABLE-EXCLUDE">Exclusion
+   Constraint</link> to enforce the constraint that a cage at a zoo
+   can contain only one kind of animal:
+  </para>
+
+<programlisting>
+=> CREATE TABLE zoo (
+  cage   INTEGER,
+  animal TEXT,
+  EXCLUDE USING gist (cage WITH =, animal WITH <>)
+);
+
+=> INSERT INTO zoo VALUES(123, 'zebra');
+INSERT 0 1
+=> INSERT INTO zoo VALUES(123, 'zebra');
+INSERT 0 1
+=> INSERT INTO zoo VALUES(123, 'lion');
+ERROR:  conflicting key value violates exclusion constraint "zoo_cage_animal_excl"
+DETAIL:  Key (cage, animal)=(123, lion) conflicts with existing key (cage, animal)=(123, zebra).
+=> INSERT INTO zoo VALUES(124, 'lion');
+INSERT 0 1
 </programlisting>
 
  </sect2>