Make ExecGetInsertedCols() and friends more robust and improve comments.

If ExecGetInsertedCols(), ExecGetUpdatedCols() or ExecGetExtraUpdatedCols()
were called with a ResultRelInfo that's not in the range table and isn't a
partition routing target, the functions would dereference a NULL pointer,
relinfo->ri_RootResultRelInfo. Such ResultRelInfos are created when firing
RI triggers in tables that are not modified directly. None of the current
callers of these functions pass such relations, so this isn't a live bug,
but let's make them more robust.

Also update comment in ResultRelInfo; after commit 6214e2b228,
ri_RangeTableIndex is zero for ResultRelInfos created for partition tuple
routing.

Noted by Coverity. Backpatch down to v11, like commit 6214e2b228.

Reviewed-by: Tom Lane, Amit Langote
This commit is contained in:
Heikki Linnakangas 2021-02-15 09:28:08 +02:00
parent 1fefe8879a
commit 6e437ce5a6

View File

@ -1075,10 +1075,10 @@ Bitmapset *
ExecGetInsertedCols(ResultRelInfo *relinfo, EState *estate)
{
/*
* The columns are stored in the range table entry. If this ResultRelInfo
* doesn't have an entry in the range table (i.e. if it represents a
* partition routing target), fetch the parent's RTE and map the columns
* to the order they are in the partition.
* The columns are stored in the range table entry. If this ResultRelInfo
* represents a partition routing target, and doesn't have an entry of its
* own in the range table, fetch the parent's RTE and map the columns to
* the order they are in the partition.
*/
if (relinfo->ri_RangeTableIndex != 0)
{
@ -1087,7 +1087,7 @@ ExecGetInsertedCols(ResultRelInfo *relinfo, EState *estate)
return rte->insertedCols;
}
else
else if (relinfo->ri_RootResultRelInfo)
{
ResultRelInfo *rootRelInfo = relinfo->ri_RootResultRelInfo;
RangeTblEntry *rte = rt_fetch(rootRelInfo->ri_RangeTableIndex,
@ -1102,6 +1102,16 @@ ExecGetInsertedCols(ResultRelInfo *relinfo, EState *estate)
else
return rte->insertedCols;
}
else
{
/*
* The relation isn't in the range table and it isn't a partition
* routing target. This ResultRelInfo must've been created only for
* firing triggers and the relation is not being inserted into. (See
* ExecGetTriggerResultRel.)
*/
return NULL;
}
}
/* Return a bitmap representing columns being updated */
@ -1116,7 +1126,7 @@ ExecGetUpdatedCols(ResultRelInfo *relinfo, EState *estate)
return rte->updatedCols;
}
else
else if (relinfo->ri_RootResultRelInfo)
{
ResultRelInfo *rootRelInfo = relinfo->ri_RootResultRelInfo;
RangeTblEntry *rte = rt_fetch(rootRelInfo->ri_RangeTableIndex,
@ -1131,4 +1141,6 @@ ExecGetUpdatedCols(ResultRelInfo *relinfo, EState *estate)
else
return rte->updatedCols;
}
else
return NULL;
}