aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2004-08-02 01:30:51 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2004-08-02 01:30:51 +0000
commitf622c5404905cb998adabe3a3527f7e9cdace229 (patch)
treebc65d3f7d71a9a8c09945e7072bbca2baeb937a3 /src/backend/executor
parent410b1dfb885f5b6d60f89003baba32a4efe93225 (diff)
downloadpostgresql-f622c5404905cb998adabe3a3527f7e9cdace229.tar.gz
postgresql-f622c5404905cb998adabe3a3527f7e9cdace229.zip
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.
Diffstat (limited to 'src/backend/executor')
-rw-r--r--src/backend/executor/execQual.c62
-rw-r--r--src/backend/executor/functions.c8
-rw-r--r--src/backend/executor/spi.c8
3 files changed, 23 insertions, 55 deletions
diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c
index e4362c38f58..6ac61d3c5be 100644
--- a/src/backend/executor/execQual.c
+++ b/src/backend/executor/execQual.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.164 2004/06/09 19:08:14 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.165 2004/08/02 01:30:41 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -589,56 +589,18 @@ ExecEvalParam(ExprState *exprstate, ExprContext *econtext,
else
{
/*
- * All other parameter types must be sought in
- * ecxt_param_list_info. NOTE: The last entry in the param array
- * is always an entry with kind == PARAM_INVALID.
+ * All other parameter types must be sought in ecxt_param_list_info.
*/
- ParamListInfo paramList = econtext->ecxt_param_list_info;
- char *thisParamName = expression->paramname;
- bool matchFound = false;
-
- if (paramList != NULL)
- {
- while (paramList->kind != PARAM_INVALID && !matchFound)
- {
- if (thisParamKind == paramList->kind)
- {
- switch (thisParamKind)
- {
- case PARAM_NAMED:
- if (strcmp(paramList->name, thisParamName) == 0)
- matchFound = true;
- break;
- case PARAM_NUM:
- if (paramList->id == thisParamId)
- matchFound = true;
- break;
- default:
- elog(ERROR, "unrecognized paramkind: %d",
- thisParamKind);
- }
- }
- if (!matchFound)
- paramList++;
- } /* while */
- } /* if */
-
- if (!matchFound)
- {
- 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)));
- }
-
- *isNull = paramList->isnull;
- return paramList->value;
+ ParamListInfo paramInfo;
+
+ paramInfo = lookupParam(econtext->ecxt_param_list_info,
+ thisParamKind,
+ expression->paramname,
+ thisParamId,
+ false);
+ Assert(paramInfo->ptype == expression->paramtype);
+ *isNull = paramInfo->isnull;
+ return paramInfo->value;
}
}
diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c
index 0073f8f55c1..cfcccb6169e 100644
--- a/src/backend/executor/functions.c
+++ b/src/backend/executor/functions.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.83 2004/07/15 13:51:38 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.84 2004/08/02 01:30:41 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -58,6 +58,7 @@ typedef struct local_es
*/
typedef struct
{
+ Oid *argtypes; /* resolved types of arguments */
Oid rettype; /* actual return type */
int typlen; /* length of the return type */
bool typbyval; /* true if return type is pass by value */
@@ -223,6 +224,7 @@ init_sql_fcache(FmgrInfo *finfo)
}
else
argOidVect = NULL;
+ fcache->argtypes = argOidVect;
tmp = SysCacheGetAttr(PROCOID,
procedureTuple,
@@ -283,7 +285,8 @@ postquel_getnext(execution_state *es)
if (es->qd->operation == CMD_UTILITY)
{
- ProcessUtility(es->qd->parsetree->utilityStmt, es->qd->dest, NULL);
+ ProcessUtility(es->qd->parsetree->utilityStmt, es->qd->params,
+ es->qd->dest, NULL);
return NULL;
}
@@ -332,6 +335,7 @@ postquel_sub_params(SQLFunctionCachePtr fcache,
{
paramLI[i].kind = PARAM_NUM;
paramLI[i].id = i + 1;
+ paramLI[i].ptype = fcache->argtypes[i];
paramLI[i].value = fcinfo->arg[i];
paramLI[i].isnull = fcinfo->argnull[i];
}
diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c
index 7840f5f787a..33379d52222 100644
--- a/src/backend/executor/spi.c
+++ b/src/backend/executor/spi.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.122 2004/07/31 20:55:41 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.123 2004/08/02 01:30:41 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -820,6 +820,7 @@ SPI_cursor_open(const char *name, void *plan, Datum *Values, const char *Nulls)
{
paramLI[k].kind = PARAM_NUM;
paramLI[k].id = k + 1;
+ paramLI[k].ptype = spiplan->argtypes[k];
paramLI[k].isnull = (Nulls && Nulls[k] == 'n');
if (paramLI[k].isnull)
{
@@ -1251,7 +1252,7 @@ _SPI_execute(const char *src, int tcount, _SPI_plan *plan)
res = SPI_OK_UTILITY;
if (plan == NULL)
{
- ProcessUtility(queryTree->utilityStmt, dest, NULL);
+ ProcessUtility(queryTree->utilityStmt, NULL, dest, NULL);
CommandCounterIncrement();
}
}
@@ -1319,6 +1320,7 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, const char *Nulls,
{
paramLI[k].kind = PARAM_NUM;
paramLI[k].id = k + 1;
+ paramLI[k].ptype = plan->argtypes[k];
paramLI[k].isnull = (Nulls && Nulls[k] == 'n');
paramLI[k].value = Values[k];
}
@@ -1366,7 +1368,7 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, const char *Nulls,
dest = CreateDestReceiver(queryTree->canSetTag ? SPI : None, NULL);
if (queryTree->commandType == CMD_UTILITY)
{
- ProcessUtility(queryTree->utilityStmt, dest, NULL);
+ ProcessUtility(queryTree->utilityStmt, paramLI, dest, NULL);
res = SPI_OK_UTILITY;
CommandCounterIncrement();
}