Tuplestore should remember the memory context it's created in - Mailing list pgsql-hackers

From Heikki Linnakangas
Subject Tuplestore should remember the memory context it's created in
Date
Msg-id 4B30B16E.3070704@enterprisedb.com
Whole thread Raw
Responses Re: Tuplestore should remember the memory context it's created in  (Greg Stark <gsstark@mit.edu>)
Re: Tuplestore should remember the memory context it's created in  (Greg Stark <gsstark@mit.edu>)
Re: Tuplestore should remember the memory context it's created in  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-hackers
With regards to this bug report:
http://archives.postgresql.org/pgsql-bugs/2009-12/msg00241.php

I think we should change tuplestore code so that callers of
tuplestore_put* don't need to switch to the correct memory context (and
resource owner, after this patch) before call. Instead,
tuplestore_begin_heap() should memorize the context and resource owner
used to create the tuplestore, and use that in tuplestore_put*
functions. AFAICS it is always a bug to be in a different memory context
in tuplestore_put* than in tuplestore_begin_heap(), so it would be more
robust to not put the burden on the callers.

Patch against CVS HEAD to do that and fix the reported bug attached. Now
that the tuplestore_put* switches to the right memory context, we could
remove that from all the callers, but this patch only does it for pl_exec.c.

Thoughts?

--
  Heikki Linnakangas
  EnterpriseDB   http://www.enterprisedb.com
