@@ -438,8 +438,8 @@ infer_arbiter_indexes(PlannerInfo *root)
438438 Bitmapset * inferAttrs = NULL ;
439439 List * inferElems = NIL ;
440440
441- /* Result */
442- List * candidates = NIL ;
441+ /* Results */
442+ List * results = NIL ;
443443
444444 /*
445445 * Quickly return NIL for ON CONFLICT DO NOTHING without an inference
@@ -565,11 +565,11 @@ infer_arbiter_indexes(PlannerInfo *root)
565565 (errcode (ERRCODE_WRONG_OBJECT_TYPE ),
566566 errmsg ("ON CONFLICT DO UPDATE not supported with exclusion constraints" )));
567567
568- candidates = lappend_oid (candidates , idxForm -> indexrelid );
568+ results = lappend_oid (results , idxForm -> indexrelid );
569569 list_free (indexList );
570570 index_close (idxRel , NoLock );
571571 heap_close (relation , NoLock );
572- return candidates ;
572+ return results ;
573573 }
574574 else if (indexOidFromConstraint != InvalidOid )
575575 {
@@ -633,7 +633,7 @@ infer_arbiter_indexes(PlannerInfo *root)
633633 * index definition.
634634 */
635635 if (elem -> infercollid != InvalidOid ||
636- elem -> inferopfamily != InvalidOid ||
636+ elem -> inferopclass != InvalidOid ||
637637 list_member (idxExprs , elem -> expr ))
638638 continue ;
639639
@@ -660,20 +660,20 @@ infer_arbiter_indexes(PlannerInfo *root)
660660 if (!predicate_implied_by (predExprs , whereExplicit ))
661661 goto next ;
662662
663- candidates = lappend_oid (candidates , idxForm -> indexrelid );
663+ results = lappend_oid (results , idxForm -> indexrelid );
664664next :
665665 index_close (idxRel , NoLock );
666666 }
667667
668668 list_free (indexList );
669669 heap_close (relation , NoLock );
670670
671- if (candidates == NIL )
671+ if (results == NIL )
672672 ereport (ERROR ,
673673 (errcode (ERRCODE_INVALID_COLUMN_REFERENCE ),
674674 errmsg ("there is no unique or exclusion constraint matching the ON CONFLICT specification" )));
675675
676- return candidates ;
676+ return results ;
677677}
678678
679679/*
@@ -709,23 +709,33 @@ infer_collation_opclass_match(InferenceElem *elem, Relation idxRel,
709709 Bitmapset * inferAttrs , List * idxExprs )
710710{
711711 AttrNumber natt ;
712+ Oid inferopfamily = InvalidOid ; /* OID of att opfamily */
713+ Oid inferopcinputtype = InvalidOid ; /* OID of att opfamily */
712714
713715 /*
714716 * If inference specification element lacks collation/opclass, then no
715717 * need to check for exact match.
716718 */
717- if (elem -> infercollid == InvalidOid && elem -> inferopfamily == InvalidOid )
719+ if (elem -> infercollid == InvalidOid && elem -> inferopclass == InvalidOid )
718720 return true;
719721
722+ /*
723+ * Lookup opfamily and input type, for matching indexes
724+ */
725+ if (elem -> inferopclass )
726+ {
727+ inferopfamily = get_opclass_family (elem -> inferopclass );
728+ inferopcinputtype = get_opclass_input_type (elem -> inferopclass );
729+ }
730+
720731 for (natt = 1 ; natt <= idxRel -> rd_att -> natts ; natt ++ )
721732 {
722733 Oid opfamily = idxRel -> rd_opfamily [natt - 1 ];
723734 Oid opcinputtype = idxRel -> rd_opcintype [natt - 1 ];
724735 Oid collation = idxRel -> rd_indcollation [natt - 1 ];
725736
726- if (elem -> inferopfamily != InvalidOid &&
727- (elem -> inferopfamily != opfamily ||
728- elem -> inferopcinputtype != opcinputtype ))
737+ if (elem -> inferopclass != InvalidOid &&
738+ (inferopfamily != opfamily || inferopcinputtype != opcinputtype ))
729739 {
730740 /* Attribute needed to match opclass, but didn't */
731741 continue ;
0 commit comments