mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-15 08:20:16 +08:00
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.
This commit is contained in:
parent
6d78fdae7f
commit
ab20692e1e
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/executor/spi.c,v 1.63 2001/11/21 18:30:58 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/executor/spi.c,v 1.64 2002/01/03 20:30:47 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -19,6 +19,7 @@
|
|||||||
#include "commands/command.h"
|
#include "commands/command.h"
|
||||||
#include "executor/spi_priv.h"
|
#include "executor/spi_priv.h"
|
||||||
#include "tcop/tcopprot.h"
|
#include "tcop/tcopprot.h"
|
||||||
|
#include "utils/lsyscache.h"
|
||||||
|
|
||||||
|
|
||||||
uint32 SPI_processed = 0;
|
uint32 SPI_processed = 0;
|
||||||
@ -782,8 +783,11 @@ SPI_cursor_open(char *name, void *plan, Datum *Values, char *Nulls)
|
|||||||
/* If the plan has parameters, put them into the executor state */
|
/* If the plan has parameters, put them into the executor state */
|
||||||
if (spiplan->nargs > 0)
|
if (spiplan->nargs > 0)
|
||||||
{
|
{
|
||||||
ParamListInfo paramLI = (ParamListInfo) palloc((spiplan->nargs + 1) *
|
ParamListInfo paramLI;
|
||||||
|
|
||||||
|
paramLI = (ParamListInfo) palloc((spiplan->nargs + 1) *
|
||||||
sizeof(ParamListInfoData));
|
sizeof(ParamListInfoData));
|
||||||
|
MemSet(paramLI, 0, (spiplan->nargs + 1) * sizeof(ParamListInfoData));
|
||||||
|
|
||||||
eState->es_param_list_info = paramLI;
|
eState->es_param_list_info = paramLI;
|
||||||
for (k = 0; k < spiplan->nargs; paramLI++, k++)
|
for (k = 0; k < spiplan->nargs; paramLI++, k++)
|
||||||
@ -791,8 +795,23 @@ SPI_cursor_open(char *name, void *plan, Datum *Values, char *Nulls)
|
|||||||
paramLI->kind = PARAM_NUM;
|
paramLI->kind = PARAM_NUM;
|
||||||
paramLI->id = k + 1;
|
paramLI->id = k + 1;
|
||||||
paramLI->isnull = (Nulls && Nulls[k] == 'n');
|
paramLI->isnull = (Nulls && Nulls[k] == 'n');
|
||||||
|
if (paramLI->isnull)
|
||||||
|
{
|
||||||
|
/* nulls just copy */
|
||||||
paramLI->value = Values[k];
|
paramLI->value = Values[k];
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* pass-by-ref values must be copied into portal context */
|
||||||
|
int16 paramTypLen;
|
||||||
|
bool paramTypByVal;
|
||||||
|
|
||||||
|
get_typlenbyval(spiplan->argtypes[k],
|
||||||
|
¶mTypLen, ¶mTypByVal);
|
||||||
|
paramLI->value = datumCopy(Values[k],
|
||||||
|
paramTypByVal, paramTypLen);
|
||||||
|
}
|
||||||
|
}
|
||||||
paramLI->kind = PARAM_INVALID;
|
paramLI->kind = PARAM_INVALID;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1077,8 +1096,11 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, char *Nulls, int tcount)
|
|||||||
state = CreateExecutorState();
|
state = CreateExecutorState();
|
||||||
if (nargs > 0)
|
if (nargs > 0)
|
||||||
{
|
{
|
||||||
ParamListInfo paramLI = (ParamListInfo) palloc((nargs + 1) *
|
ParamListInfo paramLI;
|
||||||
|
|
||||||
|
paramLI = (ParamListInfo) palloc((nargs + 1) *
|
||||||
sizeof(ParamListInfoData));
|
sizeof(ParamListInfoData));
|
||||||
|
MemSet(paramLI, 0, (nargs + 1) * sizeof(ParamListInfoData));
|
||||||
|
|
||||||
state->es_param_list_info = paramLI;
|
state->es_param_list_info = paramLI;
|
||||||
for (k = 0; k < plan->nargs; paramLI++, k++)
|
for (k = 0; k < plan->nargs; paramLI++, k++)
|
||||||
|
Loading…
Reference in New Issue
Block a user