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

Commit0053ceb

Browse files
committed
Fix coredump in plpgsql when trying to return a rowtype result.
Need to return a TupleTableSlot, not just a bare tuple.
1 parentea08e6c commit0053ceb

File tree

4 files changed

+206
-35
lines changed

4 files changed

+206
-35
lines changed

‎doc/src/sgml/spi.sgml

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,6 +1272,135 @@ TBD
12721272
<!-- *********************************************** -->
12731273
<!-- *********************************************** -->
12741274

1275+
<REFENTRY ID="SPI-SPICOPYTUPLEINTOSLOT">
1276+
<REFMETA>
1277+
<REFENTRYTITLE>SPI_copytupleintoslot</REFENTRYTITLE>
1278+
<REFMISCINFO>SPI - Tuple and Descriptor Copy</REFMISCINFO>
1279+
</REFMETA>
1280+
<REFNAMEDIV>
1281+
<REFNAME>SPI_copytupleintoslot
1282+
</REFNAME>
1283+
<REFPURPOSE>
1284+
Makes copy of tuple and descriptor in upper Executor context
1285+
</REFPURPOSE>
1286+
<INDEXTERM ID="IX-SPI-SPICOPYTUPLEINTOSLOT-1"><PRIMARY>SPI</PRIMARY><SECONDARY>copying tuples</SECONDARY></INDEXTERM>
1287+
<INDEXTERM ID="IX-SPI-SPICOPYTUPLEINTOSLOT-2"><PRIMARY>SPI_copytupleintoslot</PRIMARY></INDEXTERM>
1288+
</REFNAMEDIV>
1289+
<REFSYNOPSISDIV>
1290+
<REFSYNOPSISDIVINFO>
1291+
<DATE>1997-12-24</DATE>
1292+
</REFSYNOPSISDIVINFO>
1293+
<SYNOPSIS>
1294+
SPI_copytupleintoslot(<REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>)
1295+
</SYNOPSIS>
1296+
1297+
<REFSECT2 ID="R2-SPI-SPICOPYTUPLEINTOSLOT-1">
1298+
<REFSECT2INFO>
1299+
<DATE>1997-12-24</DATE>
1300+
</REFSECT2INFO>
1301+
<TITLE>Inputs
1302+
</TITLE>
1303+
<VARIABLELIST>
1304+
<VARLISTENTRY>
1305+
<TERM>
1306+
HeapTuple <REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>
1307+
</TERM>
1308+
<LISTITEM>
1309+
<PARA>
1310+
Input tuple to be copied
1311+
</PARA>
1312+
</LISTITEM>
1313+
</VARLISTENTRY>
1314+
<VARLISTENTRY>
1315+
<TERM>
1316+
TupleDesc <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>
1317+
</TERM>
1318+
<LISTITEM>
1319+
<PARA>
1320+
Input tuple descriptor to be copied
1321+
</PARA>
1322+
</LISTITEM>
1323+
</VARLISTENTRY>
1324+
</VARIABLELIST>
1325+
</REFSECT2>
1326+
1327+
<REFSECT2 ID="R2-SPI-SPICOPYTUPLEINTOSLOT-2">
1328+
<REFSECT2INFO>
1329+
<DATE>1997-12-24</DATE>
1330+
</REFSECT2INFO>
1331+
<TITLE>Outputs
1332+
</TITLE>
1333+
<VARIABLELIST>
1334+
<VARLISTENTRY>
1335+
<TERM>
1336+
TupleTableSlot *
1337+
</TERM>
1338+
<LISTITEM>
1339+
<PARA>
1340+
Tuple slot containing copied tuple and descriptor
1341+
<SimpleList>
1342+
<Member>
1343+
<ReturnValue>non-NULL</ReturnValue>
1344+
if <REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>
1345+
and <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>
1346+
are not NULL and the copy was successful
1347+
</Member>
1348+
<Member>
1349+
<ReturnValue>NULL</ReturnValue>
1350+
only if <REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>
1351+
or <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>
1352+
is NULL
1353+
</Member>
1354+
</SimpleList>
1355+
</para>
1356+
</LISTITEM>
1357+
</VARLISTENTRY>
1358+
</VARIABLELIST>
1359+
</REFSECT2>
1360+
</REFSYNOPSISDIV>
1361+
1362+
<REFSECT1 ID="R1-SPI-SPICOPYTUPLEINTOSLOT-1">
1363+
<REFSECT1INFO>
1364+
<DATE>1997-12-24</DATE>
1365+
</REFSECT1INFO>
1366+
<TITLE>Description
1367+
</TITLE>
1368+
<PARA>
1369+
<FUNCTION>SPI_copytupleintoslot</FUNCTION>
1370+
makes a copy of tuple in upper Executor context, returning it in the
1371+
form of a filled-in TupleTableSlot.
1372+
See the section on Memory Management.
1373+
</PARA>
1374+
</REFSECT1>
1375+
<REFSECT1 ID="R1-SPI-SPICOPYTUPLEINTOSLOT-2">
1376+
<TITLE>Usage
1377+
</TITLE>
1378+
<Para>
1379+
TBD
1380+
</PARA>
1381+
</REFSECT1>
1382+
<!--
1383+
<REFSECT1 ID="R1-SPI-SPICOPYTUPLEINTOSLOT-3">
1384+
<TITLE>Algorithm
1385+
</TITLE>
1386+
<PARA>
1387+
</PARA>
1388+
</REFSECT1>
1389+
-->
1390+
<!--
1391+
<REFSECT1 ID="R1-SPI-SPICOPYTUPLEINTOSLOT-4">
1392+
<TITLE>Structures
1393+
</TITLE>
1394+
<PARA>None
1395+
</PARA>
1396+
</REFSECT1>
1397+
-->
1398+
</REFENTRY>
1399+
1400+
<!-- *********************************************** -->
1401+
<!-- *********************************************** -->
1402+
<!-- *********************************************** -->
1403+
12751404
<REFENTRY ID="SPI-SPIMODIFYTUPLE">
12761405
<REFMETA>
12771406
<REFENTRYTITLE>SPI_modifytuple</REFENTRYTITLE>
@@ -2695,6 +2824,7 @@ made in this context.
26952824
<Function>palloc</Function>/<Function>repalloc</Function> or by SPI utility
26962825
functions (except for <Function>SPI_copytuple</Function>,
26972826
<Function>SPI_copytupledesc</Function>,
2827+
<Function>SPI_copytupleintoslot</Function>,
26982828
<Function>SPI_modifytuple</Function>,
26992829
<Function>SPI_palloc</Function> and <Function>SPI_repalloc</Function>) are
27002830
made in this context.

