@@ -465,41 +465,32 @@ infer_arbiter_indexes(PlannerInfo *root)
465465
466466 /*
467467 * Build normalized/BMS representation of plain indexed attributes, as
468- * well as direct list of inference elements . This is required for
469- * matching the cataloged definition of indexes.
468+ * well as a separate list of expression items . This simplifies matching
469+ * the cataloged definition of indexes.
470470 */
471471 foreach (l , onconflict -> arbiterElems )
472472 {
473- InferenceElem * elem ;
473+ InferenceElem * elem = ( InferenceElem * ) lfirst ( l ) ;
474474 Var * var ;
475475 int attno ;
476476
477- elem = (InferenceElem * ) lfirst (l );
478-
479- /*
480- * Parse analysis of inference elements performs full parse analysis
481- * of Vars, even for non-expression indexes (in contrast with utility
482- * command related use of IndexElem). However, indexes are cataloged
483- * with simple attribute numbers for non-expression indexes. Those
484- * are handled later.
485- */
486477 if (!IsA (elem -> expr , Var ))
487478 {
479+ /* If not a plain Var, just shove it in inferElems for now */
488480 inferElems = lappend (inferElems , elem -> expr );
489481 continue ;
490482 }
491483
492484 var = (Var * ) elem -> expr ;
493485 attno = var -> varattno ;
494486
495- if (attno < 0 )
487+ if (attno == 0 )
496488 ereport (ERROR ,
497- (errcode (ERRCODE_INVALID_COLUMN_REFERENCE ),
498- errmsg ("system columns cannot be used in an ON CONFLICT clause" )));
499- else if (attno == 0 )
500- elog (ERROR , "whole row unique index inference specifications are not valid" );
489+ (errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
490+ errmsg ("whole row unique index inference specifications are not supported" )));
501491
502- inferAttrs = bms_add_member (inferAttrs , attno );
492+ inferAttrs = bms_add_member (inferAttrs ,
493+ attno - FirstLowInvalidHeapAttributeNumber );
503494 }
504495
505496 /*
@@ -516,18 +507,18 @@ infer_arbiter_indexes(PlannerInfo *root)
516507 errmsg ("constraint in ON CONFLICT clause has no associated index" )));
517508 }
518509
519- indexList = RelationGetIndexList (relation );
520-
521510 /*
522511 * Using that representation, iterate through the list of indexes on the
523512 * target relation to try and find a match
524513 */
514+ indexList = RelationGetIndexList (relation );
515+
525516 foreach (l , indexList )
526517 {
527518 Oid indexoid = lfirst_oid (l );
528519 Relation idxRel ;
529520 Form_pg_index idxForm ;
530- Bitmapset * indexedAttrs = NULL ;
521+ Bitmapset * indexedAttrs ;
531522 List * idxExprs ;
532523 List * predExprs ;
533524 AttrNumber natt ;
@@ -586,17 +577,15 @@ infer_arbiter_indexes(PlannerInfo *root)
586577 if (!idxForm -> indisunique )
587578 goto next ;
588579
589- /* Build BMS representation of cataloged index attributes */
580+ /* Build BMS representation of plain (non expression) index attrs */
581+ indexedAttrs = NULL ;
590582 for (natt = 0 ; natt < idxForm -> indnatts ; natt ++ )
591583 {
592584 int attno = idxRel -> rd_index -> indkey .values [natt ];
593585
594- /* XXX broken */
595- if (attno < 0 )
596- elog (ERROR , "system column in index" );
597-
598586 if (attno != 0 )
599- indexedAttrs = bms_add_member (indexedAttrs , attno );
587+ indexedAttrs = bms_add_member (indexedAttrs ,
588+ attno - FirstLowInvalidHeapAttributeNumber );
600589 }
601590
602591 /* Non-expression attributes (if any) must match */
0 commit comments