Fix miscellaneous issues in EXCEPT publication clause.

Improve documentation regarding multiple publications and partition
hierarchies. Refine error reporting for excluded relations. Consolidate
docs by using table_object instead of expanded table syntax in publication
commands. Also includes minor test cleanup and naming fixes.

Reported-by: Peter Smith <smithpb2250@gmail.com>
Author: vignesh C <vignesh21@gmail.com>
Reviewed-by: Peter Smith <smithpb2250@gmail.com>
Reviewed-by: Amit Kapila <amit.kapila16@gmail.com>
Discussion: https://postgr.es/m/CALDaNm1CiBYcteE_jjPA4BPHfX30dg9eTTTkJgkjY5tgE7t=bQ@mail.gmail.com
Discussion: https://postgr.es/m/CALDaNm3=JrucjhiiwsYQw5-PGtBHFONa6F7hhWCXMsGvh=tamA@mail.gmail.com
This commit is contained in:
Amit Kapila 2026-04-01 09:08:54 +05:30
parent 852de579a6
commit 6b0550c45d
5 changed files with 19 additions and 19 deletions

View file

@ -40,12 +40,12 @@ ALTER PUBLICATION <replaceable class="parameter">name</replaceable> RENAME TO <r
<phrase>and <replaceable class="parameter">publication_drop_object</replaceable> is one of:</phrase>
TABLE [ ONLY ] <replaceable class="parameter">table_name</replaceable> [ * ] [, ... ]
TABLE <replaceable class="parameter">table_object</replaceable> [, ... ]
TABLES IN SCHEMA { <replaceable class="parameter">schema_name</replaceable> | CURRENT_SCHEMA } [, ... ]
<phrase>and <replaceable class="parameter">table_and_columns</replaceable> is:</phrase>
[ ONLY ] <replaceable class="parameter">table_name</replaceable> [ * ] [ ( <replaceable class="parameter">column_name</replaceable> [, ... ] ) ] [ WHERE ( <replaceable class="parameter">expression</replaceable> ) ]
<replaceable class="parameter">table_object</replaceable> [ ( <replaceable class="parameter">column_name</replaceable> [, ... ] ) ] [ WHERE ( <replaceable class="parameter">expression</replaceable> ) ]
<phrase>and <replaceable class="parameter">except_table_object</replaceable> is:</phrase>

View file

@ -37,7 +37,7 @@ CREATE PUBLICATION <replaceable class="parameter">name</replaceable>
<phrase>and <replaceable class="parameter">table_and_columns</replaceable> is:</phrase>
[ ONLY ] <replaceable class="parameter">table_name</replaceable> [ * ] [ ( <replaceable class="parameter">column_name</replaceable> [, ... ] ) ] [ WHERE ( <replaceable class="parameter">expression</replaceable> ) ]
<replaceable class="parameter">table_object</replaceable> [ ( <replaceable class="parameter">column_name</replaceable> [, ... ] ) ] [ WHERE ( <replaceable class="parameter">expression</replaceable> ) ]
<phrase>and <replaceable class="parameter">except_table_object</replaceable> is:</phrase>
@ -218,8 +218,8 @@ CREATE PUBLICATION <replaceable class="parameter">name</replaceable>
<para>
There can be a case where a subscription includes multiple publications.
In such a case, a table or partition that is included in one publication
and listed in the <literal>EXCEPT</literal> clause of another is
considered included for replication.
but excluded (explicitly or implicitly) by the <literal>EXCEPT</literal>
clause of another is considered included for replication.
</para>
</listitem>
</varlistentry>

View file

@ -59,7 +59,7 @@ check_publication_add_relation(PublicationRelInfo *pri)
const char *errormsg;
if (pri->except)
errormsg = gettext_noop("cannot use publication EXCEPT clause for relation \"%s\"");
errormsg = gettext_noop("cannot specify relation \"%s\" in the publication EXCEPT clause");
else
errormsg = gettext_noop("cannot add relation \"%s\" to publication");

View file

@ -449,7 +449,7 @@ Except Publications:
Number of partitions: 1 (Use \d+ to list them.)
CREATE PUBLICATION testpub9 FOR ALL TABLES EXCEPT (TABLE testpub_part1);
ERROR: cannot use publication EXCEPT clause for relation "testpub_part1"
ERROR: cannot specify relation "testpub_part1" in the publication EXCEPT clause
DETAIL: This operation is not supported for individual partitions.
CREATE TABLE tab_main (a int) PARTITION BY RANGE(a);
-- Attaching a partition is not allowed if the partitioned table appears in a

View file

