Index: src/backend/access/heap/heapam.c
===================================================================
RCS file: /Users/neilc/postgres/cvs_root/pgsql/src/backend/access/heap/heapam.c,v
retrieving revision 1.206
diff -c -r1.206 heapam.c
*** src/backend/access/heap/heapam.c	11 Jan 2006 08:43:11 -0000	1.206
--- src/backend/access/heap/heapam.c	21 Feb 2006 22:28:35 -0000
***************
*** 172,178 ****
   *		tuple as indicated by "dir"; return the next tuple in scan->rs_ctup,
   *		or set scan->rs_ctup.t_data = NULL if no more tuples.
   *
!  * dir == 0 means "re-fetch the tuple indicated by scan->rs_ctup".
   *
   * Note: the reason nkeys/key are passed separately, even though they are
   * kept in the scan descriptor, is that the caller may not want us to check
--- 172,179 ----
   *		tuple as indicated by "dir"; return the next tuple in scan->rs_ctup,
   *		or set scan->rs_ctup.t_data = NULL if no more tuples.
   *
!  * dir == NoMovementScanDirection means "re-fetch the tuple indicated
!  * by scan->rs_ctup".
   *
   * Note: the reason nkeys/key are passed separately, even though they are
   * kept in the scan descriptor, is that the caller may not want us to check
***************
*** 189,200 ****
   */
  static void
  heapgettup(HeapScanDesc scan,
! 		   int dir,
  		   int nkeys,
  		   ScanKey key)
  {
  	HeapTuple	tuple = &(scan->rs_ctup);
  	Snapshot	snapshot = scan->rs_snapshot;
  	BlockNumber page;
  	Page		dp;
  	int			lines;
--- 190,202 ----
   */
  static void
  heapgettup(HeapScanDesc scan,
! 		   ScanDirection dir,
  		   int nkeys,
  		   ScanKey key)
  {
  	HeapTuple	tuple = &(scan->rs_ctup);
  	Snapshot	snapshot = scan->rs_snapshot;
+ 	bool		backward = ScanDirectionIsBackward(dir);
  	BlockNumber page;
  	Page		dp;
  	int			lines;
***************
*** 205,215 ****
  	/*
  	 * calculate next starting lineoff, given scan direction
  	 */
! 	if (dir > 0)
  	{
- 		/*
- 		 * forward scan direction
- 		 */
  		if (!scan->rs_inited)
  		{
  			/*
--- 207,214 ----
  	/*
  	 * calculate next starting lineoff, given scan direction
  	 */
! 	if (ScanDirectionIsForward(dir))
  	{
  		if (!scan->rs_inited)
  		{
  			/*
***************
*** 242,252 ****
  
  		linesleft = lines - lineoff + 1;
  	}
! 	else if (dir < 0)
  	{
- 		/*
- 		 * reverse scan direction
- 		 */
  		if (!scan->rs_inited)
  		{
  			/*
--- 241,248 ----
  
  		linesleft = lines - lineoff + 1;
  	}
! 	else if (backward)
  	{
  		if (!scan->rs_inited)
  		{
  			/*
***************
*** 352,358 ****
  			 * otherwise move to the next item on the page
  			 */
  			--linesleft;
! 			if (dir < 0)
  			{
  				--lpp;			/* move back in this page's ItemId array */
  				--lineoff;
--- 348,354 ----
  			 * otherwise move to the next item on the page
  			 */
  			--linesleft;
! 			if (backward)
  			{
  				--lpp;			/* move back in this page's ItemId array */
  				--lineoff;
***************
*** 373,379 ****
  		/*
  		 * return NULL if we've exhausted all the pages
  		 */
! 		if ((dir < 0) ? (page == 0) : (page + 1 >= scan->rs_nblocks))
  		{
  			if (BufferIsValid(scan->rs_cbuf))
  				ReleaseBuffer(scan->rs_cbuf);
--- 369,375 ----
  		/*
  		 * return NULL if we've exhausted all the pages
  		 */
! 		if (backward ? (page == 0) : (page + 1 >= scan->rs_nblocks))
  		{
  			if (BufferIsValid(scan->rs_cbuf))
  				ReleaseBuffer(scan->rs_cbuf);
***************
*** 384,390 ****
  			return;
  		}
  
! 		page = (dir < 0) ? (page - 1) : (page + 1);
  
  		heapgetpage(scan, page);
  
--- 380,386 ----
  			return;
  		}
  
! 		page = backward ? (page - 1) : (page + 1);
  
  		heapgetpage(scan, page);
  
***************
*** 393,399 ****
  		dp = (Page) BufferGetPage(scan->rs_cbuf);
  		lines = PageGetMaxOffsetNumber((Page) dp);
  		linesleft = lines;
! 		if (dir < 0)
  		{
  			lineoff = lines;
  			lpp = PageGetItemId(dp, lines);
--- 389,395 ----
  		dp = (Page) BufferGetPage(scan->rs_cbuf);
  		lines = PageGetMaxOffsetNumber((Page) dp);
  		linesleft = lines;
! 		if (backward)
  		{
  			lineoff = lines;
  			lpp = PageGetItemId(dp, lines);
***************
*** 421,431 ****
   */
  static void
  heapgettup_pagemode(HeapScanDesc scan,
! 					int dir,
  					int nkeys,
  					ScanKey key)
  {
  	HeapTuple	tuple = &(scan->rs_ctup);
  	BlockNumber page;
  	Page		dp;
  	int			lines;
--- 417,428 ----
   */
  static void
  heapgettup_pagemode(HeapScanDesc scan,
! 					ScanDirection dir,
  					int nkeys,
  					ScanKey key)
  {
  	HeapTuple	tuple = &(scan->rs_ctup);
+ 	bool		backward = ScanDirectionIsBackward(dir);
  	BlockNumber page;
  	Page		dp;
  	int			lines;
***************
*** 437,447 ****
  	/*
  	 * calculate next starting lineindex, given scan direction
  	 */
! 	if (dir > 0)
  	{
- 		/*
- 		 * forward scan direction
- 		 */
  		if (!scan->rs_inited)
  		{
  			/*
--- 434,441 ----
  	/*
  	 * calculate next starting lineindex, given scan direction
  	 */
! 	if (ScanDirectionIsForward(dir))
  	{
  		if (!scan->rs_inited)
  		{
  			/*
***************
*** 471,481 ****
  
  		linesleft = lines - lineindex;
  	}
! 	else if (dir < 0)
  	{
- 		/*
- 		 * reverse scan direction
- 		 */
  		if (!scan->rs_inited)
  		{
  			/*
--- 465,472 ----
  
  		linesleft = lines - lineindex;
  	}
! 	else if (backward)
  	{
  		if (!scan->rs_inited)
  		{
  			/*
***************
*** 584,597 ****
  			 * otherwise move to the next item on the page
  			 */
  			--linesleft;
! 			if (dir < 0)
! 			{
  				--lineindex;
- 			}
  			else
- 			{
  				++lineindex;
- 			}
  		}
  
  		/*
--- 575,584 ----
  			 * otherwise move to the next item on the page
  			 */
  			--linesleft;
! 			if (backward)
  				--lineindex;
  			else
  				++lineindex;
  		}
  
  		/*
***************
*** 602,608 ****
  		/*
  		 * return NULL if we've exhausted all the pages
  		 */
! 		if ((dir < 0) ? (page == 0) : (page + 1 >= scan->rs_nblocks))
  		{
  			if (BufferIsValid(scan->rs_cbuf))
  				ReleaseBuffer(scan->rs_cbuf);
--- 589,595 ----
  		/*
  		 * return NULL if we've exhausted all the pages
  		 */
! 		if (backward ? (page == 0) : (page + 1 >= scan->rs_nblocks))
  		{
  			if (BufferIsValid(scan->rs_cbuf))
  				ReleaseBuffer(scan->rs_cbuf);
***************
*** 613,626 ****
  			return;
  		}
  
! 		page = (dir < 0) ? (page - 1) : (page + 1);
! 
  		heapgetpage(scan, page);
  
  		dp = (Page) BufferGetPage(scan->rs_cbuf);
  		lines = scan->rs_ntuples;
  		linesleft = lines;
! 		if (dir < 0)
  			lineindex = lines - 1;
  		else
  			lineindex = 0;
--- 600,612 ----
  			return;
  		}
  
! 		page = backward ? (page - 1) : (page + 1);
  		heapgetpage(scan, page);
  
  		dp = (Page) BufferGetPage(scan->rs_cbuf);
  		lines = scan->rs_ntuples;
  		linesleft = lines;
! 		if (backward)
  			lineindex = lines - 1;
  		else
  			lineindex = 0;
***************
*** 1008,1022 ****
  
  	HEAPDEBUG_1;				/* heap_getnext( info ) */
  
- 	/*
- 	 * Note: we depend here on the -1/0/1 encoding of ScanDirection.
- 	 */
  	if (scan->rs_pageatatime)
! 		heapgettup_pagemode(scan, (int) direction,
  							scan->rs_nkeys, scan->rs_key);
  	else
! 		heapgettup(scan, (int) direction,
! 				   scan->rs_nkeys, scan->rs_key);
  
  	if (scan->rs_ctup.t_data == NULL)
  	{
--- 994,1004 ----
  
  	HEAPDEBUG_1;				/* heap_getnext( info ) */
  
  	if (scan->rs_pageatatime)
! 		heapgettup_pagemode(scan, direction,
  							scan->rs_nkeys, scan->rs_key);
  	else
! 		heapgettup(scan, direction, scan->rs_nkeys, scan->rs_key);
  
  	if (scan->rs_ctup.t_data == NULL)
  	{
***************
*** 2745,2757 ****
  		{
  			scan->rs_cindex = scan->rs_mindex;
  			heapgettup_pagemode(scan,
! 								0,			/* "no movement" */
  								0,			/* needn't recheck scan keys */
  								NULL);
  		}
  		else
  			heapgettup(scan,
! 					   0,					/* "no movement" */
  					   0,					/* needn't recheck scan keys */
  					   NULL);
  	}
--- 2727,2739 ----
  		{
  			scan->rs_cindex = scan->rs_mindex;
  			heapgettup_pagemode(scan,
! 								NoMovementScanDirection,
  								0,			/* needn't recheck scan keys */
  								NULL);
  		}
  		else
  			heapgettup(scan,
! 					   NoMovementScanDirection,
  					   0,					/* needn't recheck scan keys */
  					   NULL);
  	}
Index: src/backend/executor/execMain.c
===================================================================
RCS file: /Users/neilc/postgres/cvs_root/pgsql/src/backend/executor/execMain.c,v
retrieving revision 1.266
diff -c -r1.266 execMain.c
*** src/backend/executor/execMain.c	19 Feb 2006 00:04:26 -0000	1.266
--- src/backend/executor/execMain.c	21 Feb 2006 22:29:16 -0000
***************
*** 218,224 ****
  	/*
  	 * run plan
  	 */
! 	if (direction == NoMovementScanDirection)
  		result = NULL;
  	else
  		result = ExecutePlan(estate,
--- 218,224 ----
  	/*
  	 * run plan
  	 */
! 	if (ScanDirectionIsNoMovement(direction))
  		result = NULL;
  	else
  		result = ExecutePlan(estate,
Index: src/backend/tcop/pquery.c
===================================================================
RCS file: /Users/neilc/postgres/cvs_root/pgsql/src/backend/tcop/pquery.c,v
retrieving revision 1.98
diff -c -r1.98 pquery.c
*** src/backend/tcop/pquery.c	22 Nov 2005 18:17:21 -0000	1.98
--- src/backend/tcop/pquery.c	21 Feb 2006 22:30:56 -0000
***************
*** 795,801 ****
  			nprocessed = queryDesc->estate->es_processed;
  		}
  
! 		if (direction != NoMovementScanDirection)
  		{
  			long		oldPos;
  
--- 795,801 ----
  			nprocessed = queryDesc->estate->es_processed;
  		}
  
! 		if (!ScanDirectionIsNoMovement(direction))
  		{
  			long		oldPos;
  
***************
*** 837,843 ****
  			nprocessed = queryDesc->estate->es_processed;
  		}
  
! 		if (direction != NoMovementScanDirection)
  		{
  			if (nprocessed > 0 && portal->atEnd)
  			{
--- 837,843 ----
  			nprocessed = queryDesc->estate->es_processed;
  		}
  
! 		if (!ScanDirectionIsNoMovement(direction))
  		{
  			if (nprocessed > 0 && portal->atEnd)
  			{
***************
*** 890,902 ****
  
  	(*dest->rStartup) (dest, CMD_SELECT, portal->tupDesc);
  
! 	if (direction == NoMovementScanDirection)
  	{
  		/* do nothing except start/stop the destination */
  	}
  	else
  	{
! 		bool		forward = (direction == ForwardScanDirection);
  
  		for (;;)
  		{
--- 890,902 ----
  
  	(*dest->rStartup) (dest, CMD_SELECT, portal->tupDesc);
  
! 	if (ScanDirectionIsNoMovement(direction))
  	{
  		/* do nothing except start/stop the destination */
  	}
  	else
  	{
! 		bool		forward = ScanDirectionIsForward(direction);
  
  		for (;;)
  		{
