James William Pye wrote:
In any case, some parts of the patch merely makes some code make use of the sdir.h macros instead of depending on -1/0/1--heapam in particular. At least those portions should be applied, no?
I've applied the attached patch to CVS HEAD that just changes the code to use the sdir.h macros when appropriate. Thanks for the patch.
-Neil
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 (;;) {
---------------------------(end of broadcast)--------------------------- TIP 6: explain analyze is your friend