Commit c6293249 authored by Andres Freund's avatar Andres Freund

Partially flatten struct tupleDesc so that it can be used in DSM.

TupleDesc's attributes were already stored in contiguous memory after the
struct.  Go one step further and get rid of the array of pointers to
attributes so that they can be stored in shared memory mapped at different
addresses in each backend.  This won't work for TupleDescs with contraints
and defaults, since those point to other objects, but for many purposes
only attributes are needed.

Author: Thomas Munro
Reviewed-By: Andres Freund
Discussion: https://postgr.es/m/CAEepm=0ZtQ-SpsgCyzzYpsXS6e=kZWqk3g5Ygn3MDV7A8dabUA@mail.gmail.com
parent 2cd70845
...@@ -41,8 +41,6 @@ TupleDesc ...@@ -41,8 +41,6 @@ TupleDesc
CreateTemplateTupleDesc(int natts, bool hasoid) CreateTemplateTupleDesc(int natts, bool hasoid)
{ {
TupleDesc desc; TupleDesc desc;
char *stg;
int attroffset;
/* /*
* sanity checks * sanity checks
...@@ -51,38 +49,10 @@ CreateTemplateTupleDesc(int natts, bool hasoid) ...@@ -51,38 +49,10 @@ CreateTemplateTupleDesc(int natts, bool hasoid)
/* /*
* Allocate enough memory for the tuple descriptor, including the * Allocate enough memory for the tuple descriptor, including the
* attribute rows, and set up the attribute row pointers. * attribute rows.
*
* Note: we assume that sizeof(struct tupleDesc) is a multiple of the
* struct pointer alignment requirement, and hence we don't need to insert
* alignment padding between the struct and the array of attribute row
* pointers.
*
* Note: Only the fixed part of pg_attribute rows is included in tuple
* descriptors, so we only need ATTRIBUTE_FIXED_PART_SIZE space per attr.
* That might need alignment padding, however.
*/ */
attroffset = sizeof(struct tupleDesc) + natts * sizeof(Form_pg_attribute); desc = (TupleDesc) palloc(offsetof(struct tupleDesc, attrs) +
attroffset = MAXALIGN(attroffset); natts * sizeof(FormData_pg_attribute));
stg = palloc(attroffset + natts * MAXALIGN(ATTRIBUTE_FIXED_PART_SIZE));
desc = (TupleDesc) stg;
if (natts > 0)
{
Form_pg_attribute *attrs;
int i;
attrs = (Form_pg_attribute *) (stg + sizeof(struct tupleDesc));
desc->attrs = attrs;
stg += attroffset;
for (i = 0; i < natts; i++)
{
attrs[i] = (Form_pg_attribute) stg;
stg += MAXALIGN(ATTRIBUTE_FIXED_PART_SIZE);
}
}
else
desc->attrs = NULL;
/* /*
* Initialize other fields of the tupdesc. * Initialize other fields of the tupdesc.
...@@ -99,12 +69,9 @@ CreateTemplateTupleDesc(int natts, bool hasoid) ...@@ -99,12 +69,9 @@ CreateTemplateTupleDesc(int natts, bool hasoid)
/* /*
* CreateTupleDesc * CreateTupleDesc
* This function allocates a new TupleDesc pointing to a given * This function allocates a new TupleDesc by copying a given
* Form_pg_attribute array. * Form_pg_attribute array.
* *
* Note: if the TupleDesc is ever freed, the Form_pg_attribute array
* will not be freed thereby.
*
* Tuple type ID information is initially set for an anonymous record type; * Tuple type ID information is initially set for an anonymous record type;
* caller can overwrite this if needed. * caller can overwrite this if needed.
*/ */
...@@ -112,20 +79,12 @@ TupleDesc ...@@ -112,20 +79,12 @@ TupleDesc
CreateTupleDesc(int natts, bool hasoid, Form_pg_attribute *attrs) CreateTupleDesc(int natts, bool hasoid, Form_pg_attribute *attrs)
{ {
TupleDesc desc; TupleDesc desc;
int i;
/* desc = CreateTemplateTupleDesc(natts, hasoid);
* sanity checks
*/
AssertArg(natts >= 0);
desc = (TupleDesc) palloc(sizeof(struct tupleDesc)); for (i = 0; i < natts; ++i)
desc->attrs = attrs; memcpy(TupleDescAttr(desc, i), attrs[i], ATTRIBUTE_FIXED_PART_SIZE);
desc->natts = natts;
desc->constr = NULL;
desc->tdtypeid = RECORDOID;
desc->tdtypmod = -1;
desc->tdhasoid = hasoid;
desc->tdrefcount = -1; /* assume not reference-counted */
return desc; return desc;
} }
...@@ -147,10 +106,12 @@ CreateTupleDescCopy(TupleDesc tupdesc) ...@@ -147,10 +106,12 @@ CreateTupleDescCopy(TupleDesc tupdesc)
for (i = 0; i < desc->natts; i++) for (i = 0; i < desc->natts; i++)
{ {
memcpy(desc->attrs[i], tupdesc->attrs[i], ATTRIBUTE_FIXED_PART_SIZE); Form_pg_attribute att = TupleDescAttr(desc, i);
desc->attrs[i]->attnotnull = false;
desc->attrs[i]->atthasdef = false; memcpy(att, &tupdesc->attrs[i], ATTRIBUTE_FIXED_PART_SIZE);
desc->attrs[i]->attidentity = '\0'; att->attnotnull = false;
att->atthasdef = false;
att->attidentity = '\0';
} }
desc->tdtypeid = tupdesc->tdtypeid; desc->tdtypeid = tupdesc->tdtypeid;
......
...@@ -71,17 +71,17 @@ typedef struct tupleConstr ...@@ -71,17 +71,17 @@ typedef struct tupleConstr
typedef struct tupleDesc typedef struct tupleDesc
{ {
int natts; /* number of attributes in the tuple */ int natts; /* number of attributes in the tuple */
Form_pg_attribute *attrs;
/* attrs[N] is a pointer to the description of Attribute Number N+1 */
TupleConstr *constr; /* constraints, or NULL if none */
Oid tdtypeid; /* composite type ID for tuple type */ Oid tdtypeid; /* composite type ID for tuple type */
int32 tdtypmod; /* typmod for tuple type */ int32 tdtypmod; /* typmod for tuple type */
bool tdhasoid; /* tuple has oid attribute in its header */ bool tdhasoid; /* tuple has oid attribute in its header */
int tdrefcount; /* reference count, or -1 if not counting */ 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];
} *TupleDesc; } *TupleDesc;
/* Accessor for the i'th attribute of tupdesc. */ /* Accessor for the i'th attribute of tupdesc. */
#define TupleDescAttr(tupdesc, i) ((tupdesc)->attrs[(i)]) #define TupleDescAttr(tupdesc, i) (&(tupdesc)->attrs[(i)])
extern TupleDesc CreateTemplateTupleDesc(int natts, bool hasoid); extern TupleDesc CreateTemplateTupleDesc(int natts, bool hasoid);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment