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;