From 14c82d10fa2f3db891b76871af87f542a371b4a5 Mon Sep 17 00:00:00 2001 From: David Rowley Date: Tue, 28 May 2024 13:49:07 +1200 Subject: [PATCH v4 1/6] Move TupleDesc.attrs out of line Change TupleDesc attrs field so that it's no longer memory allocated at the end of the TupleDesc struct. Here we change this so that 'attrs' is a pointer that always points to memory beyond the end of the struct. This is just refactoring work to make way for a follow-on commit, of which adds another variable length array to TupleDesc. --- src/backend/access/common/indextuple.c | 2 +- src/backend/access/common/tupdesc.c | 11 +++++++++-- src/backend/utils/cache/typcache.c | 15 ++++++++++++++- src/include/access/tupdesc.h | 12 ++++++++---- 4 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/backend/access/common/indextuple.c b/src/backend/access/common/indextuple.c index bb2c6a2bcc..79ae29989d 100644 --- a/src/backend/access/common/indextuple.c +++ b/src/backend/access/common/indextuple.c @@ -588,7 +588,7 @@ index_truncate_tuple(TupleDesc sourceDescriptor, IndexTuple source, return CopyIndexTuple(source); /* Create temporary descriptor to scribble on */ - truncdesc = palloc(TupleDescSize(sourceDescriptor)); + truncdesc = CreateTemplateTupleDesc(sourceDescriptor->natts); TupleDescCopy(truncdesc, sourceDescriptor); truncdesc->natts = leavenatts; diff --git a/src/backend/access/common/tupdesc.c b/src/backend/access/common/tupdesc.c index 47379fef22..fba0026520 100644 --- a/src/backend/access/common/tupdesc.c +++ b/src/backend/access/common/tupdesc.c @@ -85,7 +85,7 @@ CreateTemplateTupleDesc(int natts) * could be less due to trailing padding, although with the current * definition of pg_attribute there probably isn't any padding. */ - desc = (TupleDesc) palloc(offsetof(struct TupleDescData, attrs) + + desc = (TupleDesc) palloc(MAXALIGN(sizeof(TupleDescData)) + natts * sizeof(FormData_pg_attribute)); /* @@ -96,6 +96,7 @@ CreateTemplateTupleDesc(int natts) desc->tdtypeid = RECORDOID; desc->tdtypmod = -1; desc->tdrefcount = -1; /* assume not reference-counted */ + desc->attrs = TupleDescAttrAddress(desc); return desc; } @@ -252,9 +253,15 @@ TupleDescCopy(TupleDesc dst, TupleDesc src) { int i; - /* Flat-copy the header and attribute array */ + /* Flat-copy the header */ memcpy(dst, src, TupleDescSize(src)); + /* restore original attribute array pointer and replace contents from src */ + dst->attrs = TupleDescAttrAddress(dst); + memcpy(TupleDescAttr(dst, 0), + TupleDescAttr(src, 0), + sizeof(FormData_pg_attribute) * dst->natts); + /* * Since we're not copying constraints and defaults, clear fields * associated with them. diff --git a/src/backend/utils/cache/typcache.c b/src/backend/utils/cache/typcache.c index 2ec136b7d3..a8992b6a2d 100644 --- a/src/backend/utils/cache/typcache.c +++ b/src/backend/utils/cache/typcache.c @@ -222,12 +222,18 @@ shared_record_table_compare(const void *a, const void *b, size_t size, TupleDesc t2; if (k1->shared) + { t1 = (TupleDesc) dsa_get_address(area, k1->u.shared_tupdesc); + t1->attrs = TupleDescAttrAddress(t1); + } else t1 = k1->u.local_tupdesc; if (k2->shared) + { t2 = (TupleDesc) dsa_get_address(area, k2->u.shared_tupdesc); + t2->attrs = TupleDescAttrAddress(t2); + } else t2 = k2->u.local_tupdesc; @@ -245,7 +251,10 @@ shared_record_table_hash(const void *a, size_t size, void *arg) TupleDesc t; if (k->shared) + { t = (TupleDesc) dsa_get_address(area, k->u.shared_tupdesc); + t->attrs = TupleDescAttrAddress(t); + } else t = k->u.local_tupdesc; @@ -1797,6 +1806,7 @@ lookup_rowtype_tupdesc_internal(Oid type_id, int32 typmod, bool noError) tupdesc = (TupleDesc) dsa_get_address(CurrentSession->area, entry->shared_tupdesc); + tupdesc->attrs = TupleDescAttrAddress(tupdesc); Assert(typmod == tupdesc->tdtypmod); /* We may need to extend the local RecordCacheArray. */ @@ -2762,7 +2772,7 @@ share_tupledesc(dsa_area *area, TupleDesc tupdesc, uint32 typmod) dsa_pointer shared_dp; TupleDesc shared; - shared_dp = dsa_allocate(area, TupleDescSize(tupdesc)); + shared_dp = dsa_allocate(area, TupleDescFullSize(tupdesc)); shared = (TupleDesc) dsa_get_address(area, shared_dp); TupleDescCopy(shared, tupdesc); shared->tdtypmod = typmod; @@ -2805,6 +2815,7 @@ find_or_make_matching_shared_tupledesc(TupleDesc tupdesc) result = (TupleDesc) dsa_get_address(CurrentSession->area, record_table_entry->key.u.shared_tupdesc); + result->attrs = TupleDescAttrAddress(result); Assert(result->tdrefcount == -1); return result; @@ -2868,6 +2879,7 @@ find_or_make_matching_shared_tupledesc(TupleDesc tupdesc) result = (TupleDesc) dsa_get_address(CurrentSession->area, record_table_entry->key.u.shared_tupdesc); + result->attrs = TupleDescAttrAddress(result); Assert(result->tdrefcount == -1); return result; @@ -2880,6 +2892,7 @@ find_or_make_matching_shared_tupledesc(TupleDesc tupdesc) record_table_entry); result = (TupleDesc) dsa_get_address(CurrentSession->area, shared_dp); + result->attrs = TupleDescAttrAddress(result); Assert(result->tdrefcount == -1); return result; diff --git a/src/include/access/tupdesc.h b/src/include/access/tupdesc.h index 8930a28d66..2c435cdcb2 100644 --- a/src/include/access/tupdesc.h +++ b/src/include/access/tupdesc.h @@ -84,7 +84,7 @@ typedef struct TupleDescData int tdrefcount; /* reference count, or -1 if not counting */ TupleConstr *constr; /* constraints, or NULL if none */ /* attrs[N] is the description of Attribute Number N+1 */ - FormData_pg_attribute attrs[FLEXIBLE_ARRAY_MEMBER]; + FormData_pg_attribute *attrs; } TupleDescData; typedef struct TupleDescData *TupleDesc; @@ -99,9 +99,13 @@ extern TupleDesc CreateTupleDescCopy(TupleDesc tupdesc); extern TupleDesc CreateTupleDescCopyConstr(TupleDesc tupdesc); -#define TupleDescSize(src) \ - (offsetof(struct TupleDescData, attrs) + \ - (src)->natts * sizeof(FormData_pg_attribute)) +#define TupleDescSize(src) MAXALIGN(sizeof(TupleDescData)) + +#define TupleDescFullSize(src) \ + (MAXALIGN(sizeof(TupleDescData)) + sizeof(FormData_pg_attribute) * (src)->natts) + +#define TupleDescAttrAddress(desc) \ + (Form_pg_attribute) ((char *) (desc) + MAXALIGN(sizeof(TupleDescData))) extern void TupleDescCopy(TupleDesc dst, TupleDesc src); -- 2.34.1