mirror of
https://github.com/postgres/postgres.git
synced 2025-07-26 01:22:12 +03:00
Fix assorted missing infrastructure for ON CONFLICT.
subquery_planner() failed to apply expression preprocessing to the arbiterElems and arbiterWhere fields of an OnConflictExpr. No doubt the theory was that this wasn't necessary because we don't actually try to execute those expressions; but that's wrong, because it results in failure to match to index expressions or index predicates that are changed at all by preprocessing. Per bug #14132 from Reynold Smith. Also add pullup_replace_vars processing for onConflictWhere. Perhaps it's impossible to have a subquery reference there, but I'm not exactly convinced; and even if true today it's a failure waiting to happen. Also add some comments to other places where one or another field of OnConflictExpr is intentionally ignored, with explanation as to why it's okay to do so. Also, catalog/dependency.c failed to record any dependency on the named constraint in ON CONFLICT ON CONSTRAINT, allowing such a constraint to be dropped while rules exist that depend on it, and allowing pg_dump to dump such a rule before the constraint it refers to. The normal execution path managed to error out reasonably for a dangling constraint reference, but ruleutils.c dumped core; so in addition to fixing the omission, add a protective check in ruleutils.c, since we can't retroactively add a dependency in existing databases. Back-patch to 9.5 where this code was introduced. Report: <20160510190350.2608.48667@wrigleys.postgresql.org>
This commit is contained in:
@ -623,7 +623,6 @@ infer_arbiter_indexes(PlannerInfo *root)
|
||||
Bitmapset *indexedAttrs = NULL;
|
||||
List *idxExprs;
|
||||
List *predExprs;
|
||||
List *whereExplicit;
|
||||
AttrNumber natt;
|
||||
ListCell *el;
|
||||
|
||||
@ -685,6 +684,7 @@ infer_arbiter_indexes(PlannerInfo *root)
|
||||
{
|
||||
int attno = idxRel->rd_index->indkey.values[natt];
|
||||
|
||||
/* XXX broken */
|
||||
if (attno < 0)
|
||||
elog(ERROR, "system column in index");
|
||||
|
||||
@ -745,13 +745,12 @@ infer_arbiter_indexes(PlannerInfo *root)
|
||||
goto next;
|
||||
|
||||
/*
|
||||
* Any user-supplied ON CONFLICT unique index inference WHERE clause
|
||||
* need only be implied by the cataloged index definitions predicate.
|
||||
* If it's a partial index, its predicate must be implied by the ON
|
||||
* CONFLICT's WHERE clause.
|
||||
*/
|
||||
predExprs = RelationGetIndexPredicate(idxRel);
|
||||
whereExplicit = make_ands_implicit((Expr *) onconflict->arbiterWhere);
|
||||
|
||||
if (!predicate_implied_by(predExprs, whereExplicit))
|
||||
if (!predicate_implied_by(predExprs, (List *) onconflict->arbiterWhere))
|
||||
goto next;
|
||||
|
||||
results = lappend_oid(results, idxForm->indexrelid);
|
||||
|
Reference in New Issue
Block a user