I wrote:
> After puzzling over this for many hours, I have a theory that seems to
> fit the facts.

I think the attached patch will fix it for you --- please test.

                        regards, tom lane

Index: src/backend/utils/cache/plancache.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/utils/cache/plancache.c,v
retrieving revision 1.27.2.1
diff -c -r1.27.2.1 plancache.c
*** src/backend/utils/cache/plancache.c	14 Jul 2009 15:37:55 -0000	1.27.2.1
--- src/backend/utils/cache/plancache.c	13 Jan 2010 16:46:07 -0000
***************
*** 1050,1063 ****
  void
  ResetPlanCache(void)
  {
! 	ListCell   *lc;
  
! 	foreach(lc, cached_plans_list)
  	{
! 		CachedPlanSource *plansource = (CachedPlanSource *) lfirst(lc);
  		CachedPlan *plan = plansource->plan;
  
! 		if (plan)
! 			plan->dead = true;
  	}
  }
--- 1050,1106 ----
  void
  ResetPlanCache(void)
  {
! 	ListCell   *lc1;
  
! 	foreach(lc1, cached_plans_list)
  	{
! 		CachedPlanSource *plansource = (CachedPlanSource *) lfirst(lc1);
  		CachedPlan *plan = plansource->plan;
+ 		ListCell   *lc2;
  
! 		/* No work if it's already invalidated */
! 		if (!plan || plan->dead)
! 			continue;
! 
! 		/*
! 		 * We *must not* mark transaction control statements as dead,
! 		 * particularly not ROLLBACK, because they may need to be executed in
! 		 * aborted transactions when we can't revalidate them (cf bug #5269).
! 		 * In general there is no point in invalidating utility statements
! 		 * since they have no plans anyway.  So mark it dead only if it
! 		 * contains at least one non-utility statement.
! 		 */
! 		if (plan->fully_planned)
! 		{
! 			/* Search statement list for non-utility statements */
! 			foreach(lc2, plan->stmt_list)
! 			{
! 				PlannedStmt *plannedstmt = (PlannedStmt *) lfirst(lc2);
! 
! 				Assert(!IsA(plannedstmt, Query));
! 				if (IsA(plannedstmt, PlannedStmt))
! 				{
! 					/* non-utility statement, so invalidate */
! 					plan->dead = true;
! 					break;		/* out of stmt_list scan */
! 				}
! 			}
! 		}
! 		else
! 		{
! 			/* Search Query list for non-utility statements */
! 			foreach(lc2, plan->stmt_list)
! 			{
! 				Query	   *query = (Query *) lfirst(lc2);
! 
! 				Assert(IsA(query, Query));
! 				if (query->commandType != CMD_UTILITY)
! 				{
! 					/* non-utility statement, so invalidate */
! 					plan->dead = true;
! 					break;		/* out of stmt_list scan */
! 				}
! 			}
! 		}
  	}
  }
-- 
Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs

Reply via email to