Skip to content

Commit 0ca8e42

Browse files
author
Commitfest Bot
committed
[CF 7210] v1 - Publication of same parent table with ONLY-ness mismatch should error
This branch was automatically generated by a robot using patches from an email thread registered at: https://commitfest.postgresql.org/patch/7210 The branch will be overwritten each time a new patch version is posted to the thread, and also periodically to check for bitrot caused by changes on the master branch. Patch(es): https://www.postgresql.org/message-id/CAHut+PtKp7OFkrvg8kJxH00MKCDEJRBpAzrzWE8oz84rq5AKbg@mail.gmail.com Author(s): Peter Smith
2 parents 852fd5b + 7508de6 commit 0ca8e42

4 files changed

Lines changed: 95 additions & 5 deletions

File tree

‎doc/src/sgml/ref/create_publication.sgml‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,9 @@ CREATE PUBLICATION <replaceable class="parameter">name</replaceable>
119119
Optionally, <literal>*</literal> can be specified after the
120120
<replaceable class="parameter">table_name</replaceable> to
121121
explicitly indicate that descendant tables are included.
122-
This does not apply to a partitioned table, however. The partitions of
123-
a partitioned table are always implicitly considered part of the
124-
publication, so they are never explicitly added to the publication.
122+
For a partitioned table, <literal>ONLY</literal> and <literal>*</literal>
123+
have no effect: its partitions are always implicitly considered part of
124+
the publication, so they are never explicitly added to the publication.
125125
</para>
126126

127127
<para>

‎src/backend/commands/publicationcmds.c‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1847,6 +1847,7 @@ OpenTableList(List *tables)
18471847
ListCell *lc;
18481848
List *relids_with_rf = NIL;
18491849
List *relids_with_collist = NIL;
1850+
List *relids_recursing = NIL;
18501851

18511852
/*
18521853
* Open, share-lock, and check all the explicitly-specified relations
@@ -1888,6 +1889,22 @@ OpenTableList(List *tables)
18881889
errmsg("conflicting or redundant column lists for table \"%s\"",
18891890
RelationGetRelationName(rel))));
18901891

1892+
/*
1893+
* Disallow duplicate tables if one mention specifies ONLY and
1894+
* another does not, since it's not clear whether descendant
1895+
* tables should be included. Plain "foo, foo" (agreeing on
1896+
* ONLY-ness) remains a silently-tolerated no-op, as before.
1897+
*
1898+
* Mismatching ONLY-ness remains silently-tolerated for
1899+
* partitioned tables since ONLY has no meaning for them anyway.
1900+
*/
1901+
if (recurse != list_member_oid(relids_recursing, myrelid) &&
1902+
rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
1903+
ereport(ERROR,
1904+
(errcode(ERRCODE_DUPLICATE_OBJECT),
1905+
errmsg("conflicting ONLY specifications for table \"%s\"",
1906+
RelationGetRelationName(rel))));
1907+
18911908
table_close(rel, ShareUpdateExclusiveLock);
18921909
continue;
18931910
}
@@ -1906,6 +1923,9 @@ OpenTableList(List *tables)
19061923
if (t->columns)
19071924
relids_with_collist = lappend_oid(relids_with_collist, myrelid);
19081925

