diff --git a/doc/src/sgml/ref/fetch.sgml b/doc/src/sgml/ref/fetch.sgml
index fae7ab5ba246035a08ff26b240d2e802c271ee70..b08ad4a191e8141314d967a95163688448e87f14 100644
--- a/doc/src/sgml/ref/fetch.sgml
+++ b/doc/src/sgml/ref/fetch.sgml
@@ -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>
diff --git a/doc/src/sgml/ref/move.sgml b/doc/src/sgml/ref/move.sgml
index 46c830406eacd24c73226fc6cda5708e6e83032b..5d4f1c8309ae872866997f9cd619efcd4a6ede52 100644
--- a/doc/src/sgml/ref/move.sgml
+++ b/doc/src/sgml/ref/move.sgml
@@ -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
diff --git a/src/backend/commands/portalcmds.c b/src/backend/commands/portalcmds.c
index b1799e49f8cddf65342f7f3cedbcd4d911b80107..3a670d8f899460b581afef1d824ace37f8cdb226 100644
--- a/src/backend/commands/portalcmds.c
+++ b/src/backend/commands/portalcmds.c
@@ -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
 	 */
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index bb94d1f8e821b0840a69a945f62d2ffa2d65de2a..c19673fc42287e51b2646e69a9592a6f10ac8983 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -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; }
 		;
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 40228601d728f8cac4f0fa6c8406f421599c69f5..cc0f139b2dbb9d7c78c2a08cd96a77b7976868bb 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -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);
 
diff --git a/src/include/commands/portalcmds.h b/src/include/commands/portalcmds.h
index 5526ac997dc43a094d35ac306aafdc250a321009..d143423f6a32586d71879e142fab37b821e5ab75 100644
--- a/src/include/commands/portalcmds.h
+++ b/src/include/commands/portalcmds.h
@@ -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);
 
 /*
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index c409ec7ea847ffc7919a6cfae55ba4a5c2168539..0f9b7613a007cef63c5728710164be38c48f31e2 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -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;