1
0
mirror of https://github.com/postgres/postgres.git synced 2025-09-03 15:22:11 +03:00

Fix usage of "tableoid" in GENERATED expressions.

We consider this supported (though I've got my doubts that it's a
good idea, because tableoid is not immutable).  However, several
code paths failed to fill the field in soon enough, causing such
a GENERATED expression to see zero or the wrong value.  This
occurred when ALTER TABLE adds a new GENERATED column to a table
with existing rows, and during regular INSERT or UPDATE on a
foreign table with GENERATED columns.

Noted during investigation of a report from Vitaly Ustinov.
Back-patch to v12 where GENERATED came in.

Discussion: https://postgr.es/m/CAM_DEiWR2DPT6U4xb-Ehigozzd3n3G37ZB1+867zbsEVtYoJww@mail.gmail.com
This commit is contained in:
Tom Lane
2021-05-21 15:02:07 -04:00
parent d18ee6f92d
commit 77e3204ecb
4 changed files with 38 additions and 17 deletions

View File

@@ -437,6 +437,12 @@ ExecInsert(ModifyTableState *mtstate,
}
else if (resultRelInfo->ri_FdwRoutine)
{
/*
* GENERATED expressions might reference the tableoid column, so
* (re-)initialize tts_tableOid before evaluating them.
*/
slot->tts_tableOid = RelationGetRelid(resultRelInfo->ri_RelationDesc);
/*
* Compute stored generated columns
*/
@@ -458,7 +464,7 @@ ExecInsert(ModifyTableState *mtstate,
/*
* AFTER ROW Triggers or RETURNING expressions might reference the
* tableoid column, so (re-)initialize tts_tableOid before evaluating
* them.
* them. (This covers the case where the FDW replaced the slot.)
*/
slot->tts_tableOid = RelationGetRelid(resultRelInfo->ri_RelationDesc);
}
@@ -467,8 +473,8 @@ ExecInsert(ModifyTableState *mtstate,
WCOKind wco_kind;
/*
* Constraints might reference the tableoid column, so (re-)initialize
* tts_tableOid before evaluating them.
* Constraints and GENERATED expressions might reference the tableoid
* column, so (re-)initialize tts_tableOid before evaluating them.
*/
slot->tts_tableOid = RelationGetRelid(resultRelationDesc);
@@ -1172,6 +1178,12 @@ ExecUpdate(ModifyTableState *mtstate,
}
else if (resultRelInfo->ri_FdwRoutine)
{
/*
* GENERATED expressions might reference the tableoid column, so
* (re-)initialize tts_tableOid before evaluating them.
*/
slot->tts_tableOid = RelationGetRelid(resultRelInfo->ri_RelationDesc);
/*
* Compute stored generated columns
*/
@@ -1193,7 +1205,7 @@ ExecUpdate(ModifyTableState *mtstate,
/*
* AFTER ROW Triggers or RETURNING expressions might reference the
* tableoid column, so (re-)initialize tts_tableOid before evaluating
* them.
* them. (This covers the case where the FDW replaced the slot.)
*/
slot->tts_tableOid = RelationGetRelid(resultRelationDesc);
}
@@ -1204,8 +1216,8 @@ ExecUpdate(ModifyTableState *mtstate,
bool update_indexes;
/*
* Constraints might reference the tableoid column, so (re-)initialize
* tts_tableOid before evaluating them.
* Constraints and GENERATED expressions might reference the tableoid
* column, so (re-)initialize tts_tableOid before evaluating them.
*/
slot->tts_tableOid = RelationGetRelid(resultRelationDesc);