Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc3e10a4

Browse files
committed
1. _bt_compare fixed to work properly with new code in _bt_insertonpg
(old _bt_compare always returned >= 0 while comparing with P_HIKEY on root page - it breaks root page when _bt_insertonpg tries insert new minimal key into root page).2. Fixed bug concerns "empty" pages: non-rightmost pages with only P_HIKEY present on it. Such pages appear after vacuum.
1 parent64397b7 commitc3e10a4

File tree

1 file changed

+91
-10
lines changed

1 file changed

+91
-10
lines changed

‎src/backend/access/nbtree/nbtsearch.c

Lines changed: 91 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.10 1996/11/21 06:10:55 vadim Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.11 1996/12/06 09:41:45 vadim Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -409,9 +409,19 @@ _bt_firsteq(Relation rel,
409409
* 0 if scankey == tuple at offnum;
410410
* +1 if scankey > tuple at offnum.
411411
*
412+
*-- Old comments:
412413
*In order to avoid having to propagate changes up the tree any time
413414
*a new minimal key is inserted, the leftmost entry on the leftmost
414415
*page is less than all possible keys, by definition.
416+
*
417+
*-- New ones:
418+
*New insertion code (fix against updating _in_place_ if new minimal
419+
*key has bigger size than old one) may delete P_HIKEY entry on the
420+
*root page in order to insert new minimal key - and so this definition
421+
*does not work properly in this case and breaks key' order on root
422+
*page. BTW, this propagation occures only while page' splitting,
423+
*but not "any time a new min key is inserted" (see _bt_insertonpg).
424+
*- vadim 12/05/96
415425
*/
416426
int
417427
_bt_compare(Relationrel,
@@ -436,6 +446,8 @@ _bt_compare(Relation rel,
436446
* If this is a leftmost internal page, and if our comparison is
437447
* with the first key on the page, then the item at that position is
438448
* by definition less than the scan key.
449+
*
450+
* - see new comments above...
439451
*/
440452

441453
opaque= (BTPageOpaque)PageGetSpecialPointer(page);
@@ -453,12 +465,20 @@ _bt_compare(Relation rel,
453465
* well as the rightmost page. but that implies that this
454466
* code path only applies to the root -- which seems
455467
* unlikely..
468+
*
469+
* - see new comments above...
456470
*/
457471
if (!P_RIGHTMOST(opaque)) {
458472
elog(WARN,"_bt_compare: invalid comparison to high key");
459473
}
460474

475+
#ifdef0
461476
/*
477+
* We just have to belive that right answer will not
478+
* break anything. I've checked code and all seems to be ok.
479+
* See new comments above...
480+
*
481+
* -- Old comments
462482
* If the item on the page is equal to the scankey, that's
463483
* okay to admit. We just can't claim that the first key on
464484
* the page is greater than anything.
@@ -469,6 +489,7 @@ _bt_compare(Relation rel,
469489
return (0);
470490
}
471491
return (1);
492+
#endif
472493
}
473494

474495
btitem= (BTItem)PageGetItem(page,PageGetItemId(page,offnum));
@@ -601,6 +622,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
601622
Pagepage;
602623
BTStackstack;
603624
OffsetNumberoffnum,maxoff;
625+
booloffGmax= false;
604626
BTItembtitem;
605627
IndexTupleitup;
606628
ItemPointercurrent;
@@ -665,7 +687,10 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
665687
maxoff=PageGetMaxOffsetNumber(page);
666688

667689
if (offnum>maxoff)
690+
{
668691
offnum=maxoff;
692+
offGmax= true;
693+
}
669694

670695
blkno=BufferGetBlockNumber(buf);
671696
ItemPointerSet(current,blkno,offnum);
@@ -736,10 +761,21 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
736761
if (result>0)
737762
(void)_bt_twostep(scan,&buf,ForwardScanDirection);
738763
}
764+
elseif (offGmax&&result>0 )
765+
{/*
766+
* Just remember: _bt_binsrch() returns the OffsetNumber of
767+
* the first matching key on the page, or the OffsetNumber at
768+
* which the matching key WOULD APPEAR IF IT WERE on this page.
769+
* No key on this page, but offnum from _bt_binsrch() greater
770+
* maxoff - have to move right. - vadim 12/06/96
771+
*/
772+
(void)_bt_twostep(scan,&buf,ForwardScanDirection);
773+
}
739774
break;
740775

741776
caseBTGreaterStrategyNumber:
742-
if (result >=0) {
777+
/* offGmax helps as above */
778+
if (result >=0||offGmax) {
743779
do {
744780
if (!_bt_twostep(scan,&buf,ForwardScanDirection))
745781
break;
@@ -1084,32 +1120,77 @@ _bt_endpoint(IndexScanDesc scan, ScanDirection dir)
10841120
maxoff=PageGetMaxOffsetNumber(page);
10851121

10861122
if (ScanDirectionIsForward(dir)) {
1087-
if (PageIsEmpty(page)) {
1088-
maxoff=FirstOffsetNumber;
1089-
}else {
1090-
maxoff=PageGetMaxOffsetNumber(page);
1091-
}
1123+
if ( !P_LEFTMOST(opaque) )/* non-leftmost page ? */
1124+
elog (WARN,"_bt_endpoint: leftmost page (%u) has not leftmost flag",blkno);
10921125
start=P_RIGHTMOST(opaque) ?P_HIKEY :P_FIRSTKEY;
1093-
1126+
/*
1127+
* I don't understand this stuff! It doesn't work for non-rightmost
1128+
* pages with only one element (P_HIKEY) which we have after
1129+
* deletion itups by vacuum (it's case of start > maxoff).
1130+
* Scanning in BackwardScanDirection is not understandable at all.
1131+
* Well - new stuff. - vadim 12/06/96
1132+
*/
1133+
#ifdef0
10941134
if (PageIsEmpty(page)||start>maxoff) {
10951135
ItemPointerSet(current,blkno,maxoff);
10961136
if (!_bt_step(scan,&buf,BackwardScanDirection))
10971137
return ((RetrieveIndexResult)NULL);
10981138

10991139
start=ItemPointerGetOffsetNumber(current);
11001140
page=BufferGetPage(buf);
1101-
}else {
1141+
}
1142+
#endif
1143+
if (PageIsEmpty (page) )
1144+
{
1145+
if (start!=P_HIKEY )/* non-rightmost page */
1146+
elog (WARN,"_bt_endpoint: non-rightmost page (%u) is empty",blkno);
1147+
/* It's left- & right- most page - root page, - and it's empty... */
1148+
return ((RetrieveIndexResult)NULL);
1149+
}
1150+
if (start>maxoff )/* start == 2 && maxoff == 1 */
1151+
{
1152+
ItemPointerSet(current,blkno,maxoff);
1153+
if (!_bt_step(scan,&buf,ForwardScanDirection))
1154+
return ((RetrieveIndexResult)NULL);
1155+
1156+
start=ItemPointerGetOffsetNumber(current);
1157+
page=BufferGetPage(buf);
1158+
}
1159+
/* new stuff ends here */
1160+
else {
11021161
ItemPointerSet(current,blkno,start);
11031162
}
11041163
}elseif (ScanDirectionIsBackward(dir)) {
1164+
/*
1165+
* I don't understand this stuff too! If RIGHT-most leaf page is
1166+
* empty why do scanning in ForwardScanDirection ???
1167+
* Well - new stuff. - vadim 12/06/96
1168+
*/
1169+
#ifdef0
11051170
if (PageIsEmpty(page)) {
11061171
ItemPointerSet(current,blkno,FirstOffsetNumber);
11071172
if (!_bt_step(scan,&buf,ForwardScanDirection))
11081173
return ((RetrieveIndexResult)NULL);
11091174

11101175
start=ItemPointerGetOffsetNumber(current);
11111176
page=BufferGetPage(buf);
1112-
}else {
1177+
}
1178+
#endif
1179+
if (PageIsEmpty(page))
1180+
{
1181+
/* If it's leftmost page too - it's empty root page... */
1182+
if (P_LEFTMOST(opaque) )
1183+
return ((RetrieveIndexResult)NULL);
1184+
/* Go back ! */
1185+
ItemPointerSet(current,blkno,FirstOffsetNumber);
1186+
if (!_bt_step(scan,&buf,BackwardScanDirection))
1187+
return ((RetrieveIndexResult)NULL);
1188+
1189+
start=ItemPointerGetOffsetNumber(current);
1190+
page=BufferGetPage(buf);
1191+
}
1192+
/* new stuff ends here */
1193+
else {
11131194
start=PageGetMaxOffsetNumber(page);
11141195
ItemPointerSet(current,blkno,start);
11151196
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp