Avoid assuming that struct varattrib_pointer doesn't get padded by the
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 1 Oct 2007 16:25:56 +0000 (16:25 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 1 Oct 2007 16:25:56 +0000 (16:25 +0000)
compiler --- at least on ARM, it does.  I suspect that the varvarlena patch
has been creating larger-than-intended toast pointers all along on ARM,
but it wasn't exposed until the latest tweak added some Asserts that
calculated the expected size in a different way.  We could probably have
fixed this by adding __attribute__((packed)) as is done for ItemPointerData,
but struct varattrib_pointer isn't really all that useful anyway, so it
seems cleanest to just get rid of it and have only struct varattrib_1b_e.
Per results from buildfarm member quagga.

src/backend/access/heap/tuptoaster.c
src/include/postgres.h

index d2f1dfafd4aaab8ee6778d7ab8d01eeb66f81900..e6801e40350eebfe66b7db0a7ff80c3111b7459a 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/access/heap/tuptoaster.c,v 1.76 2007/09/30 19:54:58 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/access/heap/tuptoaster.c,v 1.77 2007/10/01 16:25:56 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -42,6 +42,9 @@
 
 #undef TOAST_DEBUG
 
+/* Size of an EXTERNAL datum that contains a standard TOAST pointer */
+#define TOAST_POINTER_SIZE (VARHDRSZ_EXTERNAL + sizeof(struct varatt_external))
+
 /*
  * Testing whether an externally-stored value is compressed now requires
  * comparing extsize (the actual length of the external data) to rawsize
@@ -597,7 +600,7 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup,
                                                                  toast_values, toast_isnull) > maxDataLen)
        {
                int                     biggest_attno = -1;
-               int32           biggest_size = MAXALIGN(sizeof(varattrib_pointer));
+               int32           biggest_size = MAXALIGN(TOAST_POINTER_SIZE);
                Datum           old_value;
                Datum           new_value;
 
@@ -660,7 +663,7 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup,
                   rel->rd_rel->reltoastrelid != InvalidOid)
        {
                int                     biggest_attno = -1;
-               int32           biggest_size = MAXALIGN(sizeof(varattrib_pointer));
+               int32           biggest_size = MAXALIGN(TOAST_POINTER_SIZE);
                Datum           old_value;
 
                /*------
@@ -710,7 +713,7 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup,
                                                                  toast_values, toast_isnull) > maxDataLen)
        {
                int                     biggest_attno = -1;
-               int32           biggest_size = MAXALIGN(sizeof(varattrib_pointer));
+               int32           biggest_size = MAXALIGN(TOAST_POINTER_SIZE);
                Datum           old_value;
                Datum           new_value;
 
@@ -772,7 +775,7 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup,
                   rel->rd_rel->reltoastrelid != InvalidOid)
        {
                int                     biggest_attno = -1;
-               int32           biggest_size = MAXALIGN(sizeof(varattrib_pointer));
+               int32           biggest_size = MAXALIGN(TOAST_POINTER_SIZE);
                Datum           old_value;
 
                /*--------
@@ -1085,7 +1088,7 @@ toast_save_datum(Relation rel, Datum value,
        Datum           t_values[3];
        bool            t_isnull[3];
        CommandId       mycid = GetCurrentCommandId();
-       varattrib_pointer *result;
+       struct varlena *result;
        struct varatt_external toast_pointer;
        struct
        {
@@ -1206,8 +1209,8 @@ toast_save_datum(Relation rel, Datum value,
        /*
         * Create the TOAST pointer value that we'll return
         */
-       result = (varattrib_pointer *) palloc(sizeof(varattrib_pointer));
-       SET_VARSIZE_EXTERNAL(result, sizeof(varattrib_pointer));
+       result = (struct varlena *) palloc(TOAST_POINTER_SIZE);
+       SET_VARSIZE_EXTERNAL(result, TOAST_POINTER_SIZE);
        memcpy(VARDATA_EXTERNAL(result), &toast_pointer, sizeof(toast_pointer));
 
        return PointerGetDatum(result);
index d7516c33036b50f9fb79cba881427e7a91ef6331..2a6def8bc92d3f6ccf5643ad47810c5abb19bc20 100644 (file)
@@ -10,7 +10,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1995, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/postgres.h,v 1.84 2007/09/30 19:54:58 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/postgres.h,v 1.85 2007/10/01 16:25:56 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -110,13 +110,6 @@ typedef struct
        char            va_data[1];                     /* Data (for now always a TOAST pointer) */
 } varattrib_1b_e;
 
-typedef struct
-{
-       uint8           va_header;                      /* Always 0x80 or 0x01 */
-       uint8           va_len_1be;                     /* Physical length of datum */
-       char            va_data[sizeof(struct varatt_external)];
-} varattrib_pointer;
-
 /*
  * Bit layouts for varlena headers on big-endian machines:
  *
@@ -225,6 +218,8 @@ typedef struct
 #define VARATT_CONVERTED_SHORT_SIZE(PTR) \
        (VARSIZE(PTR) - VARHDRSZ + VARHDRSZ_SHORT)
 
+#define VARHDRSZ_EXTERNAL              2
+
 #define VARDATA_4B(PTR)                (((varattrib_4b *) (PTR))->va_4byte.va_data)
 #define VARDATA_4B_C(PTR)      (((varattrib_4b *) (PTR))->va_compressed.va_data)
 #define VARDATA_1B(PTR)                (((varattrib_1b *) (PTR))->va_data)
@@ -276,9 +271,9 @@ typedef struct
          VARSIZE_4B(PTR)))
 
 #define VARSIZE_ANY_EXHDR(PTR) \
-       (VARATT_IS_1B_E(PTR) ? VARSIZE_1B_E(PTR)-2 : \
-        (VARATT_IS_1B(PTR) ? VARSIZE_1B(PTR)-1 : \
-         VARSIZE_4B(PTR)-4))
+       (VARATT_IS_1B_E(PTR) ? VARSIZE_1B_E(PTR)-VARHDRSZ_EXTERNAL : \
+        (VARATT_IS_1B(PTR) ? VARSIZE_1B(PTR)-VARHDRSZ_SHORT : \
+         VARSIZE_4B(PTR)-VARHDRSZ))
 
 /* caution: this will not work on an external or compressed-in-line Datum */
 /* caution: this will return a possibly unaligned pointer */