]> granicus.if.org Git - postgresql/commitdiff
Add btree_gist support for enum types.
authorAndrew Dunstan <andrew@dunslane.net>
Tue, 21 Mar 2017 14:19:03 +0000 (10:19 -0400)
committerAndrew Dunstan <andrew@dunslane.net>
Tue, 21 Mar 2017 14:43:27 +0000 (10:43 -0400)
This will allow enums to be used in exclusion constraints.

The code uses the new CallerFInfoFunctionCall infrastructure in fmgr,
and the support for it added to btree_gist in commit 393bb504d7.

Reviewed by Tom Lane and Anastasia Lubennikova

Discussion:  http://postgr.es/m/56EA8A71.8060107@dunslane.net

contrib/btree_gist/Makefile
contrib/btree_gist/btree_enum.c [new file with mode: 0644]
contrib/btree_gist/btree_gist--1.4--1.5.sql [new file with mode: 0644]
contrib/btree_gist/btree_gist.control
contrib/btree_gist/btree_gist.h
contrib/btree_gist/btree_utils_num.c
contrib/btree_gist/data/enum.data [new file with mode: 0644]
contrib/btree_gist/expected/enum.out [new file with mode: 0644]
contrib/btree_gist/sql/enum.sql [new file with mode: 0644]
doc/src/sgml/btree-gist.sgml

index c70f17869a2ab482e664b859f136ad5abc03d803..af651205ec6351762be53d64b100ba94c284b35c 100644 (file)
@@ -5,18 +5,19 @@ MODULE_big = btree_gist
 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_macaddr.o btree_macaddr8.o btree_inet.o btree_text.o \
+               btree_bytea.o 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 \
        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
+       btree_gist--1.3--1.4.sql btree_gist--1.4--1.5.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 macaddr8 inet cidr text varchar char \
-        bytea bit varbit numeric uuid not_equal
+        bytea bit varbit numeric uuid not_equal enum
 
 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 (file)
index 0000000..5e46e78
--- /dev/null
@@ -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.4--1.5.sql b/contrib/btree_gist/btree_gist--1.4--1.5.sql
new file mode 100644 (file)
index 0000000..cf974c2
--- /dev/null
@@ -0,0 +1,69 @@
+/* contrib/btree_gist/btree_gist--1.4--1.5.sql */
+
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "ALTER EXTENSION btree_gist UPDATE TO '1.5'" 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) ;
index fdf0e6ad9eedc11905f89bcd168ab39d6ea18f08..81c850905c5501e3bc21f25f55b94fc428f15373 100644 (file)
@@ -1,5 +1,5 @@
 # btree_gist extension
 comment = 'support for indexing common datatypes in GiST'
-default_version = '1.4'
+default_version = '1.5'
 module_pathname = '$libdir/btree_gist'
 relocatable = true
index f759299bb2da407b22b4226572ff7b92f72a17ae..011285abce070dc87ccc2be52e80c02d9ab44b4c 100644 (file)
@@ -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
index e30924ba1d4b4d4b56163cc2f0f06ab4f10a5db4..d4fee91ee1730e96e1271c5a1cf0d381b26b9103 100644 (file)
@@ -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 (file)
index 0000000..d03bfce
--- /dev/null
@@ -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 (file)
index 0000000..c4b769d
--- /dev/null
@@ -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 (file)
index 0000000..476211e
--- /dev/null
@@ -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;
index cfdd5be84afccdf202630e8b20954f3e7f3593ab..f3c639c2f3b562af02e5183d2178816658f97752 100644 (file)
@@ -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</>,
-  <type>cidr</> and <type>uuid</>.
+  <type>cidr</>, <type>uuid</>, and all <type>enum</> types.
  </para>
 
  <para>