Skip to content

Commit 7cbe57c

Browse files
committed
Offer triggers on foreign tables.
This covers all the SQL-standard trigger types supported for regular tables; it does not cover constraint triggers. The approach for acquiring the old row mirrors that for view INSTEAD OF triggers. For AFTER ROW triggers, we spool the foreign tuples to a tuplestore. This changes the FDW API contract; when deciding which columns to populate in the slot returned from data modification callbacks, writable FDWs will need to check for AFTER ROW triggers in addition to checking for a RETURNING clause. In support of the feature addition, refactor the TriggerFlags bits and the assembly of old tuples in ModifyTable. Ronan Dunklau, reviewed by KaiGai Kohei; some additional hacking by me.
1 parent 6115480 commit 7cbe57c

File tree

14 files changed

+1145
-202
lines changed

14 files changed

+1145
-202
lines changed

contrib/postgres_fdw/deparse.c

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ static void deparseTargetList(StringInfo buf,
110110
List **retrieved_attrs);
111111
static void deparseReturningList(StringInfo buf, PlannerInfo *root,
112112
Index rtindex, Relation rel,
113+
bool trig_after_row,
113114
List *returningList,
114115
List **retrieved_attrs);
115116
static void deparseColumnRef(StringInfo buf, int varno, int varattno,
@@ -875,11 +876,9 @@ deparseInsertSql(StringInfo buf, PlannerInfo *root,
875876
else
876877
appendStringInfoString(buf, " DEFAULT VALUES");
877878

878-
if (returningList)
879-
deparseReturningList(buf, root, rtindex, rel, returningList,
880-
retrieved_attrs);
881-
else
882-
*retrieved_attrs = NIL;
879+
deparseReturningList(buf, root, rtindex, rel,
880+
rel->trigdesc && rel->trigdesc->trig_insert_after_row,
881+
returningList, retrieved_attrs);
883882
}
884883

885884
/*
@@ -919,11 +918,9 @@ deparseUpdateSql(StringInfo buf, PlannerInfo *root,
919918
}
920919
appendStringInfoString(buf, " WHERE ctid = $1");
921920

922-
if (returningList)
923-
deparseReturningList(buf, root, rtindex, rel, returningList,
924-
retrieved_attrs);
925-
else
926-
*retrieved_attrs = NIL;
921+
deparseReturningList(buf, root, rtindex, rel,
922+
rel->trigdesc && rel->trigdesc->trig_update_after_row,
923+
returningList, retrieved_attrs);
927924
}
928925

929926
/*
@@ -943,34 +940,48 @@ deparseDeleteSql(StringInfo buf, PlannerInfo *root,
943940
deparseRelation(buf, rel);
944941
appendStringInfoString(buf, " WHERE ctid = $1");
945942

946-
if (returningList)
947-
deparseReturningList(buf, root, rtindex, rel, returningList,
948-
retrieved_attrs);
949-
else
950-
*retrieved_attrs = NIL;
943+
deparseReturningList(buf, root, rtindex, rel,
944+
rel->trigdesc && rel->trigdesc->trig_delete_after_row,
945+
returningList, retrieved_attrs);
951946
}
952947

953948
/*
954-
* deparse RETURNING clause of INSERT/UPDATE/DELETE
949+
* Add a RETURNING clause, if needed, to an INSERT/UPDATE/DELETE.
955950
*/
956951
static void
957952
deparseReturningList(StringInfo buf, PlannerInfo *root,
958953
Index rtindex, Relation rel,
954+
bool trig_after_row,
959955
List *returningList,
960956
List **retrieved_attrs)
961957
{
962-
Bitmapset *attrs_used;
958+
Bitmapset *attrs_used = NULL;
963959

964-
/*
965-
* We need the attrs mentioned in the query's RETURNING list.
966-
*/
967-
attrs_used = NULL;
968-
pull_varattnos((Node *) returningList, rtindex,
969-
&attrs_used);
960+
if (trig_after_row)
961+
{
962+
/* whole-row reference acquires all non-system columns */
963+
attrs_used =
964+
bms_make_singleton(0 - FirstLowInvalidHeapAttributeNumber);
965+
}
970966

971-
appendStringInfoString(buf, " RETURNING ");
972-
deparseTargetList(buf, root, rtindex, rel, attrs_used,
973-
retrieved_attrs);
967+
if (returningList != NIL)
968+
{
969+
/*
970+
* We need the attrs, non-system and system, mentioned in the local
971+
* query's RETURNING list.
972+
*/
973+
pull_varattnos((Node *) returningList, rtindex,
974+
&attrs_used);
975+
}
976+
977+
if (attrs_used != NULL)
978+
{
979+
appendStringInfoString(buf, " RETURNING ");
980+
deparseTargetList(buf, root, rtindex, rel, attrs_used,
981+
retrieved_attrs);
982+
}
983+
else
984+
*retrieved_attrs = NIL;
974985
}
975986

976987
/*

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