1 /*------------------------------------------------------------------------- 2 * 3 * spi_priv.h 4 * Server Programming Interface private declarations 5 * 6 * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group 7 * Portions Copyright (c) 1994, Regents of the University of California 8 * 9 * src/include/executor/spi_priv.h 10 * 11 *------------------------------------------------------------------------- 12 */ 13 #ifndef SPI_PRIV_H 14 #define SPI_PRIV_H 15 16 #include "executor/spi.h" 17 18 19 #define _SPI_PLAN_MAGIC 569278163 20 21 typedef struct 22 { 23 /* current results */ 24 uint64 processed; /* by Executor */ 25 Oid lastoid; 26 SPITupleTable *tuptable; /* tuptable currently being built */ 27 28 /* resources of this execution context */ 29 slist_head tuptables; /* list of all live SPITupleTables */ 30 MemoryContext procCxt; /* procedure context */ 31 MemoryContext execCxt; /* executor context */ 32 MemoryContext savedcxt; /* context of SPI_connect's caller */ 33 SubTransactionId connectSubid; /* ID of connecting subtransaction */ 34 35 /* subtransaction in which current Executor call was started */ 36 SubTransactionId execSubid; 37 38 /* saved values of API global variables for previous nesting level */ 39 uint64 outer_processed; 40 Oid outer_lastoid; 41 SPITupleTable *outer_tuptable; 42 int outer_result; 43 } _SPI_connection; 44 45 /* 46 * SPI plans have three states: saved, unsaved, or temporary. 47 * 48 * Ordinarily, the _SPI_plan struct itself as well as the argtypes array 49 * are in a dedicated memory context identified by plancxt (which can be 50 * really small). All the other subsidiary state is in plancache entries 51 * identified by plancache_list (note: the list cells themselves are in 52 * plancxt). 53 * 54 * In an unsaved plan, the plancxt as well as the plancache entries' contexts 55 * are children of the SPI procedure context, so they'll all disappear at 56 * function exit. plancache.c also knows that the plancache entries are 57 * "unsaved", so it doesn't link them into its global list; hence they do 58 * not respond to inval events. This is OK since we are presumably holding 59 * adequate locks to prevent other backends from messing with the tables. 60 * 61 * For a saved plan, the plancxt is made a child of CacheMemoryContext 62 * since it should persist until explicitly destroyed. Likewise, the 63 * plancache entries will be under CacheMemoryContext since we tell 64 * plancache.c to save them. We rely on plancache.c to keep the cache 65 * entries up-to-date as needed in the face of invalidation events. 66 * 67 * There are also "temporary" SPI plans, in which the _SPI_plan struct is 68 * not even palloc'd but just exists in some function's local variable. 69 * The plancache entries are unsaved and exist under the SPI executor context, 70 * while additional data such as argtypes and list cells is loose in the SPI 71 * executor context. Such plans can be identified by having plancxt == NULL. 72 * 73 * We can also have "one-shot" SPI plans (which are typically temporary, 74 * as described above). These are meant to be executed once and discarded, 75 * and various optimizations are made on the assumption of single use. 76 * Note in particular that the CachedPlanSources within such an SPI plan 77 * are not "complete" until execution. 78 * 79 * Note: if the original query string contained only whitespace and comments, 80 * the plancache_list will be NIL and so there is no place to store the 81 * query string. We don't care about that, but we do care about the 82 * argument type array, which is why it's seemingly-redundantly stored. 83 */ 84 typedef struct _SPI_plan 85 { 86 int magic; /* should equal _SPI_PLAN_MAGIC */ 87 bool saved; /* saved or unsaved plan? */ 88 bool oneshot; /* one-shot plan? */ 89 List *plancache_list; /* one CachedPlanSource per parsetree */ 90 MemoryContext plancxt; /* Context containing _SPI_plan and data */ 91 int cursor_options; /* Cursor options used for planning */ 92 int nargs; /* number of plan arguments */ 93 Oid *argtypes; /* Argument types (NULL if nargs is 0) */ 94 ParserSetupHook parserSetup; /* alternative parameter spec method */ 95 void *parserSetupArg; 96 } _SPI_plan; 97 98 #endif /* SPI_PRIV_H */ 99