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