From 568884e11a6ec495b21dc71da458b3447f99156f Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Wed, 12 Mar 2025 14:37:05 +0100 Subject: [PATCH v21.2 3/4] Allow non-btree unique indexes for partition keys We were rejecting non-btree indexes in some cases owing to the inability to determine the equality operators for other index AMs; that problem no longer exists, because we can look up the equality operator using COMPARE_EQ. The problem of not knowing the strategy number for equality in other index AMs is already resolved. Stop rejecting the indexes upfront, and instead reject any for which the equality operator lookup fails. Author: Mark Dilger --- src/backend/commands/indexcmds.c | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index 32ff3ca9a28..9f4ab9dc1ee 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -1009,20 +1009,6 @@ DefineIndex(Oid tableId, eq_strategy, key->partopcintype[i], key->partopcintype[i], key->partopfamily[i]); - /* - * We'll need to be able to identify the equality operators - * associated with index columns, too. We know what to do with - * btree opclasses; if there are ever any other index types that - * support unique indexes, this logic will need extension. But if - * we have an exclusion constraint (or a temporal PK), it already - * knows the operators, so we don't have to infer them. - */ - if (stmt->unique && !stmt->iswithoutoverlaps && accessMethodId != BTREE_AM_OID) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot match partition key to an index using access method \"%s\"", - accessMethodName))); - /* * It may be possible to support UNIQUE constraints when partition * keys are expressions, but is it worth it? Give up for now. @@ -1057,10 +1043,18 @@ DefineIndex(Oid tableId, Oid idx_eqop = InvalidOid; if (stmt->unique && !stmt->iswithoutoverlaps) - idx_eqop = get_opfamily_member(idx_opfamily, - idx_opcintype, - idx_opcintype, - BTEqualStrategyNumber); + { + idx_eqop = get_opfamily_member_for_cmptype(idx_opfamily, + idx_opcintype, + idx_opcintype, + COMPARE_EQ); + if (!idx_eqop) + ereport(ERROR, + errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("could not identify an equality operator for type %s", format_type_be(idx_opcintype)), + errdetail("There is no suitable operator in operator family \"%s\" for access method \"%s\".", + get_opfamily_name(idx_opfamily, false), get_am_name(get_opfamily_method(idx_opfamily)))); + } else if (exclusion) idx_eqop = indexInfo->ii_ExclusionOps[j]; Assert(idx_eqop); -- 2.48.1