diff options
| author | Noah Misch | 2014-03-23 06:16:34 +0000 |
|---|---|---|
| committer | Noah Misch | 2014-03-23 06:16:34 +0000 |
| commit | 7cbe57c34dec4860243e6d0f81738cfbb6e5d069 (patch) | |
| tree | 1b2e725b85caef56f986db8ae7c43732819c1f5c /src/test | |
| parent | 6115480c543c0141011a99db78987ad13540be59 (diff) | |
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 'src/test')
| -rw-r--r-- | src/test/regress/expected/foreign_data.out | 37 | ||||
| -rw-r--r-- | src/test/regress/sql/foreign_data.sql | 44 |
2 files changed, 81 insertions, 0 deletions
diff --git a/src/test/regress/expected/foreign_data.out b/src/test/regress/expected/foreign_data.out index 60506e07b1c..c34c9b4df42 100644 --- a/src/test/regress/expected/foreign_data.out +++ b/src/test/regress/expected/foreign_data.out @@ -1158,6 +1158,43 @@ CREATE USER MAPPING FOR current_user SERVER s9; DROP SERVER s9 CASCADE; -- ERROR ERROR: must be owner of foreign server s9 RESET ROLE; +-- Triggers +CREATE FUNCTION dummy_trigger() RETURNS TRIGGER AS $$ + BEGIN + RETURN NULL; + END +$$ language plpgsql; +CREATE TRIGGER trigtest_before_stmt BEFORE INSERT OR UPDATE OR DELETE +ON foreign_schema.foreign_table_1 +FOR EACH STATEMENT +EXECUTE PROCEDURE dummy_trigger(); +CREATE TRIGGER trigtest_after_stmt AFTER INSERT OR UPDATE OR DELETE +ON foreign_schema.foreign_table_1 +FOR EACH STATEMENT +EXECUTE PROCEDURE dummy_trigger(); +CREATE TRIGGER trigtest_before_row BEFORE INSERT OR UPDATE OR DELETE +ON foreign_schema.foreign_table_1 +FOR EACH ROW +EXECUTE PROCEDURE dummy_trigger(); +CREATE TRIGGER trigtest_after_row AFTER INSERT OR UPDATE OR DELETE +ON foreign_schema.foreign_table_1 +FOR EACH ROW +EXECUTE PROCEDURE dummy_trigger(); +CREATE CONSTRAINT TRIGGER trigtest_constraint AFTER INSERT OR UPDATE OR DELETE +ON foreign_schema.foreign_table_1 +FOR EACH ROW +EXECUTE PROCEDURE dummy_trigger(); +ERROR: "foreign_table_1" is a foreign table +DETAIL: Foreign tables cannot have constraint triggers. +ALTER FOREIGN TABLE foreign_schema.foreign_table_1 + DISABLE TRIGGER trigtest_before_stmt; +ALTER FOREIGN TABLE foreign_schema.foreign_table_1 + ENABLE TRIGGER trigtest_before_stmt; +DROP TRIGGER trigtest_before_stmt ON foreign_schema.foreign_table_1; +DROP TRIGGER trigtest_before_row ON foreign_schema.foreign_table_1; +DROP TRIGGER trigtest_after_stmt ON foreign_schema.foreign_table_1; +DROP TRIGGER trigtest_after_row ON foreign_schema.foreign_table_1; +DROP FUNCTION dummy_trigger(); -- DROP FOREIGN TABLE DROP FOREIGN TABLE no_table; -- ERROR ERROR: foreign table "no_table" does not exist diff --git a/src/test/regress/sql/foreign_data.sql b/src/test/regress/sql/foreign_data.sql index f819eb1b8eb..0f0869ee268 100644 --- a/src/test/regress/sql/foreign_data.sql +++ b/src/test/regress/sql/foreign_data.sql @@ -470,6 +470,50 @@ CREATE USER MAPPING FOR current_user SERVER s9; DROP SERVER s9 CASCADE; -- ERROR RESET ROLE; +-- Triggers +CREATE FUNCTION dummy_trigger() RETURNS TRIGGER AS $$ + BEGIN + RETURN NULL; + END +$$ language plpgsql; + +CREATE TRIGGER trigtest_before_stmt BEFORE INSERT OR UPDATE OR DELETE +ON foreign_schema.foreign_table_1 +FOR EACH STATEMENT +EXECUTE PROCEDURE dummy_trigger(); + +CREATE TRIGGER trigtest_after_stmt AFTER INSERT OR UPDATE OR DELETE +ON foreign_schema.foreign_table_1 +FOR EACH STATEMENT +EXECUTE PROCEDURE dummy_trigger(); + +CREATE TRIGGER trigtest_before_row BEFORE INSERT OR UPDATE OR DELETE +ON foreign_schema.foreign_table_1 +FOR EACH ROW +EXECUTE PROCEDURE dummy_trigger(); + +CREATE TRIGGER trigtest_after_row AFTER INSERT OR UPDATE OR DELETE +ON foreign_schema.foreign_table_1 +FOR EACH ROW +EXECUTE PROCEDURE dummy_trigger(); + +CREATE CONSTRAINT TRIGGER trigtest_constraint AFTER INSERT OR UPDATE OR DELETE +ON foreign_schema.foreign_table_1 +FOR EACH ROW +EXECUTE PROCEDURE dummy_trigger(); + +ALTER FOREIGN TABLE foreign_schema.foreign_table_1 + DISABLE TRIGGER trigtest_before_stmt; +ALTER FOREIGN TABLE foreign_schema.foreign_table_1 + ENABLE TRIGGER trigtest_before_stmt; + +DROP TRIGGER trigtest_before_stmt ON foreign_schema.foreign_table_1; +DROP TRIGGER trigtest_before_row ON foreign_schema.foreign_table_1; +DROP TRIGGER trigtest_after_stmt ON foreign_schema.foreign_table_1; +DROP TRIGGER trigtest_after_row ON foreign_schema.foreign_table_1; + +DROP FUNCTION dummy_trigger(); + -- DROP FOREIGN TABLE DROP FOREIGN TABLE no_table; -- ERROR DROP FOREIGN TABLE IF EXISTS no_table; |
