diff --git a/src/backend/access/common/attmap.c b/src/backend/access/common/attmap.c index 896f82a22b..1e65d8a120 100644 --- a/src/backend/access/common/attmap.c +++ b/src/backend/access/common/attmap.c @@ -169,10 +169,15 @@ build_attrmap_by_position(TupleDesc indesc, * and output columns by name. (Dropped columns are ignored in both input and * output.) This is normally a subroutine for convert_tuples_by_name in * tupconvert.c, but can be used standalone. + * + * If 'missing_ok' is true, a column from 'outdesc' not being present in + * 'indesc' is not flagged as an error; AttrMap.attnums[] entry for such an + * outdesc column will be 0 in that case. */ AttrMap * build_attrmap_by_name(TupleDesc indesc, - TupleDesc outdesc) + TupleDesc outdesc, + bool missing_ok) { AttrMap *attrMap; int outnatts; @@ -235,7 +240,7 @@ build_attrmap_by_name(TupleDesc indesc, break; } } - if (attrMap->attnums[i] == 0) + if (attrMap->attnums[i] == 0 && !missing_ok) ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), errmsg("could not convert row type"), @@ -257,12 +262,13 @@ build_attrmap_by_name(TupleDesc indesc, */ AttrMap * build_attrmap_by_name_if_req(TupleDesc indesc, - TupleDesc outdesc) + TupleDesc outdesc, + bool missing_ok) { AttrMap *attrMap; /* Verify compatibility and prepare attribute-number map */ - attrMap = build_attrmap_by_name(indesc, outdesc); + attrMap = build_attrmap_by_name(indesc, outdesc, missing_ok); /* Check if the map has a one-to-one match */ if (check_attrmap_match(indesc, outdesc, attrMap)) diff --git a/src/backend/access/common/tupconvert.c b/src/backend/access/common/tupconvert.c index 4010e20cfb..b2f892d2fd 100644 --- a/src/backend/access/common/tupconvert.c +++ b/src/backend/access/common/tupconvert.c @@ -107,7 +107,7 @@ convert_tuples_by_name(TupleDesc indesc, int n = outdesc->natts; /* Verify compatibility and prepare attribute-number map */ - attrMap = build_attrmap_by_name_if_req(indesc, outdesc); + attrMap = build_attrmap_by_name_if_req(indesc, outdesc, false); if (attrMap == NULL) { diff --git a/src/backend/catalog/partition.c b/src/backend/catalog/partition.c index c6ec479004..79ccddce55 100644 --- a/src/backend/catalog/partition.c +++ b/src/backend/catalog/partition.c @@ -227,7 +227,8 @@ map_partition_varattnos(List *expr, int fromrel_varno, bool found_whole_row; part_attmap = build_attrmap_by_name(RelationGetDescr(to_rel), - RelationGetDescr(from_rel)); + RelationGetDescr(from_rel), + false); expr = (List *) map_variable_attnos((Node *) expr, fromrel_varno, 0, part_attmap, diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index 91cee27743..b5b860c3ab 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -1290,7 +1290,8 @@ DefineIndex(Oid relationId, childidxs = RelationGetIndexList(childrel); attmap = build_attrmap_by_name(RelationGetDescr(childrel), - parentDesc); + parentDesc, + false); foreach(cell, childidxs) { diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 845208d662..10c1955884 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -1206,7 +1206,8 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, } attmap = build_attrmap_by_name(RelationGetDescr(rel), - RelationGetDescr(parent)); + RelationGetDescr(parent), + false); idxstmt = generateClonedIndexStmt(NULL, idxRel, attmap, &constraintOid); @@ -9647,7 +9648,8 @@ addFkRecurseReferenced(List **wqueue, Constraint *fkconstraint, Relation rel, * definition to match the partition's column layout. */ map = build_attrmap_by_name_if_req(RelationGetDescr(partRel), - RelationGetDescr(pkrel)); + RelationGetDescr(pkrel), + false); if (map) { mapped_pkattnum = palloc(sizeof(AttrNumber) * numfks); @@ -9814,7 +9816,8 @@ addFkRecurseReferencing(List **wqueue, Constraint *fkconstraint, Relation rel, CheckTableNotInUse(partition, "ALTER TABLE"); attmap = build_attrmap_by_name(RelationGetDescr(partition), - RelationGetDescr(rel)); + RelationGetDescr(rel), + false); for (int j = 0; j < numfks; j++) mapped_fkattnum[j] = attmap->attnums[fkattnum[j] - 1]; @@ -10022,7 +10025,8 @@ CloneFkReferenced(Relation parentRel, Relation partitionRel) trigrel = table_open(TriggerRelationId, RowExclusiveLock); attmap = build_attrmap_by_name(RelationGetDescr(partitionRel), - RelationGetDescr(parentRel)); + RelationGetDescr(parentRel), + false); foreach(cell, clone) { Oid constrOid = lfirst_oid(cell); @@ -10219,7 +10223,8 @@ CloneFkReferencing(List **wqueue, Relation parentRel, Relation partRel) * different. This map is used to convert them. */ attmap = build_attrmap_by_name(RelationGetDescr(partRel), - RelationGetDescr(parentRel)); + RelationGetDescr(parentRel), + false); partFKs = copyObject(RelationGetFKeyList(partRel)); @@ -12335,7 +12340,8 @@ ATPrepAlterColumnType(List **wqueue, cmd = copyObject(cmd); attmap = build_attrmap_by_name(RelationGetDescr(childrel), - RelationGetDescr(rel)); + RelationGetDescr(rel), + false); ((ColumnDef *) cmd->def)->cooked_default = map_variable_attnos(def->cooked_default, 1, 0, @@ -18043,7 +18049,8 @@ AttachPartitionEnsureIndexes(Relation rel, Relation attachrel) /* construct an indexinfo to compare existing indexes against */ info = BuildIndexInfo(idxRel); attmap = build_attrmap_by_name(RelationGetDescr(attachrel), - RelationGetDescr(rel)); + RelationGetDescr(rel), + false); constraintOid = get_relation_idx_constraint_oid(RelationGetRelid(rel), idx); /* @@ -18981,7 +18988,8 @@ ATExecAttachPartitionIdx(List **wqueue, Relation parentIdx, RangeVar *name) childInfo = BuildIndexInfo(partIdx); parentInfo = BuildIndexInfo(parentIdx); attmap = build_attrmap_by_name(RelationGetDescr(partTbl), - RelationGetDescr(parentTbl)); + RelationGetDescr(parentTbl), + false); if (!CompareIndexInfo(childInfo, parentInfo, partIdx->rd_indcollation, parentIdx->rd_indcollation, diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index ef828e0496..e301c687e3 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -1859,7 +1859,7 @@ ExecPartitionCheckEmitError(ResultRelInfo *resultRelInfo, old_tupdesc = RelationGetDescr(resultRelInfo->ri_RelationDesc); /* a reverse map */ - map = build_attrmap_by_name_if_req(old_tupdesc, tupdesc); + map = build_attrmap_by_name_if_req(old_tupdesc, tupdesc, false); /* * Partition-specific slot's tupdesc can't be changed, so allocate a @@ -1944,7 +1944,8 @@ ExecConstraints(ResultRelInfo *resultRelInfo, tupdesc = RelationGetDescr(rootrel->ri_RelationDesc); /* a reverse map */ map = build_attrmap_by_name_if_req(orig_tupdesc, - tupdesc); + tupdesc, + false); /* * Partition-specific slot's tupdesc can't be changed, so @@ -1996,7 +1997,8 @@ ExecConstraints(ResultRelInfo *resultRelInfo, tupdesc = RelationGetDescr(rootrel->ri_RelationDesc); /* a reverse map */ map = build_attrmap_by_name_if_req(old_tupdesc, - tupdesc); + tupdesc, + false); /* * Partition-specific slot's tupdesc can't be changed, so @@ -2103,7 +2105,8 @@ ExecWithCheckOptions(WCOKind kind, ResultRelInfo *resultRelInfo, tupdesc = RelationGetDescr(rootrel->ri_RelationDesc); /* a reverse map */ map = build_attrmap_by_name_if_req(old_tupdesc, - tupdesc); + tupdesc, + false); /* * Partition-specific slot's tupdesc can't be changed, diff --git a/src/backend/executor/execPartition.c b/src/backend/executor/execPartition.c index 262cabd940..e85f9b8f5a 100644 --- a/src/backend/executor/execPartition.c +++ b/src/backend/executor/execPartition.c @@ -582,7 +582,8 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate, */ part_attmap = build_attrmap_by_name(RelationGetDescr(partrel), - RelationGetDescr(firstResultRel)); + RelationGetDescr(firstResultRel), + false); wcoList = (List *) map_variable_attnos((Node *) wcoList, firstVarno, 0, @@ -639,7 +640,8 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate, if (part_attmap == NULL) part_attmap = build_attrmap_by_name(RelationGetDescr(partrel), - RelationGetDescr(firstResultRel)); + RelationGetDescr(firstResultRel), + false); returningList = (List *) map_variable_attnos((Node *) returningList, firstVarno, 0, @@ -780,7 +782,8 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate, if (part_attmap == NULL) part_attmap = build_attrmap_by_name(RelationGetDescr(partrel), - RelationGetDescr(firstResultRel)); + RelationGetDescr(firstResultRel), + false); onconflset = (List *) map_variable_attnos((Node *) onconflset, INNER_VAR, 0, @@ -878,7 +881,8 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate, if (part_attmap == NULL) part_attmap = build_attrmap_by_name(RelationGetDescr(partrel), - RelationGetDescr(firstResultRel)); + RelationGetDescr(firstResultRel), + false); if (unlikely(!leaf_part_rri->ri_projectNewInfoValid)) ExecInitMergeTupleSlots(mtstate, leaf_part_rri); @@ -1147,7 +1151,8 @@ ExecInitPartitionDispatchInfo(EState *estate, * routing. */ pd->tupmap = build_attrmap_by_name_if_req(RelationGetDescr(parent_pd->reldesc), - tupdesc); + tupdesc, + false); pd->tupslot = pd->tupmap ? MakeSingleTupleTableSlot(tupdesc, &TTSOpsVirtual) : NULL; } diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c index 487eb2041b..36791d8817 100644 --- a/src/backend/parser/parse_utilcmd.c +++ b/src/backend/parser/parse_utilcmd.c @@ -1232,7 +1232,8 @@ expandTableLikeClause(RangeVar *heapRel, TableLikeClause *table_like_clause) * have a failure since both tables are locked. */ attmap = build_attrmap_by_name(RelationGetDescr(childrel), - tupleDesc); + tupleDesc, + false); /* * Process defaults, if required. diff --git a/src/backend/replication/pgoutput/pgoutput.c b/src/backend/replication/pgoutput/pgoutput.c index 2ecaa5b907..f2128190d8 100644 --- a/src/backend/replication/pgoutput/pgoutput.c +++ b/src/backend/replication/pgoutput/pgoutput.c @@ -1125,7 +1125,7 @@ init_tuple_slot(PGOutputData *data, Relation relation, /* Map must live as long as the session does. */ oldctx = MemoryContextSwitchTo(CacheMemoryContext); - entry->attrmap = build_attrmap_by_name_if_req(indesc, outdesc); + entry->attrmap = build_attrmap_by_name_if_req(indesc, outdesc, false); MemoryContextSwitchTo(oldctx); RelationClose(ancestor); diff --git a/src/include/access/attmap.h b/src/include/access/attmap.h index 3ae40cade7..dc0277384f 100644 --- a/src/include/access/attmap.h +++ b/src/include/access/attmap.h @@ -42,9 +42,11 @@ extern void free_attrmap(AttrMap *map); /* Conversion routines to build mappings */ extern AttrMap *build_attrmap_by_name(TupleDesc indesc, - TupleDesc outdesc); + TupleDesc outdesc, + bool missing_ok); extern AttrMap *build_attrmap_by_name_if_req(TupleDesc indesc, - TupleDesc outdesc); + TupleDesc outdesc, + bool missing_ok); extern AttrMap *build_attrmap_by_position(TupleDesc indesc, TupleDesc outdesc, const char *msg);