1/*-------------------------------------------------------------------------
4 * Support for finding the values associated with Param nodes.
7 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
11 * src/backend/nodes/params.c
13 *-------------------------------------------------------------------------
34 * Allocate and initialize a new ParamListInfo structure.
36 * To make a new structure for the "dynamic" way (with hooks), pass 0 for
37 * numParams and set numParams manually.
39 * A default parserSetup function is supplied automatically. Callers may
40 * override it if they choose. (Note that most use-cases for ParamListInfos
41 * will never use the parserSetup function anyway.)
66 * Copy a ParamListInfo structure.
68 * The result is allocated in CurrentMemoryContext.
70 * Note: the intent of this function is to make a static, self-contained
71 * set of parameter values. If dynamic parameter hooks are present, we
72 * intentionally do not copy them into the result. Rather, we forcibly
73 * instantiate all available parameter values and copy the datum values.
75 * paramValuesStr is not copied, either.
95 /* give hook a chance in case parameter is dynamic */
97 oprm = from->
paramFetch(from,
i + 1,
false, &prmdata);
101 /* flat-copy the parameter info */
104 /* need datumCopy in case it's a pass-by-reference datatype */
116 * Set up to parse a query containing references to parameters
117 * sourced from a ParamListInfo.
123 /* no need to use p_coerce_param_hook */
128 * Transform a ParamRef using parameter type data from a ParamListInfo.
134 int paramno = pref->
number;
139 /* check parameter number is valid */
143 /* give hook a chance in case parameter is dynamic */
145 prm = paramLI->
paramFetch(paramLI, paramno,
false, &prmdata);
147 prm = ¶mLI->
params[paramno - 1];
154 param->paramid = paramno;
155 param->paramtype = prm->ptype;
156 param->paramtypmod = -1;
160 return (
Node *) param;
164 * Estimate the amount of space required to serialize a ParamListInfo.
170 Size sz =
sizeof(int);
172 if (paramLI == NULL || paramLI->
numParams <= 0)
183 /* give hook a chance in case parameter is dynamic */
185 prm = paramLI->
paramFetch(paramLI,
i + 1,
false, &prmdata);
189 typeOid = prm->
ptype;
191 sz =
add_size(sz,
sizeof(
Oid));
/* space for type OID */
194 /* space for datum/isnull */
199 /* If no type OID, assume by-value, like copyParamList does. */
200 typLen =
sizeof(
Datum);
211 * Serialize a ParamListInfo structure into caller-provided storage.
213 * We write the number of parameters first, as a 4-byte integer, and then
214 * write details for each parameter in turn. The details for each parameter
215 * consist of a 4-byte type OID, 2 bytes of flags, and then the datum as
216 * serialized by datumSerialize(). The caller is responsible for ensuring
217 * that there is enough storage to store the number of bytes that will be
218 * written; use EstimateParamListSpace to find out how many will be needed.
219 * *start_address is updated to point to the byte immediately following those
222 * RestoreParamList can be used to recreate a ParamListInfo based on the
223 * serialized representation; this will be a static, self-contained copy
224 * just as copyParamList would create.
226 * paramValuesStr is not included.
234 /* Write number of parameters. */
235 if (paramLI == NULL || paramLI->
numParams <= 0)
239 memcpy(*start_address, &nparams,
sizeof(
int));
240 *start_address +=
sizeof(int);
242 /* Write each parameter in turn. */
243 for (
i = 0;
i < nparams;
i++)
251 /* give hook a chance in case parameter is dynamic */
253 prm = paramLI->
paramFetch(paramLI,
i + 1,
false, &prmdata);
257 typeOid = prm->
ptype;
259 /* Write type OID. */
260 memcpy(*start_address, &typeOid,
sizeof(
Oid));
261 *start_address +=
sizeof(
Oid);
265 *start_address +=
sizeof(
uint16);
267 /* Write datum/isnull. */
272 /* If no type OID, assume by-value, like copyParamList does. */
273 typLen =
sizeof(
Datum);
282 * Copy a ParamListInfo structure.
284 * The result is allocated in CurrentMemoryContext.
286 * Note: the intent of this function is to make a static, self-contained
287 * set of parameter values. If dynamic parameter hooks are present, we
288 * intentionally do not copy them into the result. Rather, we forcibly
289 * instantiate all available parameter values and copy the datum values.
297 memcpy(&nparams, *start_address,
sizeof(
int));
298 *start_address +=
sizeof(int);
302 for (
int i = 0;
i < nparams;
i++)
307 memcpy(&prm->
ptype, *start_address,
sizeof(
Oid));
308 *start_address +=
sizeof(
Oid);
312 *start_address +=
sizeof(
uint16);
314 /* Read datum/isnull. */
322 * BuildParamLogString
323 * Return a string that represents the parameter list, for logging.
325 * If caller already knows textual representations for some parameters, it can
326 * pass an array of exactly params->numParams values as knownTextValues, which
327 * can contain NULLs for any unknown individual values. NULL can be given if
328 * no parameters are known.
330 * If maxlen is >= 0, that's the maximum number of bytes of any one
331 * parameter value to be printed; an ellipsis is added if the string is
332 * longer. (Added quotes are not considered in this calculation.)
342 * NB: think not of returning params->paramValuesStr! It may have been
343 * generated with a different maxlen, and so be unsuitable. Besides that,
344 * this is the function used to create that string.
348 * No work if the param fetch hook is in use. Also, it's not possible to
349 * do this in an aborted transaction. (It might be possible to improve on
350 * this last point when some knownTextValues exist, but it seems tricky.)
356 /* Initialize the output stringinfo, in caller's memory context */
359 /* Use a temporary context to call output functions, just in case */
361 "BuildParamLogString",
365 for (
int paramno = 0; paramno < params->
numParams; paramno++)
371 paramno > 0 ?
", " :
"",
378 if (knownTextValues != NULL && knownTextValues[paramno] != NULL)
401 * ParamsErrorCallback - callback for printing parameters in error context
403 * Note that this is a no-op unless BuildParamLogString has been called
412 data->params == NULL ||
413 data->params->paramValuesStr == NULL)
416 if (
data->portalName &&
data->portalName[0] !=
'0円')
417 errcontext(
"portal \"%s\" with parameters: %s",
418 data->portalName,
data->params->paramValuesStr);
420 errcontext(
"unnamed portal with parameters: %s",
421 data->params->paramValuesStr);
#define OidIsValid(objectId)
Datum datumCopy(Datum value, bool typByVal, int typLen)
Datum datumRestore(char **start_address, bool *isnull)
void datumSerialize(Datum value, bool isnull, bool typByVal, int typLen, char **start_address)
Size datumEstimateSpace(Datum value, bool isnull, bool typByVal, int typLen)
char * OidOutputFunctionCall(Oid functionId, Datum val)
if(TABLE==NULL||TABLE_index==NULL)
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
Oid get_typcollation(Oid typid)
MemoryContext CurrentMemoryContext
void MemoryContextDelete(MemoryContext context)
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
ParamListInfo makeParamList(int numParams)
ParamListInfo copyParamList(ParamListInfo from)
static Node * paramlist_param_ref(ParseState *pstate, ParamRef *pref)
static void paramlist_parser_setup(ParseState *pstate, void *arg)
Size EstimateParamListSpace(ParamListInfo paramLI)
char * BuildParamLogString(ParamListInfo params, char **knownTextValues, int maxlen)
void SerializeParamList(ParamListInfo paramLI, char **start_address)
void ParamsErrorCallback(void *arg)
ParamListInfo RestoreParamList(char **start_address)
struct ParamListInfoData * ParamListInfo
struct ParamExternData ParamExternData
Size add_size(Size s1, Size s2)
void appendStringInfo(StringInfo str, const char *fmt,...)
void appendStringInfoString(StringInfo str, const char *s)
void initStringInfo(StringInfo str)
void appendStringInfoStringQuoted(StringInfo str, const char *s, int maxlen)
ParamExternData params[FLEXIBLE_ARRAY_MEMBER]
ParserSetupHook parserSetup
ParamCompileHook paramCompile
ParamFetchHook paramFetch
ParseParamRefHook p_paramref_hook
bool IsAbortedTransactionBlockState(void)