summaryrefslogtreecommitdiff
path: root/src/include/executor/spi_priv.h
diff options
context:
space:
mode:
authorTom Lane2007-03-15 23:12:07 +0000
committerTom Lane2007-03-15 23:12:07 +0000
commit95f6d2d20921b7c2dbec29bf2706fd9448208aa6 (patch)
tree21dcb36f9df60546d82d547a7855605be73a771c /src/include/executor/spi_priv.h
parentd3ff180163a0c88d7a05e0c865f649e5d8bcd6e1 (diff)
Make use of plancache module for SPI plans. In particular, since plpgsql
uses SPI plans, this finally fixes the ancient gotcha that you can't drop and recreate a temp table used by a plpgsql function. Along the way, clean up SPI's API a little bit by declaring SPI plan pointers as "SPIPlanPtr" instead of "void *". This is cosmetic but helps to forestall simple programming mistakes. (I have changed some but not all of the callers to match; there are still some "void *"'s in contrib and the PL's. This is intentional so that we can see if anyone's compiler complains about it.)
Diffstat (limited to 'src/include/executor/spi_priv.h')
-rw-r--r--src/include/executor/spi_priv.h59
1 files changed, 39 insertions, 20 deletions
diff --git a/src/include/executor/spi_priv.h b/src/include/executor/spi_priv.h
index 5e65bd750ae..7ce7d0b0983 100644
--- a/src/include/executor/spi_priv.h
+++ b/src/include/executor/spi_priv.h
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/executor/spi_priv.h,v 1.27 2007/02/20 17:32:17 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/executor/spi_priv.h,v 1.28 2007/03/15 23:12:07 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -16,6 +16,8 @@
#include "executor/spi.h"
+#define _SPI_PLAN_MAGIC 569278163
+
typedef struct
{
/* current results */
@@ -25,29 +27,46 @@ typedef struct
MemoryContext procCxt; /* procedure context */
MemoryContext execCxt; /* executor context */
- MemoryContext savedcxt;
+ MemoryContext savedcxt; /* context of SPI_connect's caller */
SubTransactionId connectSubid; /* ID of connecting subtransaction */
} _SPI_connection;
-typedef struct
+/*
+ * SPI plans have two states: saved or unsaved.
+ *
+ * For an unsaved plan, the _SPI_plan struct and all its subsidiary data are in
+ * a dedicated memory context identified by plancxt. An unsaved plan is good
+ * at most for the current transaction, since the locks that protect it from
+ * schema changes will be lost at end of transaction. Hence the plancxt is
+ * always a transient one.
+ *
+ * For a saved plan, the _SPI_plan struct and the argument type array are in
+ * the plancxt (which can be really small). All the other subsidiary state
+ * is in plancache entries identified by plancache_list (note: the list cells
+ * themselves are in plancxt). We rely on plancache.c to keep the cache
+ * entries up-to-date as needed. The plancxt is a child of CacheMemoryContext
+ * since it should persist until explicitly destroyed.
+ *
+ * To avoid redundant coding, the representation of unsaved plans matches
+ * that of saved plans, ie, plancache_list is a list of CachedPlanSource
+ * structs which in turn point to CachedPlan structs. However, in an unsaved
+ * plan all these structs are just created by spi.c and are not known to
+ * plancache.c. We don't try very hard to make all their fields valid,
+ * only the ones spi.c actually uses.
+ *
+ * Note: if the original query string contained only whitespace and comments,
+ * the plancache_list will be NIL and so there is no place to store the
+ * query string. We don't care about that, but we do care about the
+ * argument type array, which is why it's seemingly-redundantly stored.
+ */
+typedef struct _SPI_plan
{
- /* Context containing _SPI_plan itself as well as subsidiary data */
- MemoryContext plancxt;
- /* Original query string (used for error reporting) */
- const char *query;
- /*
- * List of List of PlannedStmts and utility stmts; one sublist per
- * original parsetree
- */
- List *stmt_list_list;
- /* Argument types, if a prepared plan */
- int nargs;
- Oid *argtypes;
+ int magic; /* should equal _SPI_PLAN_MAGIC */
+ bool saved; /* saved or unsaved plan? */
+ List *plancache_list; /* one CachedPlanSource per parsetree */
+ MemoryContext plancxt; /* Context containing _SPI_plan and data */
+ int nargs; /* number of plan arguments */
+ Oid *argtypes; /* Argument types (NULL if nargs is 0) */
} _SPI_plan;
-
-#define _SPI_CPLAN_CURCXT 0
-#define _SPI_CPLAN_PROCXT 1
-#define _SPI_CPLAN_TOPCXT 2
-
#endif /* SPI_PRIV_H */