00001 /*------------------------------------------------------------------------- 00002 * 00003 * spi_priv.h 00004 * Server Programming Interface private declarations 00005 * 00006 * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group 00007 * Portions Copyright (c) 1994, Regents of the University of California 00008 * 00009 * src/include/executor/spi_priv.h 00010 * 00011 *------------------------------------------------------------------------- 00012 */ 00013 #ifndef SPI_PRIV_H 00014 #define SPI_PRIV_H 00015 00016 #include "executor/spi.h" 00017 00018 00019 #define _SPI_PLAN_MAGIC 569278163 00020 00021 typedef struct 00022 { 00023 /* current results */ 00024 uint32 processed; /* by Executor */ 00025 Oid lastoid; 00026 SPITupleTable *tuptable; 00027 00028 MemoryContext procCxt; /* procedure context */ 00029 MemoryContext execCxt; /* executor context */ 00030 MemoryContext savedcxt; /* context of SPI_connect's caller */ 00031 SubTransactionId connectSubid; /* ID of connecting subtransaction */ 00032 } _SPI_connection; 00033 00034 /* 00035 * SPI plans have three states: saved, unsaved, or temporary. 00036 * 00037 * Ordinarily, the _SPI_plan struct itself as well as the argtypes array 00038 * are in a dedicated memory context identified by plancxt (which can be 00039 * really small). All the other subsidiary state is in plancache entries 00040 * identified by plancache_list (note: the list cells themselves are in 00041 * plancxt). 00042 * 00043 * In an unsaved plan, the plancxt as well as the plancache entries' contexts 00044 * are children of the SPI procedure context, so they'll all disappear at 00045 * function exit. plancache.c also knows that the plancache entries are 00046 * "unsaved", so it doesn't link them into its global list; hence they do 00047 * not respond to inval events. This is OK since we are presumably holding 00048 * adequate locks to prevent other backends from messing with the tables. 00049 * 00050 * For a saved plan, the plancxt is made a child of CacheMemoryContext 00051 * since it should persist until explicitly destroyed. Likewise, the 00052 * plancache entries will be under CacheMemoryContext since we tell 00053 * plancache.c to save them. We rely on plancache.c to keep the cache 00054 * entries up-to-date as needed in the face of invalidation events. 00055 * 00056 * There are also "temporary" SPI plans, in which the _SPI_plan struct is 00057 * not even palloc'd but just exists in some function's local variable. 00058 * The plancache entries are unsaved and exist under the SPI executor context, 00059 * while additional data such as argtypes and list cells is loose in the SPI 00060 * executor context. Such plans can be identified by having plancxt == NULL. 00061 * 00062 * We can also have "one-shot" SPI plans (which are typically temporary, 00063 * as described above). These are meant to be executed once and discarded, 00064 * and various optimizations are made on the assumption of single use. 00065 * Note in particular that the CachedPlanSources within such an SPI plan 00066 * are not "complete" until execution. 00067 * 00068 * Note: if the original query string contained only whitespace and comments, 00069 * the plancache_list will be NIL and so there is no place to store the 00070 * query string. We don't care about that, but we do care about the 00071 * argument type array, which is why it's seemingly-redundantly stored. 00072 */ 00073 typedef struct _SPI_plan 00074 { 00075 int magic; /* should equal _SPI_PLAN_MAGIC */ 00076 bool saved; /* saved or unsaved plan? */ 00077 bool oneshot; /* one-shot plan? */ 00078 List *plancache_list; /* one CachedPlanSource per parsetree */ 00079 MemoryContext plancxt; /* Context containing _SPI_plan and data */ 00080 int cursor_options; /* Cursor options used for planning */ 00081 int nargs; /* number of plan arguments */ 00082 Oid *argtypes; /* Argument types (NULL if nargs is 0) */ 00083 ParserSetupHook parserSetup; /* alternative parameter spec method */ 00084 void *parserSetupArg; 00085 } _SPI_plan; 00086 00087 #endif /* SPI_PRIV_H */