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 | |