‎src/backend/executor/spi.c

Lines changed: 35 additions & 1 deletion
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.60 2001/10/25 05:49:29 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/executor/spi.c,v 1.61 2001/11/05 19:41:56 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -360,6 +360,40 @@ SPI_copytupledesc(TupleDesc tupdesc)
360360
returnctupdesc;
361361
}
362362

363+
TupleTableSlot*
364+
SPI_copytupleintoslot(HeapTupletuple,TupleDesctupdesc)
365+
{
366+
MemoryContextoldcxt=NULL;
367+
TupleTableSlot*cslot;
368+
HeapTuplectuple;
369+
TupleDescctupdesc;
370+
371+
if (tuple==NULL||tupdesc==NULL)
372+
{
373+
SPI_result=SPI_ERROR_ARGUMENT;
374+
returnNULL;
375+
}
376+
377+
if (_SPI_curid+1==_SPI_connected)/* connected */
378+
{
379+
if (_SPI_current!=&(_SPI_stack[_SPI_curid+1]))
380+
elog(FATAL,"SPI: stack corrupted");
381+
oldcxt=MemoryContextSwitchTo(_SPI_current->savedcxt);
382+
}
383+
384+
ctuple=heap_copytuple(tuple);
385+
ctupdesc=CreateTupleDescCopy(tupdesc);
386+
387+
cslot=MakeTupleTableSlot();
388+
ExecSetSlotDescriptor(cslot,ctupdesc, true);
389+
cslot=ExecStoreTuple(ctuple,cslot,InvalidBuffer, true);
390+
391+
if (oldcxt)
392+
MemoryContextSwitchTo(oldcxt);
393+
394+
returncslot;
395+
}
396+
363397
HeapTuple
364398
SPI_modifytuple(Relationrel,HeapTupletuple,intnatts,int*attnum,
365399
Datum*Values,char*Nulls)

‎src/include/executor/spi.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
*
33
* spi.h
44
*
5-
* $Id: spi.h,v 1.31 2001/11/0517:46:33 momjian Exp $
5+
* $Id: spi.h,v 1.32 2001/11/0519:41:56 tgl Exp $
66
*
77
*-------------------------------------------------------------------------
88
*/
@@ -89,6 +89,8 @@ extern intSPI_freeplan(void *plan);
8989

