diff options
Diffstat (limited to 'src/backend/access/heap/heapam.c')
-rw-r--r-- | src/backend/access/heap/heapam.c | 87 |
1 files changed, 58 insertions, 29 deletions
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d56d6abf2bc..49ec63658f2 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.112 2001/03/22 06:16:07 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.113 2001/03/25 23:23:58 tgl Exp $ * * * INTERFACE ROUTINES @@ -2126,10 +2126,19 @@ static XLogRecPtr log_heap_update(Relation reln, Buffer oldbuf, ItemPointerData from, Buffer newbuf, HeapTuple newtup, bool move) { - char tbuf[MAXALIGN(sizeof(xl_heap_header)) + 2 * sizeof(TransactionId)]; - xl_heap_update xlrec; - xl_heap_header *xlhdr = (xl_heap_header *) tbuf; + /* + * Note: xlhdr is declared to have adequate size and correct alignment + * for an xl_heap_header. However the two tids, if present at all, + * will be packed in with no wasted space after the xl_heap_header; + * they aren't necessarily aligned as implied by this struct declaration. + */ + struct { + xl_heap_header hdr; + TransactionId tid1; + TransactionId tid2; + } xlhdr; int hsize = SizeOfHeapHeader; + xl_heap_update xlrec; XLogRecPtr recptr; XLogRecData rdata[4]; Page page = BufferGetPage(newbuf); @@ -2148,10 +2157,10 @@ log_heap_update(Relation reln, Buffer oldbuf, ItemPointerData from, rdata[1].len = 0; rdata[1].next = &(rdata[2]); - xlhdr->t_oid = newtup->t_data->t_oid; - xlhdr->t_natts = newtup->t_data->t_natts; - xlhdr->t_hoff = newtup->t_data->t_hoff; - xlhdr->mask = newtup->t_data->t_infomask; + xlhdr.hdr.t_oid = newtup->t_data->t_oid; + xlhdr.hdr.t_natts = newtup->t_data->t_natts; + xlhdr.hdr.t_hoff = newtup->t_data->t_hoff; + xlhdr.hdr.mask = newtup->t_data->t_infomask; if (move) /* remember xmin & xmax */ { TransactionId xmax; @@ -2161,13 +2170,13 @@ log_heap_update(Relation reln, Buffer oldbuf, ItemPointerData from, xmax = InvalidTransactionId; else xmax = newtup->t_data->t_xmax; - memcpy(tbuf + hsize, &xmax, sizeof(TransactionId)); - memcpy(tbuf + hsize + sizeof(TransactionId), + memcpy((char *) &xlhdr + hsize, &xmax, sizeof(TransactionId)); + memcpy((char *) &xlhdr + hsize + sizeof(TransactionId), &(newtup->t_data->t_xmin), sizeof(TransactionId)); - hsize += (2 * sizeof(TransactionId)); + hsize += 2 * sizeof(TransactionId); } rdata[2].buffer = newbuf; - rdata[2].data = (char *) xlhdr; + rdata[2].data = (char *) &xlhdr; rdata[2].len = hsize; rdata[2].next = &(rdata[3]); @@ -2228,13 +2237,16 @@ heap_xlog_clean(bool redo, XLogRecPtr lsn, XLogRecord *record) if (record->xl_len > SizeOfHeapClean) { - char unbuf[BLCKSZ]; - OffsetNumber *unused = (OffsetNumber *) unbuf; + OffsetNumber unbuf[BLCKSZ/sizeof(OffsetNumber)]; + OffsetNumber *unused = unbuf; char *unend; ItemId lp; - memcpy(unbuf, (char *) xlrec + SizeOfHeapClean, record->xl_len - SizeOfHeapClean); - unend = unbuf + (record->xl_len - SizeOfHeapClean); + Assert((record->xl_len - SizeOfHeapClean) <= BLCKSZ); + memcpy((char *) unbuf, + (char *) xlrec + SizeOfHeapClean, + record->xl_len - SizeOfHeapClean); + unend = (char *) unbuf + (record->xl_len - SizeOfHeapClean); while ((char *) unused < unend) { @@ -2318,7 +2330,6 @@ heap_xlog_insert(bool redo, XLogRecPtr lsn, XLogRecord *record) Buffer buffer; Page page; OffsetNumber offnum; - HeapTupleHeader htup; if (redo && (record->xl_info & XLR_BKP_BLOCK_1)) return; @@ -2338,7 +2349,11 @@ heap_xlog_insert(bool redo, XLogRecPtr lsn, XLogRecord *record) if (redo) { - char tbuf[MaxTupleSize]; + struct { + HeapTupleHeaderData hdr; + char data[MaxTupleSize]; + } tbuf; + HeapTupleHeader htup; xl_heap_header xlhdr; uint32 newlen; @@ -2359,11 +2374,15 @@ heap_xlog_insert(bool redo, XLogRecPtr lsn, XLogRecord *record) elog(STOP, "heap_insert_redo: invalid max offset number"); newlen = record->xl_len - SizeOfHeapInsert - SizeOfHeapHeader; - memcpy((char *) &xlhdr, (char *) xlrec + SizeOfHeapInsert, SizeOfHeapHeader); - memcpy(tbuf + offsetof(HeapTupleHeaderData, t_bits), - (char *) xlrec + SizeOfHeapInsert + SizeOfHeapHeader, newlen); + Assert(newlen <= MaxTupleSize); + memcpy((char *) &xlhdr, + (char *) xlrec + SizeOfHeapInsert, + SizeOfHeapHeader); + memcpy((char *) &tbuf + offsetof(HeapTupleHeaderData, t_bits), + (char *) xlrec + SizeOfHeapInsert + SizeOfHeapHeader, + newlen); newlen += offsetof(HeapTupleHeaderData, t_bits); - htup = (HeapTupleHeader) tbuf; + htup = &tbuf.hdr; htup->t_oid = xlhdr.t_oid; htup->t_natts = xlhdr.t_natts; htup->t_hoff = xlhdr.t_hoff; @@ -2496,7 +2515,10 @@ newsame:; if (redo) { - char tbuf[MaxTupleSize]; + struct { + HeapTupleHeaderData hdr; + char data[MaxTupleSize]; + } tbuf; xl_heap_header xlhdr; int hsize; uint32 newlen; @@ -2522,20 +2544,27 @@ newsame:; hsize += (2 * sizeof(TransactionId)); newlen = record->xl_len - hsize; - memcpy((char *) &xlhdr, (char *) xlrec + SizeOfHeapUpdate, SizeOfHeapHeader); - memcpy(tbuf + offsetof(HeapTupleHeaderData, t_bits), - (char *) xlrec + hsize, newlen); + Assert(newlen <= MaxTupleSize); + memcpy((char *) &xlhdr, + (char *) xlrec + SizeOfHeapUpdate, + SizeOfHeapHeader); + memcpy((char *) &tbuf + offsetof(HeapTupleHeaderData, t_bits), + (char *) xlrec + hsize, + newlen); newlen += offsetof(HeapTupleHeaderData, t_bits); - htup = (HeapTupleHeader) tbuf; + htup = &tbuf.hdr; htup->t_oid = xlhdr.t_oid; htup->t_natts = xlhdr.t_natts; htup->t_hoff = xlhdr.t_hoff; if (move) { hsize = SizeOfHeapUpdate + SizeOfHeapHeader; - memcpy(&(htup->t_xmax), (char *) xlrec + hsize, sizeof(TransactionId)); + memcpy(&(htup->t_xmax), + (char *) xlrec + hsize, + sizeof(TransactionId)); memcpy(&(htup->t_xmin), - (char *) xlrec + hsize + sizeof(TransactionId), sizeof(TransactionId)); + (char *) xlrec + hsize + sizeof(TransactionId), + sizeof(TransactionId)); TransactionIdStore(record->xl_xid, (TransactionId *) &(htup->t_cmin)); htup->t_infomask = xlhdr.mask; htup->t_infomask &= ~(HEAP_XMIN_COMMITTED | |