Fix handling of temp and unlogged tables in FOR ALL TABLES publications

If a FOR ALL TABLES publication exists, temporary and unlogged tables
are ignored for publishing changes.  But CheckCmdReplicaIdentity()
would still check in that case that such a table has a replica
identity set before accepting updates.  To fix, have
GetRelationPublicationActions() return that such a table publishes no
actions.

Discussion: https://www.postgresql.org/message-id/f3f151f7-c4dd-1646-b998-f60bd6217dd3@2ndquadrant.com
This commit is contained in:
Peter Eisentraut 2019-04-16 10:37:44 +02:00
parent 1cebfdee00
commit bb385c4fb0
2 changed files with 43 additions and 1 deletions

View File

@ -5156,6 +5156,13 @@ GetRelationPublicationActions(Relation relation)
MemoryContext oldcxt;
PublicationActions *pubactions = palloc0(sizeof(PublicationActions));
/*
* If not publishable, it publishes no actions. (pgoutput_change() will
* ignore it.)
*/
if (!is_publishable_relation(relation))
return pubactions;
if (relation->rd_pubactions)
return memcpy(pubactions, relation->rd_pubactions,
sizeof(PublicationActions));

View File

@ -3,7 +3,7 @@ use strict;
use warnings;
use PostgresNode;
use TestLib;
use Test::More tests => 1;
use Test::More tests => 3;
# Bug #15114
@ -63,3 +63,38 @@ $node_publisher->safe_psql('postgres',
$node_publisher->wait_for_catchup('sub1');
pass('index predicates do not cause crash');
$node_publisher->stop('fast');
$node_subscriber->stop('fast');
# Handling of temporary and unlogged tables with FOR ALL TABLES publications
# If a FOR ALL TABLES publication exists, temporary and unlogged
# tables are ignored for publishing changes. The bug was that we
# would still check in that case that such a table has a replica
# identity set before accepting updates. If it did not it would cause
# an error when an update was attempted.
$node_publisher = get_new_node('publisher2');
$node_publisher->init(allows_streaming => 'logical');
$node_publisher->start;
$node_publisher->safe_psql('postgres',
"CREATE PUBLICATION pub FOR ALL TABLES");
is( $node_publisher->psql(
'postgres',
"CREATE TEMPORARY TABLE tt1 AS SELECT 1 AS a; UPDATE tt1 SET a = 2;"),
0,
'update to temporary table without replica identity with FOR ALL TABLES publication'
);
is( $node_publisher->psql(
'postgres',
"CREATE UNLOGGED TABLE tu1 AS SELECT 1 AS a; UPDATE tu1 SET a = 2;"),
0,
'update to unlogged table without replica identity with FOR ALL TABLES publication'
);
$node_publisher->stop('fast');