diff options
Diffstat (limited to 'src/backend/access/common/tupconvert.c')
-rw-r--r-- | src/backend/access/common/tupconvert.c | 110 |
1 files changed, 65 insertions, 45 deletions
diff --git a/src/backend/access/common/tupconvert.c b/src/backend/access/common/tupconvert.c index 945a6a2065b..bdd3aa40d2a 100644 --- a/src/backend/access/common/tupconvert.c +++ b/src/backend/access/common/tupconvert.c @@ -206,55 +206,12 @@ convert_tuples_by_name(TupleDesc indesc, { TupleConversionMap *map; AttrNumber *attrMap; - int n; + int n = outdesc->natts; int i; bool same; /* Verify compatibility and prepare attribute-number map */ - n = outdesc->natts; - attrMap = (AttrNumber *) palloc0(n * sizeof(AttrNumber)); - for (i = 0; i < n; i++) - { - Form_pg_attribute att = outdesc->attrs[i]; - char *attname; - Oid atttypid; - int32 atttypmod; - int j; - - if (att->attisdropped) - continue; /* attrMap[i] is already 0 */ - attname = NameStr(att->attname); - atttypid = att->atttypid; - atttypmod = att->atttypmod; - for (j = 0; j < indesc->natts; j++) - { - att = indesc->attrs[j]; - if (att->attisdropped) - continue; - if (strcmp(attname, NameStr(att->attname)) == 0) - { - /* Found it, check type */ - if (atttypid != att->atttypid || atttypmod != att->atttypmod) - ereport(ERROR, - (errcode(ERRCODE_DATATYPE_MISMATCH), - errmsg_internal("%s", _(msg)), - errdetail("Attribute \"%s\" of type %s does not match corresponding attribute of type %s.", - attname, - format_type_be(outdesc->tdtypeid), - format_type_be(indesc->tdtypeid)))); - attrMap[i] = (AttrNumber) (j + 1); - break; - } - } - if (attrMap[i] == 0) - ereport(ERROR, - (errcode(ERRCODE_DATATYPE_MISMATCH), - errmsg_internal("%s", _(msg)), - errdetail("Attribute \"%s\" of type %s does not exist in type %s.", - attname, - format_type_be(outdesc->tdtypeid), - format_type_be(indesc->tdtypeid)))); - } + attrMap = convert_tuples_by_name_map(indesc, outdesc, msg); /* * Check to see if the map is one-to-one and the tuple types are the same. @@ -313,6 +270,69 @@ convert_tuples_by_name(TupleDesc indesc, } /* + * Return a palloc'd bare attribute map for tuple conversion, matching input + * and output columns by name. (Dropped columns are ignored in both input and + * output.) This is normally a subroutine for convert_tuples_by_name, but can + * be used standalone. + */ +AttrNumber * +convert_tuples_by_name_map(TupleDesc indesc, + TupleDesc outdesc, + const char *msg) +{ + AttrNumber *attrMap; + int n; + int i; + + n = outdesc->natts; + attrMap = (AttrNumber *) palloc0(n * sizeof(AttrNumber)); + for (i = 0; i < n; i++) + { + Form_pg_attribute att = outdesc->attrs[i]; + char *attname; + Oid atttypid; + int32 atttypmod; + int j; + + if (att->attisdropped) + continue; /* attrMap[i] is already 0 */ + attname = NameStr(att->attname); + atttypid = att->atttypid; + atttypmod = att->atttypmod; + for (j = 0; j < indesc->natts; j++) + { + att = indesc->attrs[j]; + if (att->attisdropped) + continue; + if (strcmp(attname, NameStr(att->attname)) == 0) + { + /* Found it, check type */ + if (atttypid != att->atttypid || atttypmod != att->atttypmod) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg_internal("%s", _(msg)), + errdetail("Attribute \"%s\" of type %s does not match corresponding attribute of type %s.", + attname, + format_type_be(outdesc->tdtypeid), + format_type_be(indesc->tdtypeid)))); + attrMap[i] = (AttrNumber) (j + 1); + break; + } + } + if (attrMap[i] == 0) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg_internal("%s", _(msg)), + errdetail("Attribute \"%s\" of type %s does not exist in type %s.", + attname, + format_type_be(outdesc->tdtypeid), + format_type_be(indesc->tdtypeid)))); + } + + return attrMap; +} + +/* * Perform conversion of a tuple according to the map. */ HeapTuple |