Add more tests with triggers on partitions for logical replication
The tuple routing logic used by a logical replication worker can fire triggers on relations part of a partition tree, but there was no test coverage in this area. The existing script 003_constraints.pl included something, but nothing when a tuple is applied across partitioned tables on a subscriber. Author: Amit Langote Discussion: https://postgr.es/m/OS0PR01MB611383FA0FE92EB9DE21946AFB769@OS0PR01MB6113.jpnprd01.prod.outlook.com
This commit is contained in:
parent
f25a4584c6
commit
2ecfeda3e9
|
@ -3,7 +3,7 @@ use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use PostgresNode;
|
use PostgresNode;
|
||||||
use TestLib;
|
use TestLib;
|
||||||
use Test::More tests => 51;
|
use Test::More tests => 54;
|
||||||
|
|
||||||
# setup
|
# setup
|
||||||
|
|
||||||
|
@ -67,6 +67,40 @@ $node_subscriber1->safe_psql('postgres',
|
||||||
"CREATE SUBSCRIPTION sub1 CONNECTION '$publisher_connstr' PUBLICATION pub1"
|
"CREATE SUBSCRIPTION sub1 CONNECTION '$publisher_connstr' PUBLICATION pub1"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
# Add set of AFTER replica triggers for testing that they are fired
|
||||||
|
# correctly. This uses a table that records details of all trigger
|
||||||
|
# activities. Triggers are marked as enabled for a subset of the
|
||||||
|
# partition tree.
|
||||||
|
$node_subscriber1->safe_psql(
|
||||||
|
'postgres', qq{
|
||||||
|
CREATE TABLE sub1_trigger_activity (tgtab text, tgop text,
|
||||||
|
tgwhen text, tglevel text, olda int, newa int);
|
||||||
|
CREATE FUNCTION sub1_trigger_activity_func() RETURNS TRIGGER AS \$\$
|
||||||
|
BEGIN
|
||||||
|
IF (TG_OP = 'INSERT') THEN
|
||||||
|
INSERT INTO public.sub1_trigger_activity
|
||||||
|
SELECT TG_RELNAME, TG_OP, TG_WHEN, TG_LEVEL, NULL, NEW.a;
|
||||||
|
ELSIF (TG_OP = 'UPDATE') THEN
|
||||||
|
INSERT INTO public.sub1_trigger_activity
|
||||||
|
SELECT TG_RELNAME, TG_OP, TG_WHEN, TG_LEVEL, OLD.a, NEW.a;
|
||||||
|
END IF;
|
||||||
|
RETURN NULL;
|
||||||
|
END;
|
||||||
|
\$\$ LANGUAGE plpgsql;
|
||||||
|
CREATE TRIGGER sub1_tab1_log_op_trigger
|
||||||
|
AFTER INSERT OR UPDATE ON tab1
|
||||||
|
FOR EACH ROW EXECUTE PROCEDURE sub1_trigger_activity_func();
|
||||||
|
ALTER TABLE ONLY tab1 ENABLE REPLICA TRIGGER sub1_tab1_log_op_trigger;
|
||||||
|
CREATE TRIGGER sub1_tab1_2_log_op_trigger
|
||||||
|
AFTER INSERT OR UPDATE ON tab1_2
|
||||||
|
FOR EACH ROW EXECUTE PROCEDURE sub1_trigger_activity_func();
|
||||||
|
ALTER TABLE ONLY tab1_2 ENABLE REPLICA TRIGGER sub1_tab1_2_log_op_trigger;
|
||||||
|
CREATE TRIGGER sub1_tab1_2_2_log_op_trigger
|
||||||
|
AFTER INSERT OR UPDATE ON tab1_2_2
|
||||||
|
FOR EACH ROW EXECUTE PROCEDURE sub1_trigger_activity_func();
|
||||||
|
ALTER TABLE ONLY tab1_2_2 ENABLE REPLICA TRIGGER sub1_tab1_2_2_log_op_trigger;
|
||||||
|
});
|
||||||
|
|
||||||
# subscriber 2
|
# subscriber 2
|
||||||
#
|
#
|
||||||
# This does not use partitioning. The tables match the leaf tables on
|
# This does not use partitioning. The tables match the leaf tables on
|
||||||
|
@ -87,6 +121,34 @@ $node_subscriber2->safe_psql('postgres',
|
||||||
"CREATE SUBSCRIPTION sub2 CONNECTION '$publisher_connstr' PUBLICATION pub_all"
|
"CREATE SUBSCRIPTION sub2 CONNECTION '$publisher_connstr' PUBLICATION pub_all"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
# Add set of AFTER replica triggers for testing that they are fired
|
||||||
|
# correctly, using the same method as the first subscriber.
|
||||||
|
$node_subscriber2->safe_psql(
|
||||||
|
'postgres', qq{
|
||||||
|
CREATE TABLE sub2_trigger_activity (tgtab text,
|
||||||
|
tgop text, tgwhen text, tglevel text, olda int, newa int);
|
||||||
|
CREATE FUNCTION sub2_trigger_activity_func() RETURNS TRIGGER AS \$\$
|
||||||
|
BEGIN
|
||||||
|
IF (TG_OP = 'INSERT') THEN
|
||||||
|
INSERT INTO public.sub2_trigger_activity
|
||||||
|
SELECT TG_RELNAME, TG_OP, TG_WHEN, TG_LEVEL, NULL, NEW.a;
|
||||||
|
ELSIF (TG_OP = 'UPDATE') THEN
|
||||||
|
INSERT INTO public.sub2_trigger_activity
|
||||||
|
SELECT TG_RELNAME, TG_OP, TG_WHEN, TG_LEVEL, OLD.a, NEW.a;
|
||||||
|
END IF;
|
||||||
|
RETURN NULL;
|
||||||
|
END;
|
||||||
|
\$\$ LANGUAGE plpgsql;
|
||||||
|
CREATE TRIGGER sub2_tab1_log_op_trigger
|
||||||
|
AFTER INSERT OR UPDATE ON tab1
|
||||||
|
FOR EACH ROW EXECUTE PROCEDURE sub2_trigger_activity_func();
|
||||||
|
ALTER TABLE ONLY tab1 ENABLE REPLICA TRIGGER sub2_tab1_log_op_trigger;
|
||||||
|
CREATE TRIGGER sub2_tab1_2_log_op_trigger
|
||||||
|
AFTER INSERT OR UPDATE ON tab1_2
|
||||||
|
FOR EACH ROW EXECUTE PROCEDURE sub2_trigger_activity_func();
|
||||||
|
ALTER TABLE ONLY tab1_2 ENABLE REPLICA TRIGGER sub2_tab1_2_log_op_trigger;
|
||||||
|
});
|
||||||
|
|
||||||
# Wait for initial sync of all subscriptions
|
# Wait for initial sync of all subscriptions
|
||||||
my $synced_query =
|
my $synced_query =
|
||||||
"SELECT count(1) = 0 FROM pg_subscription_rel WHERE srsubstate NOT IN ('r', 's');";
|
"SELECT count(1) = 0 FROM pg_subscription_rel WHERE srsubstate NOT IN ('r', 's');";
|
||||||
|
@ -130,6 +192,14 @@ $result = $node_subscriber2->safe_psql('postgres',
|
||||||
"SELECT c, a FROM tab1_2 ORDER BY 1, 2");
|
"SELECT c, a FROM tab1_2 ORDER BY 1, 2");
|
||||||
is($result, qq(sub2_tab1_2|5), 'inserts into tab1_2 replicated');
|
is($result, qq(sub2_tab1_2|5), 'inserts into tab1_2 replicated');
|
||||||
|
|
||||||
|
# The AFTER trigger of tab1_2 should have recorded one INSERT.
|
||||||
|
$result = $node_subscriber2->safe_psql('postgres',
|
||||||
|
"SELECT * FROM sub2_trigger_activity ORDER BY tgtab, tgop, tgwhen, olda, newa;"
|
||||||
|
);
|
||||||
|
is( $result,
|
||||||
|
qq(tab1_2|INSERT|AFTER|ROW||5),
|
||||||
|
'check replica insert after trigger applied on subscriber');
|
||||||
|
|
||||||
$result = $node_subscriber2->safe_psql('postgres',
|
$result = $node_subscriber2->safe_psql('postgres',
|
||||||
"SELECT c, a FROM tab1_def ORDER BY 1, 2");
|
"SELECT c, a FROM tab1_def ORDER BY 1, 2");
|
||||||
is($result, qq(sub2_tab1_def|0), 'inserts into tab1_def replicated');
|
is($result, qq(sub2_tab1_def|0), 'inserts into tab1_def replicated');
|
||||||
|
@ -161,6 +231,15 @@ $result = $node_subscriber1->safe_psql('postgres',
|
||||||
"SELECT a FROM tab1_2_2 ORDER BY 1");
|
"SELECT a FROM tab1_2_2 ORDER BY 1");
|
||||||
is($result, qq(6), 'updates of tab1_2 replicated into tab1_2_2 correctly');
|
is($result, qq(6), 'updates of tab1_2 replicated into tab1_2_2 correctly');
|
||||||
|
|
||||||
|
# The AFTER trigger should have recorded the UPDATEs of tab1_2_2.
|
||||||
|
$result = $node_subscriber1->safe_psql('postgres',
|
||||||
|
"SELECT * FROM sub1_trigger_activity ORDER BY tgtab, tgop, tgwhen, olda, newa;"
|
||||||
|
);
|
||||||
|
is( $result, qq(tab1_2_2|INSERT|AFTER|ROW||6
|
||||||
|
tab1_2_2|UPDATE|AFTER|ROW|4|6
|
||||||
|
tab1_2_2|UPDATE|AFTER|ROW|6|4),
|
||||||
|
'check replica update after trigger applied on subscriber');
|
||||||
|
|
||||||
$result = $node_subscriber2->safe_psql('postgres',
|
$result = $node_subscriber2->safe_psql('postgres',
|
||||||
"SELECT c, a FROM tab1_1 ORDER BY 1, 2");
|
"SELECT c, a FROM tab1_1 ORDER BY 1, 2");
|
||||||
is( $result, qq(sub2_tab1_1|2
|
is( $result, qq(sub2_tab1_1|2
|
||||||
|
@ -170,6 +249,16 @@ $result = $node_subscriber2->safe_psql('postgres',
|
||||||
"SELECT c, a FROM tab1_2 ORDER BY 1, 2");
|
"SELECT c, a FROM tab1_2 ORDER BY 1, 2");
|
||||||
is($result, qq(sub2_tab1_2|6), 'tab1_2 updated');
|
is($result, qq(sub2_tab1_2|6), 'tab1_2 updated');
|
||||||
|
|
||||||
|
# The AFTER trigger should have recorded the updates of tab1_2.
|
||||||
|
$result = $node_subscriber2->safe_psql('postgres',
|
||||||
|
"SELECT * FROM sub2_trigger_activity ORDER BY tgtab, tgop, tgwhen, olda, newa;"
|
||||||
|
);
|
||||||
|
is( $result, qq(tab1_2|INSERT|AFTER|ROW||5
|
||||||
|
tab1_2|UPDATE|AFTER|ROW|4|6
|
||||||
|
tab1_2|UPDATE|AFTER|ROW|5|6
|
||||||
|
tab1_2|UPDATE|AFTER|ROW|6|4),
|
||||||
|
'check replica update after trigger applied on subscriber');
|
||||||
|
|
||||||
$result = $node_subscriber2->safe_psql('postgres',
|
$result = $node_subscriber2->safe_psql('postgres',
|
||||||
"SELECT c, a FROM tab1_def ORDER BY 1");
|
"SELECT c, a FROM tab1_def ORDER BY 1");
|
||||||
is($result, qq(sub2_tab1_def|0), 'tab1_def unchanged');
|
is($result, qq(sub2_tab1_def|0), 'tab1_def unchanged');
|
||||||
|
|
Loading…
Reference in New Issue