diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2002-02-14 15:24:10 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2002-02-14 15:24:10 +0000 |
commit | 3576820e7852ab20d552fe5aa7abb2847db62f6f (patch) | |
tree | 207f056de4c5e95b5000b119c4d6e0d8b0380ffa /src/backend/executor/spi.c | |
parent | 13920423466a345e832ed844e9513ad2eed43731 (diff) |
Ensure that a cursor is scanned under the same scanCommandId it was
originally created with, so that the set of visible tuples does not
change as a result of other activity. This essentially makes PG cursors
INSENSITIVE per the SQL92 definition. See bug report of 13-Feb-02.
Diffstat (limited to 'src/backend/executor/spi.c')
-rw-r--r-- | src/backend/executor/spi.c | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index 064b0255222..b9ab6422658 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.64 2002/01/03 20:30:47 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/spi.c,v 1.65 2002/02/14 15:24:08 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -740,9 +740,9 @@ SPI_cursor_open(char *name, void *plan, Datum *Values, char *Nulls) _SPI_current->processed = 0; _SPI_current->tuptable = NULL; - /* Make up a portal name if none given */ if (name == NULL) { + /* Make up a portal name if none given */ for (;;) { unnamed_portal_count++; @@ -755,11 +755,13 @@ SPI_cursor_open(char *name, void *plan, Datum *Values, char *Nulls) name = portalname; } - - /* Ensure the portal doesn't exist already */ - portal = GetPortalByName(name); - if (portal != NULL) - elog(ERROR, "cursor \"%s\" already in use", name); + else + { + /* Ensure the portal doesn't exist already */ + portal = GetPortalByName(name); + if (portal != NULL) + elog(ERROR, "cursor \"%s\" already in use", name); + } /* Create the portal */ portal = CreatePortal(name); @@ -1228,6 +1230,7 @@ _SPI_cursor_operation(Portal portal, bool forward, int count, QueryDesc *querydesc; EState *estate; MemoryContext oldcontext; + CommandId savedId; CommandDest olddest; /* Check that the portal is valid */ @@ -1245,6 +1248,7 @@ _SPI_cursor_operation(Portal portal, bool forward, int count, /* Switch to the portals memory context */ oldcontext = MemoryContextSwitchTo(PortalGetHeapMemory(portal)); + querydesc = PortalGetQueryDesc(portal); estate = PortalGetState(portal); @@ -1253,6 +1257,14 @@ _SPI_cursor_operation(Portal portal, bool forward, int count, olddest = querydesc->dest; querydesc->dest = dest; + /* + * Restore the scanCommandId that was current when the cursor was + * opened. This ensures that we see the same tuples throughout the + * execution of the cursor. + */ + savedId = GetScanCommandId(); + SetScanCommandId(PortalGetCommandId(portal)); + /* Run the executor like PerformPortalFetch and remember states */ if (forward) { @@ -1279,6 +1291,11 @@ _SPI_cursor_operation(Portal portal, bool forward, int count, } } + /* + * Restore outer command ID. + */ + SetScanCommandId(savedId); + /* Restore the old command destination and switch back to callers */ /* memory context */ querydesc->dest = olddest; |