Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitf622c54

Browse files
committed
Allow DECLARE CURSOR to take parameters from the portal in which it is
executed. Previously, the DECLARE would succeed but subsequent FETCHeswould fail since the parameter values supplied to DECLARE were notpropagated to the portal created for the cursor.In support of this, add type Oids to ParamListInfo entries, which seemslike a good idea anyway since code that extracts a value can double-checkthat it got the type of value it was expecting.Oliver Jowett, with minor editorialization by Tom Lane.
1 parent410b1df commitf622c54

File tree

18 files changed

+263
-115
lines changed

18 files changed

+263
-115
lines changed

‎src/backend/commands/portalcmds.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
*
1515
*
1616
* IDENTIFICATION
17-
* $PostgreSQL: pgsql/src/backend/commands/portalcmds.c,v 1.30 2004/07/31 00:45:31 tgl Exp $
17+
* $PostgreSQL: pgsql/src/backend/commands/portalcmds.c,v 1.31 2004/08/02 01:30:40 tgl Exp $
1818
*
1919
*-------------------------------------------------------------------------
2020
*/
@@ -36,7 +36,7 @@
3636
*Execute SQL DECLARE CURSOR command.
3737
*/
3838
void
39-
PerformCursorOpen(DeclareCursorStmt*stmt)
39+
PerformCursorOpen(DeclareCursorStmt*stmt,ParamListInfoparams)
4040
{
4141
List*rewritten;
4242
Query*query;
@@ -104,6 +104,17 @@ PerformCursorOpen(DeclareCursorStmt *stmt)
104104
list_make1(plan),
105105
PortalGetHeapMemory(portal));
106106

107+
/*
108+
* Also copy the outer portal's parameter list into the inner portal's
109+
* memory context. We want to pass down the parameter values in case
110+
* we had a command like
111+
*DECLARE c CURSOR FOR SELECT ... WHERE foo = $1
112+
* This will have been parsed using the outer parameter set and the
113+
* parameter value needs to be preserved for use when the cursor is
114+
* executed.
115+
*/
116+
params=copyParamList(params);
117+
107118
MemoryContextSwitchTo(oldContext);
108119

109120
/*
@@ -123,9 +134,9 @@ PerformCursorOpen(DeclareCursorStmt *stmt)
123134
}
124135

125136
/*
126-
* Start execution --- never any params for a cursor.
137+
* Start execution, inserting parameters if any.
127138
*/
128-
PortalStart(portal,NULL);
139+
PortalStart(portal,params);
129140

130141
Assert(portal->strategy==PORTAL_ONE_SELECT);
131142

‎src/backend/commands/prepare.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* Copyright (c) 2002-2003, PostgreSQL Global Development Group
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/commands/prepare.c,v 1.28 2004/06/11 01:08:38 tgl Exp $
13+
* $PostgreSQL: pgsql/src/backend/commands/prepare.c,v 1.29 2004/08/02 01:30:40 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -200,7 +200,7 @@ ExecuteQuery(ExecuteStmt *stmt, DestReceiver *dest, char *completionTag)
200200

201201
/*
202202
* Evaluates a list of parameters, using the given executor state. It
203-
* requires a list of the parametervalues themselves, and a list of
203+
* requires a list of the parameterexpressions themselves, and a list of
204204
* their types. It returns a filled-in ParamListInfo -- this can later
205205
* be passed to CreateQueryDesc(), which allows the executor to make use
206206
* of the parameters during query execution.
@@ -211,7 +211,7 @@ EvaluateParams(EState *estate, List *params, List *argtypes)
211211
intnargs=list_length(argtypes);
212212
ParamListInfoparamLI;
213213
List*exprstates;
214-
ListCell*l;
214+
ListCell*le,*la;
215215
inti=0;
216216

217217
/* Parser should have caught this error, but check for safety */
@@ -223,9 +223,9 @@ EvaluateParams(EState *estate, List *params, List *argtypes)
223223
paramLI= (ParamListInfo)
224224
palloc0((nargs+1)*sizeof(ParamListInfoData));
225225

