From f622c5404905cb998adabe3a3527f7e9cdace229 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 2 Aug 2004 01:30:51 +0000 Subject: Allow DECLARE CURSOR to take parameters from the portal in which it is executed. Previously, the DECLARE would succeed but subsequent FETCHes would fail since the parameter values supplied to DECLARE were not propagated to the portal created for the cursor. In support of this, add type Oids to ParamListInfo entries, which seems like a good idea anyway since code that extracts a value can double-check that it got the type of value it was expecting. Oliver Jowett, with minor editorialization by Tom Lane. --- src/backend/nodes/Makefile | 4 +- src/backend/nodes/params.c | 122 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 124 insertions(+), 2 deletions(-) create mode 100644 src/backend/nodes/params.c (limited to 'src/backend/nodes') diff --git a/src/backend/nodes/Makefile b/src/backend/nodes/Makefile index a4c19201bb2..86f533e7a0e 100644 --- a/src/backend/nodes/Makefile +++ b/src/backend/nodes/Makefile @@ -4,7 +4,7 @@ # Makefile for backend/nodes # # IDENTIFICATION -# $PostgreSQL: pgsql/src/backend/nodes/Makefile,v 1.16 2004/01/07 18:43:36 neilc Exp $ +# $PostgreSQL: pgsql/src/backend/nodes/Makefile,v 1.17 2004/08/02 01:30:42 tgl Exp $ # #------------------------------------------------------------------------- @@ -14,7 +14,7 @@ include $(top_builddir)/src/Makefile.global OBJS = nodeFuncs.o nodes.o list.o bitmapset.o \ copyfuncs.o equalfuncs.o makefuncs.o \ - outfuncs.o readfuncs.o print.o read.o value.o + outfuncs.o readfuncs.o print.o read.o params.o value.o all: SUBSYS.o diff --git a/src/backend/nodes/params.c b/src/backend/nodes/params.c new file mode 100644 index 00000000000..43bc40b9e1c --- /dev/null +++ b/src/backend/nodes/params.c @@ -0,0 +1,122 @@ +/*------------------------------------------------------------------------- + * + * params.c + * Support functions for plan parameter lists. + * + * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * $PostgreSQL: pgsql/src/backend/nodes/params.c,v 1.1 2004/08/02 01:30:42 tgl Exp $ + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include "nodes/params.h" +#include "utils/datum.h" +#include "utils/lsyscache.h" + + +/* + * Copy a ParamList. + * + * The result is allocated in CurrentMemoryContext. + */ +ParamListInfo +copyParamList(ParamListInfo from) +{ + ParamListInfo retval; + int i, size; + + if (from == NULL) + return NULL; + + size = 0; + while (from[size].kind != PARAM_INVALID) + size++; + + retval = (ParamListInfo) palloc0((size + 1) * sizeof(ParamListInfoData)); + + for (i = 0; i < size; i++) { + /* copy metadata */ + retval[i].kind = from[i].kind; + if (from[i].kind == PARAM_NAMED) + retval[i].name = pstrdup(from[i].name); + retval[i].id = from[i].id; + retval[i].ptype = from[i].ptype; + + /* copy value */ + retval[i].isnull = from[i].isnull; + if (from[i].isnull) + { + retval[i].value = from[i].value; /* nulls just copy */ + } + else + { + int16 typLen; + bool typByVal; + + get_typlenbyval(from[i].ptype, &typLen, &typByVal); + retval[i].value = datumCopy(from[i].value, typByVal, typLen); + } + } + + retval[size].kind = PARAM_INVALID; + + return retval; +} + +/* + * Search a ParamList for a given parameter. + * + * On success, returns a pointer to the parameter's entry. + * On failure, returns NULL if noError is true, else ereports the error. + */ +ParamListInfo +lookupParam(ParamListInfo paramList, int thisParamKind, + const char *thisParamName, AttrNumber thisParamId, + bool noError) +{ + if (paramList != NULL) + { + while (paramList->kind != PARAM_INVALID) + { + if (thisParamKind == paramList->kind) + { + switch (thisParamKind) + { + case PARAM_NAMED: + if (strcmp(paramList->name, thisParamName) == 0) + return paramList; + break; + case PARAM_NUM: + if (paramList->id == thisParamId) + return paramList; + break; + default: + elog(ERROR, "unrecognized paramkind: %d", + thisParamKind); + } + } + paramList++; + } + } + + if (!noError) + { + if (thisParamKind == PARAM_NAMED) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("no value found for parameter \"%s\"", + thisParamName))); + else + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("no value found for parameter %d", + thisParamId))); + } + + return NULL; +} -- cgit v1.2.3