Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit7474393

Browse files
committed
Have logical replication subscriber fire column triggers
The logical replication apply worker did not fire per-column updatetriggers because the updatedCols bitmap in the RTE was not populated.This fixes that.Reviewed-by: Euler Taveira <euler@timbira.com.br>Discussion:https://www.postgresql.org/message-id/flat/21673e2d-597c-6afe-637e-e8b10425b240%402ndquadrant.com
1 parenta8474d8 commit7474393

File tree

2 files changed

+46
-4
lines changed

2 files changed

+46
-4
lines changed

‎src/backend/replication/logical/worker.c‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include"pgstat.h"
2828
#include"funcapi.h"
2929

30+
#include"access/sysattr.h"
3031
#include"access/xact.h"
3132
#include"access/xlog_internal.h"
3233

@@ -706,6 +707,8 @@ apply_handle_update(StringInfo s)
706707
boolhas_oldtup;
707708
TupleTableSlot*localslot;
708709
TupleTableSlot*remoteslot;
710+
RangeTblEntry*target_rte;
711+
inti;
709712
boolfound;
710713
MemoryContextoldctx;
711714

@@ -735,6 +738,21 @@ apply_handle_update(StringInfo s)
735738
RelationGetDescr(rel->localrel));
736739
EvalPlanQualInit(&epqstate,estate,NULL,NIL,-1);
737740

741+
/*
742+
* Populate updatedCols so that per-column triggers can fire. This could
743+
* include more columns than were actually changed on the publisher
744+
* because the logical replication protocol doesn't contain that
745+
* information. But it would for example exclude columns that only exist
746+
* on the subscriber, since we are not touching those.
747+
*/
748+
target_rte=list_nth(estate->es_range_table,0);
749+
for (i=0;i<remoteslot->tts_tupleDescriptor->natts;i++)
750+
{
751+
if (newtup.changed[i])
752+
target_rte->updatedCols=bms_add_member(target_rte->updatedCols,
753+
i+1-FirstLowInvalidHeapAttributeNumber);
754+
}
755+
738756
PushActiveSnapshot(GetTransactionSnapshot());
739757
ExecOpenIndices(estate->es_result_relation_info, false);
740758

‎src/test/subscription/t/003_constraints.pl‎

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use warnings;
44
use PostgresNode;
55
use TestLib;
6-
use Test::Moretests=>4;
6+
use Test::Moretests=>6;
77

88
# Initialize publisher node
99
my$node_publisher = get_new_node('publisher');
@@ -82,14 +82,16 @@ BEGIN
8282
ELSE
8383
RETURN NULL;
8484
END IF;
85+
ELSIF (TG_OP = 'UPDATE') THEN
86+
RETURN NULL;
8587
ELSE
8688
RAISE WARNING 'Unknown action';
8789
RETURN NULL;
8890
END IF;
8991
END;
9092
\$\$ LANGUAGE plpgsql;
9193
CREATE TRIGGER filter_basic_dml_trg
92-
BEFORE INSERT ON tab_fk_ref
94+
BEFORE INSERTOR UPDATE OF bidON tab_fk_ref
9395
FOR EACH ROW EXECUTE PROCEDURE filter_basic_dml_fn();
9496
ALTER TABLE tab_fk_ref ENABLE REPLICA TRIGGER filter_basic_dml_trg;
9597
});
@@ -100,10 +102,32 @@ BEGIN
100102

101103
$node_publisher->wait_for_catchup($appname);
102104

103-
# The row should be skipped on subscriber
105+
# The trigger should cause the insert to be skipped on subscriber
106+
$result =$node_subscriber->safe_psql('postgres',
107+
"SELECT count(*), min(bid), max(bid) FROM tab_fk_ref;");
108+
is($result,qq(2|1|2),'check replica insert trigger applied on subscriber');
109+
110+
# Update data
111+
$node_publisher->safe_psql('postgres',
112+
"UPDATE tab_fk_ref SET bid = 2 WHERE bid = 1;");
113+
114+
$node_publisher->wait_for_catchup($appname);
115+
116+
# The trigger should cause the update to be skipped on subscriber
104117
$result =$node_subscriber->safe_psql('postgres',
105118
"SELECT count(*), min(bid), max(bid) FROM tab_fk_ref;");
106-
is($result,qq(2|1|2),'check replica trigger applied on subscriber');
119+
is($result,qq(2|1|2),'check replica update column trigger applied on subscriber');
120+
121+
# Update on a column not specified in the trigger, but it will trigger
122+
# anyway because logical replication ships all columns in an update.
123+
$node_publisher->safe_psql('postgres',
124+
"UPDATE tab_fk_ref SET id = 6 WHERE id = 1;");
125+
126+
$node_publisher->wait_for_catchup($appname);
127+
128+
$result =$node_subscriber->safe_psql('postgres',
129+
"SELECT count(*), min(id), max(id) FROM tab_fk_ref;");
130+
is($result,qq(2|1|2),'check column trigger applied on even for other column');
107131

108132
$node_subscriber->stop('fast');
109133
$node_publisher->stop('fast');

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp