\set VERBOSITY terse SET citus.next_shard_id TO 1508000; 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_tables_mx; SET search_path TO citus_local_tables_mx; -- 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; --------------------------------------------------------------------- -- triggers -- --------------------------------------------------------------------- CREATE TABLE citus_local_table (value int); SELECT create_citus_local_table('citus_local_table'); create_citus_local_table --------------------------------------------------------------------- (1 row) -- first stop metadata sync to worker_1 SELECT stop_metadata_sync_to_node('localhost', :worker_1_port); stop_metadata_sync_to_node --------------------------------------------------------------------- (1 row) CREATE FUNCTION dummy_function() RETURNS trigger AS $dummy_function$ BEGIN RAISE EXCEPTION 'a trigger that throws this exception'; END; $dummy_function$ LANGUAGE plpgsql; CREATE TRIGGER dummy_function_trigger BEFORE UPDATE OF value ON citus_local_table FOR EACH ROW EXECUTE FUNCTION dummy_function(); NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1508000, 'citus_local_tables_mx', 'CREATE TRIGGER dummy_function_trigger BEFORE UPDATE OF value ON citus_local_table FOR EACH ROW EXECUTE FUNCTION dummy_function();') -- Show that we can sync metadata successfully. That means, we create -- the function that trigger needs in mx workers too. SELECT start_metadata_sync_to_node('localhost', :worker_1_port); start_metadata_sync_to_node --------------------------------------------------------------------- (1 row) CREATE EXTENSION seg; ALTER TRIGGER dummy_function_trigger ON citus_local_table DEPENDS ON EXTENSION seg; NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1508000, 'citus_local_tables_mx', 'ALTER TRIGGER dummy_function_trigger ON citus_local_table DEPENDS ON EXTENSION seg;') ALTER TRIGGER dummy_function_trigger ON citus_local_table RENAME TO renamed_trigger; NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1508000, 'citus_local_tables_mx', 'ALTER TRIGGER dummy_function_trigger ON citus_local_table RENAME TO renamed_trigger;') ALTER TABLE citus_local_table DISABLE TRIGGER ALL; NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1508000, 'citus_local_tables_mx', 'ALTER TABLE citus_local_table DISABLE TRIGGER ALL;') -- show that update trigger mx relation are depending on seg, renamed and disabled. -- both workers should should print 1. SELECT run_command_on_workers( $$ SELECT COUNT(*) FROM pg_depend, pg_trigger, pg_extension WHERE pg_trigger.tgrelid='citus_local_tables_mx.citus_local_table'::regclass AND pg_trigger.tgname='renamed_trigger' AND pg_trigger.tgenabled='D' AND pg_depend.classid='pg_trigger'::regclass AND pg_depend.deptype='x' AND pg_trigger.oid=pg_depend.objid AND pg_extension.extname='seg' $$); run_command_on_workers --------------------------------------------------------------------- (localhost,57637,t,1) (localhost,57638,t,1) (2 rows) CREATE FUNCTION another_dummy_function() RETURNS trigger AS $another_dummy_function$ BEGIN RAISE EXCEPTION 'another trigger that throws another exception'; END; $another_dummy_function$ LANGUAGE plpgsql; -- Show that we can create the trigger successfully. That means, we create -- the function that trigger needs in mx worker too when processing CREATE -- TRIGGER commands. CREATE TRIGGER another_dummy_function_trigger AFTER TRUNCATE ON citus_local_table FOR EACH STATEMENT EXECUTE FUNCTION another_dummy_function(); -- create some test tables before next three sections -- and define some foreign keys between them CREATE TABLE citus_local_table_1(l1 int); SELECT create_citus_local_table('citus_local_table_1'); create_citus_local_table --------------------------------------------------------------------- (1 row) CREATE TABLE reference_table_1(r1 int primary key); SELECT create_reference_table('reference_table_1'); create_reference_table --------------------------------------------------------------------- (1 row) ALTER TABLE citus_local_table_1 ADD CONSTRAINT fkey_local_to_ref FOREIGN KEY(l1) REFERENCES reference_table_1(r1) ON DELETE CASCADE; NOTICE: executing the command locally: SELECT worker_apply_inter_shard_ddl_command (1508001, 'citus_local_tables_mx', 1508002, 'citus_local_tables_mx', 'ALTER TABLE citus_local_table_1 ADD CONSTRAINT fkey_local_to_ref FOREIGN KEY(l1) REFERENCES reference_table_1(r1) ON DELETE CASCADE;') CREATE TABLE citus_local_table_2(l1 int primary key); SELECT create_citus_local_table('citus_local_table_2'); create_citus_local_table --------------------------------------------------------------------- (1 row) CREATE TABLE reference_table_2(r1 int); SELECT create_reference_table('reference_table_2'); create_reference_table --------------------------------------------------------------------- (1 row) ALTER TABLE reference_table_2 ADD CONSTRAINT fkey_ref_to_local FOREIGN KEY(r1) REFERENCES citus_local_table_2(l1) ON DELETE RESTRICT; NOTICE: executing the command locally: SELECT worker_apply_inter_shard_ddl_command (1508004, 'citus_local_tables_mx', 1508003, 'citus_local_tables_mx', 'ALTER TABLE reference_table_2 ADD CONSTRAINT fkey_ref_to_local FOREIGN KEY(r1) REFERENCES citus_local_table_2(l1) ON DELETE RESTRICT;') CREATE TABLE citus_local_table_3(l1 int); SELECT create_citus_local_table('citus_local_table_3'); create_citus_local_table --------------------------------------------------------------------- (1 row) CREATE TABLE citus_local_table_4(l1 int primary key); SELECT create_citus_local_table('citus_local_table_4'); create_citus_local_table --------------------------------------------------------------------- (1 row) ALTER TABLE citus_local_table_3 ADD CONSTRAINT fkey_local_to_local FOREIGN KEY(l1) REFERENCES citus_local_table_4(l1) ON UPDATE SET NULL; NOTICE: executing the command locally: SELECT worker_apply_inter_shard_ddl_command (1508005, 'citus_local_tables_mx', 1508006, 'citus_local_tables_mx', 'ALTER TABLE citus_local_table_3 ADD CONSTRAINT fkey_local_to_local FOREIGN KEY(l1) REFERENCES citus_local_table_4(l1) ON UPDATE SET NULL;') -- and switch to worker1 \c - - - :worker_1_port SET search_path TO citus_local_tables_mx; --------------------------------------------------------------------- -- foreign key from citus local table to reference table -- --------------------------------------------------------------------- -- show that on delete cascade works INSERT INTO reference_table_1 VALUES (11); INSERT INTO citus_local_table_1 VALUES (11); DELETE FROM reference_table_1 WHERE r1=11; -- should print 0 rows SELECT * FROM citus_local_table_1 ORDER BY l1; l1 --------------------------------------------------------------------- (0 rows) -- show that we are checking for foreign key constraint, below should fail INSERT INTO citus_local_table_1 VALUES (2); ERROR: insert or update on table "citus_local_table_1_xxxxxxx" violates foreign key constraint "fkey_local_to_ref_1508001" -- below should work INSERT INTO reference_table_1 VALUES (2); INSERT INTO citus_local_table_1 VALUES (2); --------------------------------------------------------------------- -- foreign key from reference table to citus local table -- --------------------------------------------------------------------- -- show that we are checking for foreign key constraint, below should fail INSERT INTO reference_table_2 VALUES (4); ERROR: insert or update on table "reference_table_2_1508004" violates foreign key constraint "fkey_ref_to_local_1508004" -- below should work INSERT INTO citus_local_table_2 VALUES (4); INSERT INTO reference_table_2 VALUES (4); --------------------------------------------------------------------- -- foreign key from citus local table to citus local table -- --------------------------------------------------------------------- -- show that we are checking for foreign key constraint, below should fail INSERT INTO citus_local_table_3 VALUES (3); ERROR: insert or update on table "citus_local_table_3_xxxxxxx" violates foreign key constraint "fkey_local_to_local_1508005" -- below shoud work INSERT INTO citus_local_table_4 VALUES (3); INSERT INTO citus_local_table_3 VALUES (3); UPDATE citus_local_table_4 SET l1=6 WHERE l1=3; -- show that it prints only one row with l1=null due to ON UPDATE SET NULL SELECT * FROM citus_local_table_3; l1 --------------------------------------------------------------------- (1 row) -- finally show that we do not allow defining foreign key in mx nodes ALTER TABLE citus_local_table_3 ADD CONSTRAINT fkey_local_to_local_2 FOREIGN KEY(l1) REFERENCES citus_local_table_4(l1); ERROR: operation is not allowed on this node \c - - - :master_port SET search_path TO citus_local_tables_mx; SELECT master_remove_distributed_table_metadata_from_workers('citus_local_table_4'::regclass::oid, 'citus_local_tables_mx', 'citus_local_table_4'); master_remove_distributed_table_metadata_from_workers --------------------------------------------------------------------- (1 row) -- both workers should print 0 as master_remove_distributed_table_metadata_from_workers -- drops the table as well SELECT run_command_on_workers( $$ SELECT count(*) FROM pg_catalog.pg_tables WHERE tablename='citus_local_table_4' $$); run_command_on_workers --------------------------------------------------------------------- (localhost,57637,t,0) (localhost,57638,t,0) (2 rows) -- cleanup at exit DROP SCHEMA citus_local_tables_mx CASCADE; NOTICE: drop cascades to 17 other objects