greenplumn params 源码

  • 2022-08-18
  • 浏览 (255)

greenplumn params 代码

文件路径:/src/backend/nodes/params.c

/*-------------------------------------------------------------------------
 *
 * params.c
 *	  Support for finding the values associated with Param nodes.
 *
 *
 * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * IDENTIFICATION
 *	  src/backend/nodes/params.c
 *
 *-------------------------------------------------------------------------
 */

#include "postgres.h"

#include "nodes/bitmapset.h"
#include "nodes/params.h"
#include "storage/shmem.h"
#include "utils/datum.h"
#include "utils/lsyscache.h"


/*
 * Allocate and initialize a new ParamListInfo structure.
 *
 * To make a new structure for the "dynamic" way (with hooks), pass 0 for
 * numParams and set numParams manually.
 */
ParamListInfo
makeParamList(int numParams)
{
	ParamListInfo retval;
	Size		size;

	size = offsetof(ParamListInfoData, params) +
		numParams * sizeof(ParamExternData);

	retval = (ParamListInfo) palloc(size);
	retval->paramFetch = NULL;
	retval->paramFetchArg = NULL;
	retval->paramCompile = NULL;
	retval->paramCompileArg = NULL;
	retval->parserSetup = NULL;
	retval->parserSetupArg = NULL;
	retval->numParams = numParams;

	return retval;
}

/*
 * 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;

	if (from == NULL || from->numParams <= 0)
		return NULL;

	retval = makeParamList(from->numParams);

	for (int i = 0; i < from->numParams; i++)
	{
		ParamExternData *oprm;
		ParamExternData *nprm = &retval->params[i];
		ParamExternData prmdata;
		int16		typLen;
		bool		typByVal;

		/* give hook a chance in case parameter is dynamic */
		if (from->paramFetch != NULL)
			oprm = from->paramFetch(from, i + 1, false, &prmdata);
		else
			oprm = &from->params[i];

		/* 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;
}

/*
 * Estimate the amount of space required to serialize a ParamListInfo.
 */
Size
EstimateParamListSpace(ParamListInfo paramLI)
{
	int			i;
	Size		sz = sizeof(int);

	if (paramLI == NULL || paramLI->numParams <= 0)
		return sz;

	for (i = 0; i < paramLI->numParams; i++)
	{
		ParamExternData *prm;
		ParamExternData prmdata;
		Oid			typeOid;
		int16		typLen;
		bool		typByVal;

		/* give hook a chance in case parameter is dynamic */
		if (paramLI->paramFetch != NULL)
			prm = paramLI->paramFetch(paramLI, i + 1, false, &prmdata);
		else
			prm = &paramLI->params[i];

		typeOid = prm->ptype;

		sz = add_size(sz, sizeof(Oid)); /* space for type OID */
		sz = add_size(sz, sizeof(uint16));	/* space for pflags */

		/* space for datum/isnull */
		if (OidIsValid(typeOid))
			get_typlenbyval(typeOid, &typLen, &typByVal);
		else
		{
			/* If no type OID, assume by-value, like copyParamList does. */
			typLen = sizeof(Datum);
			typByVal = true;
		}
		sz = add_size(sz,
					  datumEstimateSpace(prm->value, prm->isnull, typByVal, typLen));
	}

	return sz;
}

/*
 * Serialize a paramListInfo structure into caller-provided storage.
 *
 * We write the number of parameters first, as a 4-byte integer, and then
 * write details for each parameter in turn.  The details for each parameter
 * consist of a 4-byte type OID, 2 bytes of flags, and then the datum as
 * serialized by datumSerialize().  The caller is responsible for ensuring
 * that there is enough storage to store the number of bytes that will be
 * written; use EstimateParamListSpace to find out how many will be needed.
 * *start_address is updated to point to the byte immediately following those
 * written.
 *
 * RestoreParamList can be used to recreate a ParamListInfo based on the
 * serialized representation; this will be a static, self-contained copy
 * just as copyParamList would create.
 */
void
SerializeParamList(ParamListInfo paramLI, char **start_address)
{
	int			nparams;
	int			i;

	/* Write number of parameters. */
	if (paramLI == NULL || paramLI->numParams <= 0)
		nparams = 0;
	else
		nparams = paramLI->numParams;
	memcpy(*start_address, &nparams, sizeof(int));
	*start_address += sizeof(int);

	/* Write each parameter in turn. */
	for (i = 0; i < nparams; i++)
	{
		ParamExternData *prm;
		ParamExternData prmdata;
		Oid			typeOid;
		int16		typLen;
		bool		typByVal;

		/* give hook a chance in case parameter is dynamic */
		if (paramLI->paramFetch != NULL)
			prm = paramLI->paramFetch(paramLI, i + 1, false, &prmdata);
		else
			prm = &paramLI->params[i];

		typeOid = prm->ptype;

		/* Write type OID. */
		memcpy(*start_address, &typeOid, sizeof(Oid));
		*start_address += sizeof(Oid);

		/* Write flags. */
		memcpy(*start_address, &prm->pflags, sizeof(uint16));
		*start_address += sizeof(uint16);

		/* Write datum/isnull. */
		if (OidIsValid(typeOid))
			get_typlenbyval(typeOid, &typLen, &typByVal);
		else
		{
			/* If no type OID, assume by-value, like copyParamList does. */
			typLen = sizeof(Datum);
			typByVal = true;
		}
		datumSerialize(prm->value, prm->isnull, typByVal, typLen,
					   start_address);
	}
}

/*
 * 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
RestoreParamList(char **start_address)
{
	ParamListInfo paramLI;
	int			nparams;

	memcpy(&nparams, *start_address, sizeof(int));
	*start_address += sizeof(int);

	paramLI = makeParamList(nparams);

	for (int i = 0; i < nparams; i++)
	{
		ParamExternData *prm = &paramLI->params[i];

		/* Read type OID. */
		memcpy(&prm->ptype, *start_address, sizeof(Oid));
		*start_address += sizeof(Oid);

		/* Read flags. */
		memcpy(&prm->pflags, *start_address, sizeof(uint16));
		*start_address += sizeof(uint16);

		/* Read datum/isnull. */
		prm->value = datumRestore(start_address, &prm->isnull);
	}

	return paramLI;
}

相关信息

greenplumn 源码目录

相关文章

greenplumn bitmapset 源码

greenplumn copyfuncs 源码

greenplumn equalfuncs 源码

greenplumn extensible 源码

greenplumn list 源码

greenplumn makefuncs 源码

greenplumn nodeFuncs 源码

greenplumn nodes 源码

greenplumn outfast 源码

greenplumn outfuncs 源码

0  赞