226-
foreach(l,exprstates)
226+
forboth(le,exprstates,la,argtypes)
227227
{
228-
ExprState*n=lfirst(l);
228+
ExprState*n=lfirst(le);
229229
boolisNull;
230230

231231
paramLI[i].value=ExecEvalExprSwitchContext(n,
@@ -234,6 +234,7 @@ EvaluateParams(EState *estate, List *params, List *argtypes)
234234
NULL);
235235
paramLI[i].kind=PARAM_NUM;
236236
paramLI[i].id=i+1;
237+
paramLI[i].ptype=lfirst_oid(la);
237238
paramLI[i].isnull=isNull;
238239

239240
i++;

‎src/backend/commands/schemacmds.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/commands/schemacmds.c,v 1.21 2004/08/01 20:30:48 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/commands/schemacmds.c,v 1.22 2004/08/02 01:30:40 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -168,7 +168,7 @@ CreateSchemaCommand(CreateSchemaStmt *stmt)
168168
/* schemas should contain only utility stmts */
169169
Assert(querytree->commandType==CMD_UTILITY);
170170
/* do this step */
171-
ProcessUtility(querytree->utilityStmt,None_Receiver,NULL);
171+
ProcessUtility(querytree->utilityStmt,NULL,None_Receiver,NULL);
172172
/* make sure later steps can see the object created here */
173173
CommandCounterIncrement();
174174
}

‎src/backend/executor/execQual.c

Lines changed: 12 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.164 2004/06/09 19:08:14 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.165 2004/08/02 01:30:41 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -589,56 +589,18 @@ ExecEvalParam(ExprState *exprstate, ExprContext *econtext,
589589
else
590590
{
591591
/*
592-
* All other parameter types must be sought in
593-
* ecxt_param_list_info. NOTE: The last entry in the param array
594-
* is always an entry with kind == PARAM_INVALID.
592+
* All other parameter types must be sought in ecxt_param_list_info.
595593
*/
596-
ParamListInfoparamList=econtext->ecxt_param_list_info;
597-
char*thisParamName=expression->paramname;
598-
boolmatchFound= false;
599-
600-
if (paramList!=NULL)
601-
{
602-
while (paramList->kind!=PARAM_INVALID&& !matchFound)
603-
{
604-
if (thisParamKind==paramList->kind)
605-
{
606-
switch (thisParamKind)
607-
{
608-
casePARAM_NAMED:
609-
if (strcmp(paramList->name,thisParamName)==0)
610-
matchFound= true;
611-
break;
612-
casePARAM_NUM:
613-
if (paramList->id==thisParamId)
614-
matchFound= true;
615-
break;
616-
default:
617-
elog(ERROR,"unrecognized paramkind: %d",
618-
thisParamKind);
619-
}
620-
}
621-
if (!matchFound)
622-
paramList++;
623-
}/* while */
624-
}/* if */
625-
626-
if (!matchFound)
627-
{
628-
if (thisParamKind==PARAM_NAMED)
629-
ereport(ERROR,
630-
(errcode(ERRCODE_UNDEFINED_OBJECT),
631-
errmsg("no value found for parameter \"%s\"",
632-
thisParamName)));
633-
else
634-
ereport(ERROR,
635-
(errcode(ERRCODE_UNDEFINED_OBJECT),
636-
errmsg("no value found for parameter %d",
637-
thisParamId)));
638-
}
639-
640-
*isNull=paramList->isnull;
641-
returnparamList->value;
594+
ParamListInfoparamInfo;
595+
596+
paramInfo=lookupParam(econtext->ecxt_param_list_info,
597+
thisParamKind,
598+
expression->paramname,
599+
thisParamId,
600+
false);
601+
Assert(paramInfo->ptype==expression->paramtype);
602+
*isNull=paramInfo->isnull;
603+
returnparamInfo->value;
642604
}
643605
}
644606

‎src/backend/executor/functions.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.83 2004/07/15 13:51:38 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.84 2004/08/02 01:30:41 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -58,6 +58,7 @@ typedef struct local_es
5858
*/
5959
typedefstruct
6060
{
61+
Oid*argtypes;/* resolved types of arguments */
6162
Oidrettype;/* actual return type */
6263
inttyplen;/* length of the return type */
6364
booltypbyval;/* true if return type is pass by value */
@@ -223,6 +224,7 @@ init_sql_fcache(FmgrInfo *finfo)
223224
}
224225
else
225226
argOidVect=NULL;
227+
fcache->argtypes=argOidVect;
226228

