diff options
author | Noah Misch <noah@leadboat.com> | 2014-03-23 02:16:34 -0400 |
---|---|---|
committer | Noah Misch <noah@leadboat.com> | 2014-03-23 02:16:34 -0400 |
commit | 7cbe57c34dec4860243e6d0f81738cfbb6e5d069 (patch) | |
tree | 1b2e725b85caef56f986db8ae7c43732819c1f5c /contrib/postgres_fdw/deparse.c | |
parent | 6115480c543c0141011a99db78987ad13540be59 (diff) | |
download | postgresql-7cbe57c34dec4860243e6d0f81738cfbb6e5d069.tar.gz postgresql-7cbe57c34dec4860243e6d0f81738cfbb6e5d069.zip |
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.
Diffstat (limited to 'contrib/postgres_fdw/deparse.c')
-rw-r--r-- | contrib/postgres_fdw/deparse.c | 63 |
1 files changed, 37 insertions, 26 deletions
diff --git a/contrib/postgres_fdw/deparse.c b/contrib/postgres_fdw/deparse.c index 2dfe80da0af..32c01350714 100644 --- a/contrib/postgres_fdw/deparse.c +++ b/contrib/postgres_fdw/deparse.c @@ -110,6 +110,7 @@ static void deparseTargetList(StringInfo buf, List **retrieved_attrs); static void deparseReturningList(StringInfo buf, PlannerInfo *root, Index rtindex, Relation rel, + bool trig_after_row, List *returningList, List **retrieved_attrs); static void deparseColumnRef(StringInfo buf, int varno, int varattno, @@ -875,11 +876,9 @@ deparseInsertSql(StringInfo buf, PlannerInfo *root, else appendStringInfoString(buf, " DEFAULT VALUES"); - if (returningList) - deparseReturningList(buf, root, rtindex, rel, returningList, - retrieved_attrs); - else - *retrieved_attrs = NIL; + deparseReturningList(buf, root, rtindex, rel, + rel->trigdesc && rel->trigdesc->trig_insert_after_row, + returningList, retrieved_attrs); } /* @@ -919,11 +918,9 @@ deparseUpdateSql(StringInfo buf, PlannerInfo *root, } appendStringInfoString(buf, " WHERE ctid = $1"); - if (returningList) - deparseReturningList(buf, root, rtindex, rel, returningList, - retrieved_attrs); - else - *retrieved_attrs = NIL; + deparseReturningList(buf, root, rtindex, rel, + rel->trigdesc && rel->trigdesc->trig_update_after_row, + returningList, retrieved_attrs); } /* @@ -943,34 +940,48 @@ deparseDeleteSql(StringInfo buf, PlannerInfo *root, deparseRelation(buf, rel); appendStringInfoString(buf, " WHERE ctid = $1"); - if (returningList) - deparseReturningList(buf, root, rtindex, rel, returningList, - retrieved_attrs); - else - *retrieved_attrs = NIL; + deparseReturningList(buf, root, rtindex, rel, + rel->trigdesc && rel->trigdesc->trig_delete_after_row, + returningList, retrieved_attrs); } /* - * deparse RETURNING clause of INSERT/UPDATE/DELETE + * Add a RETURNING clause, if needed, to an INSERT/UPDATE/DELETE. */ static void deparseReturningList(StringInfo buf, PlannerInfo *root, Index rtindex, Relation rel, + bool trig_after_row, List *returningList, List **retrieved_attrs) { - Bitmapset *attrs_used; + Bitmapset *attrs_used = NULL; - /* - * We need the attrs mentioned in the query's RETURNING list. - */ - attrs_used = NULL; - pull_varattnos((Node *) returningList, rtindex, - &attrs_used); + if (trig_after_row) + { + /* whole-row reference acquires all non-system columns */ + attrs_used = + bms_make_singleton(0 - FirstLowInvalidHeapAttributeNumber); + } - appendStringInfoString(buf, " RETURNING "); - deparseTargetList(buf, root, rtindex, rel, attrs_used, - retrieved_attrs); + if (returningList != NIL) + { + /* + * We need the attrs, non-system and system, mentioned in the local + * query's RETURNING list. + */ + pull_varattnos((Node *) returningList, rtindex, + &attrs_used); + } + + if (attrs_used != NULL) + { + appendStringInfoString(buf, " RETURNING "); + deparseTargetList(buf, root, rtindex, rel, attrs_used, + retrieved_attrs); + } + else + *retrieved_attrs = NIL; } /* |