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;

Reply via email to