227229
tmp=SysCacheGetAttr(PROCOID,
228230
procedureTuple,
@@ -283,7 +285,8 @@ postquel_getnext(execution_state *es)
283285

284286
if (es->qd->operation==CMD_UTILITY)
285287
{
286-
ProcessUtility(es->qd->parsetree->utilityStmt,es->qd->dest,NULL);
288+
ProcessUtility(es->qd->parsetree->utilityStmt,es->qd->params,
289+
es->qd->dest,NULL);
287290
returnNULL;
288291
}
289292

@@ -332,6 +335,7 @@ postquel_sub_params(SQLFunctionCachePtr fcache,
332335
{
333336
paramLI[i].kind=PARAM_NUM;
334337
paramLI[i].id=i+1;
338+
paramLI[i].ptype=fcache->argtypes[i];
335339
paramLI[i].value=fcinfo->arg[i];
336340
paramLI[i].isnull=fcinfo->argnull[i];
337341
}

‎src/backend/executor/spi.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.122 2004/07/31 20:55:41 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.123 2004/08/02 01:30:41 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -820,6 +820,7 @@ SPI_cursor_open(const char *name, void *plan, Datum *Values, const char *Nulls)
820820
{
821821
paramLI[k].kind=PARAM_NUM;
822822
paramLI[k].id=k+1;
823+
paramLI[k].ptype=spiplan->argtypes[k];
823824
paramLI[k].isnull= (Nulls&&Nulls[k]=='n');
824825
if (paramLI[k].isnull)
825826
{
@@ -1251,7 +1252,7 @@ _SPI_execute(const char *src, int tcount, _SPI_plan *plan)
12511252
res=SPI_OK_UTILITY;
12521253
if (plan==NULL)
12531254
{
1254-
ProcessUtility(queryTree->utilityStmt,dest,NULL);
1255+
ProcessUtility(queryTree->utilityStmt,NULL,dest,NULL);
12551256
CommandCounterIncrement();
12561257
}
12571258
}
@@ -1319,6 +1320,7 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, const char *Nulls,
13191320
{
13201321
paramLI[k].kind=PARAM_NUM;
13211322
paramLI[k].id=k+1;
1323+
paramLI[k].ptype=plan->argtypes[k];
13221324
paramLI[k].isnull= (Nulls&&Nulls[k]=='n');
13231325
paramLI[k].value=Values[k];
13241326
}
@@ -1366,7 +1368,7 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, const char *Nulls,
13661368
dest=CreateDestReceiver(queryTree->canSetTag ?SPI :None,NULL);
13671369
if (queryTree->commandType==CMD_UTILITY)
13681370
{
1369-
ProcessUtility(queryTree->utilityStmt,dest,NULL);
1371+
ProcessUtility(queryTree->utilityStmt,paramLI,dest,NULL);
13701372
res=SPI_OK_UTILITY;
13711373
CommandCounterIncrement();
13721374
}

‎src/backend/nodes/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# Makefile for backend/nodes
55
#
66
# IDENTIFICATION
7-
# $PostgreSQL: pgsql/src/backend/nodes/Makefile,v 1.16 2004/01/07 18:43:36 neilc Exp $
7+
# $PostgreSQL: pgsql/src/backend/nodes/Makefile,v 1.17 2004/08/02 01:30:42 tgl Exp $
88
#
99
#-------------------------------------------------------------------------
1010

@@ -14,7 +14,7 @@ include $(top_builddir)/src/Makefile.global
1414

1515
OBJS = nodeFuncs.o nodes.o list.o bitmapset.o\
1616
copyfuncs.o equalfuncs.o makefuncs.o\
17-
outfuncs.o readfuncs.o print.o read.o value.o
17+
outfuncs.o readfuncs.o print.o read.oparams.ovalue.o
1818

1919
all: SUBSYS.o
2020

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp