Skip to content

Commit 2b81444

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 a27f3a7 commit 2b81444

File tree

2 files changed

+30
-13
lines changed

2 files changed

+30
-13
lines changed

src/backend/executor/execUtils.c

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,18 +1182,18 @@ Bitmapset *
11821182
ExecGetInsertedCols(ResultRelInfo *relinfo, EState *estate)
11831183
{
11841184
/*
1185-
* The columns are stored in the range table entry. If this ResultRelInfo
1186-
* doesn't have an entry in the range table (i.e. if it represents a
1187-
* partition routing target), fetch the parent's RTE and map the columns
1188-
* to the order they are in the partition.
1185+
* The columns are stored in the range table entry. If this ResultRelInfo
1186+
* represents a partition routing target, and doesn't have an entry of its
1187+
* own in the range table, fetch the parent's RTE and map the columns to
1188+
* the order they are in the partition.
11891189
*/
11901190
if (relinfo->ri_RangeTableIndex != 0)
11911191
{
11921192
RangeTblEntry *rte = exec_rt_fetch(relinfo->ri_RangeTableIndex, estate);
11931193

11941194
return rte->insertedCols;
11951195
}
1196-
else
1196+
else if (relinfo->ri_RootResultRelInfo)
11971197
{
11981198
ResultRelInfo *rootRelInfo = relinfo->ri_RootResultRelInfo;
11991199
RangeTblEntry *rte = exec_rt_fetch(rootRelInfo->ri_RangeTableIndex, estate);
@@ -1205,6 +1205,16 @@ ExecGetInsertedCols(ResultRelInfo *relinfo, EState *estate)
12051205
else
12061206
return rte->insertedCols;
12071207
}
1208+
else
1209+
{
1210+
/*
1211+
* The relation isn't in the range table and it isn't a partition
1212+
* routing target. This ResultRelInfo must've been created only for
1213+
* firing triggers and the relation is not being inserted into. (See
1214+
* ExecGetTriggerResultRel.)
1215+
*/
1216+
return NULL;
1217+
}
12081218
}
12091219

12101220
/* Return a bitmap representing columns being updated */
@@ -1218,7 +1228,7 @@ ExecGetUpdatedCols(ResultRelInfo *relinfo, EState *estate)
12181228

12191229
return rte->updatedCols;
12201230
}
1221-
else
1231+
else if (relinfo->ri_RootResultRelInfo)
12221232
{
12231233
ResultRelInfo *rootRelInfo = relinfo->ri_RootResultRelInfo;
12241234
RangeTblEntry *rte = exec_rt_fetch(rootRelInfo->ri_RangeTableIndex, estate);
@@ -1230,6 +1240,8 @@ ExecGetUpdatedCols(ResultRelInfo *relinfo, EState *estate)
12301240
else
12311241
return rte->updatedCols;
12321242
}
1243+
else
1244+
return NULL;
12331245
}
12341246

12351247
/* Return a bitmap representing generated columns being updated */
@@ -1243,7 +1255,7 @@ ExecGetExtraUpdatedCols(ResultRelInfo *relinfo, EState *estate)
12431255

12441256
return rte->extraUpdatedCols;
12451257
}
1246-
else
1258+
else if (relinfo->ri_RootResultRelInfo)
12471259
{
12481260
ResultRelInfo *rootRelInfo = relinfo->ri_RootResultRelInfo;
12491261
RangeTblEntry *rte = exec_rt_fetch(rootRelInfo->ri_RangeTableIndex, estate);
@@ -1255,6 +1267,8 @@ ExecGetExtraUpdatedCols(ResultRelInfo *relinfo, EState *estate)
12551267
else
12561268
return rte->extraUpdatedCols;
12571269
}
1270+
else
1271+
return NULL;
12581272
}
12591273

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

src/include/nodes/execnodes.h

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

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy