mirror of
https://github.com/postgres/postgres.git
synced 2025-12-19 17:02:53 +03:00
parse analysis phase, rather than at execution time. This makes parameter handling work the same as it does in ordinary plannable queries, and in particular fixes the incompatibility that Pavel pointed out with plpgsql's new handling of variable references. plancache.c gets a little bit grottier, but the alternatives seem worse.
78 lines
2.1 KiB
C
78 lines
2.1 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* params.c
|
|
* Support for finding the values associated with Param nodes.
|
|
*
|
|
*
|
|
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
*
|
|
* IDENTIFICATION
|
|
* $PostgreSQL: pgsql/src/backend/nodes/params.c,v 1.14 2010/01/15 22:36:31 tgl Exp $
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
|
|
#include "postgres.h"
|
|
|
|
#include "nodes/params.h"
|
|
#include "parser/parse_param.h"
|
|
#include "utils/datum.h"
|
|
#include "utils/lsyscache.h"
|
|
|
|
|
|
/*
|
|
* Copy a ParamListInfo structure.
|
|
*
|
|
* The result is allocated in CurrentMemoryContext.
|
|
*
|
|
* Note: the intent of this function is to make a static, self-contained
|
|
* set of parameter values. If dynamic parameter hooks are present, we
|
|
* intentionally do not copy them into the result. Rather, we forcibly
|
|
* instantiate all available parameter values and copy the datum values.
|
|
*/
|
|
ParamListInfo
|
|
copyParamList(ParamListInfo from)
|
|
{
|
|
ParamListInfo retval;
|
|
Size size;
|
|
int i;
|
|
|
|
if (from == NULL || from->numParams <= 0)
|
|
return NULL;
|
|
|
|
/* sizeof(ParamListInfoData) includes the first array element */
|
|
size = sizeof(ParamListInfoData) +
|
|
(from->numParams - 1) *sizeof(ParamExternData);
|
|
|
|
retval = (ParamListInfo) palloc(size);
|
|
retval->paramFetch = NULL;
|
|
retval->paramFetchArg = NULL;
|
|
retval->parserSetup = NULL;
|
|
retval->parserSetupArg = NULL;
|
|
retval->numParams = from->numParams;
|
|
|
|
for (i = 0; i < from->numParams; i++)
|
|
{
|
|
ParamExternData *oprm = &from->params[i];
|
|
ParamExternData *nprm = &retval->params[i];
|
|
int16 typLen;
|
|
bool typByVal;
|
|
|
|
/* give hook a chance in case parameter is dynamic */
|
|
if (!OidIsValid(oprm->ptype) && from->paramFetch != NULL)
|
|
(*from->paramFetch) (from, i+1);
|
|
|
|
/* flat-copy the parameter info */
|
|
*nprm = *oprm;
|
|
|
|
/* need datumCopy in case it's a pass-by-reference datatype */
|
|
if (nprm->isnull || !OidIsValid(nprm->ptype))
|
|
continue;
|
|
get_typlenbyval(nprm->ptype, &typLen, &typByVal);
|
|
nprm->value = datumCopy(nprm->value, typByVal, typLen);
|
|
}
|
|
|
|
return retval;
|
|
}
|