Skip to content

Commit 2c4d0f3

Browse files
alvherreitscaro
andcommitted
Set ActiveSnapshot when logically replaying inserts
Input functions for the inserted tuples may require a snapshot, when they are replayed by native logical replication. An example is a domain with a constraint using a SQL-language function, which prior to this commit failed to apply on the subscriber side. Reported-by: Mai Peng <maily.peng@webedia-group.com> Co-authored-by: Minh-Quan TRAN <qtran@itscaro.me> Co-authored-by: Álvaro Herrera <alvherre@alvh.no-ip.org> Discussion: https://postgr.es/m/4EB4BD78-BFC3-4D04-B8DA-D53DF7160354@webedia-group.com Discussion: https://postgr.es/m/153211336163.1404.11721804383024050689@wrigleys.postgresql.org
1 parent 96b1d98 commit 2c4d0f3

File tree

2 files changed

+25
-3
lines changed

2 files changed

+25
-3
lines changed

src/backend/replication/logical/worker.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -607,13 +607,15 @@ apply_handle_insert(StringInfo s)
607607
remoteslot = ExecInitExtraTupleSlot(estate);
608608
ExecSetSlotDescriptor(remoteslot, RelationGetDescr(rel->localrel));
609609

610+
/* Input functions may need an active snapshot, so get one */
611+
PushActiveSnapshot(GetTransactionSnapshot());
612+
610613
/* Process and store remote tuple in the slot */
611614
oldctx = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate));
612615
slot_store_cstrings(remoteslot, rel, newtup.values);
613616
slot_fill_defaults(rel, estate, remoteslot);
614617
MemoryContextSwitchTo(oldctx);
615618

616-
PushActiveSnapshot(GetTransactionSnapshot());
617619
ExecOpenIndices(estate->es_result_relation_info, false);
618620

619621
/* Do the insert. */

src/test/subscription/t/002_types.pl

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
use warnings;
55
use PostgresNode;
66
use TestLib;
7-
use Test::More tests => 3;
7+
use Test::More tests => 4;
88

99
# Initialize publisher node
1010
my $node_publisher = get_new_node('publisher');
@@ -90,7 +90,13 @@
9090
CREATE TABLE public.tst_hstore (
9191
a INTEGER PRIMARY KEY,
9292
b public.hstore
93-
););
93+
);
94+
95+
SET check_function_bodies=off;
96+
CREATE FUNCTION public.monot_incr(int) RETURNS bool LANGUAGE sql
97+
AS ' select \$1 > max(a) from public.tst_dom_constr; ';
98+
CREATE DOMAIN monot_int AS int CHECK (monot_incr(VALUE));
99+
CREATE TABLE public.tst_dom_constr (a monot_int););
94100

95101
# Setup structure on both nodes
96102
$node_publisher->safe_psql('postgres', $ddl);
@@ -244,6 +250,9 @@
244250
(2, '"zzz"=>"foo"'),
245251
(3, '"123"=>"321"'),
246252
(4, '"yellow horse"=>"moaned"');
253+
254+
-- tst_dom_constr
255+
INSERT INTO tst_dom_constr VALUES (10);
247256
));
248257

249258
$node_publisher->poll_query_until('postgres', $caughtup_query)
@@ -548,5 +557,16 @@
548557
4|"yellow horse"=>"moaned"',
549558
'check replicated deletes on subscriber');
550559

560+
# Test a domain with a constraint backed by a SQL-language function,
561+
# which needs an active snapshot in order to operate.
562+
$node_publisher->safe_psql('postgres', "INSERT INTO tst_dom_constr VALUES (11)");
563+
564+
$node_subscriber->poll_query_until('postgres', $synced_query)
565+
or die "Timed out while waiting for subscriber to synchronize data";
566+
567+
$result =
568+
$node_subscriber->safe_psql('postgres', "SELECT sum(a) FROM tst_dom_constr");
569+
is($result, '21', 'sql-function constraint on domain');
570+
551571
$node_subscriber->stop('fast');
552572
$node_publisher->stop('fast');

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy