]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Make ExecGetInsertedCols() and friends more robust and improve comments.
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Mon, 15 Feb 2021 07:28:08 +0000 (09:28 +0200)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Mon, 15 Feb 2021 07:29:49 +0000 (09:29 +0200)
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
src/backend/executor/execUtils.c

index e91a6ebddd59063e029bfd9c36998ccb841078cb..1c2c69673cee2b4a87363dde7a60ab51664ca8a5 100644 (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;
 }