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

Commit3576820

Browse files
committed
Ensure that a cursor is scanned under the same scanCommandId it was
originally created with, so that the set of visible tuples does notchange as a result of other activity. This essentially makes PG cursorsINSENSITIVE per the SQL92 definition. See bug report of 13-Feb-02.
1 parent1392042 commit3576820

File tree

4 files changed

+48
-13
lines changed

4 files changed

+48
-13
lines changed

‎src/backend/commands/command.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.152 2002/01/03 23:19:30 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.153 2002/02/14 15:24:06 tgl Exp $
1212
*
1313
* NOTES
1414
* The PerformAddAttribute() code, like most of the relation
@@ -103,6 +103,7 @@ PerformPortalFetch(char *name,
103103
QueryDesc*queryDesc;
104104
EState*estate;
105105
MemoryContextoldcontext;
106+
CommandIdsavedId;
106107
booltemp_desc= false;
107108

108109
/*
@@ -156,7 +157,7 @@ PerformPortalFetch(char *name,
156157
}
157158

158159
/*
159-
*tell the destination to prepare to receive some tuples.
160+
*Tell the destination to prepare to receive some tuples.
160161
*/
161162
BeginCommand(name,
162163
queryDesc->operation,
@@ -168,6 +169,14 @@ PerformPortalFetch(char *name,
168169
tag,
169170
queryDesc->dest);
170171

172+
/*
173+
* Restore the scanCommandId that was current when the cursor was
174+
* opened. This ensures that we see the same tuples throughout the
175+
* execution of the cursor.
176+
*/
177+
savedId=GetScanCommandId();
178+
SetScanCommandId(PortalGetCommandId(portal));
179+
171180
/*
172181
* Determine which direction to go in, and check to see if we're
173182
* already at the end of the available tuples in that direction. If
@@ -214,6 +223,11 @@ PerformPortalFetch(char *name,
214223
}
215224
}
216225

226+
/*
227+
* Restore outer command ID.
228+
*/
229+
SetScanCommandId(savedId);
230+
217231
/*
218232
* Clean up and switch back to old context.
219233
*/

‎src/backend/executor/spi.c

Lines changed: 24 additions & 7 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.64 2002/01/03 20:30:47 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/executor/spi.c,v 1.65 2002/02/14 15:24:08 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -740,9 +740,9 @@ SPI_cursor_open(char *name, void *plan, Datum *Values, char *Nulls)
740740
_SPI_current->processed=0;
741741
_SPI_current->tuptable=NULL;
742742

743-
/* Make up a portal name if none given */
744743
if (name==NULL)
745744
{
745+
/* Make up a portal name if none given */
746746
for (;;)
747747
{
748748
unnamed_portal_count++;
@@ -755,11 +755,13 @@ SPI_cursor_open(char *name, void *plan, Datum *Values, char *Nulls)
755755

756756
name=portalname;
757757
}
758-
759-
/* Ensure the portal doesn't exist already */
760-
portal=GetPortalByName(name);
761-
if (portal!=NULL)
762-
elog(ERROR,"cursor \"%s\" already in use",name);
758+
else
759+
{
760+
/* Ensure the portal doesn't exist already */
761+
portal=GetPortalByName(name);
762+
if (portal!=NULL)
763+
elog(ERROR,"cursor \"%s\" already in use",name);
764+
}
763765

764766
/* Create the portal */
765767
portal=CreatePortal(name);
@@ -1228,6 +1230,7 @@ _SPI_cursor_operation(Portal portal, bool forward, int count,
12281230
QueryDesc*querydesc;
12291231
EState*estate;
12301232
MemoryContextoldcontext;
1233+
CommandIdsavedId;
12311234
CommandDestolddest;
12321235

12331236
/* Check that the portal is valid */
@@ -1245,6 +1248,7 @@ _SPI_cursor_operation(Portal portal, bool forward, int count,
12451248

12461249
/* Switch to the portals memory context */
12471250
oldcontext=MemoryContextSwitchTo(PortalGetHeapMemory(portal));
1251+
12481252
querydesc=PortalGetQueryDesc(portal);
12491253
estate=PortalGetState(portal);
12501254

@@ -1253,6 +1257,14 @@ _SPI_cursor_operation(Portal portal, bool forward, int count,
12531257
olddest=querydesc->dest;
12541258
querydesc->dest=dest;
12551259

1260+
/*
1261+
* Restore the scanCommandId that was current when the cursor was
1262+
* opened. This ensures that we see the same tuples throughout the
1263+
* execution of the cursor.
1264+
*/
1265+
savedId=GetScanCommandId();
1266+
SetScanCommandId(PortalGetCommandId(portal));
1267+
12561268
/* Run the executor like PerformPortalFetch and remember states */
12571269
if (forward)
12581270
{
@@ -1279,6 +1291,11 @@ _SPI_cursor_operation(Portal portal, bool forward, int count,
12791291
}
12801292
}
12811293

1294+
/*
1295+
* Restore outer command ID.
1296+
*/
1297+
SetScanCommandId(savedId);
1298+
12821299
/* Restore the old command destination and switch back to callers */
12831300
/* memory context */
12841301
querydesc->dest=olddest;

‎src/backend/utils/mmgr/portalmem.c

Lines changed: 3 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/utils/mmgr/portalmem.c,v 1.44 2001/10/25 05:49:51 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/mmgr/portalmem.c,v 1.45 2002/02/14 15:24:09 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -168,6 +168,7 @@ PortalSetQuery(Portal portal,
168168

169169
portal->queryDesc=queryDesc;
170170
portal->attinfo=attinfo;
171+
portal->commandId=GetScanCommandId();
171172
portal->state=state;
172173
portal->atStart= true;/* Allow fetch forward only */
173174
portal->atEnd= false;
@@ -213,6 +214,7 @@ CreatePortal(char *name)
213214
/* initialize portal query */
214215
portal->queryDesc=NULL;
215216
portal->attinfo=NULL;
217+
portal->commandId=0;
216218
portal->state=NULL;
217219
portal->atStart= true;/* disallow fetches until query is set */
218220
portal->atEnd= true;

‎src/include/utils/portal.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Id: portal.h,v 1.31 2001/11/05 17:46:36 momjian Exp $
10+
* $Id: portal.h,v 1.32 2002/02/14 15:24:10 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -31,6 +31,7 @@ typedef struct PortalData
3131
MemoryContextheap;/* subsidiary memory */
3232
QueryDesc*queryDesc;/* Info about query associated with portal */
3333
TupleDescattinfo;
34+
CommandIdcommandId;/* Command counter value for query */
3435
EState*state;/* Execution state of query */
3536
boolatStart;/* T => fetch backwards is not allowed */
3637
boolatEnd;/* T => fetch forwards is not allowed */
@@ -48,8 +49,9 @@ typedef struct PortalData
4849
*/
4950
#definePortalGetQueryDesc(portal)((portal)->queryDesc)
5051
#definePortalGetTupleDesc(portal)((portal)->attinfo)
51-
#definePortalGetState(portal)((portal)->state)
52-
#definePortalGetHeapMemory(portal) ((portal)->heap)
52+
#definePortalGetCommandId(portal)((portal)->commandId)
53+
#definePortalGetState(portal)((portal)->state)
54+
#definePortalGetHeapMemory(portal)((portal)->heap)
5355

5456
/*
5557
* estimate of the maximum number of open portals a user would have,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp