diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c
index a928e2f..b2139d6 100644
--- a/src/pl/plpgsql/src/pl_comp.c
+++ b/src/pl/plpgsql/src/pl_comp.c
@@ -2368,12 +2368,9 @@ delete_function(PLpgSQL_function *func)
 	/* remove function from hash table (might be done already) */
 	plpgsql_HashTableDelete(func);
 
-	/* release the function's storage if safe and not done already */
-	if (func->use_count == 0 && func->fn_cxt)
-	{
-		MemoryContextDelete(func->fn_cxt);
-		func->fn_cxt = NULL;
-	}
+	/* release the function's storage if safe */
+	if (func->use_count)
+		plpgsql_free_function_memory(func);
 }
 
 /* exported so we can call it from plpgsql_init() */
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c
index 1f4d5ac..e353374 100644
--- a/src/pl/plpgsql/src/pl_exec.c
+++ b/src/pl/plpgsql/src/pl_exec.c
@@ -2919,6 +2919,7 @@ static void
 exec_prepare_plan(PLpgSQL_execstate *estate,
 				  PLpgSQL_expr *expr, int cursorOptions)
 {
+	MemoryContext oldcxt;
 	SPIPlanPtr	plan;
 
 	/*
@@ -2956,6 +2957,11 @@ exec_prepare_plan(PLpgSQL_execstate *estate,
 	expr->plan = SPI_saveplan(plan);
 	SPI_freeplan(plan);
 	exec_simple_check_plan(expr);
+
+	/* Remember this plan so that it can be freed along with the function */
+	oldcxt = MemoryContextSwitchTo(expr->func->fn_cxt);
+	expr->func->cached_plans = lappend(expr->func->cached_plans, expr->plan);
+	MemoryContextSwitchTo(oldcxt);
 }
 
 
diff --git a/src/pl/plpgsql/src/pl_funcs.c b/src/pl/plpgsql/src/pl_funcs.c
index f13e4c3..14c5e08 100644
--- a/src/pl/plpgsql/src/pl_funcs.c
+++ b/src/pl/plpgsql/src/pl_funcs.c
@@ -15,6 +15,8 @@
 
 #include "plpgsql.h"
 
+#include "utils/memutils.h"
+
 
 /* ----------
  * Local variables for namespace handling
@@ -264,6 +266,37 @@ plpgsql_stmt_typename(PLpgSQL_stmt *stmt)
 }
 
 
+/*
+ * Release memory when a PL/pgSQL function is no longer needed
+ */
+void
+plpgsql_free_function_memory(PLpgSQL_function *func)
+{
+	ListCell   *lc;
+
+	/* Better not call this on an in-use function */
+	Assert(func->use_count == 0);
+
+	/* Release cached plans belonging to the function */
+	foreach(lc, func->cached_plans)
+	{
+		SPI_freeplan(lfirst(lc));
+	}
+	list_free(func->cached_plans);
+	func->cached_plans = NIL;
+
+	/*
+	 * And finally, release all memory except the PLpgSQL_function struct
+	 * itself (which has to be kept around because there may be multiple
+	 * fn_extra pointers to it).
+	 */
+	if (func->fn_cxt)
+	{
+		MemoryContextDelete(func->fn_cxt);
+		func->fn_cxt = NULL;
+	}
+}
+
 /**********************************************************************
  * Debug functions for analyzing the compiled code
  **********************************************************************/
diff --git a/src/pl/plpgsql/src/pl_handler.c b/src/pl/plpgsql/src/pl_handler.c
index 8f7080e..2389849 100644
--- a/src/pl/plpgsql/src/pl_handler.c
+++ b/src/pl/plpgsql/src/pl_handler.c
@@ -172,6 +172,9 @@ plpgsql_inline_handler(PG_FUNCTION_ARGS)
 	/* Compile the anonymous code block */
 	func = plpgsql_compile_inline(codeblock->source_text);
 
+	/* Mark the function as busy, just pro forma */
+	func->use_count++;
+
 	/*
 	 * Set up a fake fcinfo with just enough info to satisfy
 	 * plpgsql_exec_function().  In particular note that this sets things up
@@ -185,6 +188,13 @@ plpgsql_inline_handler(PG_FUNCTION_ARGS)
 
 	retval = plpgsql_exec_function(func, &fake_fcinfo);
 
+	/* Function should now have no remaining use-counts ... */
+	func->use_count--;
+	Assert(func->use_count == 0);
+
+	/* ... so we can free subsidiary storage */
+	plpgsql_free_function_memory(func);
+
 	/*
 	 * Disconnect from SPI manager
 	 */
diff --git a/src/pl/plpgsql/src/plpgsql.h b/src/pl/plpgsql/src/plpgsql.h
index 7015379..9efa982 100644
--- a/src/pl/plpgsql/src/plpgsql.h
+++ b/src/pl/plpgsql/src/plpgsql.h
@@ -693,6 +693,8 @@ typedef struct PLpgSQL_function
 	/* these fields change when the function is used */
 	struct PLpgSQL_execstate *cur_estate;
 	unsigned long use_count;
+
+	List	   *cached_plans;
 } PLpgSQL_function;
 
 
@@ -918,6 +920,7 @@ extern PLpgSQL_nsitem *plpgsql_ns_lookup_label(PLpgSQL_nsitem *ns_cur,
  * ----------
  */
 extern const char *plpgsql_stmt_typename(PLpgSQL_stmt *stmt);
+extern void plpgsql_free_function_memory(PLpgSQL_function *func);
 extern void plpgsql_dumptree(PLpgSQL_function *func);
 
 /* ----------
