diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2021-05-21 15:02:06 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2021-05-21 15:02:06 -0400 |
commit | 2b0ee126bbf01cbfd657bd53c94f9284ba903ca2 (patch) | |
tree | 70d96de4ee059eb932be3b523461efa7929bd341 /src/backend | |
parent | 84f5c2908dad81e8622b0406beea580e40bb03ac (diff) | |
download | postgresql-2b0ee126bbf01cbfd657bd53c94f9284ba903ca2.tar.gz postgresql-2b0ee126bbf01cbfd657bd53c94f9284ba903ca2.zip |
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
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/commands/tablecmds.c | 13 | ||||
-rw-r--r-- | src/backend/executor/nodeModifyTable.c | 24 |
2 files changed, 26 insertions, 11 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index ebc62034d26..85dcc330638 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -5762,6 +5762,14 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode) newslot->tts_isnull[lfirst_int(lc)] = true; /* + * Constraints and GENERATED expressions might reference the + * tableoid column, so fill tts_tableOid with the desired + * value. (We must do this each time, because it gets + * overwritten with newrel's OID during storing.) + */ + newslot->tts_tableOid = RelationGetRelid(oldrel); + + /* * Process supplied expressions to replace selected columns. * * First, evaluate expressions whose inputs come from the old @@ -5804,11 +5812,6 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode) &newslot->tts_isnull[ex->attnum - 1]); } - /* - * Constraints might reference the tableoid column, so - * initialize t_tableOid before evaluating them. - */ - newslot->tts_tableOid = RelationGetRelid(oldrel); insertslot = newslot; } else diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 0816027f7f7..379b0563105 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -659,6 +659,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 */ if (resultRelationDesc->rd_att->constr && @@ -729,7 +735,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); } @@ -738,8 +744,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); @@ -1630,6 +1636,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 */ if (resultRelationDesc->rd_att->constr && @@ -1651,7 +1663,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); } @@ -1662,8 +1674,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); |