]> granicus.if.org Git - postgresql/commitdiff
Use FLEXIBLE_ARRAY_MEMBER for HeapTupleHeaderData.t_bits[].
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 21 Feb 2015 20:13:06 +0000 (15:13 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 21 Feb 2015 20:13:06 +0000 (15:13 -0500)
This requires changing quite a few places that were depending on
sizeof(HeapTupleHeaderData), but it seems for the best.

Michael Paquier, some adjustments by me

19 files changed:
contrib/file_fdw/file_fdw.c
contrib/pageinspect/heapfuncs.c
contrib/postgres_fdw/postgres_fdw.c
src/backend/access/common/heaptuple.c
src/backend/access/heap/heapam.c
src/backend/access/heap/tuptoaster.c
src/backend/catalog/toasting.c
src/backend/executor/nodeHash.c
src/backend/optimizer/path/costsize.c
src/backend/optimizer/plan/planner.c
src/backend/optimizer/plan/subselect.c
src/backend/optimizer/prep/prepunion.c
src/backend/optimizer/util/plancat.c
src/backend/replication/logical/decode.c
src/backend/replication/logical/reorderbuffer.c
src/backend/utils/adt/trigfuncs.c
src/include/access/htup_details.h
src/include/access/tuptoaster.h
src/include/replication/reorderbuffer.h

index d5697602117c26aab1c3ca71d9dc2cb808c23a84..4368897581a705f1e27ac6224060eef1f039b916 100644 (file)
@@ -932,7 +932,7 @@ estimate_size(PlannerInfo *root, RelOptInfo *baserel,
                int                     tuple_width;
 
                tuple_width = MAXALIGN(baserel->width) +
-                       MAXALIGN(sizeof(HeapTupleHeaderData));
+                       MAXALIGN(SizeofHeapTupleHeader);
                ntuples = clamp_row_est((double) stat_buf.st_size /
                                                                (double) tuple_width);
        }
index c8876f3dbca5843d55cb12ef66076e67e4e02bf8..8d1666c8bda3a10e77bc7a9f33dbfd5741599e2e 100644 (file)
@@ -149,7 +149,7 @@ heap_page_items(PG_FUNCTION_ARGS)
                 * many other ways, but at least we won't crash.
                 */
                if (ItemIdHasStorage(id) &&
-                       lp_len >= sizeof(HeapTupleHeader) &&
+                       lp_len >= MinHeapTupleSize &&
                        lp_offset == MAXALIGN(lp_offset) &&
                        lp_offset + lp_len <= raw_page_size)
                {
@@ -169,18 +169,19 @@ heap_page_items(PG_FUNCTION_ARGS)
                        values[10] = UInt8GetDatum(tuphdr->t_hoff);
 
                        /*
-                        * We already checked that the item as is completely within the
-                        * raw page passed to us, with the length given in the line
-                        * pointer.. Let's check that t_hoff doesn't point over lp_len,
-                        * before using it to access t_bits and oid.
+                        * We already checked that the item is completely within the raw
+                        * page passed to us, with the length given in the line pointer.
+                        * Let's check that t_hoff doesn't point over lp_len, before using
+                        * it to access t_bits and oid.
                         */
-                       if (tuphdr->t_hoff >= sizeof(HeapTupleHeader) &&
-                               tuphdr->t_hoff <= lp_len)
+                       if (tuphdr->t_hoff >= SizeofHeapTupleHeader &&
+                               tuphdr->t_hoff <= lp_len &&
+                               tuphdr->t_hoff == MAXALIGN(tuphdr->t_hoff))
                        {
                                if (tuphdr->t_infomask & HEAP_HASNULL)
                                {
                                        bits_len = tuphdr->t_hoff -
-                                               (((char *) tuphdr->t_bits) -((char *) tuphdr));
+                                               offsetof(HeapTupleHeaderData, t_bits);
 
                                        values[11] = CStringGetTextDatum(
                                                                 bits_to_text(tuphdr->t_bits, bits_len * 8));
index d76e739f0807f3b6319549cfb83a64ab261212da..63f057704e65db38117469c6c3e42de01592bed4 100644 (file)
@@ -519,7 +519,7 @@ postgresGetForeignRelSize(PlannerInfo *root,
                {
                        baserel->pages = 10;
                        baserel->tuples =
-                               (10 * BLCKSZ) / (baserel->width + sizeof(HeapTupleHeaderData));
+                               (10 * BLCKSZ) / (baserel->width + MAXALIGN(SizeofHeapTupleHeader));
                }
 
                /* Estimate baserel size as best we can with local statistics. */
index 867035da7da5badffa46916842052042c0ed7a07..6cd4e8e11ae97a855972c02b085367deadd93e69 100644 (file)
@@ -1434,7 +1434,7 @@ heap_form_minimal_tuple(TupleDesc tupleDescriptor,
        /*
         * Determine total space needed
         */
-       len = offsetof(MinimalTupleData, t_bits);
+       len = SizeofMinimalTupleHeader;
 
        if (hasnull)
                len += BITMAPLEN(numberOfAttributes);
index 46060bc13e23be138f699cdcbac56d85e29c0378..cb6f8a392072d79d666a2400454d7ff3a6b6c247 100644 (file)
@@ -2186,8 +2186,8 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid,
                XLogRegisterBufData(0, (char *) &xlhdr, SizeOfHeapHeader);
                /* PG73FORMAT: write bitmap [+ padding] [+ oid] + data */
                XLogRegisterBufData(0,
-                       (char *) heaptup->t_data + offsetof(HeapTupleHeaderData, t_bits),
-                                        heaptup->t_len - offsetof(HeapTupleHeaderData, t_bits));
+                                                       (char *) heaptup->t_data + SizeofHeapTupleHeader,
+                                                       heaptup->t_len - SizeofHeapTupleHeader);
 
                recptr = XLogInsert(RM_HEAP_ID, info);
 
@@ -2460,9 +2460,9 @@ heap_multi_insert(Relation relation, HeapTuple *tuples, int ntuples,
                                tuphdr->t_hoff = heaptup->t_data->t_hoff;
 
                                /* write bitmap [+ padding] [+ oid] + data */
-                               datalen = heaptup->t_len - offsetof(HeapTupleHeaderData, t_bits);
+                               datalen = heaptup->t_len - SizeofHeapTupleHeader;
                                memcpy(scratchptr,
-                                          (char *) heaptup->t_data + offsetof(HeapTupleHeaderData, t_bits),
+                                          (char *) heaptup->t_data + SizeofHeapTupleHeader,
                                           datalen);
                                tuphdr->datalen = datalen;
                                scratchptr += datalen;
@@ -2904,9 +2904,9 @@ l1:
 
                        XLogRegisterData((char *) &xlhdr, SizeOfHeapHeader);
                        XLogRegisterData((char *) old_key_tuple->t_data
-                                                        + offsetof(HeapTupleHeaderData, t_bits),
+                                                        + SizeofHeapTupleHeader,
                                                         old_key_tuple->t_len
-                                                        - offsetof(HeapTupleHeaderData, t_bits));
+                                                        - SizeofHeapTupleHeader);
                }
 
                recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_DELETE);
@@ -6732,7 +6732,7 @@ log_heap_update(Relation reln, Buffer oldbuf,
        xlhdr.t_infomask2 = newtup->t_data->t_infomask2;
        xlhdr.t_infomask = newtup->t_data->t_infomask;
        xlhdr.t_hoff = newtup->t_data->t_hoff;
-       Assert(offsetof(HeapTupleHeaderData, t_bits) + prefixlen + suffixlen <= newtup->t_len);
+       Assert(SizeofHeapTupleHeader + prefixlen + suffixlen <= newtup->t_len);
 
        /*
         * PG73FORMAT: write bitmap [+ padding] [+ oid] + data
@@ -6743,8 +6743,8 @@ log_heap_update(Relation reln, Buffer oldbuf,
        if (prefixlen == 0)
        {
                XLogRegisterBufData(0,
-                  ((char *) newtup->t_data) + offsetof(HeapTupleHeaderData, t_bits),
-                  newtup->t_len - offsetof(HeapTupleHeaderData, t_bits) -suffixlen);
+                                                       ((char *) newtup->t_data) + SizeofHeapTupleHeader,
+                                                       newtup->t_len - SizeofHeapTupleHeader - suffixlen);
        }
        else
        {
@@ -6753,11 +6753,11 @@ log_heap_update(Relation reln, Buffer oldbuf,
                 * two separate rdata entries.
                 */
                /* bitmap [+ padding] [+ oid] */
-               if (newtup->t_data->t_hoff - offsetof(HeapTupleHeaderData, t_bits) >0)
+               if (newtup->t_data->t_hoff - SizeofHeapTupleHeader > 0)
                {
                        XLogRegisterBufData(0,
-                       ((char *) newtup->t_data) + offsetof(HeapTupleHeaderData, t_bits),
-                        newtup->t_data->t_hoff - offsetof(HeapTupleHeaderData, t_bits));
+                                                               ((char *) newtup->t_data) + SizeofHeapTupleHeader,
+                                                               newtup->t_data->t_hoff - SizeofHeapTupleHeader);
                }
 
                /* data after common prefix */
@@ -6777,8 +6777,8 @@ log_heap_update(Relation reln, Buffer oldbuf,
                XLogRegisterData((char *) &xlhdr_idx, SizeOfHeapHeader);
 
                /* PG73FORMAT: write bitmap [+ padding] [+ oid] + data */
-               XLogRegisterData((char *) old_key_tuple->t_data + offsetof(HeapTupleHeaderData, t_bits),
-                          old_key_tuple->t_len - offsetof(HeapTupleHeaderData, t_bits));
+               XLogRegisterData((char *) old_key_tuple->t_data + SizeofHeapTupleHeader,
+                                                old_key_tuple->t_len - SizeofHeapTupleHeader);
        }
 
        recptr = XLogInsert(RM_HEAP_ID, info);
@@ -7351,7 +7351,7 @@ heap_xlog_insert(XLogReaderState *record)
        xl_heap_insert *xlrec = (xl_heap_insert *) XLogRecGetData(record);
        Buffer          buffer;
        Page            page;
-       struct
+       union
        {
                HeapTupleHeaderData hdr;
                char            data[MaxHeapTupleSize];
@@ -7415,12 +7415,12 @@ heap_xlog_insert(XLogReaderState *record)
                data += SizeOfHeapHeader;
 
                htup = &tbuf.hdr;
-               MemSet((char *) htup, 0, sizeof(HeapTupleHeaderData));
+               MemSet((char *) htup, 0, SizeofHeapTupleHeader);
                /* PG73FORMAT: get bitmap [+ padding] [+ oid] + data */
-               memcpy((char *) htup + offsetof(HeapTupleHeaderData, t_bits),
+               memcpy((char *) htup + SizeofHeapTupleHeader,
                           data,
                           newlen);
-               newlen += offsetof(HeapTupleHeaderData, t_bits);
+               newlen += SizeofHeapTupleHeader;
                htup->t_infomask2 = xlhdr.t_infomask2;
                htup->t_infomask = xlhdr.t_infomask;
                htup->t_hoff = xlhdr.t_hoff;
@@ -7469,7 +7469,7 @@ heap_xlog_multi_insert(XLogReaderState *record)
        BlockNumber blkno;
        Buffer          buffer;
        Page            page;
-       struct
+       union
        {
                HeapTupleHeaderData hdr;
                char            data[MaxHeapTupleSize];
@@ -7548,14 +7548,14 @@ heap_xlog_multi_insert(XLogReaderState *record)
                        newlen = xlhdr->datalen;
                        Assert(newlen <= MaxHeapTupleSize);
                        htup = &tbuf.hdr;
-                       MemSet((char *) htup, 0, sizeof(HeapTupleHeaderData));
+                       MemSet((char *) htup, 0, SizeofHeapTupleHeader);
                        /* PG73FORMAT: get bitmap [+ padding] [+ oid] + data */
-                       memcpy((char *) htup + offsetof(HeapTupleHeaderData, t_bits),
+                       memcpy((char *) htup + SizeofHeapTupleHeader,
                                   (char *) tupdata,
                                   newlen);
                        tupdata += newlen;
 
-                       newlen += offsetof(HeapTupleHeaderData, t_bits);
+                       newlen += SizeofHeapTupleHeader;
                        htup->t_infomask2 = xlhdr->t_infomask2;
                        htup->t_infomask = xlhdr->t_infomask;
                        htup->t_hoff = xlhdr->t_hoff;
@@ -7618,7 +7618,7 @@ heap_xlog_update(XLogReaderState *record, bool hot_update)
        uint16          prefixlen = 0,
                                suffixlen = 0;
        char       *newp;
-       struct
+       union
        {
                HeapTupleHeaderData hdr;
                char            data[MaxHeapTupleSize];
@@ -7780,19 +7780,19 @@ heap_xlog_update(XLogReaderState *record, bool hot_update)
                Assert(tuplen <= MaxHeapTupleSize);
 
                htup = &tbuf.hdr;
-               MemSet((char *) htup, 0, sizeof(HeapTupleHeaderData));
+               MemSet((char *) htup, 0, SizeofHeapTupleHeader);
 
                /*
                 * Reconstruct the new tuple using the prefix and/or suffix from the
                 * old tuple, and the data stored in the WAL record.
                 */
-               newp = (char *) htup + offsetof(HeapTupleHeaderData, t_bits);
+               newp = (char *) htup + SizeofHeapTupleHeader;
                if (prefixlen > 0)
                {
                        int                     len;
 
                        /* copy bitmap [+ padding] [+ oid] from WAL record */
-                       len = xlhdr.t_hoff - offsetof(HeapTupleHeaderData, t_bits);
+                       len = xlhdr.t_hoff - SizeofHeapTupleHeader;
                        memcpy(newp, recdata, len);
                        recdata += len;
                        newp += len;
@@ -7802,7 +7802,7 @@ heap_xlog_update(XLogReaderState *record, bool hot_update)
                        newp += prefixlen;
 
                        /* copy new tuple data from WAL record */
-                       len = tuplen - (xlhdr.t_hoff - offsetof(HeapTupleHeaderData, t_bits));
+                       len = tuplen - (xlhdr.t_hoff - SizeofHeapTupleHeader);
                        memcpy(newp, recdata, len);
                        recdata += len;
                        newp += len;
@@ -7823,7 +7823,7 @@ heap_xlog_update(XLogReaderState *record, bool hot_update)
                if (suffixlen > 0)
                        memcpy(newp, (char *) oldtup.t_data + oldtup.t_len - suffixlen, suffixlen);
 
-               newlen = offsetof(HeapTupleHeaderData, t_bits) + tuplen + prefixlen + suffixlen;
+               newlen = SizeofHeapTupleHeader + tuplen + prefixlen + suffixlen;
                htup->t_infomask2 = xlhdr.t_infomask2;
                htup->t_infomask = xlhdr.t_infomask;
                htup->t_hoff = xlhdr.t_hoff;
index deb33720ab7568f60f6d06ea1ee8bed776be4e07..8464e8794f65e299b5eb44dc0f1d589d081f0f89 100644 (file)
@@ -677,7 +677,7 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup,
         */
 
        /* compute header overhead --- this should match heap_form_tuple() */
-       hoff = offsetof(HeapTupleHeaderData, t_bits);
+       hoff = SizeofHeapTupleHeader;
        if (has_nulls)
                hoff += BITMAPLEN(numAttrs);
        if (newtup->t_data->t_infomask & HEAP_HASOID)
@@ -963,7 +963,7 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup,
                 * different conclusion about the size of the null bitmap, or even
                 * whether there needs to be one at all.
                 */
-               new_header_len = offsetof(HeapTupleHeaderData, t_bits);
+               new_header_len = SizeofHeapTupleHeader;
                if (has_nulls)
                        new_header_len += BITMAPLEN(numAttrs);
                if (olddata->t_infomask & HEAP_HASOID)
@@ -986,7 +986,7 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup,
                /*
                 * Copy the existing tuple header, but adjust natts and t_hoff.
                 */
-               memcpy(new_data, olddata, offsetof(HeapTupleHeaderData, t_bits));
+               memcpy(new_data, olddata, SizeofHeapTupleHeader);
                HeapTupleHeaderSetNatts(new_data, numAttrs);
                new_data->t_hoff = new_header_len;
                if (olddata->t_infomask & HEAP_HASOID)
@@ -1196,7 +1196,7 @@ toast_flatten_tuple_to_datum(HeapTupleHeader tup,
         *
         * This should match the reconstruction code in toast_insert_or_update.
         */
-       new_header_len = offsetof(HeapTupleHeaderData, t_bits);
+       new_header_len = SizeofHeapTupleHeader;
        if (has_nulls)
                new_header_len += BITMAPLEN(numAttrs);
        if (tup->t_infomask & HEAP_HASOID)
@@ -1211,7 +1211,7 @@ toast_flatten_tuple_to_datum(HeapTupleHeader tup,
        /*
         * Copy the existing tuple header, but adjust natts and t_hoff.
         */
-       memcpy(new_data, tup, offsetof(HeapTupleHeaderData, t_bits));
+       memcpy(new_data, tup, SizeofHeapTupleHeader);
        HeapTupleHeaderSetNatts(new_data, numAttrs);
        new_data->t_hoff = new_header_len;
        if (tup->t_infomask & HEAP_HASOID)
index e73252c9e2a2c19cd9aef4f52b978fcd88a70515..a1efddb98f33969dd95e1c98bb78b224c3a93be9 100644 (file)
@@ -447,7 +447,7 @@ needs_toast_table(Relation rel)
                return false;                   /* nothing to toast? */
        if (maxlength_unknown)
                return true;                    /* any unlimited-length attrs? */
-       tuple_length = MAXALIGN(offsetof(HeapTupleHeaderData, t_bits) +
+       tuple_length = MAXALIGN(SizeofHeapTupleHeader +
                                                        BITMAPLEN(tupdesc->natts)) +
                MAXALIGN(data_length);
        return (tuple_length > TOAST_TUPLE_THRESHOLD);
index abd70b3b1b3319ac07faf5f413cd7707a8ed2324..b1f6c824329329fb2889f34606f2ebfcf53f9b2c 100644 (file)
@@ -439,7 +439,7 @@ ExecChooseHashTableSize(double ntuples, int tupwidth, bool useskew,
         * don't count palloc overhead either.
         */
        tupsize = HJTUPLE_OVERHEAD +
-               MAXALIGN(sizeof(MinimalTupleData)) +
+               MAXALIGN(SizeofMinimalTupleHeader) +
                MAXALIGN(tupwidth);
        inner_rel_bytes = ntuples * tupsize;
 
index 020558b430af072e464231571398d6bc77baa826..78ef22949a6bf3c958cee53f0ab9bdcb6a93561f 100644 (file)
@@ -4036,11 +4036,11 @@ set_rel_width(PlannerInfo *root, RelOptInfo *rel)
 
        /*
         * If we have a whole-row reference, estimate its width as the sum of
-        * per-column widths plus sizeof(HeapTupleHeaderData).
+        * per-column widths plus heap tuple header overhead.
         */
        if (have_wholerow_var)
        {
-               int32           wholerow_width = sizeof(HeapTupleHeaderData);
+               int32           wholerow_width = MAXALIGN(SizeofHeapTupleHeader);
 
                if (reloid != InvalidOid)
                {
@@ -4078,7 +4078,7 @@ set_rel_width(PlannerInfo *root, RelOptInfo *rel)
 static double
 relation_byte_size(double tuples, int width)
 {
-       return tuples * (MAXALIGN(width) + MAXALIGN(sizeof(HeapTupleHeaderData)));
+       return tuples * (MAXALIGN(width) + MAXALIGN(SizeofHeapTupleHeader));
 }
 
 /*
index 5c4884f46b9c0ce9b4f80640dcbc4be7e50d0e47..b02a1079ae4af7d0d93bcbf27087c4437fd26813 100644 (file)
@@ -2755,7 +2755,7 @@ choose_hashed_grouping(PlannerInfo *root,
         */
 
        /* Estimate per-hash-entry space at tuple width... */
-       hashentrysize = MAXALIGN(path_width) + MAXALIGN(sizeof(MinimalTupleData));
+       hashentrysize = MAXALIGN(path_width) + MAXALIGN(SizeofMinimalTupleHeader);
        /* plus space for pass-by-ref transition values... */
        hashentrysize += agg_costs->transitionSpace;
        /* plus the per-hash-entry overhead */
@@ -2923,7 +2923,7 @@ choose_hashed_distinct(PlannerInfo *root,
         */
 
        /* Estimate per-hash-entry space at tuple width... */
-       hashentrysize = MAXALIGN(path_width) + MAXALIGN(sizeof(MinimalTupleData));
+       hashentrysize = MAXALIGN(path_width) + MAXALIGN(SizeofMinimalTupleHeader);
        /* plus the per-hash-entry overhead */
        hashentrysize += hash_agg_entry_size(0);
 
index 78fb6b199ca45757119a7a4a3a6484d97684b2c9..5a1d539e8de94d8c510f912e707e1033fce6bb6f 100644 (file)
@@ -974,12 +974,12 @@ subplan_is_hashable(Plan *plan)
 
        /*
         * The estimated size of the subquery result must fit in work_mem. (Note:
-        * we use sizeof(HeapTupleHeaderData) here even though the tuples will
-        * actually be stored as MinimalTuples; this provides some fudge factor
-        * for hashtable overhead.)
+        * we use heap tuple overhead here even though the tuples will actually be
+        * stored as MinimalTuples; this provides some fudge factor for hashtable
+        * overhead.)
         */
        subquery_size = plan->plan_rows *
-               (MAXALIGN(plan->plan_width) + MAXALIGN(sizeof(HeapTupleHeaderData)));
+               (MAXALIGN(plan->plan_width) + MAXALIGN(SizeofHeapTupleHeader));
        if (subquery_size > work_mem * 1024L)
                return false;
 
index 05f601ec2f076e127386a2be597f399f6aa6ea4b..b90fee387b4c73af26ef1e2235fd92a7546da98e 100644 (file)
@@ -832,7 +832,7 @@ choose_hashed_setop(PlannerInfo *root, List *groupClauses,
         * Don't do it if it doesn't look like the hashtable will fit into
         * work_mem.
         */
-       hashentrysize = MAXALIGN(input_plan->plan_width) + MAXALIGN(sizeof(MinimalTupleData));
+       hashentrysize = MAXALIGN(input_plan->plan_width) + MAXALIGN(SizeofMinimalTupleHeader);
 
        if (hashentrysize * dNumGroups > work_mem * 1024L)
                return false;
index fb7db6d959990e8ea2b9618285fa5f69ebf58b8a..5cbd6a98f202b1dcdbd3df775d948e969b9d56b5 100644 (file)
@@ -508,7 +508,7 @@ estimate_rel_size(Relation rel, int32 *attr_widths,
                                int32           tuple_width;
 
                                tuple_width = get_rel_data_width(rel, attr_widths);
-                               tuple_width += sizeof(HeapTupleHeaderData);
+                               tuple_width += MAXALIGN(SizeofHeapTupleHeader);
                                tuple_width += sizeof(ItemIdData);
                                /* note: integer division is intentional here */
                                density = (BLCKSZ - SizeOfPageHeaderData) / tuple_width;
index 77c02baf1137b1c14d46016fdee496e5fea9afaa..e7614bd515afcf988fbb603d582dc20f90f8ab8b 100644 (file)
@@ -765,21 +765,19 @@ DecodeMultiInsert(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
                         * transactions.
                         */
                        tuple->tuple.t_tableOid = InvalidOid;
-                       tuple->tuple.t_data = &tuple->header;
-                       tuple->tuple.t_len = datalen
-                               + offsetof(HeapTupleHeaderData, t_bits);
+                       tuple->tuple.t_data = &tuple->t_data.header;
+                       tuple->tuple.t_len = datalen + SizeofHeapTupleHeader;
 
-                       memset(&tuple->header, 0, sizeof(HeapTupleHeaderData));
+                       memset(&tuple->t_data.header, 0, SizeofHeapTupleHeader);
 
-                       memcpy((char *) &tuple->header
-                                  + offsetof(HeapTupleHeaderData, t_bits),
+                       memcpy((char *) &tuple->t_data.header + SizeofHeapTupleHeader,
                                   (char *) data,
                                   datalen);
                        data += datalen;
 
-                       tuple->header.t_infomask = xlhdr->t_infomask;
-                       tuple->header.t_infomask2 = xlhdr->t_infomask2;
-                       tuple->header.t_hoff = xlhdr->t_hoff;
+                       tuple->t_data.header.t_infomask = xlhdr->t_infomask;
+                       tuple->t_data.header.t_infomask2 = xlhdr->t_infomask2;
+                       tuple->t_data.header.t_hoff = xlhdr->t_hoff;
                }
 
                /*
@@ -815,27 +813,27 @@ DecodeXLogTuple(char *data, Size len, ReorderBufferTupleBuf *tuple)
        Assert(datalen >= 0);
        Assert(datalen <= MaxHeapTupleSize);
 
-       tuple->tuple.t_len = datalen + offsetof(HeapTupleHeaderData, t_bits);
+       tuple->tuple.t_len = datalen + SizeofHeapTupleHeader;
 
        /* not a disk based tuple */
        ItemPointerSetInvalid(&tuple->tuple.t_self);
 
        /* we can only figure this out after reassembling the transactions */
        tuple->tuple.t_tableOid = InvalidOid;
-       tuple->tuple.t_data = &tuple->header;
+       tuple->tuple.t_data = &tuple->t_data.header;
 
        /* data is not stored aligned, copy to aligned storage */
        memcpy((char *) &xlhdr,
                   data,
                   SizeOfHeapHeader);
 
-       memset(&tuple->header, 0, sizeof(HeapTupleHeaderData));
+       memset(&tuple->t_data.header, 0, SizeofHeapTupleHeader);
 
-       memcpy((char *) &tuple->header + offsetof(HeapTupleHeaderData, t_bits),
+       memcpy((char *) &tuple->t_data.header + SizeofHeapTupleHeader,
                   data + SizeOfHeapHeader,
                   datalen);
 
-       tuple->header.t_infomask = xlhdr.t_infomask;
-       tuple->header.t_infomask2 = xlhdr.t_infomask2;
-       tuple->header.t_hoff = xlhdr.t_hoff;
+       tuple->t_data.header.t_infomask = xlhdr.t_infomask;
+       tuple->t_data.header.t_infomask2 = xlhdr.t_infomask2;
+       tuple->t_data.header.t_hoff = xlhdr.t_hoff;
 }
index bcd58966f0aca69858ec4eccf707bfbfb826d380..20bb3b78e022fe689c8e652f4fbcb70ad6e7eee5 100644 (file)
@@ -2014,14 +2014,12 @@ ReorderBufferSerializeChange(ReorderBuffer *rb, ReorderBufferTXN *txn,
                                newtup = change->data.tp.newtuple;
 
                                if (oldtup)
-                                       oldlen = offsetof(ReorderBufferTupleBuf, data)
-                                               +oldtup->tuple.t_len
-                                               - offsetof(HeapTupleHeaderData, t_bits);
+                                       oldlen = offsetof(ReorderBufferTupleBuf, t_data) +
+                                               oldtup->tuple.t_len;
 
                                if (newtup)
-                                       newlen = offsetof(ReorderBufferTupleBuf, data)
-                                               +newtup->tuple.t_len
-                                               - offsetof(HeapTupleHeaderData, t_bits);
+                                       newlen = offsetof(ReorderBufferTupleBuf, t_data) +
+                                               newtup->tuple.t_len;
 
                                sz += oldlen;
                                sz += newlen;
@@ -2262,27 +2260,25 @@ ReorderBufferRestoreChange(ReorderBuffer *rb, ReorderBufferTXN *txn,
                case REORDER_BUFFER_CHANGE_DELETE:
                        if (change->data.tp.newtuple)
                        {
-                               Size            len = offsetof(ReorderBufferTupleBuf, data)
-                               +((ReorderBufferTupleBuf *) data)->tuple.t_len
-                               - offsetof(HeapTupleHeaderData, t_bits);
+                               Size            len = offsetof(ReorderBufferTupleBuf, t_data) +
+                               ((ReorderBufferTupleBuf *) data)->tuple.t_len;
 
                                change->data.tp.newtuple = ReorderBufferGetTupleBuf(rb);
                                memcpy(change->data.tp.newtuple, data, len);
                                change->data.tp.newtuple->tuple.t_data =
-                                       &change->data.tp.newtuple->header;
+                                       &change->data.tp.newtuple->t_data.header;
                                data += len;
                        }
 
                        if (change->data.tp.oldtuple)
                        {
-                               Size            len = offsetof(ReorderBufferTupleBuf, data)
-                               +((ReorderBufferTupleBuf *) data)->tuple.t_len
-                               - offsetof(HeapTupleHeaderData, t_bits);
+                               Size            len = offsetof(ReorderBufferTupleBuf, t_data) +
+                               ((ReorderBufferTupleBuf *) data)->tuple.t_len;
 
                                change->data.tp.oldtuple = ReorderBufferGetTupleBuf(rb);
                                memcpy(change->data.tp.oldtuple, data, len);
                                change->data.tp.oldtuple->tuple.t_data =
-                                       &change->data.tp.oldtuple->header;
+                                       &change->data.tp.oldtuple->t_data.header;
                                data += len;
                        }
                        break;
@@ -2660,7 +2656,7 @@ ReorderBufferToastReplace(ReorderBuffer *rb, ReorderBufferTXN *txn,
         */
        tmphtup = heap_form_tuple(desc, attrs, isnull);
        Assert(newtup->tuple.t_len <= MaxHeapTupleSize);
-       Assert(&newtup->header == newtup->tuple.t_data);
+       Assert(&newtup->t_data.header == newtup->tuple.t_data);
 
        memcpy(newtup->tuple.t_data, tmphtup->t_data, tmphtup->t_len);
        newtup->tuple.t_len = tmphtup->t_len;
index fb79092aefcedf3d7c9318a9facb1bfffbb7209f..a8a75efd1319f48e0c8376127d853b722708e412 100644 (file)
@@ -84,9 +84,9 @@ suppress_redundant_updates_trigger(PG_FUNCTION_ARGS)
                 HeapTupleHeaderGetNatts(oldheader)) &&
                ((newheader->t_infomask & ~HEAP_XACT_MASK) ==
                 (oldheader->t_infomask & ~HEAP_XACT_MASK)) &&
-               memcmp(((char *) newheader) + offsetof(HeapTupleHeaderData, t_bits),
-                          ((char *) oldheader) + offsetof(HeapTupleHeaderData, t_bits),
-                          newtuple->t_len - offsetof(HeapTupleHeaderData, t_bits)) == 0)
+               memcmp(((char *) newheader) + SizeofHeapTupleHeader,
+                          ((char *) oldheader) + SizeofHeapTupleHeader,
+                          newtuple->t_len - SizeofHeapTupleHeader) == 0)
        {
                /* ... then suppress the update */
                rettuple = NULL;
index d2ad910a333dd10101939807c792300feba12c2a..0a673cd52679ddde5a25c4f6d3fc14c7db17914b 100644 (file)
@@ -150,13 +150,15 @@ struct HeapTupleHeaderData
 
        /* ^ - 23 bytes - ^ */
 
-       bits8           t_bits[1];              /* bitmap of NULLs -- VARIABLE LENGTH */
+       bits8           t_bits[FLEXIBLE_ARRAY_MEMBER];  /* bitmap of NULLs */
 
        /* MORE DATA FOLLOWS AT END OF STRUCT */
 };
 
 /* typedef appears in tupbasics.h */
 
+#define SizeofHeapTupleHeader offsetof(HeapTupleHeaderData, t_bits)
+
 /*
  * information stored in t_infomask:
  */
@@ -498,7 +500,7 @@ do { \
  * you can, say, fit 2 tuples of size MaxHeapTupleSize/2 on the same page.
  */
 #define MaxHeapTupleSize  (BLCKSZ - MAXALIGN(SizeOfPageHeaderData + sizeof(ItemIdData)))
-#define MinHeapTupleSize  MAXALIGN(offsetof(HeapTupleHeaderData, t_bits))
+#define MinHeapTupleSize  MAXALIGN(SizeofHeapTupleHeader)
 
 /*
  * MaxHeapTuplesPerPage is an upper bound on the number of tuples that can
@@ -513,7 +515,7 @@ do { \
  */
 #define MaxHeapTuplesPerPage   \
        ((int) ((BLCKSZ - SizeOfPageHeaderData) / \
-                       (MAXALIGN(offsetof(HeapTupleHeaderData, t_bits)) + sizeof(ItemIdData))))
+                       (MAXALIGN(SizeofHeapTupleHeader) + sizeof(ItemIdData))))
 
 /*
  * MaxAttrSize is a somewhat arbitrary upper limit on the declared size of
@@ -579,13 +581,15 @@ struct MinimalTupleData
 
        /* ^ - 23 bytes - ^ */
 
-       bits8           t_bits[1];              /* bitmap of NULLs -- VARIABLE LENGTH */
+       bits8           t_bits[FLEXIBLE_ARRAY_MEMBER];  /* bitmap of NULLs */
 
        /* MORE DATA FOLLOWS AT END OF STRUCT */
 };
 
 /* typedef appears in htup.h */
 
+#define SizeofMinimalTupleHeader offsetof(MinimalTupleData, t_bits)
+
 
 /*
  * GETSTRUCT - given a HeapTuple pointer, return address of the user data
index 331dd259ccbb93c00f23e44db15a540f0d6d83c7..7d185357714f886df52b3367c8799f9d848af4fa 100644 (file)
@@ -90,7 +90,7 @@
 
 #define TOAST_MAX_CHUNK_SIZE   \
        (EXTERN_TUPLE_MAX_SIZE -                                                        \
-        MAXALIGN(offsetof(HeapTupleHeaderData, t_bits)) -      \
+        MAXALIGN(SizeofHeapTupleHeader) -                                      \
         sizeof(Oid) -                                                                          \
         sizeof(int32) -                                                                        \
         VARHDRSZ)
index 5a1d9a067078a071a02cda90378cb13dc8a4ba9c..f1e0f57e7c2a56355fc90ec55e1d4abd0c7a7e91 100644 (file)
@@ -28,8 +28,12 @@ typedef struct ReorderBufferTupleBuf
 
        /* tuple, stored sequentially */
        HeapTupleData tuple;
-       HeapTupleHeaderData header;
-       char            data[MaxHeapTupleSize];
+       union
+       {
+               HeapTupleHeaderData header;
+               char            data[MaxHeapTupleSize];
+               double          align_it;       /* ensure t_data is MAXALIGN'd */
+       }                       t_data;
 } ReorderBufferTupleBuf;
 
 /*
@@ -77,7 +81,7 @@ typedef struct ReorderBufferChange
                        RelFileNode relnode;
 
                        /* no previously reassembled toast chunks are necessary anymore */
-                       bool clear_toast_afterwards;
+                       bool            clear_toast_afterwards;
 
                        /* valid for DELETE || UPDATE */
                        ReorderBufferTupleBuf *oldtuple;