Skip to content

Commit 428484c

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 58d8024 commit 428484c

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
@@ -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

Comments
 (0)