Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 54e51dc

Browse files
committed
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 6214e2b, ri_RangeTableIndex is zero for ResultRelInfos created for partition tuple routing. Noted by Coverity. Backpatch down to v11, like commit 6214e2b. Reviewed-by: Tom Lane, Amit Langote
1 parent 46d6e5f commit 54e51dc

File tree

2 files changed

+30
-13
lines changed

2 files changed

+30
-13
lines changed

src/backend/executor/execUtils.c

+21-7
Original file line numberDiff line numberDiff line change
@@ -1230,18 +1230,18 @@ Bitmapset *
12301230
ExecGetInsertedCols(ResultRelInfo *relinfo, EState *estate)
12311231
{
12321232
/*
1233-
* The columns are stored in the range table entry. If this ResultRelInfo
1234-
* doesn't have an entry in the range table (i.e. if it represents a
1235-
* partition routing target), fetch the parent's RTE and map the columns
1236-
* to the order they are in the partition.
1233+
* The columns are stored in the range table entry. If this ResultRelInfo
1234+
* represents a partition routing target, and doesn't have an entry of its
1235+
* own in the range table, fetch the parent's RTE and map the columns to
1236+
* the order they are in the partition.
12371237
*/
12381238
if (relinfo->ri_RangeTableIndex != 0)
12391239
{
12401240
RangeTblEntry *rte = exec_rt_fetch(relinfo->ri_RangeTableIndex, estate);
12411241

12421242
return rte->insertedCols;
12431243
}
1244-
else
1244+
else if (relinfo->ri_RootResultRelInfo)
12451245
{
12461246
ResultRelInfo *rootRelInfo = relinfo->ri_RootResultRelInfo;
12471247
RangeTblEntry *rte = exec_rt_fetch(rootRelInfo->ri_RangeTableIndex, estate);
@@ -1252,6 +1252,16 @@ ExecGetInsertedCols(ResultRelInfo *relinfo, EState *estate)
12521252
else
12531253
return rte->insertedCols;
12541254
}
1255+
else
1256+
{
1257+
/*
1258+
* The relation isn't in the range table and it isn't a partition
1259+
* routing target. This ResultRelInfo must've been created only for
1260+
* firing triggers and the relation is not being inserted into. (See
1261+
* ExecGetTriggerResultRel.)
1262+
*/
1263+
return NULL;
1264+
}
12551265
}
12561266

12571267
/* Return a bitmap representing columns being updated */
@@ -1265,7 +1275,7 @@ ExecGetUpdatedCols(ResultRelInfo *relinfo, EState *estate)
12651275

12661276
return rte->updatedCols;
12671277
}
1268-
else
1278+
else if (relinfo->ri_RootResultRelInfo)
12691279
{
12701280
ResultRelInfo *rootRelInfo = relinfo->ri_RootResultRelInfo;
12711281
RangeTblEntry *rte = exec_rt_fetch(rootRelInfo->ri_RangeTableIndex, estate);
@@ -1276,6 +1286,8 @@ ExecGetUpdatedCols(ResultRelInfo *relinfo, EState *estate)
12761286
else
12771287
return rte->updatedCols;
12781288
}
1289+
else
1290+
return NULL;
12791291
}
12801292

12811293
/* Return a bitmap representing generated columns being updated */
@@ -1289,7 +1301,7 @@ ExecGetExtraUpdatedCols(ResultRelInfo *relinfo, EState *estate)
12891301

12901302
return rte->extraUpdatedCols;
12911303
}
1292-
else
1304+
else if (relinfo->ri_RootResultRelInfo)
12931305
{
12941306
ResultRelInfo *rootRelInfo = relinfo->ri_RootResultRelInfo;
12951307
RangeTblEntry *rte = exec_rt_fetch(rootRelInfo->ri_RangeTableIndex, estate);
@@ -1300,6 +1312,8 @@ ExecGetExtraUpdatedCols(ResultRelInfo *relinfo, EState *estate)
13001312
else
13011313
return rte->extraUpdatedCols;
13021314
}
1315+
else
1316+
return NULL;
13031317
}
13041318

13051319
/* Return columns being updated, including generated columns */

src/include/nodes/execnodes.h

+9-6
Original file line numberDiff line numberDiff line change
@@ -394,12 +394,15 @@ typedef struct OnConflictSetState
394394
* relation, and perhaps also fire triggers. ResultRelInfo holds all the
395395
* information needed about a result relation, including indexes.
396396
*
397-
* Normally, a ResultRelInfo refers to a table that is in the query's
398-
* range table; then ri_RangeTableIndex is the RT index and ri_RelationDesc
399-
* is just a copy of the relevant es_relations[] entry. But sometimes,
400-
* in ResultRelInfos used only for triggers, ri_RangeTableIndex is zero
401-
* and ri_RelationDesc is a separately-opened relcache pointer that needs
402-
* to be separately closed. See ExecGetTriggerResultRel.
397+
* Normally, a ResultRelInfo refers to a table that is in the query's range
398+
* table; then ri_RangeTableIndex is the RT index and ri_RelationDesc is
399+
* just a copy of the relevant es_relations[] entry. However, in some
400+
* situations we create ResultRelInfos for relations that are not in the
401+
* range table, namely for targets of tuple routing in a partitioned table,
402+
* and when firing triggers in tables other than the target tables (See
403+
* ExecGetTriggerResultRel). In these situations, ri_RangeTableIndex is 0
404+
* and ri_RelationDesc is a separately-opened relcache pointer that needs to
405+
* be separately closed.
403406
*/
404407
typedef struct ResultRelInfo
405408
{

0 commit comments

Comments
 (0)