From ccd415c63feb034b071e28f2df189718eec6c911 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sun, 25 Mar 2001 23:23:59 +0000 Subject: [PATCH] Fix unportable assumptions about alignment of local char[n] variables. --- src/backend/access/heap/heapam.c | 87 ++++++++++++++-------- src/backend/commands/vacuum.c | 18 ++--- src/backend/storage/large_object/inv_api.c | 17 +++-- src/backend/utils/mb/wstrncmp.c | 13 ++-- 4 files changed, 82 insertions(+), 53 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d56d6abf2b..49ec63658f 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 | diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 078c9b5347..694d0e8bbc 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.188 2001/03/22 03:59:24 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.189 2001/03/25 23:23:58 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -303,10 +303,9 @@ getrels(NameData *VacRelP) found = true; d = heap_getattr(tuple, Anum_pg_class_relname, tupdesc, &n); - rname = (char *) d; + rname = (char *) DatumGetPointer(d); d = heap_getattr(tuple, Anum_pg_class_relkind, tupdesc, &n); - rkind = DatumGetChar(d); if (rkind != RELKIND_RELATION) @@ -997,8 +996,8 @@ repair_frag(VRelStats *vacrelstats, Relation onerel, blkno; Page page, ToPage = NULL; - OffsetNumber offnum = 0, - maxoff = 0, + OffsetNumber offnum, + maxoff, newoff, max_offset; ItemId itemid, @@ -1913,14 +1912,15 @@ failed to add item with len = %lu to page %u (free space %lu, nusd %u, noff %u)" if (vacpage->blkno == (BlockNumber) (blkno - 1) && vacpage->offsets_free > 0) { - char unbuf[BLCKSZ]; - OffsetNumber *unused = (OffsetNumber *) unbuf; + OffsetNumber unbuf[BLCKSZ/sizeof(OffsetNumber)]; + OffsetNumber *unused = unbuf; int uncnt; buf = ReadBuffer(onerel, vacpage->blkno); LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); page = BufferGetPage(buf); num_tuples = 0; + maxoff = PageGetMaxOffsetNumber(page); for (offnum = FirstOffsetNumber; offnum <= maxoff; offnum = OffsetNumberNext(offnum)) @@ -2061,8 +2061,8 @@ vacuum_heap(VRelStats *vacrelstats, Relation onerel, VacPageList vacuum_pages) static void vacuum_page(Relation onerel, Buffer buffer, VacPage vacpage) { - char unbuf[BLCKSZ]; - OffsetNumber *unused = (OffsetNumber *) unbuf; + OffsetNumber unbuf[BLCKSZ/sizeof(OffsetNumber)]; + OffsetNumber *unused = unbuf; int uncnt; Page page = BufferGetPage(buffer); ItemId itemid; diff --git a/src/backend/storage/large_object/inv_api.c b/src/backend/storage/large_object/inv_api.c index dba45d6590..6f20449d1f 100644 --- a/src/backend/storage/large_object/inv_api.c +++ b/src/backend/storage/large_object/inv_api.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/storage/large_object/inv_api.c,v 1.86 2001/03/22 03:59:45 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/storage/large_object/inv_api.c,v 1.87 2001/03/25 23:23:59 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -416,8 +416,11 @@ inv_write(LargeObjectDesc *obj_desc, char *buf, int nbytes) bool neednextpage; bytea *datafield; bool pfreeit; - char workbuf[LOBLKSIZE + VARHDRSZ]; - char *workb = VARATT_DATA(workbuf); + struct { + struct varlena hdr; + char data[LOBLKSIZE]; + } workbuf; + char *workb = VARATT_DATA(&workbuf.hdr); HeapTuple newtup; Datum values[Natts_pg_largeobject]; char nulls[Natts_pg_largeobject]; @@ -526,7 +529,7 @@ inv_write(LargeObjectDesc *obj_desc, char *buf, int nbytes) off += n; /* compute valid length of new page */ len = (len >= off) ? len : off; - VARATT_SIZEP(workbuf) = len + VARHDRSZ; + VARATT_SIZEP(&workbuf.hdr) = len + VARHDRSZ; /* * Form and insert updated tuple @@ -534,7 +537,7 @@ inv_write(LargeObjectDesc *obj_desc, char *buf, int nbytes) memset(values, 0, sizeof(values)); memset(nulls, ' ', sizeof(nulls)); memset(replace, ' ', sizeof(replace)); - values[Anum_pg_largeobject_data - 1] = PointerGetDatum(workbuf); + values[Anum_pg_largeobject_data - 1] = PointerGetDatum(&workbuf); replace[Anum_pg_largeobject_data - 1] = 'r'; newtup = heap_modifytuple(&oldtuple, obj_desc->heap_r, values, nulls, replace); @@ -575,7 +578,7 @@ inv_write(LargeObjectDesc *obj_desc, char *buf, int nbytes) obj_desc->offset += n; /* compute valid length of new page */ len = off + n; - VARATT_SIZEP(workbuf) = len + VARHDRSZ; + VARATT_SIZEP(&workbuf.hdr) = len + VARHDRSZ; /* * Form and insert updated tuple @@ -584,7 +587,7 @@ inv_write(LargeObjectDesc *obj_desc, char *buf, int nbytes) memset(nulls, ' ', sizeof(nulls)); values[Anum_pg_largeobject_loid - 1] = ObjectIdGetDatum(obj_desc->id); values[Anum_pg_largeobject_pageno - 1] = Int32GetDatum(pageno); - values[Anum_pg_largeobject_data - 1] = PointerGetDatum(workbuf); + values[Anum_pg_largeobject_data - 1] = PointerGetDatum(&workbuf); newtup = heap_formtuple(obj_desc->heap_r->rd_att, values, nulls); heap_insert(obj_desc->heap_r, newtup); if (write_indices) diff --git a/src/backend/utils/mb/wstrncmp.c b/src/backend/utils/mb/wstrncmp.c index 6464147897..c1aac9c66e 100644 --- a/src/backend/utils/mb/wstrncmp.c +++ b/src/backend/utils/mb/wstrncmp.c @@ -43,14 +43,12 @@ register const pg_wchar *s1, *s2; register size_t n; { - if (n == 0) return 0; do { if (*s1 != *s2++) - return (*(const pg_wchar *) s1 - - *(const pg_wchar *) (s2 - 1)); + return (*s1 - *(s2 - 1)); if (*s1++ == 0) break; } while (--n != 0); @@ -63,14 +61,12 @@ register const char *s1; register const pg_wchar *s2; register size_t n; { - if (n == 0) return 0; do { - if ((pg_wchar) * s1 != *s2++) - return (*(const pg_wchar *) s1 - - *(const pg_wchar *) (s2 - 1)); + if ((pg_wchar) ((unsigned char) *s1) != *s2++) + return ((pg_wchar) ((unsigned char) *s1) - *(s2 - 1)); if (*s1++ == 0) break; } while (--n != 0); @@ -83,6 +79,7 @@ const pg_wchar *str; { register const pg_wchar *s; - for (s = str; *s; ++s); + for (s = str; *s; ++s) + ; return (s - str); }