I noticed a gripe about plpgsql exceptions leaking memory:
(woulda been nice if he'd reported it more formally, but whatever.)

Some experimentation shows that there is indeed an issue, eg this
function leaks about 16K per iteration in HEAD:

create function fooey(int) returns void as $$
  for n in 1..$1 loop
      perform 1/0;
      when others then null;
  end loop;
end$$ language plpgsql;

I came up with the attached patch that gets rid of the bulk of the leak
--- this particular example still leaks about 48 bytes/iteration due to
the two palloc's in exec_run_select(), which it doesn't get control back
to free.  It's hard to see dealing with that without a major rewrite of
plpgsql's memory management :-(

While this patch passes all the regression tests, I'm still a bit
nervous about whether it might free data that someone still wants
somewhere.  Anyone have any complicated PL functions or handwritten
SPI-using code they'd like to try it with?

                        regards, tom lane

*** src/backend/executor/spi.c.orig     Tue Oct  3 23:16:22 2006
--- src/backend/executor/spi.c  Fri Nov  3 00:19:35 2006
*** 254,259 ****
--- 254,272 ----
                                 errmsg("subtransaction left non-empty SPI 
                                 errhint("Check for missing \"SPI_finish\" 
+       /*
+        * If we are aborting a subtransaction and there is an open SPI context
+        * surrounding the subxact, clean up to prevent memory leakage.
+        */
+       if (_SPI_current && !isCommit)
+       {
+               /* free Executor memory the same as _SPI_end_call would do */
+               MemoryContextResetAndDeleteChildren(_SPI_current->execCxt);
+               /* throw away any partially created tuple-table */
+               SPI_freetuptable(_SPI_current->tuptable);
+               _SPI_current->tuptable = NULL;
+       }

---------------------------(end of broadcast)---------------------------
TIP 5: don't forget to increase your free space map settings

Reply via email to