Re: [HACKERS] MOVE strangeness - Mailing list pgsql-patches
From | Bruce Momjian |
---|---|
Subject | Re: [HACKERS] MOVE strangeness |
Date | |
Msg-id | 200212271403.gBRE3Ki04490@candle.pha.pa.us Whole thread Raw |
Responses |
Re: [HACKERS] MOVE strangeness
|
List | pgsql-patches |
Tom Lane wrote: > Bruce Momjian <pgman@candle.pha.pa.us> writes: > > Sorry, I am not understanding. If he does: > > ... > > here, isn't he sitting at the start of the fourth row, no? > > No. He is sitting *on* the third row. If he now does FETCH 1, he will > advance to and return the fourth row; on the other hand, if he does > FETCH -1, he will back up to and return the second row. > > The cursor must be considered to be positioned on its current row, not > between rows, or the SQL-defined operations UPDATE WHERE CURRENT OF and > DELETE WHERE CURRENT OF don't make any sense. (We don't support those > yet, but we should someday.) > > BTW, looking at Date and the SQL spec, I now realize that the recently > made change to convert FETCH 0 into a no-op is wrong; per spec, FETCH > RELATIVE 0 means "re-fetch the current row, if any". By analogy, MOVE 0 > should probably return "MOVE 1" if you are on a real row, "MOVE 0" if > you are not, corresponding to the number of rows you'd have gotten from > FETCH 0. Ugly, but ... OK, patch attached. The patch also makes the cursor offset a long from the parser into the executor. The tuple counter is already a long in the executor. test=> CREATE TABLE test (x int); insert into testCREATE TABLE test=> INSERT INTO test VALUES (1); INSERT 149758 1 test=> BEGIN; BEGIN test=> DECLARE xx CURSOR FOR SELECT * FROM test; DECLARE CURSOR test=> MOVE 0 FROM xx; MOVE 0 test=> FETCH 1 FROM xx; x --- 1 (1 row) test=> MOVE 0 FROM xx; MOVE 1 test=> FETCH 0 FROM xx; x --- 1 (1 row) test=> FETCH 1 FROM xx; x --- (0 rows) test=> MOVE 0 FROM xx; MOVE 0 -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 359-1001 + If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania 19073 Index: src/backend/commands/portalcmds.c =================================================================== RCS file: /cvsroot/pgsql-server/src/backend/commands/portalcmds.c,v retrieving revision 1.6 diff -c -c -r1.6 portalcmds.c *** src/backend/commands/portalcmds.c 15 Dec 2002 16:17:42 -0000 1.6 --- src/backend/commands/portalcmds.c 27 Dec 2002 13:52:37 -0000 *************** *** 65,71 **** void PerformPortalFetch(char *name, bool forward, ! int count, CommandDest dest, char *completionTag) { --- 65,71 ---- void PerformPortalFetch(char *name, bool forward, ! long count, CommandDest dest, char *completionTag) { *************** *** 100,113 **** return; } ! /* If zero count, we are done */ if (count == 0) ! return; /* Internally, zero count processes all portal rows */ ! if (count == INT_MAX) count = 0; ! /* * switch into the portal context */ --- 100,147 ---- return; } ! /* If zero count, handle specially */ if (count == 0) ! { ! bool on_row = false; ! ! /* Are we sitting on a row? */ ! oldcontext = MemoryContextSwitchTo(PortalGetHeapMemory(portal)); ! queryDesc = PortalGetQueryDesc(portal); ! estate = queryDesc->estate; ! if (portal->atStart == false && portal->atEnd == false) ! on_row = true; ! MemoryContextSwitchTo(oldcontext); ! ! if (dest == None) ! { ! /* MOVE 0 returns 0/1 based on if FETCH 0 would return a row */ ! if (completionTag && on_row) ! strcpy(completionTag, "MOVE 1"); ! return; ! } ! else ! { ! /* If we are not on a row, FETCH 0 returns nothing */ ! if (!on_row) ! return; ! ! /* Since we are sitting on a row, return the row */ ! /* Back up so we can reread the row */ ! PerformPortalFetch(name, false /* backward */, 1, ! None, /* throw away output */ ! NULL /* do not modify the command tag */); ! ! /* Set up to fetch one row */ ! count = 1; ! forward = true; ! } ! } /* Internally, zero count processes all portal rows */ ! if (count == LONG_MAX) count = 0; ! /* * switch into the portal context */ Index: src/backend/parser/gram.y =================================================================== RCS file: /cvsroot/pgsql-server/src/backend/parser/gram.y,v retrieving revision 2.388 diff -c -c -r2.388 gram.y *** src/backend/parser/gram.y 12 Dec 2002 20:35:13 -0000 2.388 --- src/backend/parser/gram.y 27 Dec 2002 13:52:55 -0000 *************** *** 2731,2738 **** fetch_how_many: Iconst { $$ = $1; } | '-' Iconst { $$ = - $2; } ! | ALL { $$ = INT_MAX; } ! | LAST { $$ = INT_MAX; } | NEXT { $$ = 1; } | PRIOR { $$ = -1; } ; --- 2731,2738 ---- fetch_how_many: Iconst { $$ = $1; } | '-' Iconst { $$ = - $2; } ! | ALL { $$ = LONG_MAX; } ! | LAST { $$ = LONG_MAX; } | NEXT { $$ = 1; } | PRIOR { $$ = -1; } ; Index: src/backend/tcop/utility.c =================================================================== RCS file: /cvsroot/pgsql-server/src/backend/tcop/utility.c,v retrieving revision 1.185 diff -c -c -r1.185 utility.c *** src/backend/tcop/utility.c 6 Dec 2002 05:00:31 -0000 1.185 --- src/backend/tcop/utility.c 27 Dec 2002 13:53:01 -0000 *************** *** 257,263 **** FetchStmt *stmt = (FetchStmt *) parsetree; char *portalName = stmt->portalname; bool forward; ! int count; forward = (bool) (stmt->direction == FORWARD); --- 257,263 ---- FetchStmt *stmt = (FetchStmt *) parsetree; char *portalName = stmt->portalname; bool forward; ! long count; forward = (bool) (stmt->direction == FORWARD); Index: src/include/commands/portalcmds.h =================================================================== RCS file: /cvsroot/pgsql-server/src/include/commands/portalcmds.h,v retrieving revision 1.3 diff -c -c -r1.3 portalcmds.h *** src/include/commands/portalcmds.h 13 Nov 2002 00:44:09 -0000 1.3 --- src/include/commands/portalcmds.h 27 Dec 2002 13:53:05 -0000 *************** *** 25,31 **** * BadArg if forward invalid. * "ERROR" if portal not found. */ ! extern void PerformPortalFetch(char *name, bool forward, int count, CommandDest dest, char *completionTag); /* --- 25,31 ---- * BadArg if forward invalid. * "ERROR" if portal not found. */ ! extern void PerformPortalFetch(char *name, bool forward, long count, CommandDest dest, char *completionTag); /* Index: src/include/nodes/parsenodes.h =================================================================== RCS file: /cvsroot/pgsql-server/src/include/nodes/parsenodes.h,v retrieving revision 1.223 diff -c -c -r1.223 parsenodes.h *** src/include/nodes/parsenodes.h 12 Dec 2002 20:35:16 -0000 1.223 --- src/include/nodes/parsenodes.h 27 Dec 2002 13:53:11 -0000 *************** *** 1198,1204 **** { NodeTag type; int direction; /* FORWARD or BACKWARD */ ! int howMany; /* amount to fetch */ char *portalname; /* name of portal (cursor) */ bool ismove; /* TRUE if MOVE */ } FetchStmt; --- 1198,1204 ---- { NodeTag type; int direction; /* FORWARD or BACKWARD */ ! long howMany; /* amount to fetch */ char *portalname; /* name of portal (cursor) */ bool ismove; /* TRUE if MOVE */ } FetchStmt;
pgsql-patches by date: