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 */