*** pgsql/src/backend/access/nbtree/nbtree.c 2008/01/01 19:45:46 1.156 --- pgsql/src/backend/access/nbtree/nbtree.c 2008/04/10 22:25:25 1.157 *************** *** 12,18 **** * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION ! * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtree.c,v 1.155 2007/05/30 20:11:53 tgl Exp $ * *------------------------------------------------------------------------- */ --- 12,18 ---- * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION ! * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtree.c,v 1.156 2008/01/01 19:45:46 momjian Exp $ * *------------------------------------------------------------------------- */ *************** *** 22,27 **** --- 22,28 ---- #include "access/nbtree.h" #include "catalog/index.h" #include "commands/vacuum.h" + #include "miscadmin.h" #include "storage/freespace.h" #include "storage/lmgr.h" #include "utils/memutils.h" *************** btgettuple(PG_FUNCTION_ARGS) *** 278,319 **** } /* ! * btgetmulti() -- get multiple tuples at once ! * ! * In the current implementation there seems no strong reason to stop at ! * index page boundaries; we just press on until we fill the caller's buffer ! * or run out of matches. */ Datum ! btgetmulti(PG_FUNCTION_ARGS) { IndexScanDesc scan = (IndexScanDesc) PG_GETARG_POINTER(0); ! ItemPointer tids = (ItemPointer) PG_GETARG_POINTER(1); ! int32 max_tids = PG_GETARG_INT32(2); ! int32 *returned_tids = (int32 *) PG_GETARG_POINTER(3); BTScanOpaque so = (BTScanOpaque) scan->opaque; ! bool res = true; ! int32 ntids = 0; ! ! if (max_tids <= 0) /* behave correctly in boundary case */ ! PG_RETURN_BOOL(true); ! /* If we haven't started the scan yet, fetch the first page & tuple. */ ! if (!BTScanPosIsValid(so->currPos)) { ! res = _bt_first(scan, ForwardScanDirection); ! if (!res) ! { ! /* empty scan */ ! *returned_tids = ntids; ! PG_RETURN_BOOL(res); ! } ! /* Save tuple ID, and continue scanning */ ! tids[ntids] = scan->xs_ctup.t_self; ! ntids++; } ! while (ntids < max_tids) { /* * Advance to next tuple within page. This is the same as the easy --- 279,307 ---- } /* ! * btgetbitmap() -- gets all matching tuples, and adds them to a bitmap */ Datum ! btgetbitmap(PG_FUNCTION_ARGS) { IndexScanDesc scan = (IndexScanDesc) PG_GETARG_POINTER(0); ! TIDBitmap *tbm = (TIDBitmap *) PG_GETARG_POINTER(1); BTScanOpaque so = (BTScanOpaque) scan->opaque; ! int64 ntids = 0; ! ItemPointer heapTid; ! /* Fetch the first page & tuple. */ ! if (!_bt_first(scan, ForwardScanDirection)) { ! /* empty scan */ ! PG_RETURN_INT64(0); } + /* Save tuple ID, and continue scanning */ + heapTid = &scan->xs_ctup.t_self; + tbm_add_tuples(tbm, heapTid, 1, false); + ntids++; ! for (;;) { /* * Advance to next tuple within page. This is the same as the easy *************** btgetmulti(PG_FUNCTION_ARGS) *** 321,339 **** */ if (++so->currPos.itemIndex > so->currPos.lastItem) { /* let _bt_next do the heavy lifting */ ! res = _bt_next(scan, ForwardScanDirection); ! if (!res) break; } /* Save tuple ID, and continue scanning */ ! tids[ntids] = so->currPos.items[so->currPos.itemIndex].heapTid; ntids++; } ! *returned_tids = ntids; ! PG_RETURN_BOOL(res); } /* --- 309,328 ---- */ if (++so->currPos.itemIndex > so->currPos.lastItem) { + CHECK_FOR_INTERRUPTS(); + /* let _bt_next do the heavy lifting */ ! if (!_bt_next(scan, ForwardScanDirection)) break; } /* Save tuple ID, and continue scanning */ ! heapTid = &so->currPos.items[so->currPos.itemIndex].heapTid; ! tbm_add_tuples(tbm, heapTid, 1, false); ntids++; } ! PG_RETURN_INT64(ntids); } /*