@ -70,7 +70,7 @@ sub test_except_root_partition
# EXCEPT clause test cases for non-partitioned tables and inherited tables.
# ============================================
# Create schemas and tables on publisher
# Create tables on publisher
$node_publisher->safe_psql(
'postgres', qq(
CREATE TABLE tab1 AS SELECT generate_series(1,10) AS a;
@ -80,7 +80,7 @@ $node_publisher->safe_psql(
CREATE TABLE child1 (b int) INHERITS (parent1);
));
# Create schemas and tables on subscriber
# Create tables on subscriber
$node_subscriber->safe_psql(
'postgres', qq(
CREATE TABLE tab1 (a int);
@ -94,7 +94,7 @@ $node_subscriber->safe_psql(
# to verify exclusion behavior for inherited tables, including the effect of
# ONLY in the EXCEPT clause.
$node_publisher->safe_psql('postgres',
"CREATE PUBLICATION tab_pub FOR ALL TABLES EXCEPT (TABLE tab1, parent, only parent1)"
"CREATE PUBLICATION tap_pub FOR ALL TABLES EXCEPT (TABLE tab1, parent, only parent1)"
);
# Create a logical replication slot to help with later tests.
@ -102,11 +102,11 @@ $node_publisher->safe_psql('postgres',
"SELECT pg_create_logical_replication_slot('test_slot', 'pgoutput')");
$node_subscriber->safe_psql('postgres',
"CREATE SUBSCRIPTION tab_sub CONNECTION '$publisher_connstr' PUBLICATION tab_pub"
"CREATE SUBSCRIPTION tap_sub CONNECTION '$publisher_connstr' PUBLICATION tap_pub"
);
# Wait for initial table sync to finish
$node_subscriber->wait_for_subscription_sync($node_publisher, 'tab_sub');
$node_subscriber->wait_for_subscription_sync($node_publisher, 'tap_sub');
# Check the table data does not sync for the tables specified in the EXCEPT
# clause.
@ -126,7 +126,7 @@ $node_publisher->safe_psql(
# Verify that data inserted into a table listed in the EXCEPT clause is
# not published.
$result = $node_publisher->safe_psql('postgres',
"SELECT count(*) = 0 FROM pg_logical_slot_get_binary_changes('test_slot', NULL, NULL, 'proto_version', '1', 'publication_names', 'tab_pub')"
"SELECT count(*) = 0 FROM pg_logical_slot_get_binary_changes('test_slot', NULL, NULL, 'proto_version', '1', 'publication_names', 'tap_pub')"
);
is($result, qq(t),
'verify no changes for table listed in the EXCEPT clause are present in the replication slot'
@ -141,7 +141,7 @@ $node_publisher->safe_psql('postgres',
# Verify that data inserted into a table listed in the EXCEPT clause is
# not replicated.
$node_publisher->wait_for_catchup('tab_sub');
$node_publisher->wait_for_catchup('tap_sub');
$result =
$node_subscriber->safe_psql('postgres', "SELECT count(*) FROM tab1");
is($result, qq(0), 'check replicated inserts on subscriber');
@ -158,15 +158,15 @@ $node_subscriber->safe_psql('postgres', "CREATE TABLE tab2 (a int)");
# Replace the table list in the EXCEPT clause so that only tab2 is excluded.
$node_publisher->safe_psql('postgres',
"ALTER PUBLICATION tab_pub SET ALL TABLES EXCEPT (TABLE tab2)");
"ALTER PUBLICATION tap_pub SET ALL TABLES EXCEPT (TABLE tab2)");
# Refresh the subscription so the subscriber picks up the updated
# publication definition and initiates table synchronization.
$node_subscriber->safe_psql('postgres',
"ALTER SUBSCRIPTION tab_sub REFRESH PUBLICATION");
"ALTER SUBSCRIPTION tap_sub REFRESH PUBLICATION");
# Wait for initial table sync to finish
$node_subscriber->wait_for_subscription_sync($node_publisher, 'tab_sub');
$node_subscriber->wait_for_subscription_sync($node_publisher, 'tap_sub');
# Verify that initial table synchronization does not occur for tables
# listed in the EXCEPT clause.
@ -187,13 +187,13 @@ is($result, qq(20),
# cleanup
$node_subscriber->safe_psql(
'postgres', qq(
DROP SUBSCRIPTION tab_sub;
DROP SUBSCRIPTION tap_sub;
TRUNCATE TABLE tab1;
DROP TABLE parent, parent1, child, child1, tab2;
));
$node_publisher->safe_psql(
'postgres', qq(
DROP PUBLICATION tab_pub;
DROP PUBLICATION tap_pub;
TRUNCATE TABLE tab1;
DROP TABLE parent, parent1, child, child1, tab2;
));