mirror of
https://github.com/postgres/postgres.git
synced 2025-05-03 22:24:49 +03:00
Fix table syncing with different column order
Logical replication supports replicating between tables with different column order. But this failed for the initial table sync because of a logic error in how the column list for the internal COPY command was composed. Fix that and also add a test. Also fix a minor omission in the column name mapping cache. When creating the mapping list, it would not skip locally dropped columns. So if a remote column had the same name as a locally dropped column (...pg.dropped...), then the expected error would not occur.
This commit is contained in:
parent
92ecb148e5
commit
073ce405d6
@ -277,8 +277,13 @@ logicalrep_rel_open(LogicalRepRelId remoteid, LOCKMODE lockmode)
|
||||
found = 0;
|
||||
for (i = 0; i < desc->natts; i++)
|
||||
{
|
||||
int attnum = logicalrep_rel_att_by_name(remoterel,
|
||||
NameStr(desc->attrs[i]->attname));
|
||||
int attnum;
|
||||
|
||||
if (desc->attrs[i]->attisdropped)
|
||||
continue;
|
||||
|
||||
attnum = logicalrep_rel_att_by_name(remoterel,
|
||||
NameStr(desc->attrs[i]->attname));
|
||||
|
||||
entry->attrmap[i] = attnum;
|
||||
if (attnum >= 0)
|
||||
|
@ -492,25 +492,15 @@ static List *
|
||||
make_copy_attnamelist(LogicalRepRelMapEntry *rel)
|
||||
{
|
||||
List *attnamelist = NIL;
|
||||
TupleDesc desc = RelationGetDescr(rel->localrel);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < desc->natts; i++)
|
||||
for (i = 0; i < rel->remoterel.natts; i++)
|
||||
{
|
||||
int remoteattnum = rel->attrmap[i];
|
||||
|
||||
/* Skip dropped attributes. */
|
||||
if (desc->attrs[i]->attisdropped)
|
||||
continue;
|
||||
|
||||
/* Skip attributes that are missing on remote side. */
|
||||
if (remoteattnum < 0)
|
||||
continue;
|
||||
|
||||
attnamelist = lappend(attnamelist,
|
||||
makeString(rel->remoterel.attnames[remoteattnum]));
|
||||
makeString(rel->remoterel.attnames[i]));
|
||||
}
|
||||
|
||||
|
||||
return attnamelist;
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@ use strict;
|
||||
use warnings;
|
||||
use PostgresNode;
|
||||
use TestLib;
|
||||
use Test::More tests => 14;
|
||||
use Test::More tests => 15;
|
||||
|
||||
# Initialize publisher node
|
||||
my $node_publisher = get_new_node('publisher');
|
||||
@ -24,6 +24,10 @@ $node_publisher->safe_psql('postgres',
|
||||
"CREATE TABLE tab_full AS SELECT generate_series(1,10) AS a");
|
||||
$node_publisher->safe_psql('postgres',
|
||||
"CREATE TABLE tab_rep (a int primary key)");
|
||||
$node_publisher->safe_psql('postgres',
|
||||
"CREATE TABLE tab_mixed (a int primary key, b text)");
|
||||
$node_publisher->safe_psql('postgres',
|
||||
"INSERT INTO tab_mixed (a, b) VALUES (1, 'foo')");
|
||||
|
||||
# Setup structure on subscriber
|
||||
$node_subscriber->safe_psql('postgres', "CREATE TABLE tab_notrep (a int)");
|
||||
@ -31,6 +35,9 @@ $node_subscriber->safe_psql('postgres', "CREATE TABLE tab_ins (a int)");
|
||||
$node_subscriber->safe_psql('postgres', "CREATE TABLE tab_full (a int)");
|
||||
$node_subscriber->safe_psql('postgres',
|
||||
"CREATE TABLE tab_rep (a int primary key)");
|
||||
# different column count and order than on publisher
|
||||
$node_subscriber->safe_psql('postgres',
|
||||
"CREATE TABLE tab_mixed (c text, b text, a int primary key)");
|
||||
|
||||
# Setup logical replication
|
||||
my $publisher_connstr = $node_publisher->connstr . ' dbname=postgres';
|
||||
@ -38,7 +45,7 @@ $node_publisher->safe_psql('postgres', "CREATE PUBLICATION tap_pub");
|
||||
$node_publisher->safe_psql('postgres',
|
||||
"CREATE PUBLICATION tap_pub_ins_only WITH (publish = insert)");
|
||||
$node_publisher->safe_psql('postgres',
|
||||
"ALTER PUBLICATION tap_pub ADD TABLE tab_rep, tab_full");
|
||||
"ALTER PUBLICATION tap_pub ADD TABLE tab_rep, tab_full, tab_mixed");
|
||||
$node_publisher->safe_psql('postgres',
|
||||
"ALTER PUBLICATION tap_pub_ins_only ADD TABLE tab_ins");
|
||||
|
||||
@ -88,6 +95,10 @@ $result = $node_subscriber->safe_psql('postgres',
|
||||
"SELECT count(*), min(a), max(a) FROM tab_rep");
|
||||
is($result, qq(20|-20|-1), 'check replicated changes on subscriber');
|
||||
|
||||
$result = $node_subscriber->safe_psql('postgres',
|
||||
"SELECT c, b, a FROM tab_mixed");
|
||||
is($result, qq(|foo|1), 'check replicated changes with different column order');
|
||||
|
||||
# insert some duplicate rows
|
||||
$node_publisher->safe_psql('postgres',
|
||||
"INSERT INTO tab_full SELECT generate_series(1,10)");
|
||||
|
Loading…
x
Reference in New Issue
Block a user