Re: BUG #5269: postgres backend terminates with SIGSEGV - Mailing list pgsql-bugs

From Tom Lane
Subject Re: BUG #5269: postgres backend terminates with SIGSEGV
Date
Msg-id 14512.1263401928@sss.pgh.pa.us
Whole thread Raw
In response to Re: BUG #5269: postgres backend terminates with SIGSEGV  (Tom Lane <tgl@sss.pgh.pa.us>)
Responses Re: BUG #5269: postgres backend terminates with SIGSEGV  (Justin Pitts <justinpitts@gmail.com>)
List pgsql-bugs
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 */
!                 }
!             }
!         }
      }
  }

pgsql-bugs by date:

Previous
From: Greg Stark
Date:
Subject: Re: BUG #2197: PostgreSQL error- 'could not read block 0 of relation'
Next
From: Tom Lane
Date:
Subject: Re: Substring auto trim