1926+
if (recurse)
1927+
relids_recursing = lappend_oid(relids_recursing, myrelid);
1928+
19091929
/*
19101930
* Add children of this rel, if requested, so that they too are added
19111931
* to the publication. A partitioned table can't have any inheritance

‎src/test/regress/expected/publication.out‎

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -474,9 +474,38 @@ CREATE PUBLICATION testpub7 FOR ALL TABLES EXCEPT (TABLE ONLY testpub_tbl_parent
474474
Except tables:
475475
"public.testpub_tbl_parent"
476476

477+
-- Listing the same table twice is fine as long as the mentions agree on
478+
-- ONLY-ness.
479+
CREATE PUBLICATION testpub_dup1 FOR TABLE testpub_tbl_parent, TABLE testpub_tbl_parent;
480+
\dRp+ testpub_dup1
481+
Publication testpub_dup1
482+
Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Generated columns | Via root | Description
483+
--------------------------+------------+---------------+---------+---------+---------+-----------+-------------------+----------+-------------
484+
regress_publication_user | f | f | t | t | t | t | none | f |
485+
Tables:
486+
"public.testpub_tbl_child"
487+
"public.testpub_tbl_parent"
488+
489+
CREATE PUBLICATION testpub_dup2 FOR TABLE ONLY testpub_tbl_parent, TABLE ONLY testpub_tbl_parent;
490+
\dRp+ testpub_dup2
491+
Publication testpub_dup2
492+
Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Generated columns | Via root | Description
493+
--------------------------+------------+---------------+---------+---------+---------+-----------+-------------------+----------+-------------
494+
regress_publication_user | f | f | t | t | t | t | none | f |
495+
Tables:
496+
"public.testpub_tbl_parent"
497+
498+
-- But mixing ONLY and non-ONLY mentions of the same table is ambiguous
499+
-- (would descendants be included or not?) and must be rejected.
477500
RESET client_min_messages;
501+
CREATE PUBLICATION testpub_conflict1 FOR TABLE testpub_tbl_parent, TABLE ONLY testpub_tbl_parent;
502+
ERROR: conflicting ONLY specifications for table "testpub_tbl_parent"
503+
CREATE PUBLICATION testpub_conflict2 FOR TABLE ONLY testpub_tbl_parent, TABLE testpub_tbl_parent;
504+
ERROR: conflicting ONLY specifications for table "testpub_tbl_parent"
505+
SET client_min_messages = 'ERROR';
478506
DROP TABLE testpub_tbl_parent, testpub_tbl_child;
479507
DROP PUBLICATION testpub3, testpub4, testpub5, testpub6, testpub7;
508+
DROP PUBLICATION testpub_dup1, testpub_dup2;
480509
---------------------------------------------
481510
-- EXCEPT clause tests for partitioned tables
482511
---------------------------------------------
@@ -656,8 +685,28 @@ HINT: To enable updating the table, set REPLICA IDENTITY using ALTER TABLE.
656685
ALTER PUBLICATION testpub_forparted DROP TABLE testpub_parted;
657686
-- works again, because update is no longer replicated
658687
UPDATE testpub_parted2 SET a = 2;
688+
-- Mixing ONLY and non-ONLY mentions of the same partitioned table is silently
689+
-- tolerated because ONLY has no effect for partitioned tables anyway.
690+
CREATE PUBLICATION testpub_dup1 FOR TABLE testpub_parted, TABLE ONLY testpub_parted;
691+
\dRp+ testpub_dup1
692+
Publication testpub_dup1
693+
Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Generated columns | Via root | Description
694+
--------------------------+------------+---------------+---------+---------+---------+-----------+-------------------+----------+-------------
695+
regress_publication_user | f | f | t | t | t | t | none | f |
696+
Tables:
697+
"public.testpub_parted"
698+
699+
CREATE PUBLICATION testpub_dup2 FOR TABLE ONLY testpub_parted, TABLE testpub_parted;
700+
\dRp+ testpub_dup2
701+
Publication testpub_dup2
702+
Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Generated columns | Via root | Description
703+
--------------------------+------------+---------------+---------+---------+---------+-----------+-------------------+----------+-------------
704+
regress_publication_user | f | f | t | t | t | t | none | f |
705+
Tables:
706+
"public.testpub_parted"
707+
659708
DROP TABLE testpub_parted1, testpub_parted2;
660-
DROP PUBLICATION testpub_forparted, testpub_forparted1;
709+
DROP PUBLICATION testpub_forparted, testpub_forparted1, testpub_dup1, testpub_dup2;
661710
-- Tests for row filters
662711
CREATE TABLE testpub_rf_tbl1 (a integer, b text);
663712
CREATE TABLE testpub_rf_tbl2 (c text, d integer);

‎src/test/regress/sql/publication.sql‎

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,9 +234,23 @@ CREATE PUBLICATION testpub6 FOR ALL TABLES EXCEPT (TABLE testpub_tbl_parent *);
234234
CREATE PUBLICATION testpub7 FOR ALL TABLES EXCEPT (TABLE ONLY testpub_tbl_parent);
235235
\dRp+ testpub7
236236

237+
-- Listing the same table twice is fine as long as the mentions agree on
238+
-- ONLY-ness.
239+
CREATE PUBLICATION testpub_dup1 FOR TABLE testpub_tbl_parent, TABLE testpub_tbl_parent;
240+
\dRp+ testpub_dup1
241+
CREATE PUBLICATION testpub_dup2 FOR TABLE ONLY testpub_tbl_parent, TABLE ONLY testpub_tbl_parent;
242+
\dRp+ testpub_dup2
243+
244+
-- But mixing ONLY and non-ONLY mentions of the same table is ambiguous
245+
-- (would descendants be included or not?) and must be rejected.
237246
RESET client_min_messages;
247+
CREATE PUBLICATION testpub_conflict1 FOR TABLE testpub_tbl_parent, TABLE ONLY testpub_tbl_parent;
248+
CREATE PUBLICATION testpub_conflict2 FOR TABLE ONLY testpub_tbl_parent, TABLE testpub_tbl_parent;
249+
250+
SET client_min_messages = 'ERROR';
238251
DROP TABLE testpub_tbl_parent, testpub_tbl_child;
239252
DROP PUBLICATION testpub3, testpub4, testpub5, testpub6, testpub7;
253+
DROP PUBLICATION testpub_dup1, testpub_dup2;
240254

241255
---------------------------------------------
242256
-- EXCEPT clause tests for partitioned tables
@@ -335,8 +349,15 @@ UPDATE testpub_parted2 SET a = 2;
335349
ALTER PUBLICATION testpub_forparted DROP TABLE testpub_parted;
336350
-- works again, because update is no longer replicated
337351
UPDATE testpub_parted2 SET a = 2;
352+
-- Mixing ONLY and non-ONLY mentions of the same partitioned table is silently
353+
-- tolerated because ONLY has no effect for partitioned tables anyway.
354+
CREATE PUBLICATION testpub_dup1 FOR TABLE testpub_parted, TABLE ONLY testpub_parted;
355+
\dRp+ testpub_dup1
356+
CREATE PUBLICATION testpub_dup2 FOR TABLE ONLY testpub_parted, TABLE testpub_parted;
357+
\dRp+ testpub_dup2
358+
338359
DROP TABLE testpub_parted1, testpub_parted2;
339-
DROP PUBLICATION testpub_forparted, testpub_forparted1;
360+
DROP PUBLICATION testpub_forparted, testpub_forparted1, testpub_dup1, testpub_dup2;
340361

341362
-- Tests for row filters
342363
CREATE TABLE testpub_rf_tbl1 (a integer, b text);

0 commit comments

Comments
 (0)