As previously discussed at [1], contrib/intarray's GiST opclasses
do not index empty arrays in a useful way, meaning that
"indexedcol <@ something" has to do a full-index search to ensure
that it finds empty arrays, which such a query should always find.
We'd be better off to not consider <@ indexable at all by these
opclasses, but removing it has been problematic because of
dependencies [2]. Now that commit 9f9682783 is in, the dependency
problem is fixed, so here are a couple of patches to remove the
operator's opclass membership.
Patch 0001 is a minimal patch to just drop the opclass membership.
We could do that and stop there, but if we do, <@ searches will
continue to be slow until people think to update their extensions
(which pg_upgrade does nothing to encourage). Alternatively,
we could replace the now-dead support code with something that
throws an error telling people to update the extension, as in 0002.
I'm honestly not sure whether 0002 is a good idea or not. Thoughts?
regards, tom lane
[1] https://www.postgresql.org/message-id/flat/458.1565114141%40sss.pgh.pa.us
[2] https://www.postgresql.org/message-id/flat/4578.1565195302%40sss.pgh.pa.us
diff --git a/contrib/intarray/Makefile b/contrib/intarray/Makefile
index b68959ebd6..01faa36b10 100644
--- a/contrib/intarray/Makefile
+++ b/contrib/intarray/Makefile
@@ -12,7 +12,8 @@ OBJS = \
_intbig_gist.o
EXTENSION = intarray
-DATA = intarray--1.2--1.3.sql intarray--1.2.sql intarray--1.1--1.2.sql \
+DATA = intarray--1.3--1.4.sql intarray--1.2--1.3.sql \
+ intarray--1.2.sql intarray--1.1--1.2.sql \
intarray--1.0--1.1.sql
PGFILEDESC = "intarray - functions and operators for arrays of integers"
diff --git a/contrib/intarray/intarray--1.3--1.4.sql b/contrib/intarray/intarray--1.3--1.4.sql
new file mode 100644
index 0000000000..3fbebb5417
--- /dev/null
+++ b/contrib/intarray/intarray--1.3--1.4.sql
@@ -0,0 +1,21 @@
+/* contrib/intarray/intarray--1.3--1.4.sql */
+
+-- complain if script is sourced in psql, rather than via ALTER EXTENSION
+\echo Use "ALTER EXTENSION intarray UPDATE TO '1.4'" to load this file. \quit
+
+-- Remove <@ from the GiST opclasses, as it's not usefully indexable
+-- due to mishandling of empty arrays. (It's OK in GIN.)
+
+ALTER OPERATOR FAMILY gist__int_ops USING gist
+DROP OPERATOR 8 (_int4, _int4);
+
+ALTER OPERATOR FAMILY gist__intbig_ops USING gist
+DROP OPERATOR 8 (_int4, _int4);
+
+-- Likewise for the old spelling ~.
+
+ALTER OPERATOR FAMILY gist__int_ops USING gist
+DROP OPERATOR 14 (_int4, _int4);
+
+ALTER OPERATOR FAMILY gist__intbig_ops USING gist
+DROP OPERATOR 14 (_int4, _int4);
diff --git a/contrib/intarray/intarray.control b/contrib/intarray/intarray.control
index db7746b6c7..bbc837c573 100644
--- a/contrib/intarray/intarray.control
+++ b/contrib/intarray/intarray.control
@@ -1,6 +1,6 @@
# intarray extension
comment = 'functions, operators, and index support for 1-D arrays of integers'
-default_version = '1.3'
+default_version = '1.4'
module_pathname = '$libdir/_int'
relocatable = true
trusted = true
diff --git a/contrib/intarray/_int_gist.c b/contrib/intarray/_int_gist.c
index fb05b06af9..fd05247bbf 100644
--- a/contrib/intarray/_int_gist.c
+++ b/contrib/intarray/_int_gist.c
@@ -93,17 +93,19 @@ g_int_consistent(PG_FUNCTION_ARGS)
break;
case RTContainedByStrategyNumber:
case RTOldContainedByStrategyNumber:
- if (GIST_LEAF(entry))
- retval = inner_int_contains(query,
- (ArrayType *) DatumGetPointer(entry->key));
- else
- {
- /*
- * Unfortunately, because empty arrays could be anywhere in
- * the index, we must search the whole tree.
- */
- retval = true;
- }
+
+ /*
+ * Unfortunately, because empty arrays could be anywhere in the
+ * index, implementing this would require searching the whole
+ * tree. As of intarray 1.4, <@ is no longer part of the opclass.
+ * If we get here anyway, an obsolete opclass definition must
+ * still be installed.
+ */
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("<@ operator is no longer supported by gist__int_ops"),
+ errdetail("Please update to intarray 1.4 or later.")));
+ retval = false; /* keep compiler quiet */
break;
default:
retval = false;
diff --git a/contrib/intarray/_intbig_gist.c b/contrib/intarray/_intbig_gist.c
index 67c44e99a9..5fe110e9ce 100644
--- a/contrib/intarray/_intbig_gist.c
+++ b/contrib/intarray/_intbig_gist.c
@@ -533,39 +533,19 @@ g_intbig_consistent(PG_FUNCTION_ARGS)
break;
case RTContainedByStrategyNumber:
case RTOldContainedByStrategyNumber:
- if (GIST_LEAF(entry))
- {
- int i,
- num = ARRNELEMS(query);
- int32 *ptr = ARRPTR(query);
- BITVECP dq = palloc0(siglen),
- de;
- while (num--)
- {
- HASH(dq, *ptr, siglen);
- ptr++;
- }
-
- de = GETSIGN((GISTTYPE *) DatumGetPointer(entry->key));
- retval = true;
- LOOPBYTE(siglen)
- {
- if (de[i] & ~dq[i])
- {
- retval = false;
- break;
- }
- }
- }
- else
- {
- /*
- * Unfortunately, because empty arrays could be anywhere in
- * the index, we must search the whole tree.
- */
- retval = true;
- }
+ /*
+ * Unfortunately, because empty arrays could be anywhere in the
+ * index, implementing this would require searching the whole
+ * tree. As of intarray 1.4, <@ is no longer part of the opclass.
+ * If we get here anyway, an obsolete opclass definition must
+ * still be installed.
+ */
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("<@ operator is no longer supported by gist__intbig_ops"),
+ errdetail("Please update to intarray 1.4 or later.")));
+ retval = false; /* keep compiler quiet */
break;
default:
retval = false;