9090
externHeapTupleSPI_copytuple(HeapTupletuple);
9191
externTupleDescSPI_copytupledesc(TupleDesctupdesc);
92+
externTupleTableSlot*SPI_copytupleintoslot(HeapTupletuple,
93+
TupleDesctupdesc);
9294
externHeapTupleSPI_modifytuple(Relationrel,HeapTupletuple,intnatts,
9395
int*attnum,Datum*Values,char*Nulls);
9496
externintSPI_fnumber(TupleDesctupdesc,char*fname);

‎src/pl/plpgsql/src/pl_exec.c

Lines changed: 38 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* procedural language
44
*
55
* IDENTIFICATION
6-
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.48 2001/10/25 05:50:20 momjian Exp $
6+
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.49 2001/11/05 19:41:56 tgl Exp $
77
*
88
* This software is copyrighted by Jan Wieck - Hamburg.
99
*
@@ -400,32 +400,43 @@ plpgsql_exec_function(PLpgSQL_function * func, FunctionCallInfo fcinfo)
400400

401401
fcinfo->isnull=estate.retisnull;
402402

403-
if (!estate.retistuple)
403+
if (!estate.retisnull)
404404
{
405-
estate.retval=exec_cast_value(estate.retval,estate.rettype,
406-
func->fn_rettype,
407-
&(func->fn_retinput),
408-
func->fn_rettypelem,
409-
-1,
410-
&fcinfo->isnull);
411-
412-
/*
413-
* If the functions return type isn't by value, copy the value
414-
* into upper executor memory context.
415-
*/
416-
if (!fcinfo->isnull&& !func->fn_retbyval)
405+
if (estate.retistuple)
406+
{
407+
/* Copy tuple to upper executor memory */
408+
/* Here we need to return a TupleTableSlot not just a tuple */
409+
estate.retval= (Datum)
410+
SPI_copytupleintoslot((HeapTuple) (estate.retval),
411+
estate.rettupdesc);
412+
}
413+
else
417414
{
418-
intlen;
419-
Datumtmp;
415+
/* Cast value to proper type */
416+
estate.retval=exec_cast_value(estate.retval,estate.rettype,
417+
func->fn_rettype,
418+
&(func->fn_retinput),
419+
func->fn_rettypelem,
420+
-1,
421+
&fcinfo->isnull);
422+
/*
423+
* If the functions return type isn't by value, copy the value
424+
* into upper executor memory context.
425+
*/
426+
if (!fcinfo->isnull&& !func->fn_retbyval)
427+
{
428+
intlen;
429+
Datumtmp;
420430

421-
if (func->fn_rettyplen<0)
422-
len=VARSIZE(estate.retval);
423-
else
424-
len=func->fn_rettyplen;
431+
if (func->fn_rettyplen<0)
432+
len=VARSIZE(estate.retval);
433+
else
434+
len=func->fn_rettyplen;
425435

426-
tmp= (Datum)SPI_palloc(len);
427-
memcpy((void*)tmp, (void*)estate.retval,len);
428-
estate.retval=tmp;
436+
tmp= (Datum)SPI_palloc(len);
437+
memcpy((void*)tmp, (void*)estate.retval,len);
438+
estate.retval=tmp;
439+
}
429440
}
430441
}
431442

@@ -1619,8 +1630,8 @@ exec_stmt_return(PLpgSQL_execstate * estate, PLpgSQL_stmt_return * stmt)
16191630

16201631
if (HeapTupleIsValid(rec->tup))
16211632
{
1622-
estate->retval= (Datum)SPI_copytuple(rec->tup);
1623-
estate->rettupdesc=SPI_copytupledesc(rec->tupdesc);
1633+
estate->retval= (Datum)rec->tup;
1634+
estate->rettupdesc=rec->tupdesc;
16241635
estate->retisnull= false;
16251636
}
16261637
returnPLPGSQL_RC_RETURN;
@@ -1631,16 +1642,10 @@ exec_stmt_return(PLpgSQL_execstate * estate, PLpgSQL_stmt_return * stmt)
16311642
exec_run_select(estate,stmt->expr,1,NULL);
16321643
if (estate->eval_processed>0)
16331644
{
1634-
estate->retval= (Datum)SPI_copytuple(estate->eval_tuptable->vals[0]);
1635-
estate->rettupdesc=SPI_copytupledesc(estate->eval_tuptable->tupdesc);
1645+
estate->retval= (Datum)estate->eval_tuptable->vals[0];
1646+
estate->rettupdesc=estate->eval_tuptable->tupdesc;
16361647
estate->retisnull= false;
16371648
}
1638-
1639-
/*
1640-
* Okay to clean up here, since we already copied result tuple
1641-
* to upper executor.
1642-
*/
1643-
exec_eval_cleanup(estate);
16441649
}
16451650
returnPLPGSQL_RC_RETURN;
16461651
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp