| 1 | /*------------------------------------------------------------------------- |
| 2 | * |
| 3 | * params.h |
| 4 | * Support for finding the values associated with Param nodes. |
| 5 | * |
| 6 | * |
| 7 | * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group |
| 8 | * Portions Copyright (c) 1994, Regents of the University of California |
| 9 | * |
| 10 | * src/include/nodes/params.h |
| 11 | * |
| 12 | *------------------------------------------------------------------------- |
| 13 | */ |
| 14 | #ifndef PARAMS_H |
| 15 | #define PARAMS_H |
| 16 | |
| 17 | /* Forward declarations, to avoid including other headers */ |
| 18 | struct Bitmapset; |
| 19 | struct ExprState; |
| 20 | struct Param; |
| 21 | struct ParseState; |
| 22 | |
| 23 | |
| 24 | /* |
| 25 | * ParamListInfo |
| 26 | * |
| 27 | * ParamListInfo structures are used to pass parameters into the executor |
| 28 | * for parameterized plans. We support two basic approaches to supplying |
| 29 | * parameter values, the "static" way and the "dynamic" way. |
| 30 | * |
| 31 | * In the static approach, per-parameter data is stored in an array of |
| 32 | * ParamExternData structs appended to the ParamListInfo struct. |
| 33 | * Each entry in the array defines the value to be substituted for a |
| 34 | * PARAM_EXTERN parameter. The "paramid" of a PARAM_EXTERN Param |
| 35 | * can range from 1 to numParams. |
| 36 | * |
| 37 | * Although parameter numbers are normally consecutive, we allow |
| 38 | * ptype == InvalidOid to signal an unused array entry. |
| 39 | * |
| 40 | * pflags is a flags field. Currently the only used bit is: |
| 41 | * PARAM_FLAG_CONST signals the planner that it may treat this parameter |
| 42 | * as a constant (i.e., generate a plan that works only for this value |
| 43 | * of the parameter). |
| 44 | * |
| 45 | * In the dynamic approach, all access to parameter values is done through |
| 46 | * hook functions found in the ParamListInfo struct. In this case, |
| 47 | * the ParamExternData array is typically unused and not allocated; |
| 48 | * but the legal range of paramid is still 1 to numParams. |
| 49 | * |
| 50 | * Although the data structure is really an array, not a list, we keep |
| 51 | * the old typedef name to avoid unnecessary code changes. |
| 52 | * |
| 53 | * There are 3 hook functions that can be associated with a ParamListInfo |
| 54 | * structure: |
| 55 | * |
| 56 | * If paramFetch isn't null, it is called to fetch the ParamExternData |
| 57 | * for a particular param ID, rather than accessing the relevant element |
| 58 | * of the ParamExternData array. This supports the case where the array |
| 59 | * isn't there at all, as well as cases where the data in the array |
| 60 | * might be obsolete or lazily evaluated. paramFetch must return the |
| 61 | * address of a ParamExternData struct describing the specified param ID; |
| 62 | * the convention above about ptype == InvalidOid signaling an invalid |
| 63 | * param ID still applies. The returned struct can either be placed in |
| 64 | * the "workspace" supplied by the caller, or it can be in storage |
| 65 | * controlled by the paramFetch hook if that's more convenient. |
| 66 | * (In either case, the struct is not expected to be long-lived.) |
| 67 | * If "speculative" is true, the paramFetch hook should not risk errors |
| 68 | * in trying to fetch the parameter value, and should report an invalid |
| 69 | * parameter instead. |
| 70 | * |
| 71 | * If paramCompile isn't null, then it controls what execExpr.c compiles |
| 72 | * for PARAM_EXTERN Param nodes --- typically, this hook would emit a |
| 73 | * EEOP_PARAM_CALLBACK step. This allows unnecessary work to be |
| 74 | * optimized away in compiled expressions. |
| 75 | * |
| 76 | * If parserSetup isn't null, then it is called to re-instantiate the |
| 77 | * original parsing hooks when a query needs to be re-parsed/planned. |
| 78 | * This is especially useful if the types of parameters might change |
| 79 | * from time to time, since it can replace the need to supply a fixed |
| 80 | * list of parameter types to the parser. |
| 81 | * |
| 82 | * Notice that the paramFetch and paramCompile hooks are actually passed |
| 83 | * the ParamListInfo struct's address; they can therefore access all |
| 84 | * three of the "arg" fields, and the distinction between paramFetchArg |
| 85 | * and paramCompileArg is rather arbitrary. |
| 86 | */ |
| 87 | |
| 88 | #define PARAM_FLAG_CONST 0x0001 /* parameter is constant */ |
| 89 | |
| 90 | typedef struct ParamExternData |
| 91 | { |
| 92 | Datum value; /* parameter value */ |
| 93 | bool isnull; /* is it NULL? */ |
| 94 | uint16 pflags; /* flag bits, see above */ |
| 95 | Oid ptype; /* parameter's datatype, or 0 */ |
| 96 | } ParamExternData; |
| 97 | |
| 98 | typedef struct ParamListInfoData *ParamListInfo; |
| 99 | |
| 100 | typedef ParamExternData *(*ParamFetchHook) (ParamListInfo params, |
| 101 | int paramid, bool speculative, |
| 102 | ParamExternData *workspace); |
| 103 | |
| 104 | typedef void (*ParamCompileHook) (ParamListInfo params, struct Param *param, |
| 105 | struct ExprState *state, |
| 106 | Datum *resv, bool *resnull); |
| 107 | |
| 108 | typedef void (*ParserSetupHook) (struct ParseState *pstate, void *arg); |
| 109 | |
| 110 | typedef struct ParamListInfoData |
| 111 | { |
| 112 | ParamFetchHook paramFetch; /* parameter fetch hook */ |
| 113 | void *paramFetchArg; |
| 114 | ParamCompileHook paramCompile; /* parameter compile hook */ |
| 115 | void *paramCompileArg; |
| 116 | ParserSetupHook parserSetup; /* parser setup hook */ |
| 117 | void *parserSetupArg; |
| 118 | int numParams; /* nominal/maximum # of Params represented */ |
| 119 | |
| 120 | /* |
| 121 | * params[] may be of length zero if paramFetch is supplied; otherwise it |
| 122 | * must be of length numParams. |
| 123 | */ |
| 124 | ParamExternData params[FLEXIBLE_ARRAY_MEMBER]; |
| 125 | } ParamListInfoData; |
| 126 | |
| 127 | |
| 128 | /* ---------------- |
| 129 | * ParamExecData |
| 130 | * |
| 131 | * ParamExecData entries are used for executor internal parameters |
| 132 | * (that is, values being passed into or out of a sub-query). The |
| 133 | * paramid of a PARAM_EXEC Param is a (zero-based) index into an |
| 134 | * array of ParamExecData records, which is referenced through |
| 135 | * es_param_exec_vals or ecxt_param_exec_vals. |
| 136 | * |
| 137 | * If execPlan is not NULL, it points to a SubPlanState node that needs |
| 138 | * to be executed to produce the value. (This is done so that we can have |
| 139 | * lazy evaluation of InitPlans: they aren't executed until/unless a |
| 140 | * result value is needed.) Otherwise the value is assumed to be valid |
| 141 | * when needed. |
| 142 | * ---------------- |
| 143 | */ |
| 144 | |
| 145 | typedef struct ParamExecData |
| 146 | { |
| 147 | void *execPlan; /* should be "SubPlanState *" */ |
| 148 | Datum value; |
| 149 | bool isnull; |
| 150 | } ParamExecData; |
| 151 | |
| 152 | |
| 153 | /* Functions found in src/backend/nodes/params.c */ |
| 154 | extern ParamListInfo makeParamList(int numParams); |
| 155 | extern ParamListInfo copyParamList(ParamListInfo from); |
| 156 | extern Size EstimateParamListSpace(ParamListInfo paramLI); |
| 157 | extern void SerializeParamList(ParamListInfo paramLI, char **start_address); |
| 158 | extern ParamListInfo RestoreParamList(char **start_address); |
| 159 | |
| 160 | #endif /* PARAMS_H */ |
| 161 | |