diff options
author | Michael Paquier <michael@paquier.xyz> | 2019-12-18 16:23:02 +0900 |
---|---|---|
committer | Michael Paquier <michael@paquier.xyz> | 2019-12-18 16:23:02 +0900 |
commit | e1551f96e643a52a035c3b35777d968bc073f7fc (patch) | |
tree | 9010890c3289462dc42a51a4d03498423359d375 /src/backend/parser/parse_utilcmd.c | |
parent | 04c8a69c0cccbc271e0feeb22a74c69fbd87c37e (diff) | |
download | postgresql-e1551f96e643a52a035c3b35777d968bc073f7fc.tar.gz postgresql-e1551f96e643a52a035c3b35777d968bc073f7fc.zip |
Refactor attribute mappings used in logical tuple conversion
Tuple conversion support in tupconvert.c is able to convert rowtypes
between two relations, inner and outer, which are logically equivalent
but have a different ordering or even dropped columns (used mainly for
inheritance tree and partitions). This makes use of attribute mappings,
which are simple arrays made of AttrNumber elements with a length
matching the number of attributes of the outer relation. The length of
the attribute mapping has been treated as completely independent of the
mapping itself until now, making it easy to pass down an incorrect
mapping length.
This commit refactors the code related to attribute mappings and moves
it into an independent facility called attmap.c, extracted from
tupconvert.c. This merges the attribute mapping with its length,
avoiding to try to guess what is the length of a mapping to use as this
is computed once, when the map is built.
This will avoid mistakes like what has been fixed in dc816e58, which has
used an incorrect mapping length by matching it with the number of
attributes of an inner relation (a child partition) instead of an outer
relation (a partitioned table).
Author: Michael Paquier
Reviewed-by: Amit Langote
Discussion: https://postgr.es/m/20191121042556.GD153437@paquier.xyz
Diffstat (limited to 'src/backend/parser/parse_utilcmd.c')
-rw-r--r-- | src/backend/parser/parse_utilcmd.c | 18 |
1 files changed, 9 insertions, 9 deletions
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c index b761fdfd7d7..45bb31ecf8f 100644 --- a/src/backend/parser/parse_utilcmd.c +++ b/src/backend/parser/parse_utilcmd.c @@ -917,7 +917,7 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla Relation relation; TupleDesc tupleDesc; TupleConstr *constr; - AttrNumber *attmap; + AttrMap *attmap; AclResult aclresult; char *comment; ParseCallbackState pcbstate; @@ -974,7 +974,7 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla * since dropped columns in the source table aren't copied, so the new * table can have different column numbers. */ - attmap = (AttrNumber *) palloc0(sizeof(AttrNumber) * tupleDesc->natts); + attmap = make_attrmap(tupleDesc->natts); /* * Insert the copied attributes into the cxt for the new table definition. @@ -1020,7 +1020,7 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla */ cxt->columns = lappend(cxt->columns, def); - attmap[parent_attno - 1] = list_length(cxt->columns); + attmap->attnums[parent_attno - 1] = list_length(cxt->columns); /* * Copy default, if present and it should be copied. We have separate @@ -1051,7 +1051,7 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla def->cooked_default = map_variable_attnos(this_default, 1, 0, - attmap, tupleDesc->natts, + attmap, InvalidOid, &found_whole_row); /* @@ -1134,7 +1134,7 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla ccbin_node = map_variable_attnos(stringToNode(ccbin), 1, 0, - attmap, tupleDesc->natts, + attmap, InvalidOid, &found_whole_row); /* @@ -1200,7 +1200,7 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla /* Build CREATE INDEX statement to recreate the parent_index */ index_stmt = generateClonedIndexStmt(cxt->relation, parent_index, - attmap, tupleDesc->natts, + attmap, NULL); /* Copy comment on index, if requested */ @@ -1332,7 +1332,7 @@ transformOfType(CreateStmtContext *cxt, TypeName *ofTypename) */ IndexStmt * generateClonedIndexStmt(RangeVar *heapRel, Relation source_idx, - const AttrNumber *attmap, int attmap_length, + const AttrMap *attmap, Oid *constraintOid) { Oid source_relid = RelationGetRelid(source_idx); @@ -1552,7 +1552,7 @@ generateClonedIndexStmt(RangeVar *heapRel, Relation source_idx, /* Adjust Vars to match new table's column numbering */ indexkey = map_variable_attnos(indexkey, 1, 0, - attmap, attmap_length, + attmap, InvalidOid, &found_whole_row); /* As in transformTableLikeClause, reject whole-row variables */ @@ -1659,7 +1659,7 @@ generateClonedIndexStmt(RangeVar *heapRel, Relation source_idx, /* Adjust Vars to match new table's column numbering */ pred_tree = map_variable_attnos(pred_tree, 1, 0, - attmap, attmap_length, + attmap, InvalidOid, &found_whole_row); /* As in transformTableLikeClause, reject whole-row variables */ |