00001 /*------------------------------------------------------------------------- 00002 * 00003 * params.c 00004 * Support for finding the values associated with Param nodes. 00005 * 00006 * 00007 * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group 00008 * Portions Copyright (c) 1994, Regents of the University of California 00009 * 00010 * IDENTIFICATION 00011 * src/backend/nodes/params.c 00012 * 00013 *------------------------------------------------------------------------- 00014 */ 00015 00016 #include "postgres.h" 00017 00018 #include "nodes/params.h" 00019 #include "utils/datum.h" 00020 #include "utils/lsyscache.h" 00021 00022 00023 /* 00024 * Copy a ParamListInfo structure. 00025 * 00026 * The result is allocated in CurrentMemoryContext. 00027 * 00028 * Note: the intent of this function is to make a static, self-contained 00029 * set of parameter values. If dynamic parameter hooks are present, we 00030 * intentionally do not copy them into the result. Rather, we forcibly 00031 * instantiate all available parameter values and copy the datum values. 00032 */ 00033 ParamListInfo 00034 copyParamList(ParamListInfo from) 00035 { 00036 ParamListInfo retval; 00037 Size size; 00038 int i; 00039 00040 if (from == NULL || from->numParams <= 0) 00041 return NULL; 00042 00043 /* sizeof(ParamListInfoData) includes the first array element */ 00044 size = sizeof(ParamListInfoData) + 00045 (from->numParams - 1) * sizeof(ParamExternData); 00046 00047 retval = (ParamListInfo) palloc(size); 00048 retval->paramFetch = NULL; 00049 retval->paramFetchArg = NULL; 00050 retval->parserSetup = NULL; 00051 retval->parserSetupArg = NULL; 00052 retval->numParams = from->numParams; 00053 00054 for (i = 0; i < from->numParams; i++) 00055 { 00056 ParamExternData *oprm = &from->params[i]; 00057 ParamExternData *nprm = &retval->params[i]; 00058 int16 typLen; 00059 bool typByVal; 00060 00061 /* give hook a chance in case parameter is dynamic */ 00062 if (!OidIsValid(oprm->ptype) && from->paramFetch != NULL) 00063 (*from->paramFetch) (from, i + 1); 00064 00065 /* flat-copy the parameter info */ 00066 *nprm = *oprm; 00067 00068 /* need datumCopy in case it's a pass-by-reference datatype */ 00069 if (nprm->isnull || !OidIsValid(nprm->ptype)) 00070 continue; 00071 get_typlenbyval(nprm->ptype, &typLen, &typByVal); 00072 nprm->value = datumCopy(nprm->value, typByVal, typLen); 00073 } 00074 00075 return retval; 00076 }