88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.64 2000/10/05 20:10:20 tgl Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.65 2000/10/13 02:03:00 vadim Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -61,6 +61,10 @@ static void _bt_pgaddtup(Relation rel, Page page,
6161static bool _bt_isequal (TupleDesc itupdesc ,Page page ,OffsetNumber offnum ,
6262int keysz ,ScanKey scankey );
6363
64+ #ifdef XLOG
65+ static Relation _xlheapRel ;/* temporary hack */
66+ #endif
67+
6468/*
6569 *_bt_doinsert() -- Handle insertion of a single btitem in the tree.
6670 *
@@ -119,6 +123,10 @@ _bt_doinsert(Relation rel, BTItem btitem,
119123}
120124}
121125
126+ #ifdef XLOG
127+ _xlheapRel = heapRel ;/* temporary hack */
128+ #endif
129+
122130/* do the insertion */
123131res = _bt_insertonpg (rel ,buf ,stack ,natts ,itup_scankey ,btitem ,0 );
124132
@@ -517,21 +525,38 @@ _bt_insertonpg(Relation rel,
517525#ifdef XLOG
518526/* XLOG stuff */
519527{
520- char xlbuf [sizeof (xl_btree_insert )+ 2 * sizeof (CommandId )];
528+ char xlbuf [sizeof (xl_btree_insert )+
529+ sizeof (CommandId )+ sizeof (RelFileNode )];
521530xl_btree_insert * xlrec = xlbuf ;
522531int hsize = SizeOfBtreeInsert ;
532+ BTItemData truncitem ;
533+ BTItem xlitem = btitem ;
534+ Size xlsize = IndexTupleDSize (btitem -> bti_itup )+
535+ (sizeof (BTItemData )- sizeof (IndexTupleData ));
523536
524537xlrec -> target .node = rel -> rd_node ;
525538ItemPointerSet (& (xlrec -> target .tid ),BufferGetBlockNumber (buf ),newitemoff );
526539if (P_ISLEAF (lpageop ))
527- {
540+ {
528541CommandId cid = GetCurrentCommandId ();
529- memcpy (xlbuf + SizeOfBtreeInsert ,& ( char * ) cid ,sizeof (CommandId ));
542+ memcpy (xlbuf + hsize ,& cid ,sizeof (CommandId ));
530543hsize += sizeof (CommandId );
544+ memcpy (xlbuf + hsize ,& (_xlheapRel -> rd_node ),sizeof (RelFileNode ));
545+ hsize += sizeof (RelFileNode );
546+ }
547+ /*
548+ * Read comments in _bt_pgaddtup
549+ */
550+ else if (newitemoff == P_FIRSTDATAKEY (lpageop ))
551+ {
552+ truncitem = * btitem ;
553+ truncitem .bti_itup .t_info = sizeof (BTItemData );
554+ xlitem = & truncitem ;
555+ xlsize = sizeof (BTItemData );
531556}
532557
533558XLogRecPtr recptr = XLogInsert (RM_BTREE_ID ,XLOG_BTREE_INSERT ,
534- xlbuf ,hsize , (char * )btitem , itemsz );
559+ xlbuf ,hsize , (char * )xlitem , xlsize );
535560
536561PageSetLSN (page ,recptr );
537562PageSetSUI (page ,ThisStartUpID );
@@ -752,7 +777,7 @@ _bt_split(Relation rel, Buffer buf, OffsetNumber firstright,
752777 */
753778{
754779char xlbuf [sizeof (xl_btree_split )+
755- 2 * sizeof (CommandId )+ BLCKSZ ];
780+ sizeof ( CommandId ) + sizeof (RelFileNode )+ BLCKSZ ];
756781xl_btree_split * xlrec = xlbuf ;
757782int hsize = SizeOfBtreeSplit ;
758783int flag = (newitemonleft ) ?
@@ -765,11 +790,30 @@ _bt_split(Relation rel, Buffer buf, OffsetNumber firstright,
765790CommandId cid = GetCurrentCommandId ();
766791memcpy (xlbuf + hsize ,& (char * )cid ,sizeof (CommandId ));
767792hsize += sizeof (CommandId );
793+ memcpy (xlbuf + hsize ,& (_xlheapRel -> rd_node ),sizeof (RelFileNode ));
794+ hsize += sizeof (RelFileNode );
768795}
769796if (newitemonleft )
770797{
771- memcpy (xlbuf + hsize , (char * )newitem ,newitemsz );
772- hsize += newitemsz ;
798+ /*
799+ * Read comments in _bt_pgaddtup.
800+ * Actually, seems that in non-leaf splits newitem shouldn't
801+ * go to first data key position.
802+ */
803+ if (!P_ISLEAF (lopaque )&& itup_off == P_FIRSTDATAKEY (lopaque ))
804+ {
805+ BTItemData truncitem = * newitem ;
806+ truncitem .bti_itup .t_info = sizeof (BTItemData );
807+ memcpy (xlbuf + hsize ,& truncitem ,sizeof (BTItemData ));
808+ hsize += sizeof (BTItemData );
809+ }
810+ else
811+ {
812+ Size itemsz = IndexTupleDSize (newitem -> bti_itup )+
813+ (sizeof (BTItemData )- sizeof (IndexTupleData ));
814+ memcpy (xlbuf + hsize , (char * )newitem ,itemsz );
815+ hsize += itemsz ;
816+ }
773817xlrec -> otherblk = BufferGetBlockNumber (rbuf );
774818}
775819else
@@ -1012,7 +1056,7 @@ static Buffer
10121056_bt_getstackbuf (Relation rel ,BTStack stack )
10131057{
10141058BlockNumber blkno ;
1015- Buffer buf ;
1059+ Buffer buf , newbuf ;
10161060OffsetNumber start ,
10171061offnum ,
10181062maxoff ;
@@ -1101,11 +1145,18 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
11011145Size itemsz ;
11021146BTItem new_item ;
11031147
1148+ #ifdef XLOG
1149+ Buffer metabuf ;
1150+ #endif
1151+
11041152/* get a new root page */
11051153rootbuf = _bt_getbuf (rel ,P_NEW ,BT_WRITE );
11061154rootpage = BufferGetPage (rootbuf );
11071155rootblknum = BufferGetBlockNumber (rootbuf );
11081156
1157+ #ifdef XLOG
1158+ metabuf = _bt_getbuf (rel ,BTREE_METAPAGE ,BT_WRITE );
1159+ #endif
11091160
11101161/* NO ELOG(ERROR) from here till newroot op is logged */
11111162
@@ -1168,9 +1219,12 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
11681219#ifdef XLOG
11691220/* XLOG stuff */
11701221{
1171- xl_btree_newroot xlrec ;
1222+ xl_btree_newroot xlrec ;
1223+ Page metapg = BufferGetPage (metabuf );
1224+ BTMetaPageData * metad = BTPageGetMeta (metapg );
1225+
11721226xlrec .node = rel -> rd_node ;
1173- xlrec .rootblk = rootblknum ;
1227+ BlockIdSet ( & ( xlrec .rootblk ), rootblknum ) ;
11741228
11751229/*
11761230 * Dirrect access to page is not good but faster - we should
@@ -1181,16 +1235,25 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
11811235(char * )rootpage + (PageHeader )rootpage )-> pd_upper ,
11821236((PageHeader )rootpage )-> pd_special - ((PageHeader )rootpage )-> upper );
11831237
1238+ metad -> btm_root = rootblknum ;
1239+ (metad -> btm_level )++ ;
1240+
11841241PageSetLSN (rootpage ,recptr );
11851242PageSetSUI (rootpage ,ThisStartUpID );
1243+ PageSetLSN (metapg ,recptr );
1244+ PageSetSUI (metapg ,ThisStartUpID );
1245+
1246+ _bt_wrtbuf (rel ,metabuf );
11861247}
11871248#endif
11881249
11891250/* write and let go of the new root buffer */
11901251_bt_wrtbuf (rel ,rootbuf );
11911252
1253+ #ifndef XLOG
11921254/* update metadata page with new root block number */
11931255_bt_metaproot (rel ,rootblknum ,0 );
1256+ #endif
11941257
11951258/* update and release new sibling, and finally the old root */
11961259_bt_wrtbuf (rel ,rbuf );