aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/nbtree/nbtinsert.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access/nbtree/nbtinsert.c')
-rw-r--r--src/backend/access/nbtree/nbtinsert.c85
1 files changed, 74 insertions, 11 deletions
diff --git a/src/backend/access/nbtree/nbtinsert.c b/src/backend/access/nbtree/nbtinsert.c
index e454a989ee4..c72b8ca3df6 100644
--- a/src/backend/access/nbtree/nbtinsert.c
+++ b/src/backend/access/nbtree/nbtinsert.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.64 2000/10/05 20:10:20 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.65 2000/10/13 02:03:00 vadim Exp $
*
*-------------------------------------------------------------------------
*/
@@ -61,6 +61,10 @@ static void _bt_pgaddtup(Relation rel, Page page,
static bool _bt_isequal(TupleDesc itupdesc, Page page, OffsetNumber offnum,
int keysz, ScanKey scankey);
+#ifdef XLOG
+static Relation _xlheapRel; /* temporary hack */
+#endif
+
/*
* _bt_doinsert() -- Handle insertion of a single btitem in the tree.
*
@@ -119,6 +123,10 @@ top:
}
}
+#ifdef XLOG
+ _xlheapRel = heapRel; /* temporary hack */
+#endif
+
/* do the insertion */
res = _bt_insertonpg(rel, buf, stack, natts, itup_scankey, btitem, 0);
@@ -517,21 +525,38 @@ _bt_insertonpg(Relation rel,
#ifdef XLOG
/* XLOG stuff */
{
- char xlbuf[sizeof(xl_btree_insert) + 2 * sizeof(CommandId)];
+ char xlbuf[sizeof(xl_btree_insert) +
+ sizeof(CommandId) + sizeof(RelFileNode)];
xl_btree_insert *xlrec = xlbuf;
int hsize = SizeOfBtreeInsert;
+ BTItemData truncitem;
+ BTItem xlitem = btitem;
+ Size xlsize = IndexTupleDSize(btitem->bti_itup) +
+ (sizeof(BTItemData) - sizeof(IndexTupleData));
xlrec->target.node = rel->rd_node;
ItemPointerSet(&(xlrec->target.tid), BufferGetBlockNumber(buf), newitemoff);
if (P_ISLEAF(lpageop))
- {
+ {
CommandId cid = GetCurrentCommandId();
- memcpy(xlbuf + SizeOfBtreeInsert, &(char*)cid, sizeof(CommandId));
+ memcpy(xlbuf + hsize, &cid, sizeof(CommandId));
hsize += sizeof(CommandId);
+ memcpy(xlbuf + hsize, &(_xlheapRel->rd_node), sizeof(RelFileNode));
+ hsize += sizeof(RelFileNode);
+ }
+ /*
+ * Read comments in _bt_pgaddtup
+ */
+ else if (newitemoff == P_FIRSTDATAKEY(lpageop))
+ {
+ truncitem = *btitem;
+ truncitem.bti_itup.t_info = sizeof(BTItemData);
+ xlitem = &truncitem;
+ xlsize = sizeof(BTItemData);
}
XLogRecPtr recptr = XLogInsert(RM_BTREE_ID, XLOG_BTREE_INSERT,
- xlbuf, hsize, (char*) btitem, itemsz);
+ xlbuf, hsize, (char*) xlitem, xlsize);
PageSetLSN(page, recptr);
PageSetSUI(page, ThisStartUpID);
@@ -752,7 +777,7 @@ _bt_split(Relation rel, Buffer buf, OffsetNumber firstright,
*/
{
char xlbuf[sizeof(xl_btree_split) +
- 2 * sizeof(CommandId) + BLCKSZ];
+ sizeof(CommandId) + sizeof(RelFileNode) + BLCKSZ];
xl_btree_split *xlrec = xlbuf;
int hsize = SizeOfBtreeSplit;
int flag = (newitemonleft) ?
@@ -765,11 +790,30 @@ _bt_split(Relation rel, Buffer buf, OffsetNumber firstright,
CommandId cid = GetCurrentCommandId();
memcpy(xlbuf + hsize, &(char*)cid, sizeof(CommandId));
hsize += sizeof(CommandId);
+ memcpy(xlbuf + hsize, &(_xlheapRel->rd_node), sizeof(RelFileNode));
+ hsize += sizeof(RelFileNode);
}
if (newitemonleft)
{
- memcpy(xlbuf + hsize, (char*) newitem, newitemsz);
- hsize += newitemsz;
+ /*
+ * Read comments in _bt_pgaddtup.
+ * Actually, seems that in non-leaf splits newitem shouldn't
+ * go to first data key position.
+ */
+ if (! P_ISLEAF(lopaque) && itup_off == P_FIRSTDATAKEY(lopaque))
+ {
+ BTItemData truncitem = *newitem;
+ truncitem.bti_itup.t_info = sizeof(BTItemData);
+ memcpy(xlbuf + hsize, &truncitem, sizeof(BTItemData));
+ hsize += sizeof(BTItemData);
+ }
+ else
+ {
+ Size itemsz = IndexTupleDSize(newitem->bti_itup) +
+ (sizeof(BTItemData) - sizeof(IndexTupleData));
+ memcpy(xlbuf + hsize, (char*) newitem, itemsz);
+ hsize += itemsz;
+ }
xlrec->otherblk = BufferGetBlockNumber(rbuf);
}
else
@@ -1012,7 +1056,7 @@ static Buffer
_bt_getstackbuf(Relation rel, BTStack stack)
{
BlockNumber blkno;
- Buffer buf;
+ Buffer buf, newbuf;
OffsetNumber start,
offnum,
maxoff;
@@ -1101,11 +1145,18 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
Size itemsz;
BTItem new_item;
+#ifdef XLOG
+ Buffer metabuf;
+#endif
+
/* get a new root page */
rootbuf = _bt_getbuf(rel, P_NEW, BT_WRITE);
rootpage = BufferGetPage(rootbuf);
rootblknum = BufferGetBlockNumber(rootbuf);
+#ifdef XLOG
+ metabuf = _bt_getbuf(rel, BTREE_METAPAGE,BT_WRITE);
+#endif
/* NO ELOG(ERROR) from here till newroot op is logged */
@@ -1168,9 +1219,12 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
#ifdef XLOG
/* XLOG stuff */
{
- xl_btree_newroot xlrec;
+ xl_btree_newroot xlrec;
+ Page metapg = BufferGetPage(metabuf);
+ BTMetaPageData *metad = BTPageGetMeta(metapg);
+
xlrec.node = rel->rd_node;
- xlrec.rootblk = rootblknum;
+ BlockIdSet(&(xlrec.rootblk), rootblknum);
/*
* Dirrect access to page is not good but faster - we should
@@ -1181,16 +1235,25 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
(char*)rootpage + (PageHeader) rootpage)->pd_upper,
((PageHeader) rootpage)->pd_special - ((PageHeader) rootpage)->upper);
+ metad->btm_root = rootblknum;
+ (metad->btm_level)++;
+
PageSetLSN(rootpage, recptr);
PageSetSUI(rootpage, ThisStartUpID);
+ PageSetLSN(metapg, recptr);
+ PageSetSUI(metapg, ThisStartUpID);
+
+ _bt_wrtbuf(rel, metabuf);
}
#endif
/* write and let go of the new root buffer */
_bt_wrtbuf(rel, rootbuf);
+#ifndef XLOG
/* update metadata page with new root block number */
_bt_metaproot(rel, rootblknum, 0);
+#endif
/* update and release new sibling, and finally the old root */
_bt_wrtbuf(rel, rbuf);