From ad8f54cdb5776146f17d1038bb295b5f13b549f1 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Mon, 16 Feb 2015 03:53:38 +0900 Subject: [PATCH 3/3] Update varlena in c.h to use FLEXIBLE_ARRAY_MEMBER Places using a variable-length variable not at the end of a structure are changed with workaround, without impacting what those features do. --- src/backend/access/heap/tuptoaster.c | 16 ++++++------ src/backend/storage/large_object/inv_api.c | 40 ++++++++++++++---------------- src/include/c.h | 2 +- src/include/catalog/pg_authid.h | 8 +++--- 4 files changed, 31 insertions(+), 35 deletions(-) diff --git a/src/backend/access/heap/tuptoaster.c b/src/backend/access/heap/tuptoaster.c index f8c1401..a8f178c 100644 --- a/src/backend/access/heap/tuptoaster.c +++ b/src/backend/access/heap/tuptoaster.c @@ -1365,12 +1365,7 @@ toast_save_datum(Relation rel, Datum value, CommandId mycid = GetCurrentCommandId(true); struct varlena *result; struct varatt_external toast_pointer; - struct - { - struct varlena hdr; - char data[TOAST_MAX_CHUNK_SIZE]; /* make struct big enough */ - int32 align_it; /* ensure struct is aligned well enough */ - } chunk_data; + struct varlena *chunk_data; int32 chunk_size; int32 chunk_seq = 0; char *data_p; @@ -1381,6 +1376,9 @@ toast_save_datum(Relation rel, Datum value, Assert(!VARATT_IS_EXTERNAL(value)); + chunk_data = (struct varlena *) + palloc(MAXALIGN(TOAST_MAX_CHUNK_SIZE + VARHDRSZ)); + /* * Open the toast relation and its indexes. We can use the index to check * uniqueness of the OID we assign to the toasted item, even though it has @@ -1523,7 +1521,7 @@ toast_save_datum(Relation rel, Datum value, * Initialize constant parts of the tuple data */ t_values[0] = ObjectIdGetDatum(toast_pointer.va_valueid); - t_values[2] = PointerGetDatum(&chunk_data); + t_values[2] = PointerGetDatum(chunk_data); t_isnull[0] = false; t_isnull[1] = false; t_isnull[2] = false; @@ -1546,8 +1544,8 @@ toast_save_datum(Relation rel, Datum value, * Build a tuple and store it */ t_values[1] = Int32GetDatum(chunk_seq++); - SET_VARSIZE(&chunk_data, chunk_size + VARHDRSZ); - memcpy(VARDATA(&chunk_data), data_p, chunk_size); + SET_VARSIZE(chunk_data, chunk_size + VARHDRSZ); + memcpy(VARDATA(chunk_data), data_p, chunk_size); toasttup = heap_form_tuple(toasttupDesc, t_values, t_isnull); heap_insert(toastrel, toasttup, mycid, options, NULL); diff --git a/src/backend/storage/large_object/inv_api.c b/src/backend/storage/large_object/inv_api.c index a19c401..b44fae7 100644 --- a/src/backend/storage/large_object/inv_api.c +++ b/src/backend/storage/large_object/inv_api.c @@ -562,13 +562,8 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes) bool neednextpage; bytea *datafield; bool pfreeit; - struct - { - bytea hdr; - char data[LOBLKSIZE]; /* make struct big enough */ - int32 align_it; /* ensure struct is aligned well enough */ - } workbuf; - char *workb = VARDATA(&workbuf.hdr); + bytea *workbuf; + char *workb; HeapTuple newtup; Datum values[Natts_pg_largeobject]; bool nulls[Natts_pg_largeobject]; @@ -591,6 +586,9 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes) errmsg("invalid large object write request size: %d", nbytes))); + workbuf = (bytea *) palloc(MAXALIGN(LOBLKSIZE + VARHDRSZ)); + workb = VARDATA(workbuf); + open_lo_relation(); indstate = CatalogOpenIndexes(lo_heap_r); @@ -664,7 +662,7 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes) off += n; /* compute valid length of new page */ len = (len >= off) ? len : off; - SET_VARSIZE(&workbuf.hdr, len + VARHDRSZ); + SET_VARSIZE(workbuf, len + VARHDRSZ); /* * Form and insert updated tuple @@ -672,7 +670,7 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes) memset(values, 0, sizeof(values)); memset(nulls, false, sizeof(nulls)); memset(replace, false, sizeof(replace)); - values[Anum_pg_largeobject_data - 1] = PointerGetDatum(&workbuf); + values[Anum_pg_largeobject_data - 1] = PointerGetDatum(workbuf); replace[Anum_pg_largeobject_data - 1] = true; newtup = heap_modify_tuple(oldtuple, RelationGetDescr(lo_heap_r), values, nulls, replace); @@ -708,7 +706,7 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes) obj_desc->offset += n; /* compute valid length of new page */ len = off + n; - SET_VARSIZE(&workbuf.hdr, len + VARHDRSZ); + SET_VARSIZE(workbuf, len + VARHDRSZ); /* * Form and insert updated tuple @@ -717,7 +715,7 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes) memset(nulls, false, 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_form_tuple(lo_heap_r->rd_att, values, nulls); simple_heap_insert(lo_heap_r, newtup); CatalogIndexInsert(indstate, newtup); @@ -748,13 +746,8 @@ inv_truncate(LargeObjectDesc *obj_desc, int64 len) SysScanDesc sd; HeapTuple oldtuple; Form_pg_largeobject olddata; - struct - { - bytea hdr; - char data[LOBLKSIZE]; /* make struct big enough */ - int32 align_it; /* ensure struct is aligned well enough */ - } workbuf; - char *workb = VARDATA(&workbuf.hdr); + bytea *workbuf; + char *workb; HeapTuple newtup; Datum values[Natts_pg_largeobject]; bool nulls[Natts_pg_largeobject]; @@ -776,6 +769,9 @@ inv_truncate(LargeObjectDesc *obj_desc, int64 len) errmsg_internal("invalid large object truncation target: " INT64_FORMAT, len))); + workbuf = (bytea *) palloc(MAXALIGN(LOBLKSIZE + VARHDRSZ)); + workb = VARDATA(workbuf); + open_lo_relation(); indstate = CatalogOpenIndexes(lo_heap_r); @@ -834,7 +830,7 @@ inv_truncate(LargeObjectDesc *obj_desc, int64 len) MemSet(workb + pagelen, 0, off - pagelen); /* compute length of new page */ - SET_VARSIZE(&workbuf.hdr, off + VARHDRSZ); + SET_VARSIZE(workbuf, off + VARHDRSZ); /* * Form and insert updated tuple @@ -842,7 +838,7 @@ inv_truncate(LargeObjectDesc *obj_desc, int64 len) memset(values, 0, sizeof(values)); memset(nulls, false, sizeof(nulls)); memset(replace, false, sizeof(replace)); - values[Anum_pg_largeobject_data - 1] = PointerGetDatum(&workbuf); + values[Anum_pg_largeobject_data - 1] = PointerGetDatum(workbuf); replace[Anum_pg_largeobject_data - 1] = true; newtup = heap_modify_tuple(oldtuple, RelationGetDescr(lo_heap_r), values, nulls, replace); @@ -873,7 +869,7 @@ inv_truncate(LargeObjectDesc *obj_desc, int64 len) MemSet(workb, 0, off); /* compute length of new page */ - SET_VARSIZE(&workbuf.hdr, off + VARHDRSZ); + SET_VARSIZE(workbuf, off + VARHDRSZ); /* * Form and insert new tuple @@ -882,7 +878,7 @@ inv_truncate(LargeObjectDesc *obj_desc, int64 len) memset(nulls, false, 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_form_tuple(lo_heap_r->rd_att, values, nulls); simple_heap_insert(lo_heap_r, newtup); CatalogIndexInsert(indstate, newtup); diff --git a/src/include/c.h b/src/include/c.h index bbd0d53..36ec468 100644 --- a/src/include/c.h +++ b/src/include/c.h @@ -391,7 +391,7 @@ typedef struct struct varlena { char vl_len_[4]; /* Do not touch this field directly! */ - char vl_dat[1]; + char vl_dat[FLEXIBLE_ARRAY_MEMBER]; }; #define VARHDRSZ ((int32) sizeof(int32)) diff --git a/src/include/catalog/pg_authid.h b/src/include/catalog/pg_authid.h index e01e6aa..d8789a5 100644 --- a/src/include/catalog/pg_authid.h +++ b/src/include/catalog/pg_authid.h @@ -56,8 +56,10 @@ CATALOG(pg_authid,1260) BKI_SHARED_RELATION BKI_ROWTYPE_OID(2842) BKI_SCHEMA_MAC int32 rolconnlimit; /* max connections allowed (-1=no limit) */ /* remaining fields may be null; use heap_getattr to read them! */ - text rolpassword; /* password, if any */ timestamptz rolvaliduntil; /* password expiration time, if any */ +#ifdef CATALOG_VARLEN + text rolpassword; /* password, if any */ +#endif } FormData_pg_authid; #undef timestamptz @@ -85,8 +87,8 @@ typedef FormData_pg_authid *Form_pg_authid; #define Anum_pg_authid_rolreplication 8 #define Anum_pg_authid_rolbypassrls 9 #define Anum_pg_authid_rolconnlimit 10 -#define Anum_pg_authid_rolpassword 11 -#define Anum_pg_authid_rolvaliduntil 12 +#define Anum_pg_authid_rolvaliduntil 11 +#define Anum_pg_authid_rolpassword 12 /* ---------------- * initial contents of pg_authid -- 2.3.0