? GNUmakefile
? config.log
? config.status
? gin-splay-1.patch
? gin-splay-2.patch
? gin-splay-3.patch
? md-1.c
? md-1.patch
? temp-file-resowner-2.patch
? contrib/fuzzystrmatch/.deps
? contrib/fuzzystrmatch/fuzzystrmatch.sql
? contrib/pg_standby/.deps
? contrib/pg_standby/pg_standby
? contrib/pgbench/fsynctest
? contrib/pgbench/fsynctest.c
? contrib/pgbench/fsynctestfile
? contrib/spi/.deps
? src/Makefile.global
? src/backend/aaa.patch
? src/backend/postgres
? src/backend/access/common/.deps
? src/backend/access/gin/.deps
? src/backend/access/gist/.deps
? src/backend/access/hash/.deps
? src/backend/access/heap/.deps
? src/backend/access/index/.deps
? src/backend/access/nbtree/.deps
? src/backend/access/transam/.deps
? src/backend/bootstrap/.deps
? src/backend/catalog/.deps
? src/backend/catalog/postgres.bki
? src/backend/catalog/postgres.description
? src/backend/catalog/postgres.shdescription
? src/backend/commands/.deps
? src/backend/executor/.deps
? src/backend/foreign/.deps
? src/backend/foreign/dummy/.deps
? src/backend/foreign/postgresql/.deps
? src/backend/lib/.deps
? src/backend/libpq/.deps
? src/backend/main/.deps
? src/backend/nodes/.deps
? src/backend/optimizer/geqo/.deps
? src/backend/optimizer/path/.deps
? src/backend/optimizer/plan/.deps
? src/backend/optimizer/prep/.deps
? src/backend/optimizer/util/.deps
? src/backend/parser/.deps
? src/backend/po/af.mo
? src/backend/po/cs.mo
? src/backend/po/de.mo
? src/backend/po/es.mo
? src/backend/po/fr.mo
? src/backend/po/hr.mo
? src/backend/po/hu.mo
? src/backend/po/it.mo
? src/backend/po/ja.mo
? src/backend/po/ko.mo
? src/backend/po/nb.mo
? src/backend/po/nl.mo
? src/backend/po/pl.mo
? src/backend/po/pt_BR.mo
? src/backend/po/ro.mo
? src/backend/po/ru.mo
? src/backend/po/sk.mo
? src/backend/po/sl.mo
? src/backend/po/sv.mo
? src/backend/po/tr.mo
? src/backend/po/zh_CN.mo
? src/backend/po/zh_TW.mo
? src/backend/port/.deps
? src/backend/postmaster/.deps
? src/backend/regex/.deps
? src/backend/rewrite/.deps
? src/backend/snowball/.deps
? src/backend/snowball/snowball_create.sql
? src/backend/storage/buffer/.deps
? src/backend/storage/file/.deps
? src/backend/storage/freespace/.deps
? src/backend/storage/ipc/.deps
? src/backend/storage/large_object/.deps
? src/backend/storage/lmgr/.deps
? src/backend/storage/page/.deps
? src/backend/storage/smgr/.deps
? src/backend/tcop/.deps
? src/backend/tsearch/.deps
? src/backend/utils/.deps
? src/backend/utils/probes.h
? src/backend/utils/adt/.deps
? src/backend/utils/cache/.deps
? src/backend/utils/error/.deps
? src/backend/utils/fmgr/.deps
? src/backend/utils/hash/.deps
? src/backend/utils/init/.deps
? src/backend/utils/mb/.deps
? src/backend/utils/mb/Unicode/BIG5.TXT
? src/backend/utils/mb/Unicode/CP950.TXT
? src/backend/utils/mb/conversion_procs/conversion_create.sql
? src/backend/utils/mb/conversion_procs/ascii_and_mic/.deps
? src/backend/utils/mb/conversion_procs/cyrillic_and_mic/.deps
? src/backend/utils/mb/conversion_procs/euc2004_sjis2004/.deps
? src/backend/utils/mb/conversion_procs/euc_cn_and_mic/.deps
? src/backend/utils/mb/conversion_procs/euc_jis_2004_and_shift_jis_2004/.deps
? src/backend/utils/mb/conversion_procs/euc_jp_and_sjis/.deps
? src/backend/utils/mb/conversion_procs/euc_kr_and_mic/.deps
? src/backend/utils/mb/conversion_procs/euc_tw_and_big5/.deps
? src/backend/utils/mb/conversion_procs/latin2_and_win1250/.deps
? src/backend/utils/mb/conversion_procs/latin_and_mic/.deps
? src/backend/utils/mb/conversion_procs/utf8_and_ascii/.deps
? src/backend/utils/mb/conversion_procs/utf8_and_big5/.deps
? src/backend/utils/mb/conversion_procs/utf8_and_cyrillic/.deps
? src/backend/utils/mb/conversion_procs/utf8_and_euc2004/.deps
? src/backend/utils/mb/conversion_procs/utf8_and_euc_cn/.deps
? src/backend/utils/mb/conversion_procs/utf8_and_euc_jis_2004/.deps
? src/backend/utils/mb/conversion_procs/utf8_and_euc_jp/.deps
? src/backend/utils/mb/conversion_procs/utf8_and_euc_kr/.deps
? src/backend/utils/mb/conversion_procs/utf8_and_euc_tw/.deps
? src/backend/utils/mb/conversion_procs/utf8_and_gb18030/.deps
? src/backend/utils/mb/conversion_procs/utf8_and_gbk/.deps
? src/backend/utils/mb/conversion_procs/utf8_and_iso8859/.deps
? src/backend/utils/mb/conversion_procs/utf8_and_iso8859_1/.deps
? src/backend/utils/mb/conversion_procs/utf8_and_johab/.deps
? src/backend/utils/mb/conversion_procs/utf8_and_shift_jis_2004/.deps
? src/backend/utils/mb/conversion_procs/utf8_and_sjis/.deps
? src/backend/utils/mb/conversion_procs/utf8_and_sjis2004/.deps
? src/backend/utils/mb/conversion_procs/utf8_and_uhc/.deps
? src/backend/utils/mb/conversion_procs/utf8_and_win/.deps
? src/backend/utils/misc/.deps
? src/backend/utils/mmgr/.deps
? src/backend/utils/resowner/.deps
? src/backend/utils/sort/.deps
? src/backend/utils/time/.deps
? src/bin/initdb/.deps
? src/bin/initdb/initdb
? src/bin/initdb/po/cs.mo
? src/bin/initdb/po/de.mo
? src/bin/initdb/po/es.mo
? src/bin/initdb/po/fr.mo
? src/bin/initdb/po/it.mo
? src/bin/initdb/po/ja.mo
? src/bin/initdb/po/ko.mo
? src/bin/initdb/po/pl.mo
? src/bin/initdb/po/pt_BR.mo
? src/bin/initdb/po/ro.mo
? src/bin/initdb/po/ru.mo
? src/bin/initdb/po/sk.mo
? src/bin/initdb/po/sl.mo
? src/bin/initdb/po/sv.mo
? src/bin/initdb/po/ta.mo
? src/bin/initdb/po/tr.mo
? src/bin/initdb/po/zh_CN.mo
? src/bin/initdb/po/zh_TW.mo
? src/bin/pg_config/.deps
? src/bin/pg_config/pg_config
? src/bin/pg_config/po/cs.mo
? src/bin/pg_config/po/de.mo
? src/bin/pg_config/po/es.mo
? src/bin/pg_config/po/fr.mo
? src/bin/pg_config/po/it.mo
? src/bin/pg_config/po/ja.mo
? src/bin/pg_config/po/ko.mo
? src/bin/pg_config/po/nb.mo
? src/bin/pg_config/po/pl.mo
? src/bin/pg_config/po/pt_BR.mo
? src/bin/pg_config/po/ro.mo
? src/bin/pg_config/po/ru.mo
? src/bin/pg_config/po/sl.mo
? src/bin/pg_config/po/sv.mo
? src/bin/pg_config/po/ta.mo
? src/bin/pg_config/po/tr.mo
? src/bin/pg_config/po/zh_CN.mo
? src/bin/pg_config/po/zh_TW.mo
? src/bin/pg_controldata/.deps
? src/bin/pg_controldata/pg_controldata
? src/bin/pg_controldata/po/cs.mo
? src/bin/pg_controldata/po/de.mo
? src/bin/pg_controldata/po/es.mo
? src/bin/pg_controldata/po/fa.mo
? src/bin/pg_controldata/po/fr.mo
? src/bin/pg_controldata/po/hu.mo
? src/bin/pg_controldata/po/it.mo
? src/bin/pg_controldata/po/ja.mo
? src/bin/pg_controldata/po/ko.mo
? src/bin/pg_controldata/po/nb.mo
? src/bin/pg_controldata/po/pl.mo
? src/bin/pg_controldata/po/pt_BR.mo
? src/bin/pg_controldata/po/ro.mo
? src/bin/pg_controldata/po/ru.mo
? src/bin/pg_controldata/po/sk.mo
? src/bin/pg_controldata/po/sl.mo
? src/bin/pg_controldata/po/sv.mo
? src/bin/pg_controldata/po/ta.mo
? src/bin/pg_controldata/po/tr.mo
? src/bin/pg_controldata/po/zh_CN.mo
? src/bin/pg_controldata/po/zh_TW.mo
? src/bin/pg_ctl/.deps
? src/bin/pg_ctl/pg_ctl
? src/bin/pg_ctl/po/cs.mo
? src/bin/pg_ctl/po/de.mo
? src/bin/pg_ctl/po/es.mo
? src/bin/pg_ctl/po/fr.mo
? src/bin/pg_ctl/po/it.mo
? src/bin/pg_ctl/po/ja.mo
? src/bin/pg_ctl/po/ko.mo
? src/bin/pg_ctl/po/pt_BR.mo
? src/bin/pg_ctl/po/ro.mo
? src/bin/pg_ctl/po/ru.mo
? src/bin/pg_ctl/po/sk.mo
? src/bin/pg_ctl/po/sl.mo
? src/bin/pg_ctl/po/sv.mo
? src/bin/pg_ctl/po/ta.mo
? src/bin/pg_ctl/po/tr.mo
? src/bin/pg_ctl/po/zh_CN.mo
? src/bin/pg_ctl/po/zh_TW.mo
? src/bin/pg_dump/.deps
? src/bin/pg_dump/pg_dump
? src/bin/pg_dump/pg_dumpall
? src/bin/pg_dump/pg_restore
? src/bin/pg_dump/po/cs.mo
? src/bin/pg_dump/po/de.mo
? src/bin/pg_dump/po/es.mo
? src/bin/pg_dump/po/fr.mo
? src/bin/pg_dump/po/it.mo
? src/bin/pg_dump/po/ja.mo
? src/bin/pg_dump/po/ko.mo
? src/bin/pg_dump/po/nb.mo
? src/bin/pg_dump/po/pt_BR.mo
? src/bin/pg_dump/po/ro.mo
? src/bin/pg_dump/po/ru.mo
? src/bin/pg_dump/po/sk.mo
? src/bin/pg_dump/po/sl.mo
? src/bin/pg_dump/po/sv.mo
? src/bin/pg_dump/po/tr.mo
? src/bin/pg_dump/po/zh_CN.mo
? src/bin/pg_dump/po/zh_TW.mo
? src/bin/pg_resetxlog/.deps
? src/bin/pg_resetxlog/pg_resetxlog
? src/bin/pg_resetxlog/po/cs.mo
? src/bin/pg_resetxlog/po/de.mo
? src/bin/pg_resetxlog/po/es.mo
? src/bin/pg_resetxlog/po/fr.mo
? src/bin/pg_resetxlog/po/hu.mo
? src/bin/pg_resetxlog/po/it.mo
? src/bin/pg_resetxlog/po/ja.mo
? src/bin/pg_resetxlog/po/ko.mo
? src/bin/pg_resetxlog/po/nb.mo
? src/bin/pg_resetxlog/po/pt_BR.mo
? src/bin/pg_resetxlog/po/ro.mo
? src/bin/pg_resetxlog/po/ru.mo
? src/bin/pg_resetxlog/po/sk.mo
? src/bin/pg_resetxlog/po/sl.mo
? src/bin/pg_resetxlog/po/sv.mo
? src/bin/pg_resetxlog/po/ta.mo
? src/bin/pg_resetxlog/po/tr.mo
? src/bin/pg_resetxlog/po/zh_CN.mo
? src/bin/pg_resetxlog/po/zh_TW.mo
? src/bin/psql/.deps
? src/bin/psql/psql
? src/bin/psql/po/cs.mo
? src/bin/psql/po/de.mo
? src/bin/psql/po/es.mo
? src/bin/psql/po/fa.mo
? src/bin/psql/po/fr.mo
? src/bin/psql/po/hu.mo
? src/bin/psql/po/it.mo
? src/bin/psql/po/ja.mo
? src/bin/psql/po/ko.mo
? src/bin/psql/po/nb.mo
? src/bin/psql/po/pt_BR.mo
? src/bin/psql/po/ro.mo
? src/bin/psql/po/ru.mo
? src/bin/psql/po/sk.mo
? src/bin/psql/po/sl.mo
? src/bin/psql/po/sv.mo
? src/bin/psql/po/tr.mo
? src/bin/psql/po/zh_CN.mo
? src/bin/psql/po/zh_TW.mo
? src/bin/scripts/.deps
? src/bin/scripts/clusterdb
? src/bin/scripts/createdb
? src/bin/scripts/createlang
? src/bin/scripts/createuser
? src/bin/scripts/dropdb
? src/bin/scripts/droplang
? src/bin/scripts/dropuser
? src/bin/scripts/reindexdb
? src/bin/scripts/vacuumdb
? src/bin/scripts/po/cs.mo
? src/bin/scripts/po/de.mo
? src/bin/scripts/po/es.mo
? src/bin/scripts/po/fr.mo
? src/bin/scripts/po/it.mo
? src/bin/scripts/po/ja.mo
? src/bin/scripts/po/ko.mo
? src/bin/scripts/po/pt_BR.mo
? src/bin/scripts/po/ro.mo
? src/bin/scripts/po/ru.mo
? src/bin/scripts/po/sk.mo
? src/bin/scripts/po/sl.mo
? src/bin/scripts/po/sv.mo
? src/bin/scripts/po/ta.mo
? src/bin/scripts/po/tr.mo
? src/bin/scripts/po/zh_CN.mo
? src/bin/scripts/po/zh_TW.mo
? src/include/pg_config.h
? src/include/stamp-h
? src/interfaces/ecpg/compatlib/.deps
? src/interfaces/ecpg/compatlib/exports.list
? src/interfaces/ecpg/compatlib/libecpg_compat.so.3.1
? src/interfaces/ecpg/compatlib/libecpg_compat.so.3.2
? src/interfaces/ecpg/ecpglib/.deps
? src/interfaces/ecpg/ecpglib/exports.list
? src/interfaces/ecpg/ecpglib/libecpg.so.6.1
? src/interfaces/ecpg/ecpglib/libecpg.so.6.2
? src/interfaces/ecpg/ecpglib/po/de.mo
? src/interfaces/ecpg/ecpglib/po/es.mo
? src/interfaces/ecpg/ecpglib/po/fr.mo
? src/interfaces/ecpg/ecpglib/po/it.mo
? src/interfaces/ecpg/ecpglib/po/ja.mo
? src/interfaces/ecpg/ecpglib/po/pt_BR.mo
? src/interfaces/ecpg/ecpglib/po/tr.mo
? src/interfaces/ecpg/include/ecpg_config.h
? src/interfaces/ecpg/include/stamp-h
? src/interfaces/ecpg/pgtypeslib/.deps
? src/interfaces/ecpg/pgtypeslib/exports.list
? src/interfaces/ecpg/pgtypeslib/libpgtypes.so.3.1
? src/interfaces/ecpg/pgtypeslib/libpgtypes.so.3.2
? src/interfaces/ecpg/preproc/.deps
? src/interfaces/ecpg/preproc/ecpg
? src/interfaces/ecpg/preproc/po/de.mo
? src/interfaces/ecpg/preproc/po/es.mo
? src/interfaces/ecpg/preproc/po/fr.mo
? src/interfaces/ecpg/preproc/po/it.mo
? src/interfaces/ecpg/preproc/po/ja.mo
? src/interfaces/ecpg/preproc/po/pt_BR.mo
? src/interfaces/ecpg/preproc/po/tr.mo
? src/interfaces/libpq/.deps
? src/interfaces/libpq/exports.list
? src/interfaces/libpq/libpq.so.5.2
? src/interfaces/libpq/libpq.so.5.3
? src/interfaces/libpq/po/af.mo
? src/interfaces/libpq/po/cs.mo
? src/interfaces/libpq/po/de.mo
? src/interfaces/libpq/po/es.mo
? src/interfaces/libpq/po/fr.mo
? src/interfaces/libpq/po/hr.mo
? src/interfaces/libpq/po/it.mo
? src/interfaces/libpq/po/ja.mo
? src/interfaces/libpq/po/ko.mo
? src/interfaces/libpq/po/nb.mo
? src/interfaces/libpq/po/pl.mo
? src/interfaces/libpq/po/pt_BR.mo
? src/interfaces/libpq/po/ru.mo
? src/interfaces/libpq/po/sk.mo
? src/interfaces/libpq/po/sl.mo
? src/interfaces/libpq/po/sv.mo
? src/interfaces/libpq/po/ta.mo
? src/interfaces/libpq/po/tr.mo
? src/interfaces/libpq/po/zh_CN.mo
? src/interfaces/libpq/po/zh_TW.mo
? src/pl/plperl/.deps
? src/pl/plperl/SPI.c
? src/pl/plperl/results
? src/pl/plperl/po/de.mo
? src/pl/plperl/po/es.mo
? src/pl/plperl/po/fr.mo
? src/pl/plperl/po/it.mo
? src/pl/plperl/po/ja.mo
? src/pl/plperl/po/pt_BR.mo
? src/pl/plperl/po/tr.mo
? src/pl/plpgsql/src/.deps
? src/pl/plpgsql/src/pl_scan.c
? src/pl/plpgsql/src/po/de.mo
? src/pl/plpgsql/src/po/es.mo
? src/pl/plpgsql/src/po/fr.mo
? src/pl/plpgsql/src/po/it.mo
? src/pl/plpgsql/src/po/ja.mo
? src/pl/plpgsql/src/po/ro.mo
? src/pl/plpgsql/src/po/tr.mo
? src/port/.deps
? src/port/pg_config_paths.h
? src/test/regress/.deps
? src/test/regress/log
? src/test/regress/pg_regress
? src/test/regress/results
? src/test/regress/testtablespace
? src/test/regress/tmp_check
? src/test/regress/expected/constraints.out
? src/test/regress/expected/copy.out
? src/test/regress/expected/create_function_1.out
? src/test/regress/expected/create_function_2.out
? src/test/regress/expected/largeobject.out
? src/test/regress/expected/largeobject_1.out
? src/test/regress/expected/misc.out
? src/test/regress/expected/tablespace.out
? src/test/regress/sql/constraints.sql
? src/test/regress/sql/copy.sql
? src/test/regress/sql/create_function_1.sql
? src/test/regress/sql/create_function_2.sql
? src/test/regress/sql/largeobject.sql
? src/test/regress/sql/misc.sql
? src/test/regress/sql/tablespace.sql
? src/timezone/.deps
? src/timezone/zic
Index: src/backend/utils/sort/tuplestore.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/utils/sort/tuplestore.c,v
retrieving revision 1.48
diff -c -r1.48 tuplestore.c
*** src/backend/utils/sort/tuplestore.c    11 Jun 2009 14:49:06 -0000    1.48
--- src/backend/utils/sort/tuplestore.c    22 Dec 2009 11:39:11 -0000
***************
*** 58,63 ****
--- 58,64 ----
  #include "executor/executor.h"
  #include "storage/buffile.h"
  #include "utils/memutils.h"
