8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.74 2000/07/02 22:00:27 momjian Exp $
11
+ * $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.75 2000/07/03 02:54:15 vadim Exp $
12
12
*
13
13
*
14
14
* INTERFACE ROUTINES
@@ -1271,10 +1271,9 @@ heap_get_latest_tid(Relation relation,
1271
1271
Oid
1272
1272
heap_insert (Relation relation , HeapTuple tup )
1273
1273
{
1274
- /* ----------------
1275
- * increment access statistics
1276
- * ----------------
1277
- */
1274
+ Buffer buffer ;
1275
+
1276
+ /* increment access statistics */
1278
1277
tup -> tableOid = relation -> rd_id ;
1279
1278
IncrHeapAccessStat (local_insert );
1280
1279
IncrHeapAccessStat (global_insert );
@@ -1300,15 +1299,20 @@ heap_insert(Relation relation, HeapTuple tup)
1300
1299
tup -> t_data -> t_infomask &= ~(HEAP_XACT_MASK );
1301
1300
tup -> t_data -> t_infomask |= HEAP_XMAX_INVALID ;
1302
1301
1303
- RelationPutHeapTupleAtEnd (relation , tup );
1302
+ /* Find buffer for this tuple */
1303
+ buffer = RelationGetBufferForTuple (relation , tup -> t_len , InvalidBuffer );
1304
+
1305
+ /* NO ELOG(ERROR) from here till changes are logged */
1306
+ RelationPutHeapTuple (relation , buffer , tup );
1304
1307
1305
1308
#ifdef XLOG
1306
1309
/* XLOG stuff */
1307
1310
{
1308
1311
xl_heap_insert xlrec ;
1309
1312
xlrec .itid .dbId = relation -> rd_lockInfo .lockRelId .dbId ;
1310
1313
xlrec .itid .relId = relation -> rd_lockInfo .lockRelId .relId ;
1311
- XXX xlrec .itid .tid = tp .t_self ;
1314
+ xlrec .itid .cid = GetCurrentCommandId ();
1315
+ xlrec .itid .tid = tup -> t_self ;
1312
1316
xlrec .t_natts = tup -> t_data -> t_natts ;
1313
1317
xlrec .t_oid = tup -> t_data -> t_oid ;
1314
1318
xlrec .t_hoff = tup -> t_data -> t_hoff ;
@@ -1319,10 +1323,14 @@ XXX xlrec.itid.tid = tp.t_self;
1319
1323
(char * ) tup -> t_data + offsetof(HeapTupleHeaderData , tbits ),
1320
1324
tup -> t_len - offsetof(HeapTupleHeaderData , tbits ));
1321
1325
1322
- dp -> pd_lsn = recptr ;
1326
+ ((PageHeader ) BufferGetPage (buffer ))-> pd_lsn = recptr ;
1327
+ ((PageHeader ) BufferGetPage (buffer ))-> pd_sui = ThisStartUpID ;
1323
1328
}
1324
1329
#endif
1325
1330
1331
+ LockBuffer (buffer , BUFFER_LOCK_UNLOCK );
1332
+ WriteBuffer (buffer );
1333
+
1326
1334
if (IsSystemRelationName (RelationGetRelationName (relation )))
1327
1335
RelationMark4RollbackHeapTuple (relation , tup );
1328
1336
@@ -1417,11 +1425,13 @@ heap_delete(Relation relation, ItemPointer tid, ItemPointer ctid)
1417
1425
xl_heap_delete xlrec ;
1418
1426
xlrec .dtid .dbId = relation -> rd_lockInfo .lockRelId .dbId ;
1419
1427
xlrec .dtid .relId = relation -> rd_lockInfo .lockRelId .relId ;
1428
+ xlrec .dtid .cid = GetCurrentCommandId ();
1420
1429
xlrec .dtid .tid = tp .t_self ;
1421
1430
XLogRecPtr recptr = XLogInsert (RM_HEAP_ID , XLOG_HEAP_DELETE ,
1422
1431
(char * ) xlrec , sizeof (xlrec ), NULL , 0 );
1423
1432
1424
1433
dp -> pd_lsn = recptr ;
1434
+ dp -> pd_sui = ThisStartUpID ;
1425
1435
}
1426
1436
#endif
1427
1437
@@ -1451,7 +1461,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
1451
1461
ItemId lp ;
1452
1462
HeapTupleData oldtup ;
1453
1463
PageHeader dp ;
1454
- Buffer buffer ;
1464
+ Buffer buffer , newbuf ;
1455
1465
int result ;
1456
1466
1457
1467
newtup -> tableOid = relation -> rd_id ;
@@ -1531,43 +1541,65 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
1531
1541
newtup -> t_data -> t_infomask &= ~(HEAP_XACT_MASK );
1532
1542
newtup -> t_data -> t_infomask |= (HEAP_XMAX_INVALID | HEAP_UPDATED );
1533
1543
1534
- /* logically delete old item */
1544
+ /* Find buffer for new tuple */
1545
+
1546
+ if ((unsigned ) MAXALIGN (newtup -> t_len ) <= PageGetFreeSpace ((Page ) dp ))
1547
+ newbuf = buffer ;
1548
+ else
1549
+ newbuf = RelationGetBufferForTuple (relation , newtup -> t_len , buffer );
1550
+
1551
+ /* NO ELOG(ERROR) from here till changes are logged */
1552
+
1553
+ /* insert new tuple */
1554
+ RelationPutHeapTuple (relation , newbuf , newtup );
1555
+
1556
+ /* logically delete old tuple */
1535
1557
TransactionIdStore (GetCurrentTransactionId (), & (oldtup .t_data -> t_xmax ));
1536
1558
oldtup .t_data -> t_cmax = GetCurrentCommandId ();
1537
1559
oldtup .t_data -> t_infomask &= ~(HEAP_XMAX_COMMITTED |
1538
1560
HEAP_XMAX_INVALID | HEAP_MARKED_FOR_UPDATE );
1539
1561
1540
- /* insert new item */
1541
- if ((unsigned ) MAXALIGN (newtup -> t_len ) <= PageGetFreeSpace ((Page ) dp ))
1542
- RelationPutHeapTuple (relation , buffer , newtup );
1543
- else
1562
+ /* record address of new tuple in t_ctid of old one */
1563
+ oldtup .t_data -> t_ctid = newtup -> t_self ;
1564
+
1565
+ #ifdef XLOG
1566
+ /* XLOG stuff */
1544
1567
{
1568
+ xl_heap_update xlrec ;
1569
+ xlrec .dtid .dbId = relation -> rd_lockInfo .lockRelId .dbId ;
1570
+ xlrec .dtid .relId = relation -> rd_lockInfo .lockRelId .relId ;
1571
+ xlrec .dtid .cid = GetCurrentCommandId ();
1572
+ xlrec .itid .tid = newtup -> t_self ;
1573
+ xlrec .t_natts = newtup -> t_data -> t_natts ;
1574
+ xlrec .t_hoff = newtup -> t_data -> t_hoff ;
1575
+ xlrec .mask = newtup -> t_data -> t_infomask ;
1576
+
1577
+ XLogRecPtr recptr = XLogInsert (RM_HEAP_ID , XLOG_HEAP_UPDATE ,
1578
+ (char * ) xlrec , sizeof (xlrec ),
1579
+ (char * ) newtup -> t_data + offsetof(HeapTupleHeaderData , tbits ),
1580
+ newtup -> t_len - offsetof(HeapTupleHeaderData , tbits ));
1545
1581
1546
- /*
1547
- * New item won't fit on same page as old item, have to look for a
1548
- * new place to put it. Note that we have to unlock current buffer
1549
- * context - not good but RelationPutHeapTupleAtEnd uses extend
1550
- * lock.
1551
- */
1552
- LockBuffer (buffer , BUFFER_LOCK_UNLOCK );
1553
- RelationPutHeapTupleAtEnd (relation , newtup );
1554
- LockBuffer (buffer , BUFFER_LOCK_EXCLUSIVE );
1582
+ if (newbuf != buffer )
1583
+ {
1584
+ ((PageHeader ) BufferGetPage (newbuf ))-> pd_lsn = recptr ;
1585
+ ((PageHeader ) BufferGetPage (newbuf ))-> pd_sui = ThisStartUpID ;
1586
+ }
1587
+ ((PageHeader ) BufferGetPage (buffer ))-> pd_lsn = recptr ;
1588
+ ((PageHeader ) BufferGetPage (buffer ))-> pd_sui = ThisStartUpID ;
1555
1589
}
1556
- /* mark for rollback caches */
1557
- RelationMark4RollbackHeapTuple (relation , newtup );
1558
-
1559
- /*
1560
- * New item in place, now record address of new tuple in t_ctid of old
1561
- * one.
1562
- */
1563
- oldtup .t_data -> t_ctid = newtup -> t_self ;
1590
+ #endif
1564
1591
1592
+ if (newbuf != buffer )
1593
+ {
1594
+ LockBuffer (newbuf , BUFFER_LOCK_UNLOCK );
1595
+ WriteBuffer (newbuf );
1596
+ }
1565
1597
LockBuffer (buffer , BUFFER_LOCK_UNLOCK );
1598
+ WriteBuffer (buffer );
1566
1599
1567
1600
/* invalidate caches */
1568
1601
RelationInvalidateHeapTuple (relation , & oldtup );
1569
-
1570
- WriteBuffer (buffer );
1602
+ RelationMark4RollbackHeapTuple (relation , newtup );
1571
1603
1572
1604
return HeapTupleMayBeUpdated ;
1573
1605
}
@@ -1648,6 +1680,14 @@ heap_mark4update(Relation relation, HeapTuple tuple, Buffer *buffer)
1648
1680
return result ;
1649
1681
}
1650
1682
1683
+ #ifdef XLOG
1684
+ /*
1685
+ * XLOG stuff: no logging is required as long as we have no
1686
+ * savepoints. For savepoints private log could be used...
1687
+ */
1688
+ ((PageHeader ) BufferGetPage (* buffer ))-> pd_sui = ThisStartUpID ;
1689
+ #endif
1690
+
1651
1691
/* store transaction information of xact marking the tuple */
1652
1692
TransactionIdStore (GetCurrentTransactionId (), & (tuple -> t_data -> t_xmax ));
1653
1693
tuple -> t_data -> t_cmax = GetCurrentCommandId ();
0 commit comments