mirror of
https://github.com/postgres/postgres.git
synced 2025-06-30 21:42:05 +03:00
Fix the plan-invalidation mechanism to treat regclass constants that refer to
a relation as a reason to invalidate a plan when the relation changes. This handles scenarios such as dropping/recreating a sequence that is referenced by nextval('seq') in a cached plan. Rather than teach plancache.c all about digging through plan trees to find regclass Consts, we charge the planner's setrefs.c with making a list of the relation OIDs on which each plan depends. That way the list can be built cheaply during a plan tree traversal that has to happen anyway. Per bug #3662 and subsequent discussion.
This commit is contained in:
21
src/backend/utils/cache/plancache.c
vendored
21
src/backend/utils/cache/plancache.c
vendored
@ -33,7 +33,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/cache/plancache.c,v 1.11 2007/09/20 17:56:31 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/cache/plancache.c,v 1.12 2007/10/11 18:05:27 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -921,26 +921,17 @@ PlanCacheCallback(Datum arg, Oid relid)
|
||||
foreach(lc2, plan->stmt_list)
|
||||
{
|
||||
PlannedStmt *plannedstmt = (PlannedStmt *) lfirst(lc2);
|
||||
ListCell *lc3;
|
||||
|
||||
Assert(!IsA(plannedstmt, Query));
|
||||
if (!IsA(plannedstmt, PlannedStmt))
|
||||
continue; /* Ignore utility statements */
|
||||
foreach(lc3, plannedstmt->rtable)
|
||||
if ((relid == InvalidOid) ? plannedstmt->relationOids != NIL :
|
||||
list_member_oid(plannedstmt->relationOids, relid))
|
||||
{
|
||||
RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc3);
|
||||
|
||||
if (rte->rtekind != RTE_RELATION)
|
||||
continue;
|
||||
if (relid == rte->relid || relid == InvalidOid)
|
||||
{
|
||||
/* Invalidate the plan! */
|
||||
plan->dead = true;
|
||||
break; /* out of rangetable scan */
|
||||
}
|
||||
}
|
||||
if (plan->dead)
|
||||
/* Invalidate the plan! */
|
||||
plan->dead = true;
|
||||
break; /* out of stmt_list scan */
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
Reference in New Issue
Block a user