提交 82d8ab6f 编写于 作者: T Tom Lane

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.
上级 68b08b25
......@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.382 2007/09/03 18:46:30 tgl Exp $
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.383 2007/10/11 18:05:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -83,6 +83,7 @@ _copyPlannedStmt(PlannedStmt *from)
COPY_BITMAPSET_FIELD(rewindPlanIDs);
COPY_NODE_FIELD(returningLists);
COPY_NODE_FIELD(rowMarks);
COPY_NODE_FIELD(relationOids);
COPY_SCALAR_FIELD(nParamExec);
return newnode;
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.314 2007/08/31 01:44:05 tgl Exp $
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.315 2007/10/11 18:05:27 tgl Exp $
*
* NOTES
* Every node type that can appear in stored rules' parsetrees *must*
......@@ -250,6 +250,7 @@ _outPlannedStmt(StringInfo str, PlannedStmt *node)
WRITE_BITMAPSET_FIELD(rewindPlanIDs);
WRITE_NODE_FIELD(returningLists);
WRITE_NODE_FIELD(rowMarks);
WRITE_NODE_FIELD(relationOids);
WRITE_INT_FIELD(nParamExec);
}
......@@ -1300,6 +1301,7 @@ _outPlannerGlobal(StringInfo str, PlannerGlobal *node)
WRITE_NODE_FIELD(subrtables);
WRITE_BITMAPSET_FIELD(rewindPlanIDs);
WRITE_NODE_FIELD(finalrtable);
WRITE_NODE_FIELD(relationOids);
}
static void
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.222 2007/09/20 17:56:31 tgl Exp $
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.223 2007/10/11 18:05:27 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -134,6 +134,7 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
glob->subrtables = NIL;
glob->rewindPlanIDs = NULL;
glob->finalrtable = NIL;
glob->relationOids = NIL;
glob->transientPlan = false;
/* Determine what fraction of the plan is likely to be scanned */
......@@ -194,6 +195,7 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
result->rewindPlanIDs = glob->rewindPlanIDs;
result->returningLists = root->returningLists;
result->rowMarks = parse->rowMarks;
result->relationOids = glob->relationOids;
result->nParamExec = list_length(glob->paramlist);
return result;
......@@ -1184,7 +1186,8 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
List *rlist;
Assert(parse->resultRelation);
rlist = set_returning_clause_references(parse->returningList,
rlist = set_returning_clause_references(root->glob,
parse->returningList,
result_plan,
parse->resultRelation);
root->returningLists = list_make1(rlist);
......
......@@ -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
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/nodes/plannodes.h,v 1.95 2007/09/20 17:56:32 tgl Exp $
* $PostgreSQL: pgsql/src/include/nodes/plannodes.h,v 1.96 2007/10/11 18:05:27 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -70,6 +70,8 @@ typedef struct PlannedStmt
List *rowMarks; /* a list of RowMarkClause's */
List *relationOids; /* OIDs of relations the plan depends on */
int nParamExec; /* number of PARAM_EXEC Params used */
} PlannedStmt;
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.146 2007/09/20 17:56:32 tgl Exp $
* $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.147 2007/10/11 18:05:27 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -72,6 +72,8 @@ typedef struct PlannerGlobal
List *finalrtable; /* "flat" rangetable for executor */
List *relationOids; /* OIDs of relations the plan depends on */
bool transientPlan; /* redo plan when TransactionXmin changes? */
} PlannerGlobal;
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/optimizer/planmain.h,v 1.102 2007/10/04 20:44:47 tgl Exp $
* $PostgreSQL: pgsql/src/include/optimizer/planmain.h,v 1.103 2007/10/11 18:05:27 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -96,7 +96,8 @@ extern RestrictInfo *build_implied_join_equality(Oid opno,
extern Plan *set_plan_references(PlannerGlobal *glob,
Plan *plan,
List *rtable);
extern List *set_returning_clause_references(List *rlist,
extern List *set_returning_clause_references(PlannerGlobal *glob,
List *rlist,
Plan *topplan,
Index resultRelation);
extern void fix_opfuncids(Node *node);
......
......@@ -202,3 +202,20 @@ drop schema s1 cascade;
NOTICE: drop cascades to table s1.abc
drop schema s2 cascade;
NOTICE: drop cascades to table abc
-- Check that invalidation deals with regclass constants
create temp sequence seq;
prepare p2 as select nextval('seq');
execute p2;
nextval
---------
1
(1 row)
drop sequence seq;
create temp sequence seq;
execute p2;
nextval
---------
1
(1 row)
......@@ -123,3 +123,17 @@ execute p1;
drop schema s1 cascade;
drop schema s2 cascade;
-- Check that invalidation deals with regclass constants
create temp sequence seq;
prepare p2 as select nextval('seq');
execute p2;
drop sequence seq;
create temp sequence seq;
execute p2;
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册