diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index 36f8c548eb..1a541788eb 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -996,11 +996,10 @@ transformOnConflictClause(ParseState *pstate, exclRelIndex = list_length(pstate->p_rtable); /* - * Build a targetlist for the EXCLUDED pseudo relation. Have to be - * careful to use resnos that correspond to attnos of the underlying - * relation. + * Build a targetlist representing the columns of the EXCLUDED pseudo + * relation. Have to be careful to use resnos that correspond to + * attnos of the underlying relation. */ - Assert(pstate->p_next_resno == 1); for (attno = 0; attno < targetrel->rd_rel->relnatts; attno++) { Form_pg_attribute attr = targetrel->rd_att->attrs[attno]; @@ -1021,14 +1020,11 @@ transformOnConflictClause(ParseState *pstate, attr->atttypid, attr->atttypmod, attr->attcollation, 0); - var->location = -1; - - name = NameStr(attr->attname); + name = pstrdup(NameStr(attr->attname)); } - Assert(pstate->p_next_resno == attno + 1); te = makeTargetEntry((Expr *) var, - pstate->p_next_resno++, + attno + 1, name, false); @@ -1037,15 +1033,16 @@ transformOnConflictClause(ParseState *pstate, } /* - * Additionally add a whole row tlist entry for EXCLUDED. That's - * really only needed for ruleutils' benefit, which expects to find - * corresponding entries in child tlists. Alternatively we could do - * this only when required, but that doesn't seem worth the trouble. + * Add a whole-row-Var entry to support references to "EXCLUDED.*". + * Like the other entries in exclRelTlist, its resno must match the + * Var's varattno, else the wrong things happen while resolving + * references in setrefs.c. This is against normal conventions for + * targetlists, but it's okay since we don't use this as a real tlist. */ var = makeVar(exclRelIndex, InvalidAttrNumber, - RelationGetRelid(targetrel), + targetrel->rd_rel->reltype, -1, InvalidOid, 0); - te = makeTargetEntry((Expr *) var, 0, NULL, true); + te = makeTargetEntry((Expr *) var, InvalidAttrNumber, NULL, true); exclRelTlist = lappend(exclRelTlist, te); /*