mirror of
https://github.com/postgres/postgres.git
synced 2025-05-06 19:59:18 +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;
|
found = 0;
|
||||||
for (i = 0; i < desc->natts; i++)
|
for (i = 0; i < desc->natts; i++)
|
||||||
{
|
{
|
||||||
int attnum = logicalrep_rel_att_by_name(remoterel,
|
int attnum;
|
||||||
NameStr(desc->attrs[i]->attname));
|
|
||||||
|
if (desc->attrs[i]->attisdropped)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
attnum = logicalrep_rel_att_by_name(remoterel,
|
||||||
|
NameStr(desc->attrs[i]->attname));
|
||||||
|
|
||||||
entry->attrmap[i] = attnum;
|
entry->attrmap[i] = attnum;
|
||||||
if (attnum >= 0)
|
if (attnum >= 0)
|
||||||
|
@ -492,25 +492,15 @@ static List *
|
|||||||
make_copy_attnamelist(LogicalRepRelMapEntry *rel)
|
make_copy_attnamelist(LogicalRepRelMapEntry *rel)
|
||||||
{
|
{
|
||||||
List *attnamelist = NIL;
|
List *attnamelist = NIL;
|
||||||
TupleDesc desc = RelationGetDescr(rel->localrel);
|
|
||||||
int i;
|
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,
|
attnamelist = lappend(attnamelist,
|
||||||
makeString(rel->remoterel.attnames[remoteattnum]));
|
makeString(rel->remoterel.attnames[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return attnamelist;
|
return attnamelist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
use PostgresNode;
|
use PostgresNode;
|
||||||
use TestLib;
|
use TestLib;
|
||||||
use Test::More tests => 14;
|
use Test::More tests => 15;
|
||||||
|
|
||||||
# Initialize publisher node
|
# Initialize publisher node
|
||||||
my $node_publisher = get_new_node('publisher');
|
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");
|
"CREATE TABLE tab_full AS SELECT generate_series(1,10) AS a");
|
||||||
$node_publisher->safe_psql('postgres',
|
$node_publisher->safe_psql('postgres',
|
||||||
"CREATE TABLE tab_rep (a int primary key)");
|
"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
|
# Setup structure on subscriber
|
||||||
$node_subscriber->safe_psql('postgres', "CREATE TABLE tab_notrep (a int)");
|
$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_full (a int)");
|
||||||
$node_subscriber->safe_psql('postgres',
|
$node_subscriber->safe_psql('postgres',
|
||||||
"CREATE TABLE tab_rep (a int primary key)");
|
"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
|
# Setup logical replication
|
||||||
my $publisher_connstr = $node_publisher->connstr . ' dbname=postgres';
|
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',
|
$node_publisher->safe_psql('postgres',
|
||||||
"CREATE PUBLICATION tap_pub_ins_only WITH (publish = insert)");
|
"CREATE PUBLICATION tap_pub_ins_only WITH (publish = insert)");
|
||||||
$node_publisher->safe_psql('postgres',
|
$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',
|
$node_publisher->safe_psql('postgres',
|
||||||
"ALTER PUBLICATION tap_pub_ins_only ADD TABLE tab_ins");
|
"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");
|
"SELECT count(*), min(a), max(a) FROM tab_rep");
|
||||||
is($result, qq(20|-20|-1), 'check replicated changes on subscriber');
|
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
|
# insert some duplicate rows
|
||||||
$node_publisher->safe_psql('postgres',
|
$node_publisher->safe_psql('postgres',
|
||||||
"INSERT INTO tab_full SELECT generate_series(1,10)");
|
"INSERT INTO tab_full SELECT generate_series(1,10)");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user