Skip to content

Commit ab20692

Browse files
committed
SPI_cursor_open must copy by-reference parameter values into the
portal's memory context, so that they will live as long as the portal does.
1 parent 6d78fda commit ab20692

File tree

1 file changed

+28
-6
lines changed
  • src/backend/executor

1 file changed

+28
-6
lines changed

src/backend/executor/spi.c

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/executor/spi.c,v 1.63 2001/11/21 18:30:58 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/executor/spi.c,v 1.64 2002/01/03 20:30:47 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -19,6 +19,7 @@
1919
#include "commands/command.h"
2020
#include "executor/spi_priv.h"
2121
#include "tcop/tcopprot.h"
22+
#include "utils/lsyscache.h"
2223

2324

2425
uint32 SPI_processed = 0;
@@ -782,16 +783,34 @@ SPI_cursor_open(char *name, void *plan, Datum *Values, char *Nulls)
782783
/* If the plan has parameters, put them into the executor state */
783784
if (spiplan->nargs > 0)
784785
{
785-
ParamListInfo paramLI = (ParamListInfo) palloc((spiplan->nargs + 1) *
786-
sizeof(ParamListInfoData));
786+
ParamListInfo paramLI;
787+
788+
paramLI = (ParamListInfo) palloc((spiplan->nargs + 1) *
789+
sizeof(ParamListInfoData));
790+
MemSet(paramLI, 0, (spiplan->nargs + 1) * sizeof(ParamListInfoData));
787791

788792
eState->es_param_list_info = paramLI;
789793
for (k = 0; k < spiplan->nargs; paramLI++, k++)
790794
{
791795
paramLI->kind = PARAM_NUM;
792796
paramLI->id = k + 1;
793797
paramLI->isnull = (Nulls && Nulls[k] == 'n');
794-
paramLI->value = Values[k];
798+
if (paramLI->isnull)
799+
{
800+
/* nulls just copy */
801+
paramLI->value = Values[k];
802+
}
803+
else
804+
{
805+
/* pass-by-ref values must be copied into portal context */
806+
int16 paramTypLen;
807+
bool paramTypByVal;
808+
809+
get_typlenbyval(spiplan->argtypes[k],
810+
&paramTypLen, &paramTypByVal);
811+
paramLI->value = datumCopy(Values[k],
812+
paramTypByVal, paramTypLen);
813+
}
795814
}
796815
paramLI->kind = PARAM_INVALID;
797816
}
@@ -1077,8 +1096,11 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, char *Nulls, int tcount)
10771096
state = CreateExecutorState();
10781097
if (nargs > 0)
10791098
{
1080-
ParamListInfo paramLI = (ParamListInfo) palloc((nargs + 1) *
1081-
sizeof(ParamListInfoData));
1099+
ParamListInfo paramLI;
1100+
1101+
paramLI = (ParamListInfo) palloc((nargs + 1) *
1102+
sizeof(ParamListInfoData));
1103+
MemSet(paramLI, 0, (nargs + 1) * sizeof(ParamListInfoData));
10821104

10831105
state->es_param_list_info = paramLI;
10841106
for (k = 0; k < plan->nargs; paramLI++, k++)

0 commit comments

Comments
 (0)