mirror of
https://github.com/postgres/postgres.git
synced 2025-07-15 19:21:59 +03:00
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.
This commit is contained in:
@ -1199,7 +1199,7 @@ static void
|
||||
rewriteTargetListUD(Query *parsetree, RangeTblEntry *target_rte,
|
||||
Relation target_relation)
|
||||
{
|
||||
Var *var;
|
||||
Var *var = NULL;
|
||||
const char *attrname;
|
||||
TargetEntry *tle;
|
||||
|
||||
@ -1231,7 +1231,26 @@ rewriteTargetListUD(Query *parsetree, RangeTblEntry *target_rte,
|
||||
fdwroutine->AddForeignUpdateTargets(parsetree, target_rte,
|
||||
target_relation);
|
||||
|
||||
return;
|
||||
/*
|
||||
* If we have a row-level trigger corresponding to the operation, emit
|
||||
* a whole-row Var so that executor will have the "old" row to pass to
|
||||
* the trigger. Alas, this misses system columns.
|
||||
*/
|
||||
if (target_relation->trigdesc &&
|
||||
((parsetree->commandType == CMD_UPDATE &&
|
||||
(target_relation->trigdesc->trig_update_after_row ||
|
||||
target_relation->trigdesc->trig_update_before_row)) ||
|
||||
(parsetree->commandType == CMD_DELETE &&
|
||||
(target_relation->trigdesc->trig_delete_after_row ||
|
||||
target_relation->trigdesc->trig_delete_before_row))))
|
||||
{
|
||||
var = makeWholeRowVar(target_rte,
|
||||
parsetree->resultRelation,
|
||||
0,
|
||||
false);
|
||||
|
||||
attrname = "wholerow";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1247,12 +1266,15 @@ rewriteTargetListUD(Query *parsetree, RangeTblEntry *target_rte,
|
||||
attrname = "wholerow";
|
||||
}
|
||||
|
||||
tle = makeTargetEntry((Expr *) var,
|
||||
list_length(parsetree->targetList) + 1,
|
||||
pstrdup(attrname),
|
||||
true);
|
||||
if (var != NULL)
|
||||
{
|
||||
tle = makeTargetEntry((Expr *) var,
|
||||
list_length(parsetree->targetList) + 1,
|
||||
pstrdup(attrname),
|
||||
true);
|
||||
|
||||
parsetree->targetList = lappend(parsetree->targetList, tle);
|
||||
parsetree->targetList = lappend(parsetree->targetList, tle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user