This patch refactors CreateTupleDescCopy() and CreateTupleDescCopyConstr() to remove some duplicated code, and clean things up a little bit.
-Neil
Index: src/backend/access/common/tupdesc.c =================================================================== RCS file: /var/lib/cvs/pgsql-server/src/backend/access/common/tupdesc.c,v retrieving revision 1.100 diff -c -r1.100 tupdesc.c *** src/backend/access/common/tupdesc.c 25 Sep 2003 06:57:56 -0000 1.100 --- src/backend/access/common/tupdesc.c 17 Nov 2003 20:17:54 -0000 *************** *** 95,100 **** --- 95,134 ---- return desc; } + /* + * Performs a "simple copy" of the specified TupleDesc. Storage for + * the new TupleDesc and its attributes is allocated via palloc, and + * the existing TupleDesc is copied EXCEPT for its constraints: the + * 'constr' field of the returned TupleDesc is undefined, and should be + * filled in by the caller. + */ + static TupleDesc + SimpleTupleDescCopy(TupleDesc tupdesc) + { + TupleDesc copy; + + copy = (TupleDesc) palloc(sizeof(*copy)); + copy->natts = tupdesc->natts; + copy->tdhasoid = tupdesc->tdhasoid; + + if (copy->natts > 0) + { + int i, size; + + size = copy->natts * sizeof(Form_pg_attribute); + copy->attrs = (Form_pg_attribute *) palloc(size); + for (i = 0; i < copy->natts; i++) + { + copy->attrs[i] = (Form_pg_attribute) palloc(ATTRIBUTE_TUPLE_SIZE); + memcpy(copy->attrs[i], tupdesc->attrs[i], ATTRIBUTE_TUPLE_SIZE); + } + } + else + copy->attrs = NULL; + + return copy; + } + /* ---------------------------------------------------------------- * CreateTupleDescCopy * *************** *** 107,134 **** TupleDesc CreateTupleDescCopy(TupleDesc tupdesc) { ! TupleDesc desc; ! int i, ! size; ! desc = (TupleDesc) palloc(sizeof(struct tupleDesc)); ! desc->natts = tupdesc->natts; if (desc->natts > 0) { ! size = desc->natts * sizeof(Form_pg_attribute); ! desc->attrs = (Form_pg_attribute *) palloc(size); for (i = 0; i < desc->natts; i++) { - desc->attrs[i] = (Form_pg_attribute) palloc(ATTRIBUTE_TUPLE_SIZE); - memcpy(desc->attrs[i], tupdesc->attrs[i], ATTRIBUTE_TUPLE_SIZE); desc->attrs[i]->attnotnull = false; desc->attrs[i]->atthasdef = false; } } - else - desc->attrs = NULL; - desc->constr = NULL; - desc->tdhasoid = tupdesc->tdhasoid; return desc; } --- 141,165 ---- TupleDesc CreateTupleDescCopy(TupleDesc tupdesc) { ! TupleDesc desc; ! desc = SimpleTupleDescCopy(tupdesc); ! desc->constr = NULL; ! ! /* ! * Fix up the attributes to remove NOT NULL or DEFAULT indicators, ! * because we didn't copy the tupdesc's constraints ! */ if (desc->natts > 0) { ! int i; ! for (i = 0; i < desc->natts; i++) { desc->attrs[i]->attnotnull = false; desc->attrs[i]->atthasdef = false; } } return desc; } *************** *** 143,174 **** TupleDesc CreateTupleDescCopyConstr(TupleDesc tupdesc) { ! TupleDesc desc; ! TupleConstr *constr = tupdesc->constr; ! int i, ! size; - desc = (TupleDesc) palloc(sizeof(struct tupleDesc)); - desc->natts = tupdesc->natts; - if (desc->natts > 0) - { - size = desc->natts * sizeof(Form_pg_attribute); - desc->attrs = (Form_pg_attribute *) palloc(size); - for (i = 0; i < desc->natts; i++) - { - desc->attrs[i] = (Form_pg_attribute) palloc(ATTRIBUTE_TUPLE_SIZE); - memcpy(desc->attrs[i], tupdesc->attrs[i], ATTRIBUTE_TUPLE_SIZE); - } - } - else - desc->attrs = NULL; if (constr) { ! TupleConstr *cpy = (TupleConstr *) palloc(sizeof(TupleConstr)); ! cpy->has_not_null = constr->has_not_null; ! if ((cpy->num_defval = constr->num_defval) > 0) { cpy->defval = (AttrDefault *) palloc(cpy->num_defval * sizeof(AttrDefault)); memcpy(cpy->defval, constr->defval, cpy->num_defval * sizeof(AttrDefault)); --- 174,196 ---- TupleDesc CreateTupleDescCopyConstr(TupleDesc tupdesc) { ! TupleDesc desc; ! TupleConstr *constr; ! ! desc = SimpleTupleDescCopy(tupdesc); ! constr = tupdesc->constr; if (constr) { ! int i; ! TupleConstr *cpy; ! cpy = (TupleConstr *) palloc(sizeof(TupleConstr)); ! memcpy(cpy, constr, sizeof(*cpy)); ! cpy->defval = NULL; ! cpy->check = NULL; ! if (cpy->num_defval > 0) { cpy->defval = (AttrDefault *) palloc(cpy->num_defval * sizeof(AttrDefault)); memcpy(cpy->defval, constr->defval, cpy->num_defval * sizeof(AttrDefault)); *************** *** 179,185 **** } } ! if ((cpy->num_check = constr->num_check) > 0) { cpy->check = (ConstrCheck *) palloc(cpy->num_check * sizeof(ConstrCheck)); memcpy(cpy->check, constr->check, cpy->num_check * sizeof(ConstrCheck)); --- 201,207 ---- } } ! if (cpy->num_check > 0) { cpy->check = (ConstrCheck *) palloc(cpy->num_check * sizeof(ConstrCheck)); memcpy(cpy->check, constr->check, cpy->num_check * sizeof(ConstrCheck)); *************** *** 197,203 **** else desc->constr = NULL; - desc->tdhasoid = tupdesc->tdhasoid; return desc; } --- 219,224 ----
---------------------------(end of broadcast)--------------------------- TIP 7: don't forget to increase your free space map settings