summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlvaro Herrera2022-11-29 08:39:36 +0000
committerAlvaro Herrera2022-11-29 08:39:36 +0000
commitad86d159b6ab90b195b06fb5c7b593900a7f9cd8 (patch)
treeacea26f7f4dd2c3bfd2e17dea81d3bc616926594
parent00ae5d6f588e9d21fa4f4d267811f3f602fe45af (diff)
Add 'missing_ok' argument to build_attrmap_by_name
When it's given as true, return a 0 in the position of the missing column rather than raising an error. This is currently unused, but it allows us to reimplement column permission checking in a subsequent commit. It seems worth breaking into a separate commit because it affects unrelated code. Author: Amit Langote <[email protected]> Discussion: https://postgr.es/m/CA+HiwqFfiai=qBxPDTjaio_ZcaqUKh+FC=prESrB8ogZgFNNNQ@mail.gmail.com
-rw-r--r--src/backend/access/common/attmap.c14
-rw-r--r--src/backend/access/common/tupconvert.c2
-rw-r--r--src/backend/catalog/partition.c3
-rw-r--r--src/backend/commands/indexcmds.c3
-rw-r--r--src/backend/commands/tablecmds.c24
-rw-r--r--src/backend/executor/execMain.c11
-rw-r--r--src/backend/executor/execPartition.c15
-rw-r--r--src/backend/parser/parse_utilcmd.c3
-rw-r--r--src/backend/replication/pgoutput/pgoutput.c2
-rw-r--r--src/include/access/attmap.h6
10 files changed, 55 insertions, 28 deletions
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);