When modifying a foreign table, initialize tableoid field properly.
authorRobert Haas <rhaas@postgresql.org>
Fri, 5 Feb 2016 02:15:57 +0000 (21:15 -0500)
committerRobert Haas <rhaas@postgresql.org>
Fri, 5 Feb 2016 02:17:53 +0000 (21:17 -0500)
Failure to do this can cause AFTER ROW triggers or RETURNING expressions
that reference this field to misbehave.

Etsuro Fujita, reviewed by Thom Brown

src/backend/executor/nodeModifyTable.c

index 46299fc7619e64f42d99aeaa88639bef97cbdd5b..27051e80b087fdd568438f0b8388922c491bfccd 100644 (file)
@@ -308,6 +308,12 @@ ExecInsert(ModifyTableState *mtstate,
                /* FDW might have changed tuple */
                tuple = ExecMaterializeSlot(slot);
 
+               /*
+                * AFTER ROW Triggers or RETURNING expressions might reference the
+                * tableoid column, so initialize t_tableOid before evaluating them.
+                */
+               tuple->t_tableOid = RelationGetRelid(resultRelationDesc);
+
                newId = InvalidOid;
        }
        else
@@ -561,6 +567,8 @@ ExecDelete(ItemPointer tupleid,
        }
        else if (resultRelInfo->ri_FdwRoutine)
        {
+               HeapTuple       tuple;
+
                /*
                 * delete from foreign table: let the FDW do it
                 *
@@ -579,6 +587,15 @@ ExecDelete(ItemPointer tupleid,
 
                if (slot == NULL)               /* "do nothing" */
                        return NULL;
+
+               /*
+                * RETURNING expressions might reference the tableoid column, so
+                * initialize t_tableOid before evaluating them.
+                */
+               if (slot->tts_isempty)
+                       ExecStoreAllNullTuple(slot);
+               tuple = ExecMaterializeSlot(slot);
+               tuple->t_tableOid = RelationGetRelid(resultRelationDesc);
        }
        else
        {
@@ -838,6 +855,12 @@ ExecUpdate(ItemPointer tupleid,
 
                /* FDW might have changed tuple */
                tuple = ExecMaterializeSlot(slot);
+
+               /*
+                * AFTER ROW Triggers or RETURNING expressions might reference the
+                * tableoid column, so initialize t_tableOid before evaluating them.
+                */
+               tuple->t_tableOid = RelationGetRelid(resultRelationDesc);
        }
        else
        {