Commit 47c6772e authored by Tom Lane's avatar Tom Lane

Clean up tupdesc.c for recent changes.

TupleDescCopy needs to have the same effects as CreateTupleDescCopy in
that, since it doesn't copy constraints, it should clear the per-attribute
fields associated with them.  Oversight in commit cc5f8136.

Since TupleDescCopy has already established the presumption that it
can just flat-copy the entire attribute array in one go, propagate
that approach into CreateTupleDescCopy and CreateTupleDescCopyConstr.
(I'm suspicious that this would lead to valgrind complaints if we
had any trailing padding in the struct, but we do not, and anyway
fixing that seems like a job for a separate commit.)

Add some better comments.

Thomas Munro, reviewed by Vik Fearing, some additional hacking by me

Discussion: https://postgr.es/m/CAEepm=0NvOGZ8B6GbQyQe2C_c2m3LKJ9w=8OMBaYRLgZ_Gw6Nw@mail.gmail.com
parent bab29698
...@@ -52,6 +52,14 @@ CreateTemplateTupleDesc(int natts, bool hasoid) ...@@ -52,6 +52,14 @@ 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. * attribute rows.
*
* Note: the attribute array stride is sizeof(FormData_pg_attribute),
* since we declare the array elements as FormData_pg_attribute for
* notational convenience. However, we only guarantee that the first
* ATTRIBUTE_FIXED_PART_SIZE bytes of each entry are valid; most code that
* copies tupdesc entries around copies just that much. In principle that
* 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 tupleDesc, attrs) + desc = (TupleDesc) palloc(offsetof(struct tupleDesc, attrs) +
natts * sizeof(FormData_pg_attribute)); natts * sizeof(FormData_pg_attribute));
...@@ -106,16 +114,25 @@ CreateTupleDescCopy(TupleDesc tupdesc) ...@@ -106,16 +114,25 @@ CreateTupleDescCopy(TupleDesc tupdesc)
desc = CreateTemplateTupleDesc(tupdesc->natts, tupdesc->tdhasoid); desc = CreateTemplateTupleDesc(tupdesc->natts, tupdesc->tdhasoid);
/* Flat-copy the attribute array */
memcpy(TupleDescAttr(desc, 0),
TupleDescAttr(tupdesc, 0),
desc->natts * sizeof(FormData_pg_attribute));
/*
* Since we're not copying constraints and defaults, clear fields
* associated with them.
*/
for (i = 0; i < desc->natts; i++) for (i = 0; i < desc->natts; i++)
{ {
Form_pg_attribute att = TupleDescAttr(desc, i); Form_pg_attribute att = TupleDescAttr(desc, i);
memcpy(att, &tupdesc->attrs[i], ATTRIBUTE_FIXED_PART_SIZE);
att->attnotnull = false; att->attnotnull = false;
att->atthasdef = false; att->atthasdef = false;
att->attidentity = '\0'; att->attidentity = '\0';
} }
/* We can copy the tuple type identification, too */
desc->tdtypeid = tupdesc->tdtypeid; desc->tdtypeid = tupdesc->tdtypeid;
desc->tdtypmod = tupdesc->tdtypmod; desc->tdtypmod = tupdesc->tdtypmod;
...@@ -136,13 +153,12 @@ CreateTupleDescCopyConstr(TupleDesc tupdesc) ...@@ -136,13 +153,12 @@ CreateTupleDescCopyConstr(TupleDesc tupdesc)
desc = CreateTemplateTupleDesc(tupdesc->natts, tupdesc->tdhasoid); desc = CreateTemplateTupleDesc(tupdesc->natts, tupdesc->tdhasoid);
for (i = 0; i < desc->natts; i++) /* Flat-copy the attribute array */
{ memcpy(TupleDescAttr(desc, 0),
memcpy(TupleDescAttr(desc, i), TupleDescAttr(tupdesc, 0),
TupleDescAttr(tupdesc, i), desc->natts * sizeof(FormData_pg_attribute));
ATTRIBUTE_FIXED_PART_SIZE);
}
/* Copy the TupleConstr data structure, if any */
if (constr) if (constr)
{ {
TupleConstr *cpy = (TupleConstr *) palloc0(sizeof(TupleConstr)); TupleConstr *cpy = (TupleConstr *) palloc0(sizeof(TupleConstr));
...@@ -178,6 +194,7 @@ CreateTupleDescCopyConstr(TupleDesc tupdesc) ...@@ -178,6 +194,7 @@ CreateTupleDescCopyConstr(TupleDesc tupdesc)
desc->constr = cpy; desc->constr = cpy;
} }
/* We can copy the tuple type identification, too */
desc->tdtypeid = tupdesc->tdtypeid; desc->tdtypeid = tupdesc->tdtypeid;
desc->tdtypmod = tupdesc->tdtypmod; desc->tdtypmod = tupdesc->tdtypmod;
...@@ -195,8 +212,29 @@ CreateTupleDescCopyConstr(TupleDesc tupdesc) ...@@ -195,8 +212,29 @@ CreateTupleDescCopyConstr(TupleDesc tupdesc)
void void
TupleDescCopy(TupleDesc dst, TupleDesc src) TupleDescCopy(TupleDesc dst, TupleDesc src)
{ {
int i;
/* Flat-copy the header and attribute array */
memcpy(dst, src, TupleDescSize(src)); memcpy(dst, src, TupleDescSize(src));
/*
* Since we're not copying constraints and defaults, clear fields
* associated with them.
*/
for (i = 0; i < dst->natts; i++)
{
Form_pg_attribute att = TupleDescAttr(dst, i);
att->attnotnull = false;
att->atthasdef = false;
att->attidentity = '\0';
}
dst->constr = NULL; dst->constr = NULL;
/*
* Also, assume the destination is not to be ref-counted. (Copying the
* source's refcount would be wrong in any case.)
*/
dst->tdrefcount = -1; dst->tdrefcount = -1;
} }
......
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