|
|
@ -43,7 +43,7 @@ static bool _bt_steppage(IndexScanDesc scan, ScanDirection dir); |
|
|
|
static bool _bt_readnextpage(IndexScanDesc scan, BlockNumber blkno, ScanDirection dir); |
|
|
|
static bool _bt_readnextpage(IndexScanDesc scan, BlockNumber blkno, ScanDirection dir); |
|
|
|
static bool _bt_parallel_readpage(IndexScanDesc scan, BlockNumber blkno, |
|
|
|
static bool _bt_parallel_readpage(IndexScanDesc scan, BlockNumber blkno, |
|
|
|
ScanDirection dir); |
|
|
|
ScanDirection dir); |
|
|
|
static Buffer _bt_walk_left(Relation rel, Buffer buf, Snapshot snapshot); |
|
|
|
static Buffer _bt_walk_left(Relation rel, Buffer buf); |
|
|
|
static bool _bt_endpoint(IndexScanDesc scan, ScanDirection dir); |
|
|
|
static bool _bt_endpoint(IndexScanDesc scan, ScanDirection dir); |
|
|
|
static inline void _bt_initialize_more_data(BTScanOpaque so, ScanDirection dir); |
|
|
|
static inline void _bt_initialize_more_data(BTScanOpaque so, ScanDirection dir); |
|
|
|
|
|
|
|
|
|
|
@ -83,10 +83,6 @@ _bt_drop_lock_and_maybe_pin(IndexScanDesc scan, BTScanPos sp) |
|
|
|
* which is locked and pinned. No locks are held on the parent pages, |
|
|
|
* which is locked and pinned. No locks are held on the parent pages, |
|
|
|
* however! |
|
|
|
* however! |
|
|
|
* |
|
|
|
* |
|
|
|
* If the snapshot parameter is not NULL, "old snapshot" checking will take |
|
|
|
|
|
|
|
* place during the descent through the tree. This is not needed when |
|
|
|
|
|
|
|
* positioning for an insert or delete, so NULL is used for those cases. |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* The returned buffer is locked according to access parameter. Additionally, |
|
|
|
* The returned buffer is locked according to access parameter. Additionally, |
|
|
|
* access = BT_WRITE will allow an empty root page to be created and returned. |
|
|
|
* access = BT_WRITE will allow an empty root page to be created and returned. |
|
|
|
* When access = BT_READ, an empty index will result in *bufP being set to |
|
|
|
* When access = BT_READ, an empty index will result in *bufP being set to |
|
|
@ -98,7 +94,7 @@ _bt_drop_lock_and_maybe_pin(IndexScanDesc scan, BTScanPos sp) |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
BTStack |
|
|
|
BTStack |
|
|
|
_bt_search(Relation rel, Relation heaprel, BTScanInsert key, Buffer *bufP, |
|
|
|
_bt_search(Relation rel, Relation heaprel, BTScanInsert key, Buffer *bufP, |
|
|
|
int access, Snapshot snapshot) |
|
|
|
int access) |
|
|
|
{ |
|
|
|
{ |
|
|
|
BTStack stack_in = NULL; |
|
|
|
BTStack stack_in = NULL; |
|
|
|
int page_access = BT_READ; |
|
|
|
int page_access = BT_READ; |
|
|
@ -138,7 +134,7 @@ _bt_search(Relation rel, Relation heaprel, BTScanInsert key, Buffer *bufP, |
|
|
|
* opportunity to finish splits of internal pages too. |
|
|
|
* opportunity to finish splits of internal pages too. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
*bufP = _bt_moveright(rel, heaprel, key, *bufP, (access == BT_WRITE), |
|
|
|
*bufP = _bt_moveright(rel, heaprel, key, *bufP, (access == BT_WRITE), |
|
|
|
stack_in, page_access, snapshot); |
|
|
|
stack_in, page_access); |
|
|
|
|
|
|
|
|
|
|
|
/* if this is a leaf page, we're done */ |
|
|
|
/* if this is a leaf page, we're done */ |
|
|
|
page = BufferGetPage(*bufP); |
|
|
|
page = BufferGetPage(*bufP); |
|
|
@ -198,8 +194,7 @@ _bt_search(Relation rel, Relation heaprel, BTScanInsert key, Buffer *bufP, |
|
|
|
* but before we acquired a write lock. If it has, we may need to |
|
|
|
* but before we acquired a write lock. If it has, we may need to |
|
|
|
* move right to its new sibling. Do that. |
|
|
|
* move right to its new sibling. Do that. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
*bufP = _bt_moveright(rel, heaprel, key, *bufP, true, stack_in, BT_WRITE, |
|
|
|
*bufP = _bt_moveright(rel, heaprel, key, *bufP, true, stack_in, BT_WRITE); |
|
|
|
snapshot); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return stack_in; |
|
|
|
return stack_in; |
|
|
@ -235,10 +230,6 @@ _bt_search(Relation rel, Relation heaprel, BTScanInsert key, Buffer *bufP, |
|
|
|
* On entry, we have the buffer pinned and a lock of the type specified by |
|
|
|
* On entry, we have the buffer pinned and a lock of the type specified by |
|
|
|
* 'access'. If we move right, we release the buffer and lock and acquire |
|
|
|
* 'access'. If we move right, we release the buffer and lock and acquire |
|
|
|
* the same on the right sibling. Return value is the buffer we stop at. |
|
|
|
* the same on the right sibling. Return value is the buffer we stop at. |
|
|
|
* |
|
|
|
|
|
|
|
* If the snapshot parameter is not NULL, "old snapshot" checking will take |
|
|
|
|
|
|
|
* place during the descent through the tree. This is not needed when |
|
|
|
|
|
|
|
* positioning for an insert or delete, so NULL is used for those cases. |
|
|
|
|
|
|
|
*/ |
|
|
|
*/ |
|
|
|
Buffer |
|
|
|
Buffer |
|
|
|
_bt_moveright(Relation rel, |
|
|
|
_bt_moveright(Relation rel, |
|
|
@ -247,8 +238,7 @@ _bt_moveright(Relation rel, |
|
|
|
Buffer buf, |
|
|
|
Buffer buf, |
|
|
|
bool forupdate, |
|
|
|
bool forupdate, |
|
|
|
BTStack stack, |
|
|
|
BTStack stack, |
|
|
|
int access, |
|
|
|
int access) |
|
|
|
Snapshot snapshot) |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
Page page; |
|
|
|
Page page; |
|
|
|
BTPageOpaque opaque; |
|
|
|
BTPageOpaque opaque; |
|
|
@ -1373,7 +1363,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) |
|
|
|
* Use the manufactured insertion scan key to descend the tree and |
|
|
|
* Use the manufactured insertion scan key to descend the tree and |
|
|
|
* position ourselves on the target leaf page. |
|
|
|
* position ourselves on the target leaf page. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
stack = _bt_search(rel, NULL, &inskey, &buf, BT_READ, scan->xs_snapshot); |
|
|
|
stack = _bt_search(rel, NULL, &inskey, &buf, BT_READ); |
|
|
|
|
|
|
|
|
|
|
|
/* don't need to keep the stack around... */ |
|
|
|
/* don't need to keep the stack around... */ |
|
|
|
_bt_freestack(stack); |
|
|
|
_bt_freestack(stack); |
|
|
@ -1392,8 +1382,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) |
|
|
|
if (IsolationIsSerializable()) |
|
|
|
if (IsolationIsSerializable()) |
|
|
|
{ |
|
|
|
{ |
|
|
|
PredicateLockRelation(rel, scan->xs_snapshot); |
|
|
|
PredicateLockRelation(rel, scan->xs_snapshot); |
|
|
|
stack = _bt_search(rel, NULL, &inskey, &buf, BT_READ, |
|
|
|
stack = _bt_search(rel, NULL, &inskey, &buf, BT_READ); |
|
|
|
scan->xs_snapshot); |
|
|
|
|
|
|
|
_bt_freestack(stack); |
|
|
|
_bt_freestack(stack); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -2113,8 +2102,7 @@ _bt_readnextpage(IndexScanDesc scan, BlockNumber blkno, ScanDirection dir) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* Step to next physical page */ |
|
|
|
/* Step to next physical page */ |
|
|
|
so->currPos.buf = _bt_walk_left(rel, so->currPos.buf, |
|
|
|
so->currPos.buf = _bt_walk_left(rel, so->currPos.buf); |
|
|
|
scan->xs_snapshot); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* if we're physically at end of index, return failure */ |
|
|
|
/* if we're physically at end of index, return failure */ |
|
|
|
if (so->currPos.buf == InvalidBuffer) |
|
|
|
if (so->currPos.buf == InvalidBuffer) |
|
|
@ -2205,7 +2193,7 @@ _bt_parallel_readpage(IndexScanDesc scan, BlockNumber blkno, ScanDirection dir) |
|
|
|
* again if it's important. |
|
|
|
* again if it's important. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
static Buffer |
|
|
|
static Buffer |
|
|
|
_bt_walk_left(Relation rel, Buffer buf, Snapshot snapshot) |
|
|
|
_bt_walk_left(Relation rel, Buffer buf) |
|
|
|
{ |
|
|
|
{ |
|
|
|
Page page; |
|
|
|
Page page; |
|
|
|
BTPageOpaque opaque; |
|
|
|
BTPageOpaque opaque; |
|
|
@ -2320,8 +2308,7 @@ _bt_walk_left(Relation rel, Buffer buf, Snapshot snapshot) |
|
|
|
* The returned buffer is pinned and read-locked. |
|
|
|
* The returned buffer is pinned and read-locked. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
Buffer |
|
|
|
Buffer |
|
|
|
_bt_get_endpoint(Relation rel, uint32 level, bool rightmost, |
|
|
|
_bt_get_endpoint(Relation rel, uint32 level, bool rightmost) |
|
|
|
Snapshot snapshot) |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
Buffer buf; |
|
|
|
Buffer buf; |
|
|
|
Page page; |
|
|
|
Page page; |
|
|
@ -2417,7 +2404,7 @@ _bt_endpoint(IndexScanDesc scan, ScanDirection dir) |
|
|
|
* version of _bt_search(). We don't maintain a stack since we know we |
|
|
|
* version of _bt_search(). We don't maintain a stack since we know we |
|
|
|
* won't need it. |
|
|
|
* won't need it. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
buf = _bt_get_endpoint(rel, 0, ScanDirectionIsBackward(dir), scan->xs_snapshot); |
|
|
|
buf = _bt_get_endpoint(rel, 0, ScanDirectionIsBackward(dir)); |
|
|
|
|
|
|
|
|
|
|
|
if (!BufferIsValid(buf)) |
|
|
|
if (!BufferIsValid(buf)) |
|
|
|
{ |
|
|
|
{ |
|
|
|