1212 * Portions Copyright (c) 1994, Regents of the University of California
1313 *
1414 * IDENTIFICATION
15- * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.64 2000/10/1302:03:00 vadim Exp $
15+ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.65 2000/10/1312:05:20 vadim Exp $
1616 *
1717 *-------------------------------------------------------------------------
1818 */
@@ -837,7 +837,7 @@ static void btree_xlog_insert(bool redo, XLogRecPtr lsn, XLogRecord *record)
837837ItemPointerGetOffsetNumber (& (xlrec -> target .tid )),
838838(char * )xlrec + hsize ,
839839record -> xl_len - hsize ,
840- & hnode ))
840+ hnode ))
841841elog (STOP ,"btree_insert_redo: failed to add item" );
842842
843843PageSetLSN (page ,lsn );
@@ -908,7 +908,7 @@ btree_xlog_split(bool redo, bool onleft, XLogRecPtr lsn, XLogRecord *record)
908908else
909909{
910910/* Delete items related to new right sibling */
911- _bt_thin_left_page (page ,record );
911+ _bt_fix_left_page (page ,record , onleft );
912912
913913if (onleft )
914914{
@@ -924,6 +924,13 @@ btree_xlog_split(bool redo, bool onleft, XLogRecPtr lsn, XLogRecord *record)
924924memcpy (& hnode , (char * )xlrec + SizeOfBtreeSplit +
925925sizeof (CommandId ),sizeof (RelFileNode ));
926926}
927+ else
928+ {
929+ memcpy (& btdata , (char * )xlrec + hsize ,sizeof (BTItemData ));
930+ itemsz = IndexTupleDSize (btdata .bti_itup )+
931+ (sizeof (BTItemData )- sizeof (IndexTupleData ));
932+ hsize += itemsz ;
933+ }
927934
928935memcpy (& btdata , (char * )xlrec + hsize ,sizeof (BTItemData ));
929936itemsz = IndexTupleDSize (btdata .bti_itup )+
@@ -933,7 +940,7 @@ btree_xlog_split(bool redo, bool onleft, XLogRecPtr lsn, XLogRecord *record)
933940ItemPointerGetOffsetNumber (& (xlrec -> target .tid )),
934941(char * )xlrec + hsize ,
935942itemsz ,
936- & hnode ))
943+ hnode ))
937944elog (STOP ,"btree_split_redo: failed to add item" );
938945}
939946else
@@ -994,6 +1001,13 @@ btree_xlog_split(bool redo, bool onleft, XLogRecPtr lsn, XLogRecord *record)
9941001pageop -> btpo_flags |=BTP_LEAF ;
9951002hsize += (sizeof (CommandId )+ sizeof (RelFileNode ));
9961003}
1004+ else
1005+ {
1006+ memcpy (& btdata , (char * )xlrec + hsize ,sizeof (BTItemData ));
1007+ itemsz = IndexTupleDSize (btdata .bti_itup )+
1008+ (sizeof (BTItemData )- sizeof (IndexTupleData ));
1009+ hsize += itemsz ;
1010+ }
9971011if (onleft )/* skip target item */
9981012{
9991013memcpy (& btdata , (char * )xlrec + hsize ,sizeof (BTItemData ));
@@ -1198,17 +1212,28 @@ _bt_del_item(Relation reln, Buffer buffer, BTItem btitem, bool insert,
11981212{
11991213char * xlrec = (char * )XLogRecGetData (record );
12001214Page page = (Page )BufferGetPage (buffer );
1201- BTPageOpaque pageop ;
1215+ BTPageOpaque pageop = ( BTPageOpaque ) PageGetSpecialPointer ( page ) ;
12021216BlockNumber blkno ;
12031217OffsetNumber offno ;
12041218ItemId lp ;
1219+ BTItem item ;
12051220
12061221for ( ; ; )
12071222{
1208- offno = _bt_find_btitem (page ,btitem );
1209- if (offno != InvalidOffsetNumber )
1223+ OffsetNumber maxoff = PageGetMaxOffsetNumber (page );
1224+
1225+ for (offno = P_FIRSTDATAKEY (pageop );
1226+ offno <=maxoff ;
1227+ offno = OffsetNumberNext (offno ))
1228+ {
1229+ lp = PageGetItemId (page ,offno );
1230+ item = (BTItem )PageGetItem (page ,lp );
1231+ if (BTItemSame (item ,btitem ))
1232+ break ;
1233+ }
1234+ if (offno <=maxoff )
12101235break ;
1211- pageop = ( BTPageOpaque ) PageGetSpecialPointer ( page ) ;
1236+ offno = InvalidOffsetNumber ;
12121237if (P_RIGHTMOST (pageop ))
12131238break ;
12141239blkno = pageop -> btpo_next ;
@@ -1221,6 +1246,7 @@ _bt_del_item(Relation reln, Buffer buffer, BTItem btitem, bool insert,
12211246if (PageIsNew ((PageHeader )page ))
12221247elog (STOP ,"btree_%s_undo: uninitialized right sibling" ,
12231248(insert ) ?"insert" :"split" );
1249+ pageop = (BTPageOpaque )PageGetSpecialPointer (page );
12241250if (XLByteLT (PageGetLSN (page ),lsn ))
12251251break ;
12261252}
@@ -1250,9 +1276,9 @@ _bt_del_item(Relation reln, Buffer buffer, BTItem btitem, bool insert,
12501276
12511277memcpy (& cid , (char * )xlrec + hsize ,sizeof (CommandId ));
12521278memcpy (& hnode , (char * )xlrec + hsize + sizeof (CommandId ),sizeof (RelFileNode ));
1253- result = XLogCheckHeapTuple (hnode ,& (btitem -> bti_itup .t_tid ),
1279+ result = XLogIsOwnerOfTuple (hnode ,& (btitem -> bti_itup .t_tid ),
12541280record -> xl_xid ,cid );
1255- if (result <= 0 )/* no tuple or not owner */
1281+ if (result < 0 )/* not owner */
12561282{
12571283UnlockAndReleaseBuffer (buffer );
12581284return ;
@@ -1278,7 +1304,7 @@ _bt_del_item(Relation reln, Buffer buffer, BTItem btitem, bool insert,
12781304
12791305static bool
12801306_bt_add_item (Page page ,OffsetNumber offno ,
1281- char * item ,Size size ,RelFileNode * hnode )
1307+ char * item ,Size size ,RelFileNode hnode )
12821308{
12831309BTPageOpaque pageop = (BTPageOpaque )PageGetSpecialPointer (page );
12841310
@@ -1309,4 +1335,125 @@ _bt_add_item(Page page, OffsetNumber offno,
13091335return (true);
13101336}
13111337
1338+ static bool
1339+ _bt_cleanup_page (Page page ,RelFileNode hnode )
1340+ {
1341+ OffsetNumber maxoff = PageGetMaxOffsetNumber (page );
1342+ OffsetNumber offno ;
1343+ ItemId lp ;
1344+ BTItem item ;
1345+ bool result = false;
1346+
1347+ for (offno = P_FIRSTDATAKEY (pageop );offno <=maxoff ; )
1348+ {
1349+ lp = PageGetItemId (page ,offno );
1350+ item = (BTItem )PageGetItem (page ,lp );
1351+ if (XLogIsValidTuple (hnode ,& (item -> bti_itup .t_tid ))
1352+ offno = OffsetNumberNext (offno );
1353+ else
1354+ {
1355+ PageIndexTupleDelete (page ,offno );
1356+ maxoff = PageGetMaxOffsetNumber (page );
1357+ result = true;
1358+ }
1359+ }
1360+
1361+ return (result );
1362+ }
1363+
1364+ /*
1365+ * Remove from left sibling items belonging to right sibling
1366+ * and change P_HIKEY
1367+ */
1368+ static void
1369+ _bt_fix_left_page (Page page ,XLogRecord * record ,bool onleft )
1370+ {
1371+ char * xlrec = (char * )XLogRecGetData (record );
1372+ BTPageOpaque pageop = (BTPageOpaque )PageGetSpecialPointer (page );
1373+ Size hsize = SizeOfBtreeSplit ;
1374+ RelFileNode hnode ;
1375+ BTItemData btdata ;
1376+ OffsetNumber maxoff = PageGetMaxOffsetNumber (page );
1377+ OffsetNumber offno ;
1378+ char * item ;
1379+ Size itemsz ;
1380+ char * previtem = NULL ;
1381+ char * lhikey = NULL ;
1382+ Size lhisize = 0 ;
1383+
1384+ if (pageop -> btpo_flags & BTP_LEAF )
1385+ {
1386+ hsize += (sizeof (CommandId )+ sizeof (RelFileNode ));
1387+ memcpy (& hnode , (char * )xlrec + SizeOfBtreeSplit +
1388+ sizeof (CommandId ),sizeof (RelFileNode ));
1389+ }
1390+ else
1391+ {
1392+ lhikey = (char * )xlrec + hsize ;
1393+ memcpy (& btdata ,lhikey ,sizeof (BTItemData ));
1394+ lhisize = IndexTupleDSize (btdata .bti_itup )+
1395+ (sizeof (BTItemData )- sizeof (IndexTupleData ));
1396+ hsize += lhisize ;
1397+ }
1398+
1399+ if (!P_RIGHTMOST (pageop ))
1400+ PageIndexTupleDelete (page ,P_HIKEY );
1401+
1402+ if (onleft )/* skip target item */
1403+ {
1404+ memcpy (& btdata , (char * )xlrec + hsize ,sizeof (BTItemData ));
1405+ itemsz = IndexTupleDSize (btdata .bti_itup )+
1406+ (sizeof (BTItemData )- sizeof (IndexTupleData ));
1407+ hsize += itemsz ;
1408+ }
1409+
1410+ for (item = (char * )xlrec + hsize ; ; )
1411+ {
1412+ memcpy (& btdata ,item ,sizeof (BTItemData ));
1413+ for (offno = P_FIRSTDATAKEY (pageop );
1414+ offno <=maxoff ;
1415+ offno = OffsetNumberNext (offno ))
1416+ {
1417+ ItemId lp = PageGetItemId (page ,offno );
1418+ BTItem btitem = (BTItem )PageGetItem (page ,lp );
1419+
1420+ if (BTItemSame (& btdata ,btitem ))
1421+ {
1422+ PageIndexTupleDelete (page ,offno );
1423+ break ;
1424+ }
1425+ }
1426+
1427+ itemsz = IndexTupleDSize (btdata .bti_itup )+
1428+ (sizeof (BTItemData )- sizeof (IndexTupleData ));
1429+ itemsz = MAXALIGN (itemsz );
1430+
1431+ if (item + itemsz < (char * )record + record -> xl_len )
1432+ {
1433+ previtem = item ;
1434+ item += itemsz ;
1435+ }
1436+ else
1437+ break ;
1438+ }
1439+
1440+ /* time to insert hi-key */
1441+ if (pageop -> btpo_flags & BTP_LEAF )
1442+ {
1443+ lhikey = (P_RIGHTMOST (pageop )) ?item :previtem ;
1444+ memcpy (& btdata ,lhikey ,sizeof (BTItemData ));
1445+ lhisize = IndexTupleDSize (btdata .bti_itup )+
1446+ (sizeof (BTItemData )- sizeof (IndexTupleData ));
1447+ }
1448+
1449+ if (!_bt_add_item (page ,
1450+ P_HIKEY ,
1451+ lhikey ,
1452+ lhisize ,
1453+ & hnode ))
1454+ elog (STOP ,"btree_split_redo: failed to add hi key to left sibling" );
1455+
1456+ return ;
1457+ }
1458+
13121459#endif