diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index a1bb3e9..1ec60a1 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -354,6 +354,13 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, * adjustments will be needed below. */ + if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("\"%s\" is a partitioned table", + RelationGetRelationName(rel)), + errdetail("Triggers on partitioned tables cannot have transition tables."))); + if (stmt->timing != TRIGGER_TYPE_AFTER) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), diff --git a/src/test/regress/expected/triggers.out b/src/test/regress/expected/triggers.out index f408475..4b0b3b7 100644 --- a/src/test/regress/expected/triggers.out +++ b/src/test/regress/expected/triggers.out @@ -1763,3 +1763,27 @@ select * from upsert; drop table upsert; drop function upsert_before_func(); drop function upsert_after_func(); +-- +-- Verify that triggers are prevented on partitioned tables if they would +-- access row data (ROW and STATEMENT-with-transition-table) +-- +create table my_table (i int) partition by list (i); +create table my_table_42 partition of my_table for values in (42); +create function my_trigger_function() returns trigger as $$ begin end; $$ language plpgsql; +create trigger my_trigger before update on my_table for each row execute procedure my_trigger_function(); +ERROR: "my_table" is a partitioned table +DETAIL: Partitioned tables cannot have ROW triggers. +create trigger my_trigger after update on my_table referencing old table as old_table + for each statement execute procedure my_trigger_function(); +ERROR: "my_table" is a partitioned table +DETAIL: Triggers on partitioned tables cannot have transition tables. +-- +-- Verify that triggers are allowed on partitions +-- +create trigger my_trigger before update on my_table_42 for each row execute procedure my_trigger_function(); +drop trigger my_trigger on my_table_42; +create trigger my_trigger after update on my_table_42 referencing old table as old_table + for each statement execute procedure my_trigger_function(); +drop trigger my_trigger on my_table_42; +drop table my_table_42; +drop table my_table; diff --git a/src/test/regress/sql/triggers.sql b/src/test/regress/sql/triggers.sql index b6de1b3..4473ce0 100644 --- a/src/test/regress/sql/triggers.sql +++ b/src/test/regress/sql/triggers.sql @@ -1240,3 +1240,26 @@ select * from upsert; drop table upsert; drop function upsert_before_func(); drop function upsert_after_func(); + +-- +-- Verify that triggers are prevented on partitioned tables if they would +-- access row data (ROW and STATEMENT-with-transition-table) +-- + +create table my_table (i int) partition by list (i); +create table my_table_42 partition of my_table for values in (42); +create function my_trigger_function() returns trigger as $$ begin end; $$ language plpgsql; +create trigger my_trigger before update on my_table for each row execute procedure my_trigger_function(); +create trigger my_trigger after update on my_table referencing old table as old_table + for each statement execute procedure my_trigger_function(); + +-- +-- Verify that triggers are allowed on partitions +-- +create trigger my_trigger before update on my_table_42 for each row execute procedure my_trigger_function(); +drop trigger my_trigger on my_table_42; +create trigger my_trigger after update on my_table_42 referencing old table as old_table + for each statement execute procedure my_trigger_function(); +drop trigger my_trigger on my_table_42; +drop table my_table_42; +drop table my_table;