GiST operator class for bool
It could be useful to use bool in exclusion constraints, but it's
currently not nicely supported. The attached patch adds support for
bool to the btree_gist extension, so we can do this.
I am adding this to the commitfest 2021-07.
Attachments:
0001-btree_gist-Support-bool.patchapplication/octet-stream; name=0001-btree_gist-Support-bool.patchDownload
From 95d864ac93fa272f936e78ca4c03b0277a093379 Mon Sep 17 00:00:00 2001
From: Emre Hasegeli <emre@hasegeli.com>
Date: Tue, 8 Jun 2021 12:53:25 +0300
Subject: [PATCH] btree_gist: Support bool
---
contrib/btree_gist/Makefile | 5 +-
contrib/btree_gist/btree_bool.c | 169 ++++++++++++++++++++
contrib/btree_gist/btree_gist--1.6--1.7.sql | 62 +++++++
contrib/btree_gist/btree_gist.control | 2 +-
contrib/btree_gist/btree_gist.h | 1 +
contrib/btree_gist/btree_utils_num.c | 8 +
contrib/btree_gist/expected/bool.out | 66 ++++++++
contrib/btree_gist/sql/bool.sql | 31 ++++
8 files changed, 341 insertions(+), 3 deletions(-)
create mode 100644 contrib/btree_gist/btree_bool.c
create mode 100644 contrib/btree_gist/btree_gist--1.6--1.7.sql
create mode 100644 contrib/btree_gist/expected/bool.out
create mode 100644 contrib/btree_gist/sql/bool.sql
diff --git a/contrib/btree_gist/Makefile b/contrib/btree_gist/Makefile
index e92d974a1a..48997c75f6 100644
--- a/contrib/btree_gist/Makefile
+++ b/contrib/btree_gist/Makefile
@@ -1,17 +1,18 @@
# contrib/btree_gist/Makefile
MODULE_big = btree_gist
OBJS = \
$(WIN32RES) \
btree_bit.o \
+ btree_bool.o \
btree_bytea.o \
btree_cash.o \
btree_date.o \
btree_enum.o \
btree_float4.o \
btree_float8.o \
btree_gist.o \
btree_inet.o \
btree_int2.o \
btree_int4.o \
@@ -25,26 +26,26 @@ OBJS = \
btree_time.o \
btree_ts.o \
btree_utils_num.o \
btree_utils_var.o \
btree_uuid.o
EXTENSION = btree_gist
DATA = 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.4--1.5.sql \
- btree_gist--1.5--1.6.sql
+ btree_gist--1.5--1.6.sql btree_gist--1.6--1.7.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 enum
+ bytea bit varbit numeric uuid not_equal enum bool
SHLIB_LINK += $(filter -lm, $(LIBS))
ifdef USE_PGXS
PG_CONFIG = pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS)
else
subdir = contrib/btree_gist
top_builddir = ../..
diff --git a/contrib/btree_gist/btree_bool.c b/contrib/btree_gist/btree_bool.c
new file mode 100644
index 0000000000..25ce1e2b77
--- /dev/null
+++ b/contrib/btree_gist/btree_bool.c
@@ -0,0 +1,169 @@
+/*
+ * contrib/btree_gist/btree_bool.c
+ */
+#include "postgres.h"
+
+#include "btree_gist.h"
+#include "btree_utils_num.h"
+#include "common/int.h"
+
+typedef struct boolkey
+{
+ bool lower;
+ bool upper;
+} boolKEY;
+
+/*
+** bool ops
+*/
+PG_FUNCTION_INFO_V1(gbt_bool_compress);
+PG_FUNCTION_INFO_V1(gbt_bool_fetch);
+PG_FUNCTION_INFO_V1(gbt_bool_union);
+PG_FUNCTION_INFO_V1(gbt_bool_picksplit);
+PG_FUNCTION_INFO_V1(gbt_bool_consistent);
+PG_FUNCTION_INFO_V1(gbt_bool_penalty);
+PG_FUNCTION_INFO_V1(gbt_bool_same);
+
+static bool
+gbt_boolgt(const void *a, const void *b, FmgrInfo *flinfo)
+{
+ return (*((const bool *) a) > *((const bool *) b));
+}
+static bool
+gbt_boolge(const void *a, const void *b, FmgrInfo *flinfo)
+{
+ return (*((const bool *) a) >= *((const bool *) b));
+}
+static bool
+gbt_booleq(const void *a, const void *b, FmgrInfo *flinfo)
+{
+ return (*((const bool *) a) == *((const bool *) b));
+}
+static bool
+gbt_boolle(const void *a, const void *b, FmgrInfo *flinfo)
+{
+ return (*((const bool *) a) <= *((const bool *) b));
+}
+static bool
+gbt_boollt(const void *a, const void *b, FmgrInfo *flinfo)
+{
+ return (*((const bool *) a) < *((const bool *) b));
+}
+
+static int
+gbt_boolkey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
+{
+ boolKEY *ia = (boolKEY *) (((const Nsrt *) a)->t);
+ boolKEY *ib = (boolKEY *) (((const Nsrt *) b)->t);
+
+ if (ia->lower == ib->lower)
+ {
+ if (ia->upper == ib->upper)
+ return 0;
+
+ return (ia->upper > ib->upper) ? 1 : -1;
+ }
+
+ return (ia->lower > ib->lower) ? 1 : -1;
+}
+
+
+static const gbtree_ninfo tinfo =
+{
+ gbt_t_bool,
+ sizeof(bool),
+ 4, /* sizeof(gbtreekey4) */
+ gbt_boolgt,
+ gbt_boolge,
+ gbt_booleq,
+ gbt_boolle,
+ gbt_boollt,
+ gbt_boolkey_cmp,
+};
+
+
+/**************************************************
+ * bool ops
+ **************************************************/
+
+
+Datum
+gbt_bool_compress(PG_FUNCTION_ARGS)
+{
+ GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+
+ PG_RETURN_POINTER(gbt_num_compress(entry, &tinfo));
+}
+
+Datum
+gbt_bool_fetch(PG_FUNCTION_ARGS)
+{
+ GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+
+ PG_RETURN_POINTER(gbt_num_fetch(entry, &tinfo));
+}
+
+Datum
+gbt_bool_consistent(PG_FUNCTION_ARGS)
+{
+ GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+ bool query = PG_GETARG_INT16(1);
+ StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
+
+ /* Oid subtype = PG_GETARG_OID(3); */
+ bool *recheck = (bool *) PG_GETARG_POINTER(4);
+ boolKEY *kkk = (boolKEY *) 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_bool_union(PG_FUNCTION_ARGS)
+{
+ GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
+ void *out = palloc(sizeof(boolKEY));
+
+ *(int *) PG_GETARG_POINTER(1) = sizeof(boolKEY);
+ PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
+}
+
+
+Datum
+gbt_bool_penalty(PG_FUNCTION_ARGS)
+{
+ boolKEY *origentry = (boolKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
+ boolKEY *newentry = (boolKEY *) 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_bool_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_bool_same(PG_FUNCTION_ARGS)
+{
+ boolKEY *b1 = (boolKEY *) PG_GETARG_POINTER(0);
+ boolKEY *b2 = (boolKEY *) 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.6--1.7.sql b/contrib/btree_gist/btree_gist--1.6--1.7.sql
new file mode 100644
index 0000000000..0e68356982
--- /dev/null
+++ b/contrib/btree_gist/btree_gist--1.6--1.7.sql
@@ -0,0 +1,62 @@
+/* contrib/btree_gist/btree_gist--1.6--1.7.sql */
+
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "ALTER EXTENSION btree_gist UPDATE TO '1.7'" to load this file. \quit
+
+-- This upgrade scripts add support for bool.
+
+-- Define the GiST support methods
+CREATE FUNCTION gbt_bool_consistent(internal,bool,int2,oid,internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bool_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bool_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bool_penalty(internal,internal,internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bool_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bool_union(internal, internal)
+RETURNS gbtreekey8
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gbt_bool_same(gbtreekey8, gbtreekey8, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+-- Create the operator class
+CREATE OPERATOR CLASS gist_bool_ops
+DEFAULT FOR TYPE bool USING gist
+AS
+ OPERATOR 1 < ,
+ OPERATOR 2 <= ,
+ OPERATOR 3 = ,
+ OPERATOR 4 >= ,
+ OPERATOR 5 > ,
+ OPERATOR 6 <> ,
+ FUNCTION 1 gbt_bool_consistent (internal, bool, int2, oid, internal),
+ FUNCTION 2 gbt_bool_union (internal, internal),
+ FUNCTION 3 gbt_bool_compress (internal),
+ FUNCTION 4 gbt_decompress (internal),
+ FUNCTION 5 gbt_bool_penalty (internal, internal, internal),
+ FUNCTION 6 gbt_bool_picksplit (internal, internal),
+ FUNCTION 7 gbt_bool_same (gbtreekey8, gbtreekey8, internal),
+ FUNCTION 9 gbt_bool_fetch (internal),
+ STORAGE gbtreekey8;
diff --git a/contrib/btree_gist/btree_gist.control b/contrib/btree_gist/btree_gist.control
index e5c41fe8f3..fa9171a80a 100644
--- a/contrib/btree_gist/btree_gist.control
+++ b/contrib/btree_gist/btree_gist.control
@@ -1,6 +1,6 @@
# btree_gist extension
comment = 'support for indexing common datatypes in GiST'
-default_version = '1.6'
+default_version = '1.7'
module_pathname = '$libdir/btree_gist'
relocatable = true
trusted = true
diff --git a/contrib/btree_gist/btree_gist.h b/contrib/btree_gist/btree_gist.h
index 14c7c8ee19..f22f14ac4c 100644
--- a/contrib/btree_gist/btree_gist.h
+++ b/contrib/btree_gist/btree_gist.h
@@ -25,16 +25,17 @@ enum gbtree_type
gbt_t_oid,
gbt_t_time,
gbt_t_date,
gbt_t_intv,
gbt_t_macad,
gbt_t_macad8,
gbt_t_text,
gbt_t_bpchar,
gbt_t_bytea,
gbt_t_bit,
+ gbt_t_bool,
gbt_t_inet,
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 7564a403c7..5632ee0586 100644
--- a/contrib/btree_gist/btree_utils_num.c
+++ b/contrib/btree_gist/btree_utils_num.c
@@ -12,36 +12,41 @@
GISTENTRY *
gbt_num_compress(GISTENTRY *entry, const gbtree_ninfo *tinfo)
{
GISTENTRY *retval;
if (entry->leafkey)
{
union
{
+ bool bo;
int16 i2;
int32 i4;
int64 i8;
float4 f4;
float8 f8;
DateADT dt;
TimeADT tm;
Timestamp ts;
Cash ch;
} v;
GBT_NUMKEY *r = (GBT_NUMKEY *) palloc0(tinfo->indexsize);
void *leaf = NULL;
switch (tinfo->t)
{
+ case gbt_t_bool:
+ v.bo = DatumGetBool(entry->key);
+ leaf = &v.bo;
+ break;
case gbt_t_int2:
v.i2 = DatumGetInt16(entry->key);
leaf = &v.i2;
break;
case gbt_t_int4:
v.i4 = DatumGetInt32(entry->key);
leaf = &v.i4;
break;
case gbt_t_int8:
v.i8 = DatumGetInt64(entry->key);
@@ -106,20 +111,23 @@ gbt_num_fetch(GISTENTRY *entry, const gbtree_ninfo *tinfo)
Assert(tinfo->indexsize >= 2 * tinfo->size);
/*
* Get the original Datum from the stored datum. On leaf entries, the
* lower and upper bound are the same. We just grab the lower bound and
* return it.
*/
switch (tinfo->t)
{
+ case gbt_t_bool:
+ datum = BoolGetDatum(*(bool *) entry->key);
+ break;
case gbt_t_int2:
datum = Int16GetDatum(*(int16 *) entry->key);
break;
case gbt_t_int4:
datum = Int32GetDatum(*(int32 *) entry->key);
break;
case gbt_t_int8:
datum = Int64GetDatum(*(int64 *) entry->key);
break;
case gbt_t_oid:
diff --git a/contrib/btree_gist/expected/bool.out b/contrib/btree_gist/expected/bool.out
new file mode 100644
index 0000000000..eda7f1f6be
--- /dev/null
+++ b/contrib/btree_gist/expected/bool.out
@@ -0,0 +1,66 @@
+-- bool check
+CREATE TABLE booltmp (a bool);
+INSERT INTO booltmp VALUES (false), (true);
+SET enable_seqscan=on;
+SELECT count(*) FROM booltmp WHERE a < true;
+ count
+-------
+ 1
+(1 row)
+
+SELECT count(*) FROM booltmp WHERE a <= true;
+ count
+-------
+ 2
+(1 row)
+
+SELECT count(*) FROM booltmp WHERE a = true;
+ count
+-------
+ 1
+(1 row)
+
+SELECT count(*) FROM booltmp WHERE a >= true;
+ count
+-------
+ 1
+(1 row)
+
+SELECT count(*) FROM booltmp WHERE a > true;
+ count
+-------
+ 0
+(1 row)
+
+CREATE INDEX boolidx ON booltmp USING gist ( a );
+SET enable_seqscan=off;
+SELECT count(*) FROM booltmp WHERE a < true;
+ count
+-------
+ 1
+(1 row)
+
+SELECT count(*) FROM booltmp WHERE a <= true;
+ count
+-------
+ 2
+(1 row)
+
+SELECT count(*) FROM booltmp WHERE a = true;
+ count
+-------
+ 1
+(1 row)
+
+SELECT count(*) FROM booltmp WHERE a >= true;
+ count
+-------
+ 1
+(1 row)
+
+SELECT count(*) FROM booltmp WHERE a > true;
+ count
+-------
+ 0
+(1 row)
+
diff --git a/contrib/btree_gist/sql/bool.sql b/contrib/btree_gist/sql/bool.sql
new file mode 100644
index 0000000000..e0c2a40e2b
--- /dev/null
+++ b/contrib/btree_gist/sql/bool.sql
@@ -0,0 +1,31 @@
+-- bool check
+
+CREATE TABLE booltmp (a bool);
+
+INSERT INTO booltmp VALUES (false), (true);
+
+SET enable_seqscan=on;
+
+SELECT count(*) FROM booltmp WHERE a < true;
+
+SELECT count(*) FROM booltmp WHERE a <= true;
+
+SELECT count(*) FROM booltmp WHERE a = true;
+
+SELECT count(*) FROM booltmp WHERE a >= true;
+
+SELECT count(*) FROM booltmp WHERE a > true;
+
+CREATE INDEX boolidx ON booltmp USING gist ( a );
+
+SET enable_seqscan=off;
+
+SELECT count(*) FROM booltmp WHERE a < true;
+
+SELECT count(*) FROM booltmp WHERE a <= true;
+
+SELECT count(*) FROM booltmp WHERE a = true;
+
+SELECT count(*) FROM booltmp WHERE a >= true;
+
+SELECT count(*) FROM booltmp WHERE a > true;
--
2.30.1 (Apple Git-130)
Hi!
8 июня 2021 г., в 13:48, Emre Hasegeli <emre@hasegeli.com> написал(а):
It could be useful to use bool in exclusion constraints, but it's
currently not nicely supported. The attached patch adds support for
bool to the btree_gist extension, so we can do this.I am adding this to the commitfest 2021-07.
<0001-btree_gist-Support-bool.patch>
It definitely makes sense to include bool into list of supported types.
But patch that you propose does not support sorting build added in PG14.
Or we can add this functionality later in https://commitfest.postgresql.org/31/2824/ ...
Thanks!
Best regards, Andrey Borodin.
But patch that you propose does not support sorting build added in PG14.
It looks like the change to btree_gist is not committed yet. I'll
rebase my patch once it's committed.
It was a long thread. I couldn't read all of it. Though, the last
patches felt to me like a part of what's already been committed.
Shouldn't they also be committed to version 14?
8 июня 2021 г., в 19:53, Emre Hasegeli <emre@hasegeli.com> написал(а):
But patch that you propose does not support sorting build added in PG14.
It looks like the change to btree_gist is not committed yet. I'll
rebase my patch once it's committed.
Changes to GiST are committed. There will be no need to rebase anyway :)
It was a long thread. I couldn't read all of it. Though, the last
patches felt to me like a part of what's already been committed.
Shouldn't they also be committed to version 14?
Well, yeah, it could would be cool to have gist build and gist_btree support it together, but there was many parts and we could did not finish it before feature freeze.
Best regards, Andrey Borodin.
Hi,
I looked at this patch today - it's pretty simple and in pretty good
shape, I can't think of anything that'd need fixing. Perhaps the test
might also do EXPLAIN like for other types, to verify the new index is
actually used. But that's minor enough to handle during commit.
I've marked this as RFC and will get it committed in a day or two.
--
Tomas Vondra
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
On 11/3/21 16:18, Tomas Vondra wrote:
Hi,
I looked at this patch today - it's pretty simple and in pretty good
shape, I can't think of anything that'd need fixing. Perhaps the test
might also do EXPLAIN like for other types, to verify the new index is
actually used. But that's minor enough to handle during commit.I've marked this as RFC and will get it committed in a day or two.
Pushed, after adding some simple EXPLAIN to the regression test.
Thanks for the patch!
regards
--
Tomas Vondra
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
Tomas Vondra <tomas.vondra@enterprisedb.com> writes:
Pushed, after adding some simple EXPLAIN to the regression test.
skink is reporting that this has some valgrind issues [1]https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=skink&dt=2021-11-06%2023%3A56%3A57.
I suspect sloppy conversion between bool and Datum, but
didn't go looking.
==1805451== VALGRINDERROR-BEGIN
==1805451== Uninitialised byte(s) found during client check request
==1805451== at 0x59EFEA: PageAddItemExtended (bufpage.c:346)
==1805451== by 0x2100B9: gistfillbuffer (gistutil.c:46)
==1805451== by 0x2050F9: gistplacetopage (gist.c:562)
==1805451== by 0x20546B: gistinserttuples (gist.c:1277)
==1805451== by 0x205BB5: gistinserttuple (gist.c:1230)
==1805451== by 0x206067: gistdoinsert (gist.c:885)
==1805451== by 0x2084FB: gistBuildCallback (gistbuild.c:829)
==1805451== by 0x23B572: heapam_index_build_range_scan (heapam_handler.c:1694)
==1805451== by 0x208E7D: table_index_build_scan (tableam.h:1756)
==1805451== by 0x208E7D: gistbuild (gistbuild.c:309)
==1805451== by 0x2D10C8: index_build (index.c:2983)
==1805451== by 0x2D2A7D: index_create (index.c:1232)
==1805451== by 0x383E67: DefineIndex (indexcmds.c:1128)
==1805451== Address 0x10cab1e4 is 12 bytes inside a block of size 16 client-defined
==1805451== at 0x712AC5: palloc0 (mcxt.c:1118)
==1805451== by 0x1E0A07: index_form_tuple (indextuple.c:146)
==1805451== by 0x210BA8: gistFormTuple (gistutil.c:582)
==1805451== by 0x2084C2: gistBuildCallback (gistbuild.c:813)
==1805451== by 0x23B572: heapam_index_build_range_scan (heapam_handler.c:1694)
==1805451== by 0x208E7D: table_index_build_scan (tableam.h:1756)
==1805451== by 0x208E7D: gistbuild (gistbuild.c:309)
==1805451== by 0x2D10C8: index_build (index.c:2983)
==1805451== by 0x2D2A7D: index_create (index.c:1232)
==1805451== by 0x383E67: DefineIndex (indexcmds.c:1128)
==1805451== by 0x5AED2E: ProcessUtilitySlow (utility.c:1535)
==1805451== by 0x5AE262: standard_ProcessUtility (utility.c:1066)
==1805451== by 0x5AE33A: ProcessUtility (utility.c:527)
==1805451==
==1805451== VALGRINDERROR-END
regards, tom lane
[1]: https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=skink&dt=2021-11-06%2023%3A56%3A57
Hi,
On 11/7/21 17:44, Tom Lane wrote:
Tomas Vondra <tomas.vondra@enterprisedb.com> writes:
Pushed, after adding some simple EXPLAIN to the regression test.
skink is reporting that this has some valgrind issues [1].
I suspect sloppy conversion between bool and Datum, but
didn't go looking.
It's actually a bit worse than that :-( The opclass is somewhat confused
about the type it should use for storage. The gbtree_ninfo struct says
it's using gbtreekey4, the SQL script claims the params are gbtreekey8,
and it should actually use gbtreekey2. Sorry for not noticing that.
The attached patch fixes the valgrind error for me.
regards
--
Tomas Vondra
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
Attachments:
btree_gist-bool-fix.patchtext/x-patch; charset=UTF-8; name=btree_gist-bool-fix.patchDownload
diff --git a/contrib/btree_gist/btree_bool.c b/contrib/btree_gist/btree_bool.c
index 25ce1e2b77..1be246ea5e 100644
--- a/contrib/btree_gist/btree_bool.c
+++ b/contrib/btree_gist/btree_bool.c
@@ -72,7 +72,7 @@ static const gbtree_ninfo tinfo =
{
gbt_t_bool,
sizeof(bool),
- 4, /* sizeof(gbtreekey4) */
+ 2, /* sizeof(gbtreekey2) */
gbt_boolgt,
gbt_boolge,
gbt_booleq,
diff --git a/contrib/btree_gist/btree_gist--1.6--1.7.sql b/contrib/btree_gist/btree_gist--1.6--1.7.sql
index 0e68356982..1085216501 100644
--- a/contrib/btree_gist/btree_gist--1.6--1.7.sql
+++ b/contrib/btree_gist/btree_gist--1.6--1.7.sql
@@ -4,6 +4,21 @@
\echo Use "ALTER EXTENSION btree_gist UPDATE TO '1.7'" to load this file. \quit
-- This upgrade scripts add support for bool.
+CREATE FUNCTION gbtreekey2_in(cstring)
+RETURNS gbtreekey2
+AS 'MODULE_PATHNAME', 'gbtreekey_in'
+LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
+
+CREATE FUNCTION gbtreekey2_out(gbtreekey2)
+RETURNS cstring
+AS 'MODULE_PATHNAME', 'gbtreekey_out'
+LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
+
+CREATE TYPE gbtreekey2 (
+ INTERNALLENGTH = 2,
+ INPUT = gbtreekey2_in,
+ OUTPUT = gbtreekey2_out
+);
-- Define the GiST support methods
CREATE FUNCTION gbt_bool_consistent(internal,bool,int2,oid,internal)
@@ -32,11 +47,11 @@ AS 'MODULE_PATHNAME'
LANGUAGE C IMMUTABLE STRICT;
CREATE FUNCTION gbt_bool_union(internal, internal)
-RETURNS gbtreekey8
+RETURNS gbtreekey2
AS 'MODULE_PATHNAME'
LANGUAGE C IMMUTABLE STRICT;
-CREATE FUNCTION gbt_bool_same(gbtreekey8, gbtreekey8, internal)
+CREATE FUNCTION gbt_bool_same(gbtreekey2, gbtreekey2, internal)
RETURNS internal
AS 'MODULE_PATHNAME'
LANGUAGE C IMMUTABLE STRICT;
@@ -57,6 +72,6 @@ AS
FUNCTION 4 gbt_decompress (internal),
FUNCTION 5 gbt_bool_penalty (internal, internal, internal),
FUNCTION 6 gbt_bool_picksplit (internal, internal),
- FUNCTION 7 gbt_bool_same (gbtreekey8, gbtreekey8, internal),
+ FUNCTION 7 gbt_bool_same (gbtreekey2, gbtreekey2, internal),
FUNCTION 9 gbt_bool_fetch (internal),
- STORAGE gbtreekey8;
+ STORAGE gbtreekey2;
On 11/7/21 20:53, Tomas Vondra wrote:
Hi,
On 11/7/21 17:44, Tom Lane wrote:
Tomas Vondra <tomas.vondra@enterprisedb.com> writes:
Pushed, after adding some simple EXPLAIN to the regression test.
skink is reporting that this has some valgrind issues [1].
I suspect sloppy conversion between bool and Datum, but
didn't go looking.It's actually a bit worse than that :-( The opclass is somewhat confused
about the type it should use for storage. The gbtree_ninfo struct says
it's using gbtreekey4, the SQL script claims the params are gbtreekey8,
and it should actually use gbtreekey2. Sorry for not noticing that.The attached patch fixes the valgrind error for me.
I've pushed the fix, hopefully that'll make skink happy.
What surprised me a bit is that the opclass used gbtreekey4 storage, the
equality support proc was defined as using gbtreekey8
FUNCTION 7 gbt_bool_same (gbtreekey8, gbtreekey8, internal),
yet the gistvalidate() did not report this. Turns out this is because
ok = check_amproc_signature(procform->amproc, INTERNALOID, false,
3, 3, opckeytype, opckeytype,
INTERNALOID);
i.e. with exact=false, so these type differences are ignored. Changing
it to true reports the issue (and no other issues in check-world).
But maybe there are reasons to keep using false?
regards
--
Tomas Vondra
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
Attachments:
gistvalidate.patchtext/x-patch; charset=UTF-8; name=gistvalidate.patchDownload
diff --git a/src/backend/access/gist/gistvalidate.c b/src/backend/access/gist/gistvalidate.c
index b885fa2b25..31cc4f0a21 100644
--- a/src/backend/access/gist/gistvalidate.c
+++ b/src/backend/access/gist/gistvalidate.c
@@ -131,7 +131,7 @@ gistvalidate(Oid opclassoid)
2, 2, INTERNALOID, INTERNALOID);
break;
case GIST_EQUAL_PROC:
- ok = check_amproc_signature(procform->amproc, INTERNALOID, false,
+ ok = check_amproc_signature(procform->amproc, INTERNALOID, true,
3, 3, opckeytype, opckeytype,
INTERNALOID);
break;
Hello,
I don't see any changes in the documentation.[1]https://www.postgresql.org/docs/devel/btree-gist.html
Should bool appear in the looong list of supported operator classes?
[1]: https://www.postgresql.org/docs/devel/btree-gist.html
--
Pavel Luzanov
Postgres Professional: https://postgrespro.com
The Russian Postgres Company
On 12/6/21 22:35, Pavel Luzanov wrote:
Hello,
I don't see any changes in the documentation.[1]
Should bool appear in the looong list of supported operator classes?
You're right, I forgot to update the list of data types in the docs.
Fixed, thanks for the report.
regards
--
Tomas Vondra
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company