diff --git a/src/pl/plpython/plpy_main.c b/src/pl/plpython/plpy_main.c
index ae9d87e..79d7784 100644
*** a/src/pl/plpython/plpy_main.c
--- b/src/pl/plpython/plpy_main.c
***************
*** 12,17 ****
--- 12,18 ----
  #include "executor/spi.h"
  #include "miscadmin.h"
  #include "utils/guc.h"
+ #include "utils/memutils.h"
  #include "utils/syscache.h"
  
  #include "plpython.h"
*************** plpython_inline_handler(PG_FUNCTION_ARGS
*** 268,273 ****
--- 269,279 ----
  
  	MemSet(&proc, 0, sizeof(PLyProcedure));
  	proc.pyname = PLy_strdup("__plpython_inline_block");
+ 	proc.tmp_ctx = AllocSetContextCreate(TopMemoryContext,
+ 										 "PL/Python temporary ctx",
+ 										 ALLOCSET_DEFAULT_MINSIZE,
+ 										 ALLOCSET_DEFAULT_INITSIZE,
+ 										 ALLOCSET_DEFAULT_MAXSIZE);
  	proc.result.out.d.typoid = VOIDOID;
  
  	PG_TRY();
diff --git a/src/pl/plpython/plpy_procedure.c b/src/pl/plpython/plpy_procedure.c
index 229966a..f539cec 100644
*** a/src/pl/plpython/plpy_procedure.c
--- b/src/pl/plpython/plpy_procedure.c
***************
*** 12,17 ****
--- 12,18 ----
  #include "catalog/pg_type.h"
  #include "utils/builtins.h"
  #include "utils/hsearch.h"
+ #include "utils/memutils.h"
  #include "utils/syscache.h"
  
  #include "plpython.h"
*************** PLy_procedure_create(HeapTuple procTup,
*** 169,174 ****
--- 170,180 ----
  	proc->setof = NULL;
  	proc->src = NULL;
  	proc->argnames = NULL;
+ 	proc->tmp_ctx = AllocSetContextCreate(TopMemoryContext,
+ 										  "PL/Python temporary ctx",
+ 										  ALLOCSET_DEFAULT_MINSIZE,
+ 										  ALLOCSET_DEFAULT_INITSIZE,
+ 										  ALLOCSET_DEFAULT_MAXSIZE);
  
  	PG_TRY();
  	{
*************** PLy_procedure_delete(PLyProcedure *proc)
*** 411,416 ****
--- 417,424 ----
  		PLy_free(proc->src);
  	if (proc->argnames)
  		PLy_free(proc->argnames);
+ 	if (proc->tmp_ctx)
+ 		MemoryContextDelete(proc->tmp_ctx);
  }
  
  /*
diff --git a/src/pl/plpython/plpy_procedure.h b/src/pl/plpython/plpy_procedure.h
index e986c7e..5ee73fa 100644
*** a/src/pl/plpython/plpy_procedure.h
--- b/src/pl/plpython/plpy_procedure.h
*************** typedef struct PLyProcedure
*** 30,35 ****
--- 30,36 ----
  	PyObject   *code;			/* compiled procedure code */
  	PyObject   *statics;		/* data saved across calls, local scope */
  	PyObject   *globals;		/* data saved across calls, global scope */
+ 	MemoryContext tmp_ctx;
  } PLyProcedure;
  
  /* the procedure cache entry */
diff --git a/src/pl/plpython/plpy_typeio.c b/src/pl/plpython/plpy_typeio.c
index d5cac9f..6f0eb46 100644
*** a/src/pl/plpython/plpy_typeio.c
--- b/src/pl/plpython/plpy_typeio.c
***************
*** 23,28 ****
--- 23,29 ----
  #include "plpy_typeio.h"
  
  #include "plpy_elog.h"
+ #include "plpy_procedure.h"
  
  
  /* I/O function caching */
*************** PLy_output_record_funcs(PLyTypeInfo *arg
*** 258,268 ****
  	Assert(arg->is_rowtype == 1);
  }
  
  PyObject *
  PLyDict_FromTuple(PLyTypeInfo *info, HeapTuple tuple, TupleDesc desc)
  {
! 	PyObject   *volatile dict;
! 	int			i;
  
  	if (info->is_rowtype != 1)
  		elog(ERROR, "PLyTypeInfo structure describes a datum");
--- 259,274 ----
  	Assert(arg->is_rowtype == 1);
  }
  
+ /*
+  * Transform a tuple into a Python dict object. The transformation can result
+  * in memory allocation, so it's done in a scratch memory context.
+  */
  PyObject *
  PLyDict_FromTuple(PLyTypeInfo *info, HeapTuple tuple, TupleDesc desc)
  {
! 	PyObject		*volatile dict;
! 	MemoryContext	oldcontext;
! 	int				i;
  
  	if (info->is_rowtype != 1)
  		elog(ERROR, "PLyTypeInfo structure describes a datum");
*************** PLyDict_FromTuple(PLyTypeInfo *info, Hea
*** 271,276 ****
--- 277,284 ----
  	if (dict == NULL)
  		PLy_elog(ERROR, "could not create new dictionary");
  
+ 	oldcontext = MemoryContextSwitchTo(PLy_curr_procedure->tmp_ctx);
+ 
  	PG_TRY();
  	{
  		for (i = 0; i < info->in.r.natts; i++)
*************** PLyDict_FromTuple(PLyTypeInfo *info, Hea
*** 298,308 ****
--- 306,322 ----
  	}
  	PG_CATCH();
  	{
+ 		MemoryContextSwitchTo(oldcontext);
+ 		MemoryContextReset(PLy_curr_procedure->tmp_ctx);
+ 
  		Py_DECREF(dict);
  		PG_RE_THROW();
  	}
  	PG_END_TRY();
  
+ 	MemoryContextSwitchTo(oldcontext);
+ 	MemoryContextReset(PLy_curr_procedure->tmp_ctx);
+ 
  	return dict;
  }
  
