diff options
| author | Tom Lane | 2007-03-15 23:12:07 +0000 |
|---|---|---|
| committer | Tom Lane | 2007-03-15 23:12:07 +0000 |
| commit | 95f6d2d20921b7c2dbec29bf2706fd9448208aa6 (patch) | |
| tree | 21dcb36f9df60546d82d547a7855605be73a771c /src/include/executor/spi_priv.h | |
| parent | d3ff180163a0c88d7a05e0c865f649e5d8bcd6e1 (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.h | 59 |
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 */ |
