aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/spi.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2003-08-08 19:18:21 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2003-08-08 19:18:21 +0000
commit332c694085611df78ddc58dfcd46f43e6bb088aa (patch)
tree42ed31490b5f326a680998c2c2d8df40ed73bd3c /src/backend/executor/spi.c
parent4ae02fd03ea12cdedbcb124a2ff1df5b6c19816c (diff)
downloadpostgresql-332c694085611df78ddc58dfcd46f43e6bb088aa.tar.gz
postgresql-332c694085611df78ddc58dfcd46f43e6bb088aa.zip
Fix nasty little order-of-operations bug in _SPI_cursor_operation.
Per report from Mendola Gaetano.
Diffstat (limited to 'src/backend/executor/spi.c')
-rw-r--r--src/backend/executor/spi.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c
index 064f64c6838..985b966d5d1 100644
--- a/src/backend/executor/spi.c
+++ b/src/backend/executor/spi.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/spi.c,v 1.101 2003/08/04 02:39:59 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/spi.c,v 1.102 2003/08/08 19:18:21 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1263,6 +1263,8 @@ static void
_SPI_cursor_operation(Portal portal, bool forward, int count,
DestReceiver *dest)
{
+ long nfetched;
+
/* Check that the portal is valid */
if (!PortalIsValid(portal))
elog(ERROR, "invalid portal in SPI cursor operation");
@@ -1277,11 +1279,20 @@ _SPI_cursor_operation(Portal portal, bool forward, int count,
_SPI_current->tuptable = NULL;
/* Run the cursor */
- _SPI_current->processed =
- PortalRunFetch(portal,
- forward ? FETCH_FORWARD : FETCH_BACKWARD,
- (long) count,
- dest);
+ nfetched = PortalRunFetch(portal,
+ forward ? FETCH_FORWARD : FETCH_BACKWARD,
+ (long) count,
+ dest);
+
+ /*
+ * Think not to combine this store with the preceding function call.
+ * If the portal contains calls to functions that use SPI, then
+ * SPI_stack is likely to move around while the portal runs. When
+ * control returns, _SPI_current will point to the correct stack entry...
+ * but the pointer may be different than it was beforehand. So we must
+ * be sure to re-fetch the pointer after the function call completes.
+ */
+ _SPI_current->processed = nfetched;
if (dest->mydest == SPI && _SPI_checktuples())
elog(ERROR, "consistency check on SPI tuple count failed");