citus/src/test/regress/expected/citus_local_table_triggers.out

443 lines
24 KiB
Plaintext

\set VERBOSITY terse
SET citus.next_shard_id TO 1507000;
SET citus.shard_replication_factor TO 1;
SET citus.enable_local_execution TO ON;
SET citus.log_local_commands TO ON;
CREATE SCHEMA citus_local_table_triggers;
SET search_path TO citus_local_table_triggers;
-- ensure that coordinator is added to pg_dist_node
SET client_min_messages to ERROR;
SELECT 1 FROM master_add_node('localhost', :master_port, groupId => 0);
?column?
---------------------------------------------------------------------
1
(1 row)
RESET client_min_messages;
CREATE TABLE citus_local_table (value int);
SELECT create_citus_local_table('citus_local_table');
create_citus_local_table
---------------------------------------------------------------------
(1 row)
---------------------------------------------------------------------
-- DELETE trigger --
---------------------------------------------------------------------
BEGIN;
CREATE TABLE distributed_table(value int);
SELECT create_distributed_table('distributed_table', 'value');
create_distributed_table
---------------------------------------------------------------------
(1 row)
CREATE FUNCTION insert_42() RETURNS trigger AS $insert_42$
BEGIN
INSERT INTO distributed_table VALUES (42);
RETURN NEW;
END;
$insert_42$ LANGUAGE plpgsql;
CREATE TRIGGER insert_42_trigger
AFTER DELETE ON citus_local_table
FOR EACH ROW EXECUTE FUNCTION insert_42();
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1507000, 'citus_local_table_triggers', 'CREATE TRIGGER insert_42_trigger
AFTER DELETE ON citus_local_table
FOR EACH ROW EXECUTE FUNCTION insert_42();')
-- select should print two rows with "42" as delete from citus_local_table will
-- insert 42 per deleted row
DELETE FROM citus_local_table;
NOTICE: executing the command locally: DELETE FROM citus_local_table_triggers.citus_local_table_1507000 citus_local_table
SELECT * FROM distributed_table;
value
---------------------------------------------------------------------
(0 rows)
ROLLBACK;
---------------------------------------------------------------------
-- TRUNCATE trigger --
---------------------------------------------------------------------
BEGIN;
CREATE TABLE reference_table(value int);
SELECT create_reference_table('reference_table');
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1507005, 'citus_local_table_triggers', 'CREATE TABLE citus_local_table_triggers.reference_table (value integer)');SELECT worker_apply_shard_ddl_command (1507005, 'citus_local_table_triggers', 'ALTER TABLE citus_local_table_triggers.reference_table OWNER TO postgres')
create_reference_table
---------------------------------------------------------------------
(1 row)
CREATE FUNCTION insert_100() RETURNS trigger AS $insert_100$
BEGIN
INSERT INTO reference_table VALUES (100);
RETURN NEW;
END;
$insert_100$ LANGUAGE plpgsql;
CREATE TRIGGER insert_100_trigger
AFTER TRUNCATE ON citus_local_table
FOR EACH STATEMENT EXECUTE FUNCTION insert_100();
-- As TRUNCATE triggers are executed by utility hook, it's critical to see that they
-- are executed only for once.
-- select should print a row with "100" as truncate from citus_local_table will insert 100
TRUNCATE citus_local_table;
NOTICE: executing the command locally: INSERT INTO citus_local_table_triggers.reference_table_1507005 (value) VALUES (100)
NOTICE: executing the command locally: TRUNCATE TABLE citus_local_table_triggers.citus_local_table_xxxxx CASCADE
SELECT * FROM reference_table;
NOTICE: executing the command locally: SELECT value FROM citus_local_table_triggers.reference_table_1507005 reference_table
value
---------------------------------------------------------------------
100
(1 row)
ROLLBACK;
---------------------------------------------------------------------
-- INSERT trigger --
---------------------------------------------------------------------
BEGIN;
CREATE TABLE local_table(value int);
CREATE FUNCTION increment_value() RETURNS trigger AS $increment_value$
BEGIN
UPDATE local_table SET value=value+1;
RETURN NEW;
END;
$increment_value$ LANGUAGE plpgsql;
CREATE TRIGGER increment_value_trigger
AFTER INSERT ON citus_local_table
FOR EACH ROW EXECUTE FUNCTION increment_value();
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1507000, 'citus_local_table_triggers', 'CREATE TRIGGER increment_value_trigger
AFTER INSERT ON citus_local_table
FOR EACH ROW EXECUTE FUNCTION increment_value();')
-- insert initial data to the table that increment_value_trigger will execute for
INSERT INTO local_table VALUES (0);
-- select should print a row with "2" as insert into citus_local_table will
-- increment all rows per inserted row
INSERT INTO citus_local_table VALUES(0), (1);
NOTICE: executing the command locally: INSERT INTO citus_local_table_triggers.citus_local_table_1507000 AS citus_table_alias (value) VALUES (0), (1)
SELECT * FROM local_table;
value
---------------------------------------------------------------------
2
(1 row)
ROLLBACK;
---------------------------------------------------------------------
-- UPDATE trigger --
---------------------------------------------------------------------
BEGIN;
CREATE FUNCTION error_for_5() RETURNS trigger AS $error_for_5$
BEGIN
IF OLD.value = 5 THEN
RAISE EXCEPTION 'cannot update update for value=5';
END IF;
END;
$error_for_5$ LANGUAGE plpgsql;
CREATE TRIGGER error_for_5_trigger
BEFORE UPDATE OF value ON citus_local_table
FOR EACH ROW EXECUTE FUNCTION error_for_5();
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1507000, 'citus_local_table_triggers', 'CREATE TRIGGER error_for_5_trigger
BEFORE UPDATE OF value ON citus_local_table
FOR EACH ROW EXECUTE FUNCTION error_for_5();')
-- below update will error out as trigger raises exception
INSERT INTO citus_local_table VALUES (5);
NOTICE: executing the command locally: INSERT INTO citus_local_table_triggers.citus_local_table_1507000 (value) VALUES (5)
UPDATE citus_local_table SET value=value*2 WHERE value=5;
NOTICE: executing the command locally: UPDATE citus_local_table_triggers.citus_local_table_1507000 citus_local_table SET value = (value OPERATOR(pg_catalog.*) 2) WHERE (value OPERATOR(pg_catalog.=) 5)
ERROR: cannot update update for value=5
ROLLBACK;
---------------------------------------------------------------------
-- Test other trigger commands + weird object names --
---------------------------------------------------------------------
CREATE SCHEMA "interesting!schema";
-- below view is a helper to print triggers on both shell relation and
-- shard relation for "citus_local_table"
CREATE VIEW citus_local_table_triggers AS
SELECT tgname, tgrelid::regclass, tgenabled
FROM pg_trigger
WHERE tgrelid::regclass::text like '"interesting!schema"."citus_local!_table%"'
ORDER BY 1, 2;
CREATE FUNCTION dummy_function() RETURNS trigger AS $dummy_function$
BEGIN
NEW.value := value+1;
RETURN NEW;
END;
$dummy_function$ LANGUAGE plpgsql;
BEGIN;
CREATE TABLE "interesting!schema"."citus_local!_table"(value int);
CREATE TRIGGER initial_truncate_trigger
AFTER TRUNCATE ON "interesting!schema"."citus_local!_table"
FOR EACH STATEMENT EXECUTE FUNCTION dummy_function();
SELECT create_citus_local_table('"interesting!schema"."citus_local!_table"');
create_citus_local_table
---------------------------------------------------------------------
(1 row)
-- we shouldn't see truncate trigger on shard relation as we drop it
SELECT * FROM citus_local_table_triggers;
tgname | tgrelid | tgenabled
---------------------------------------------------------------------
initial_truncate_trigger | "interesting!schema"."citus_local!_table" | O
truncate_trigger_xxxxxxx | "interesting!schema"."citus_local!_table" | O
(2 rows)
ROLLBACK;
CREATE TABLE "interesting!schema"."citus_local!_table"(value int);
SELECT create_citus_local_table('"interesting!schema"."citus_local!_table"');
create_citus_local_table
---------------------------------------------------------------------
(1 row)
CREATE TRIGGER "trigger\'name"
BEFORE INSERT ON "interesting!schema"."citus_local!_table"
FOR EACH STATEMENT EXECUTE FUNCTION dummy_function();
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1507007, 'interesting!schema', E'CREATE TRIGGER "trigger\\''name"
BEFORE INSERT ON "interesting!schema"."citus_local!_table"
FOR EACH STATEMENT EXECUTE FUNCTION dummy_function();')
BEGIN;
CREATE EXTENSION seg;
-- ALTER TRIGGER DEPENDS ON
ALTER TRIGGER "trigger\'name" ON "interesting!schema"."citus_local!_table" DEPENDS ON EXTENSION seg;
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1507007, 'interesting!schema', E'ALTER TRIGGER "trigger\\''name" ON "interesting!schema"."citus_local!_table" DEPENDS ON EXTENSION seg;')
-- show that triggers on both shell relation and shard relation are depending on seg
SELECT tgname FROM pg_depend, pg_trigger, pg_extension
WHERE deptype = 'x' and classid='pg_trigger'::regclass and
pg_trigger.oid=pg_depend.objid and extname='seg'
ORDER BY 1;
tgname
---------------------------------------------------------------------
trigger\'name
trigger\'name_1507007
(2 rows)
DROP EXTENSION seg;
-- show that dropping extension drops the triggers automatically
SELECT * FROM citus_local_table_triggers;
tgname | tgrelid | tgenabled
---------------------------------------------------------------------
truncate_trigger_xxxxxxx | "interesting!schema"."citus_local!_table" | O
(1 row)
ROLLBACK;
-- ALTER TRIGGER RENAME
ALTER TRIGGER "trigger\'name" ON "interesting!schema"."citus_local!_table" RENAME TO "trigger\'name22";
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1507007, 'interesting!schema', E'ALTER TRIGGER "trigger\\''name" ON "interesting!schema"."citus_local!_table" RENAME TO "trigger\\''name22";')
-- show that triggers on both shell relation and shard relation are renamed
SELECT * FROM citus_local_table_triggers;
tgname | tgrelid | tgenabled
---------------------------------------------------------------------
trigger\'name22 | "interesting!schema"."citus_local!_table" | O
trigger\'name22_1507007 | "interesting!schema"."citus_local!_table_1507007" | O
truncate_trigger_xxxxxxx | "interesting!schema"."citus_local!_table" | O
(3 rows)
-- ALTER TABLE DISABLE trigger
ALTER TABLE "interesting!schema"."citus_local!_table" DISABLE TRIGGER "trigger\'name22";
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1507007, 'interesting!schema', E'ALTER TABLE "interesting!schema"."citus_local!_table" DISABLE TRIGGER "trigger\\''name22";')
SELECT * FROM citus_local_table_triggers;
tgname | tgrelid | tgenabled
---------------------------------------------------------------------
trigger\'name22 | "interesting!schema"."citus_local!_table" | D
trigger\'name22_1507007 | "interesting!schema"."citus_local!_table_1507007" | D
truncate_trigger_xxxxxxx | "interesting!schema"."citus_local!_table" | O
(3 rows)
-- ALTER TABLE ENABLE trigger
ALTER TABLE "interesting!schema"."citus_local!_table" ENABLE TRIGGER "trigger\'name22";
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1507007, 'interesting!schema', E'ALTER TABLE "interesting!schema"."citus_local!_table" ENABLE TRIGGER "trigger\\''name22";')
SELECT * FROM citus_local_table_triggers;
tgname | tgrelid | tgenabled
---------------------------------------------------------------------
trigger\'name22 | "interesting!schema"."citus_local!_table" | O
trigger\'name22_1507007 | "interesting!schema"."citus_local!_table_1507007" | O
truncate_trigger_xxxxxxx | "interesting!schema"."citus_local!_table" | O
(3 rows)
CREATE TRIGGER another_trigger
AFTER DELETE ON "interesting!schema"."citus_local!_table"
FOR EACH STATEMENT EXECUTE FUNCTION dummy_function();
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1507007, 'interesting!schema', 'CREATE TRIGGER another_trigger
AFTER DELETE ON "interesting!schema"."citus_local!_table"
FOR EACH STATEMENT EXECUTE FUNCTION dummy_function();')
ALTER TABLE "interesting!schema"."citus_local!_table" DISABLE TRIGGER USER;
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1507007, 'interesting!schema', 'ALTER TABLE "interesting!schema"."citus_local!_table" DISABLE TRIGGER USER;')
-- show that all triggers except the internal ones are disabled
SELECT * FROM citus_local_table_triggers;
tgname | tgrelid | tgenabled
---------------------------------------------------------------------
another_trigger | "interesting!schema"."citus_local!_table" | D
another_trigger_1507007 | "interesting!schema"."citus_local!_table_1507007" | D
trigger\'name22 | "interesting!schema"."citus_local!_table" | D
trigger\'name22_1507007 | "interesting!schema"."citus_local!_table_1507007" | D
truncate_trigger_xxxxxxx | "interesting!schema"."citus_local!_table" | O
(5 rows)
ALTER TABLE "interesting!schema"."citus_local!_table" ENABLE TRIGGER USER;
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1507007, 'interesting!schema', 'ALTER TABLE "interesting!schema"."citus_local!_table" ENABLE TRIGGER USER;')
-- show that all triggers except the internal ones are enabled again
SELECT * FROM citus_local_table_triggers;
tgname | tgrelid | tgenabled
---------------------------------------------------------------------
another_trigger | "interesting!schema"."citus_local!_table" | O
another_trigger_1507007 | "interesting!schema"."citus_local!_table_1507007" | O
trigger\'name22 | "interesting!schema"."citus_local!_table" | O
trigger\'name22_1507007 | "interesting!schema"."citus_local!_table_1507007" | O
truncate_trigger_xxxxxxx | "interesting!schema"."citus_local!_table" | O
(5 rows)
ALTER TABLE "interesting!schema"."citus_local!_table" DISABLE TRIGGER ALL;
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1507007, 'interesting!schema', 'ALTER TABLE "interesting!schema"."citus_local!_table" DISABLE TRIGGER ALL;')
-- show that all triggers including internal triggers are disabled
SELECT * FROM citus_local_table_triggers;
tgname | tgrelid | tgenabled
---------------------------------------------------------------------
another_trigger | "interesting!schema"."citus_local!_table" | D
another_trigger_1507007 | "interesting!schema"."citus_local!_table_1507007" | D
trigger\'name22 | "interesting!schema"."citus_local!_table" | D
trigger\'name22_1507007 | "interesting!schema"."citus_local!_table_1507007" | D
truncate_trigger_xxxxxxx | "interesting!schema"."citus_local!_table" | D
(5 rows)
ALTER TABLE "interesting!schema"."citus_local!_table" ENABLE TRIGGER ALL;
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1507007, 'interesting!schema', 'ALTER TABLE "interesting!schema"."citus_local!_table" ENABLE TRIGGER ALL;')
-- show that all triggers including internal triggers are enabled again
SELECT * FROM citus_local_table_triggers;
tgname | tgrelid | tgenabled
---------------------------------------------------------------------
another_trigger | "interesting!schema"."citus_local!_table" | O
another_trigger_1507007 | "interesting!schema"."citus_local!_table_1507007" | O
trigger\'name22 | "interesting!schema"."citus_local!_table" | O
trigger\'name22_1507007 | "interesting!schema"."citus_local!_table_1507007" | O
truncate_trigger_xxxxxxx | "interesting!schema"."citus_local!_table" | O
(5 rows)
DROP TRIGGER another_trigger ON "interesting!schema"."citus_local!_table";
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1507007, 'interesting!schema', 'DROP TRIGGER another_trigger ON "interesting!schema"."citus_local!_table";')
DROP TRIGGER "trigger\'name22" ON "interesting!schema"."citus_local!_table";
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1507007, 'interesting!schema', E'DROP TRIGGER "trigger\\''name22" ON "interesting!schema"."citus_local!_table";')
-- show that drop trigger works as expected
SELECT * FROM citus_local_table_triggers;
tgname | tgrelid | tgenabled
---------------------------------------------------------------------
truncate_trigger_xxxxxxx | "interesting!schema"."citus_local!_table" | O
(1 row)
BEGIN;
CREATE TRIGGER "another_trigger\'name"
AFTER TRUNCATE ON "interesting!schema"."citus_local!_table"
FOR EACH STATEMENT EXECUTE FUNCTION dummy_function();
ALTER TABLE "interesting!schema"."citus_local!_table" DISABLE TRIGGER "another_trigger\'name";
-- show that our truncate trigger is disabled ..
SELECT * FROM citus_local_table_triggers;
tgname | tgrelid | tgenabled
---------------------------------------------------------------------
another_trigger\'name | "interesting!schema"."citus_local!_table" | D
truncate_trigger_xxxxxxx | "interesting!schema"."citus_local!_table" | O
(2 rows)
ALTER TABLE "interesting!schema"."citus_local!_table" ENABLE TRIGGER ALL;
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1507007, 'interesting!schema', 'ALTER TABLE "interesting!schema"."citus_local!_table" ENABLE TRIGGER ALL;')
-- .. and now it is enabled back
SELECT * FROM citus_local_table_triggers;
tgname | tgrelid | tgenabled
---------------------------------------------------------------------
another_trigger\'name | "interesting!schema"."citus_local!_table" | O
truncate_trigger_xxxxxxx | "interesting!schema"."citus_local!_table" | O
(2 rows)
ROLLBACK;
-- as we create ddl jobs for DROP TRIGGER before standard process utility,
-- it's important to see that we properly handle non-existing triggers
-- and relations
DROP TRIGGER no_such_trigger ON "interesting!schema"."citus_local!_table";
ERROR: trigger "no_such_trigger" for table "citus_local!_table" does not exist
DROP TRIGGER no_such_trigger ON no_such_relation;
ERROR: relation "no_such_relation" does not exist
---------------------------------------------------------------------
-- a complex test case with triggers --
---------------------------------------------------------------------
-- create test tables and some foreign key relationships between them to see
-- that triggers are properly handled when ddl cascades to referencing table
CREATE TABLE another_citus_local_table (value int unique);
SELECT create_citus_local_table('another_citus_local_table');
create_citus_local_table
---------------------------------------------------------------------
(1 row)
ALTER TABLE another_citus_local_table ADD CONSTRAINT fkey_self FOREIGN KEY(value) REFERENCES another_citus_local_table(value);
NOTICE: executing the command locally: SELECT worker_apply_inter_shard_ddl_command (1507008, 'citus_local_table_triggers', 1507008, 'citus_local_table_triggers', 'ALTER TABLE another_citus_local_table ADD CONSTRAINT fkey_self FOREIGN KEY(value) REFERENCES another_citus_local_table(value);')
ALTER TABLE citus_local_table ADD CONSTRAINT fkey_c_to_c FOREIGN KEY(value) REFERENCES another_citus_local_table(value) ON UPDATE CASCADE;
NOTICE: executing the command locally: SELECT worker_apply_inter_shard_ddl_command (1507000, 'citus_local_table_triggers', 1507008, 'citus_local_table_triggers', 'ALTER TABLE citus_local_table ADD CONSTRAINT fkey_c_to_c FOREIGN KEY(value) REFERENCES another_citus_local_table(value) ON UPDATE CASCADE;')
CREATE TABLE reference_table(value int);
SELECT create_reference_table('reference_table');
create_reference_table
---------------------------------------------------------------------
(1 row)
CREATE FUNCTION insert_100() RETURNS trigger AS $insert_100$
BEGIN
INSERT INTO reference_table VALUES (100);
RETURN NEW;
END;
$insert_100$ LANGUAGE plpgsql;
BEGIN;
CREATE TRIGGER insert_100_trigger
AFTER TRUNCATE ON another_citus_local_table
FOR EACH STATEMENT EXECUTE FUNCTION insert_100();
CREATE TRIGGER insert_100_trigger
AFTER TRUNCATE ON citus_local_table
FOR EACH STATEMENT EXECUTE FUNCTION insert_100();
TRUNCATE another_citus_local_table CASCADE;
NOTICE: truncate cascades to table "citus_local_table"
NOTICE: executing the command locally: INSERT INTO citus_local_table_triggers.reference_table_1507009 (value) VALUES (100)
NOTICE: executing the command locally: TRUNCATE TABLE citus_local_table_triggers.another_citus_local_table_xxxxx CASCADE
NOTICE: truncate cascades to table "citus_local_table_xxxxx"
NOTICE: executing the command locally: INSERT INTO citus_local_table_triggers.reference_table_1507009 (value) VALUES (100)
NOTICE: executing the command locally: TRUNCATE TABLE citus_local_table_triggers.citus_local_table_xxxxx CASCADE
-- we should see two rows with "100"
SELECT * FROM reference_table;
NOTICE: executing the command locally: SELECT value FROM citus_local_table_triggers.reference_table_1507009 reference_table
value
---------------------------------------------------------------------
100
100
(2 rows)
ROLLBACK;
BEGIN;
-- update should actually update something to test ON UPDATE CASCADE logic
INSERT INTO another_citus_local_table VALUES (600);
NOTICE: executing the command locally: INSERT INTO citus_local_table_triggers.another_citus_local_table_1507008 (value) VALUES (600)
INSERT INTO citus_local_table VALUES (600);
NOTICE: executing the command locally: INSERT INTO citus_local_table_triggers.citus_local_table_1507000 (value) VALUES (600)
CREATE TRIGGER insert_100_trigger
AFTER UPDATE ON another_citus_local_table
FOR EACH STATEMENT EXECUTE FUNCTION insert_100();
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1507008, 'citus_local_table_triggers', 'CREATE TRIGGER insert_100_trigger
AFTER UPDATE ON another_citus_local_table
FOR EACH STATEMENT EXECUTE FUNCTION insert_100();')
CREATE TRIGGER insert_100_trigger
AFTER UPDATE ON citus_local_table
FOR EACH STATEMENT EXECUTE FUNCTION insert_100();
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1507000, 'citus_local_table_triggers', 'CREATE TRIGGER insert_100_trigger
AFTER UPDATE ON citus_local_table
FOR EACH STATEMENT EXECUTE FUNCTION insert_100();')
UPDATE another_citus_local_table SET value=value-1;;
NOTICE: executing the command locally: UPDATE citus_local_table_triggers.another_citus_local_table_1507008 another_citus_local_table SET value = (value OPERATOR(pg_catalog.-) 1)
NOTICE: executing the command locally: INSERT INTO citus_local_table_triggers.reference_table_1507009 (value) VALUES (100)
NOTICE: executing the command locally: INSERT INTO citus_local_table_triggers.reference_table_1507009 (value) VALUES (100)
-- we should see two rows with "100"
SELECT * FROM reference_table;
NOTICE: executing the command locally: SELECT value FROM citus_local_table_triggers.reference_table_1507009 reference_table
value
---------------------------------------------------------------------
100
100
(2 rows)
ROLLBACK;
-- cleanup at exit
DROP SCHEMA citus_local_table_triggers, "interesting!schema" CASCADE;
NOTICE: drop cascades to 11 other objects