Cause FETCH 1 to return the current cursor row, or zero if at
authorBruce Momjian <bruce@momjian.us>
Mon, 30 Dec 2002 15:31:51 +0000 (15:31 +0000)
committerBruce Momjian <bruce@momjian.us>
Mon, 30 Dec 2002 15:31:51 +0000 (15:31 +0000)
beginning/end of cursor.

Have MOVE return 0/1 depending on cursor position.

Matches SQL spec.

Pass cursor counter from parser as a long rather than int.

Doc updates.

doc/src/sgml/ref/fetch.sgml
doc/src/sgml/ref/move.sgml
src/backend/commands/portalcmds.c
src/backend/parser/gram.y
src/backend/tcop/utility.c
src/include/commands/portalcmds.h
src/include/nodes/parsenodes.h

index fae7ab5ba246035a08ff26b240d2e802c271ee70..b08ad4a191e8141314d967a95163688448e87f14 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/ref/fetch.sgml,v 1.21 2002/04/21 19:02:39 thomas Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/fetch.sgml,v 1.22 2002/12/30 15:31:47 momjian Exp $
 PostgreSQL documentation
 -->
 
@@ -89,7 +89,7 @@ FETCH [ FORWARD | BACKWARD | RELATIVE ] [ <replaceable class="PARAMETER">#</repl
           <para>
            A signed integer that specifies how many rows to fetch.
            Note that a negative integer is equivalent to changing the sense of
-           FORWARD and BACKWARD.
+           FORWARD and BACKWARD. Zero re-fetches the current row.
           </para>
          </listitem>
         </varlistentry>
@@ -180,30 +180,6 @@ WARNING:  FETCH/ABSOLUTE not supported, using RELATIVE
       </listitem>
      </varlistentry>
 
-     <varlistentry>
-      <term><computeroutput>
-ERROR:  FETCH/RELATIVE at current position is not supported
-       </computeroutput></term>
-      <listitem>
-       <para>
-       <acronym>SQL92</acronym> allows one to repetitively retrieve the cursor
-       at its <quote>current position</quote> using the syntax
-       <synopsis>
-FETCH RELATIVE 0 FROM <replaceable class="PARAMETER">cursor</replaceable>.
-       </synopsis>
-       </para>
-
-       <para>
-       <productname>PostgreSQL</productname> does not currently support
-       this notion; in fact the value zero is reserved to indicate that
-       all rows should be retrieved and is equivalent to specifying the ALL keyword.
-       If the RELATIVE keyword has been used, <productname>PostgreSQL</productname> 
-       assumes that the user intended <acronym>SQL92</acronym> behavior
-       and returns this error message.
-       </para>
-      </listitem>
-     </varlistentry>
-
     </variablelist>
    </para>
   </refsect2>
index 46c830406eacd24c73226fc6cda5708e6e83032b..5d4f1c8309ae872866997f9cd619efcd4a6ede52 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/ref/move.sgml,v 1.14 2002/11/13 00:44:08 momjian Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/move.sgml,v 1.15 2002/12/30 15:31:47 momjian Exp $
 PostgreSQL documentation
 -->
 
@@ -35,8 +35,8 @@ MOVE [ <replaceable class="PARAMETER">direction</replaceable> ]
    Description
   </title>
   <para>
-   <command>MOVE</command> allows a user to move cursor position a specified
-   number of rows.
+   <command>MOVE</command> allows a user to move the cursor position a 
+   specified number of rows.
    <command>MOVE</command> works like the <command>FETCH</command> command,
    but only positions the cursor and does not return rows.
    <replaceable class="PARAMETER">LAST</replaceable> moves to the end
index b1799e49f8cddf65342f7f3cedbcd4d911b80107..3a670d8f899460b581afef1d824ace37f8cdb226 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/portalcmds.c,v 1.6 2002/12/15 16:17:42 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/portalcmds.c,v 1.7 2002/12/30 15:31:47 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -65,7 +65,7 @@ PortalCleanup(Portal portal)
 void
 PerformPortalFetch(char *name,
                                   bool forward,
-                                  int count,
+                                  long count,
                                   CommandDest dest,
                                   char *completionTag)
 {
@@ -100,14 +100,48 @@ PerformPortalFetch(char *name,
                return;
        }
 
-       /* If zero count, we are done */
+       /* If zero count, handle specially */
        if (count == 0)
-               return;
+       {
+               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 == INT_MAX)
+       if (count == LONG_MAX)
                count = 0;
-               
+
        /*
         * switch into the portal context
         */
index bb94d1f8e821b0840a69a945f62d2ffa2d65de2a..c19673fc42287e51b2646e69a9592a6f10ac8983 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.388 2002/12/12 20:35:13 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.389 2002/12/30 15:31:47 momjian Exp $
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -2591,13 +2591,6 @@ comment_text:
 FetchStmt:     FETCH direction fetch_how_many from_in name
                                {
                                        FetchStmt *n = makeNode(FetchStmt);
-                                       if ($2 == RELATIVE)
-                                       {
-                                               if ($3 == 0)
-                                                       elog(ERROR,
-                                       "FETCH / RELATIVE at current position is not supported");
-                                               $2 = FORWARD;
-                                       }
                                        if ($3 < 0)
                                        {
                                                $3 = -$3;
@@ -2629,10 +2622,6 @@ FetchStmt:       FETCH direction fetch_how_many from_in name
                        | FETCH direction from_in name
                                {
                                        FetchStmt *n = makeNode(FetchStmt);
-                                       if ($2 == RELATIVE)
-                                       {
-                                               $2 = FORWARD;
-                                       }
                                        n->direction = $2;
                                        n->howMany = 1;
                                        n->portalname = $4;
@@ -2719,20 +2708,20 @@ FetchStmt:      FETCH direction fetch_how_many from_in name
 
 direction:     FORWARD                                                                 { $$ = FORWARD; }
                        | BACKWARD                                                              { $$ = BACKWARD; }
-                       | RELATIVE                                                              { $$ = RELATIVE; }
+                       | RELATIVE                                                              { $$ = FORWARD; }
                        | ABSOLUTE
                                {
                                        elog(NOTICE,
                                        "FETCH / ABSOLUTE not supported, using RELATIVE");
-                                       $$ = RELATIVE;
+                                       $$ = FORWARD;
                                }
                ;
 
 fetch_how_many:
                        Iconst                                                                  { $$ = $1; }
                        | '-' Iconst                                                    { $$ = - $2; }
-                       | ALL                                                                   { $$ = INT_MAX; }
-                       | LAST                                                                  { $$ = INT_MAX; }
+                       | ALL                                                                   { $$ = LONG_MAX; }
+                       | LAST                                                                  { $$ = LONG_MAX; }
                        | NEXT                                                                  { $$ = 1; }
                        | PRIOR                                                                 { $$ = -1; }
                ;
index 40228601d728f8cac4f0fa6c8406f421599c69f5..cc0f139b2dbb9d7c78c2a08cd96a77b7976868bb 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.185 2002/12/06 05:00:31 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.186 2002/12/30 15:31:48 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -257,7 +257,7 @@ ProcessUtility(Node *parsetree,
                                FetchStmt  *stmt = (FetchStmt *) parsetree;
                                char       *portalName = stmt->portalname;
                                bool            forward;
-                               int                     count;
+                               long            count;
 
                                forward = (bool) (stmt->direction == FORWARD);
 
index 5526ac997dc43a094d35ac306aafdc250a321009..d143423f6a32586d71879e142fab37b821e5ab75 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: portalcmds.h,v 1.3 2002/11/13 00:44:09 momjian Exp $
+ * $Id: portalcmds.h,v 1.4 2002/12/30 15:31:50 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -25,7 +25,7 @@
  *             BadArg if forward invalid.
  *             "ERROR" if portal not found.
  */
-extern void PerformPortalFetch(char *name, bool forward, int count,
+extern void PerformPortalFetch(char *name, bool forward, long count,
                                   CommandDest dest, char *completionTag);
 
 /*
index c409ec7ea847ffc7919a6cfae55ba4a5c2168539..0f9b7613a007cef63c5728710164be38c48f31e2 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parsenodes.h,v 1.223 2002/12/12 20:35:16 tgl Exp $
+ * $Id: parsenodes.h,v 1.224 2002/12/30 15:31:51 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1198,7 +1198,7 @@ typedef struct FetchStmt
 {
        NodeTag         type;
        int                     direction;              /* FORWARD or BACKWARD */
-       int                     howMany;                /* amount to fetch */
+       long            howMany;                /* amount to fetch */
        char       *portalname;         /* name of portal (cursor) */
        bool            ismove;                 /* TRUE if MOVE */
 } FetchStmt;