+ #include "utils/resowner.h"
  #include "utils/tuplestore.h"


***************
*** 105,110 ****
--- 106,113 ----
      bool        truncated;        /* tuplestore_trim has removed tuples? */
      long        availMem;        /* remaining memory available, in bytes */
      BufFile    *myfile;            /* underlying file, or NULL if none */
+     MemoryContext context;        /* memory context for holding tuples */
+     ResourceOwner resowner;

      /*
       * These function pointers decouple the routines that must know what kind
***************
*** 246,251 ****
--- 249,256 ----
      state->truncated = false;
      state->availMem = maxKBytes * 1024L;
      state->myfile = NULL;
+     state->context = CurrentMemoryContext;
+     state->resowner = CurrentResourceOwner;

      state->memtupcount = 0;
      state->memtupsize = 1024;    /* initial guess */
***************
*** 533,538 ****
--- 538,546 ----
                          TupleTableSlot *slot)
  {
      MinimalTuple tuple;
+     MemoryContext oldcxt;
+
+     oldcxt = MemoryContextSwitchTo(state->context);

      /*
       * Form a MinimalTuple in working memory
***************
*** 541,546 ****
--- 549,556 ----
      USEMEM(state, GetMemoryChunkSpace(tuple));

      tuplestore_puttuple_common(state, (void *) tuple);
+
+     MemoryContextSwitchTo(oldcxt);
  }

  /*
***************
*** 550,561 ****
--- 560,575 ----
  void
  tuplestore_puttuple(Tuplestorestate *state, HeapTuple tuple)
  {
+     MemoryContext oldcxt = MemoryContextSwitchTo(state->context);
+
      /*
       * Copy the tuple.    (Must do this even in WRITEFILE case.)
       */
      tuple = COPYTUP(state, tuple);

      tuplestore_puttuple_common(state, (void *) tuple);
+
+     MemoryContextSwitchTo(oldcxt);
  }

  /*
***************
*** 568,577 ****
--- 582,596 ----
                       Datum *values, bool *isnull)
  {
      MinimalTuple tuple;
+     MemoryContext oldcxt;
+
+     oldcxt = MemoryContextSwitchTo(state->context);

      tuple = heap_form_minimal_tuple(tdesc, values, isnull);

      tuplestore_puttuple_common(state, (void *) tuple);
+
+     MemoryContextSwitchTo(oldcxt);
  }

  static void
***************
*** 579,584 ****
--- 598,604 ----
  {
      TSReadPointer *readptr;
      int            i;
+     ResourceOwner oldowner;

      switch (state->status)
      {
***************
*** 635,641 ****
--- 655,664 ----
               * the temp file(s) are created in suitable temp tablespaces.
               */
              PrepareTempTablespaces();
+             oldowner = CurrentResourceOwner;
+             CurrentResourceOwner = state->resowner;
              state->myfile = BufFileCreateTemp(state->interXact);
+             CurrentResourceOwner = oldowner;

              /*
               * Freeze the decision about whether trailing length words will be
Index: src/pl/plpgsql/src/pl_exec.c
===================================================================
RCS file: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v
retrieving revision 1.251
diff -c -r1.251 pl_exec.c
*** src/pl/plpgsql/src/pl_exec.c    9 Nov 2009 00:26:55 -0000    1.251
--- src/pl/plpgsql/src/pl_exec.c    22 Dec 2009 11:39:12 -0000
***************
*** 2172,2178 ****
  {
      TupleDesc    tupdesc;
      int            natts;
-     MemoryContext oldcxt;
      HeapTuple    tuple = NULL;
      bool        free_tuple = false;

--- 2172,2177 ----
***************
*** 2212,2221 ****
                                                  tupdesc->attrs[0]->atttypmod,
                                                      isNull);

-                     oldcxt = MemoryContextSwitchTo(estate->tuple_store_cxt);
                      tuplestore_putvalues(estate->tuple_store, tupdesc,
                                           &retval, &isNull);
-                     MemoryContextSwitchTo(oldcxt);
                  }
                  break;

--- 2211,2218 ----
***************
*** 2285,2294 ****
                                          tupdesc->attrs[0]->atttypmod,
                                          isNull);

-         oldcxt = MemoryContextSwitchTo(estate->tuple_store_cxt);
          tuplestore_putvalues(estate->tuple_store, tupdesc,
                               &retval, &isNull);
-         MemoryContextSwitchTo(oldcxt);

          exec_eval_cleanup(estate);
      }
--- 2282,2289 ----
***************
*** 2301,2309 ****

      if (HeapTupleIsValid(tuple))
      {
-         oldcxt = MemoryContextSwitchTo(estate->tuple_store_cxt);
          tuplestore_puttuple(estate->tuple_store, tuple);
-         MemoryContextSwitchTo(oldcxt);

          if (free_tuple)
              heap_freetuple(tuple);
--- 2296,2302 ----
***************
*** 2353,2366 ****

      while (true)
      {
-         MemoryContext old_cxt;
          int            i;

          SPI_cursor_fetch(portal, true, 50);
          if (SPI_processed == 0)
              break;

-         old_cxt = MemoryContextSwitchTo(estate->tuple_store_cxt);
          for (i = 0; i < SPI_processed; i++)
          {
              HeapTuple    tuple = SPI_tuptable->vals[i];
--- 2346,2357 ----
***************
*** 2372,2378 ****
                  heap_freetuple(tuple);
              processed++;
          }
-         MemoryContextSwitchTo(old_cxt);

          SPI_freetuptable(SPI_tuptable);
      }
--- 2363,2368 ----
***************
*** 2394,2399 ****
--- 2384,2390 ----
  {
      ReturnSetInfo *rsi = estate->rsi;
      MemoryContext oldcxt;
+     ResourceOwner oldowner;

      /*
       * Check caller can handle a set result in the way we want
***************
*** 2408,2416 ****
--- 2399,2410 ----
      estate->tuple_store_cxt = rsi->econtext->ecxt_per_query_memory;

      oldcxt = MemoryContextSwitchTo(estate->tuple_store_cxt);
+     oldowner = CurrentResourceOwner;
+     CurrentResourceOwner = estate->tuple_store_owner;
      estate->tuple_store =
          tuplestore_begin_heap(rsi->allowedModes & SFRM_Materialize_Random,
                                false, work_mem);
+     CurrentResourceOwner = oldowner;
      MemoryContextSwitchTo(oldcxt);

      estate->rettupdesc = rsi->expectedDesc;
***************
*** 2636,2641 ****
--- 2630,2636 ----

      estate->tuple_store = NULL;
      estate->tuple_store_cxt = NULL;
+     estate->tuple_store_owner = CurrentResourceOwner;
      estate->rsi = rsi;

      estate->found_varno = func->found_varno;
Index: src/pl/plpgsql/src/plpgsql.h
===================================================================
RCS file: /cvsroot/pgsql/src/pl/plpgsql/src/plpgsql.h,v
retrieving revision 1.125
diff -c -r1.125 plpgsql.h
*** src/pl/plpgsql/src/plpgsql.h    13 Nov 2009 22:43:42 -0000    1.125
--- src/pl/plpgsql/src/plpgsql.h    22 Dec 2009 11:39:12 -0000
***************
*** 701,706 ****
--- 701,707 ----

      Tuplestorestate *tuple_store;        /* SRFs accumulate results here */
      MemoryContext tuple_store_cxt;
+     ResourceOwner tuple_store_owner;
      ReturnSetInfo *rsi;

      int            found_varno;

pgsql-hackers by date:

Previous
From: Greg Stark
Date:
Subject: Re: alpha3 release schedule?
Next
From: Heikki Linnakangas
Date:
Subject: Re: Streaming replication and non-blocking I/O