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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy