Skip to content

Commit 8a13d5e

Browse files
committed
Fix infer_arbiter_indexes() to not barf on system columns.
While it could be argued that rejecting system column mentions in the ON CONFLICT list is an unsupported feature, falling over altogether just because the table has a unique index on OID is indubitably a bug. As far as I can tell, fixing infer_arbiter_indexes() is sufficient to make ON CONFLICT (oid) actually work, though making a regression test for that case is problematic because of the impossibility of setting the OID counter to a known value. Minor cosmetic cleanups along with the bug fix.
1 parent 26e6618 commit 8a13d5e

File tree

1 file changed

+16
-27
lines changed

1 file changed

+16
-27
lines changed

src/backend/optimizer/util/plancat.c

Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -558,41 +558,32 @@ infer_arbiter_indexes(PlannerInfo *root)
558558

559559
/*
560560
* Build normalized/BMS representation of plain indexed attributes, as
561-
* well as direct list of inference elements. This is required for
562-
* matching the cataloged definition of indexes.
561+
* well as a separate list of expression items. This simplifies matching
562+
* the cataloged definition of indexes.
563563
*/
564564
foreach(l, onconflict->arbiterElems)
565565
{
566-
InferenceElem *elem;
566+
InferenceElem *elem = (InferenceElem *) lfirst(l);
567567
Var *var;
568568
int attno;
569569

570-
elem = (InferenceElem *) lfirst(l);
571-
572-
/*
573-
* Parse analysis of inference elements performs full parse analysis
574-
* of Vars, even for non-expression indexes (in contrast with utility
575-
* command related use of IndexElem). However, indexes are cataloged
576-
* with simple attribute numbers for non-expression indexes. Those
577-
* are handled later.
578-
*/
579570
if (!IsA(elem->expr, Var))
580571
{
572+
/* If not a plain Var, just shove it in inferElems for now */
581573
inferElems = lappend(inferElems, elem->expr);
582574
continue;
583575
}
584576

585577
var = (Var *) elem->expr;
586578
attno = var->varattno;
587579

588-
if (attno < 0)
580+
if (attno == 0)
589581
ereport(ERROR,
590-
(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
591-
errmsg("system columns cannot be used in an ON CONFLICT clause")));
592-
else if (attno == 0)
593-
elog(ERROR, "whole row unique index inference specifications are not valid");
582+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
583+
errmsg("whole row unique index inference specifications are not supported")));
594584

595-
inferAttrs = bms_add_member(inferAttrs, attno);
585+
inferAttrs = bms_add_member(inferAttrs,
586+
attno - FirstLowInvalidHeapAttributeNumber);
596587
}
597588

598589
/*
@@ -609,18 +600,18 @@ infer_arbiter_indexes(PlannerInfo *root)
609600
errmsg("constraint in ON CONFLICT clause has no associated index")));
610601
}
611602

612-
indexList = RelationGetIndexList(relation);
613-
614603
/*
615604
* Using that representation, iterate through the list of indexes on the
616605
* target relation to try and find a match
617606
*/
607+
indexList = RelationGetIndexList(relation);
608+
618609
foreach(l, indexList)
619610
{
620611
Oid indexoid = lfirst_oid(l);
621612
Relation idxRel;
622613
Form_pg_index idxForm;
623-
Bitmapset *indexedAttrs = NULL;
614+
Bitmapset *indexedAttrs;
624615
List *idxExprs;
625616
List *predExprs;
626617
AttrNumber natt;
@@ -679,17 +670,15 @@ infer_arbiter_indexes(PlannerInfo *root)
679670
if (!idxForm->indisunique)
680671
goto next;
681672

682-
/* Build BMS representation of cataloged index attributes */
673+
/* Build BMS representation of plain (non expression) index attrs */
674+
indexedAttrs = NULL;
683675
for (natt = 0; natt < idxForm->indnatts; natt++)
684676
{
685677
int attno = idxRel->rd_index->indkey.values[natt];
686678

687-
/* XXX broken */
688-
if (attno < 0)
689-
elog(ERROR, "system column in index");
690-
691679
if (attno != 0)
692-
indexedAttrs = bms_add_member(indexedAttrs, attno);
680+
indexedAttrs = bms_add_member(indexedAttrs,
681+
attno - FirstLowInvalidHeapAttributeNumber);
693682
}
694683

695684
/* Non-expression attributes (if any) must match */

0 commit comments

Comments
 (0)