Skip to content

Commit 4148c8b

Browse files
alvherreHou zj
and
Hou zj
committed
Improve some publication-related error messages
While at it, remove an unused queryString parameter from CheckPubRelationColumnList() and make other minor stylistic changes. Backpatch to 15. Reported by Kyotaro Horiguchi <horikyota.ntt@gmail.com> Co-authored-by: Hou zj <houzj.fnst@fujitsu.com> Discussion: https://postgr.es/m/20220926.160426.454497059203258582.horikyota.ntt@gmail.com
1 parent 249b040 commit 4148c8b

File tree

2 files changed

+47
-36
lines changed

2 files changed

+47
-36
lines changed

src/backend/commands/publicationcmds.c

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
#include "utils/syscache.h"
5454
#include "utils/varlena.h"
5555

56+
5657
/*
5758
* Information used to validate the columns in the row filter expression. See
5859
* contain_invalid_rfcolumn_walker for details.
@@ -76,6 +77,7 @@ static void PublicationAddSchemas(Oid pubid, List *schemas, bool if_not_exists,
7677
AlterPublicationStmt *stmt);
7778
static void PublicationDropSchemas(Oid pubid, List *schemas, bool missing_ok);
7879

80+
7981
static void
8082
parse_publication_options(ParseState *pstate,
8183
List *options,
@@ -125,7 +127,8 @@ parse_publication_options(ParseState *pstate,
125127
if (!SplitIdentifierString(publish, ',', &publish_list))
126128
ereport(ERROR,
127129
(errcode(ERRCODE_SYNTAX_ERROR),
128-
errmsg("invalid list syntax for \"publish\" option")));
130+
errmsg("invalid list syntax in parameter \"%s\"",
131+
"publish")));
129132

130133
/* Process the option list. */
131134
foreach(lc, publish_list)
@@ -143,7 +146,8 @@ parse_publication_options(ParseState *pstate,
143146
else
144147
ereport(ERROR,
145148
(errcode(ERRCODE_SYNTAX_ERROR),
146-
errmsg("unrecognized \"publish\" value: \"%s\"", publish_opt)));
149+
errmsg("unrecognized value for publication option \"%s\": \"%s\"",
150+
"publish", publish_opt)));
147151
}
148152
}
149153
else if (strcmp(defel->defname, "publish_via_partition_root") == 0)
@@ -444,10 +448,12 @@ contain_mutable_or_user_functions_checker(Oid func_id, void *context)
444448
}
445449

446450
/*
447-
* Check if the node contains any unallowed object. See
451+
* Check if the node contains any disallowed object. Subroutine for
448452
* check_simple_rowfilter_expr_walker.
449453
*
450-
* Returns the error detail message in errdetail_msg for unallowed expressions.
454+
* If a disallowed object is found, *errdetail_msg is set to a (possibly
455+
* translated) message to use as errdetail. If none, *errdetail_msg is not
456+
* modified.
451457
*/
452458
static void
453459
expr_allowed_in_node(Node *node, ParseState *pstate, char **errdetail_msg)
@@ -678,10 +684,17 @@ TransformPubWhereClauses(List *tables, const char *queryString,
678684

679685

680686
/*
681-
* Check the publication column lists expression for all relations in the list.
687+
* Given a list of tables that are going to be added to a publication,
688+
* verify that they fulfill the necessary preconditions, namely: no tables
689+
* have a column list if any schema is published; and partitioned tables do
690+
* not have column lists if publish_via_partition_root is not set.
691+
*
692+
* 'publish_schema' indicates that the publication contains any TABLES IN
693+
* SCHEMA elements (newly added in this command, or preexisting).
694+
* 'pubviaroot' is the value of publish_via_partition_root.
682695
*/
683696
static void
684-
CheckPubRelationColumnList(List *tables, const char *queryString,
697+
CheckPubRelationColumnList(char *pubname, List *tables,
685698
bool publish_schema, bool pubviaroot)
686699
{
687700
ListCell *lc;
@@ -706,23 +719,24 @@ CheckPubRelationColumnList(List *tables, const char *queryString,
706719
if (publish_schema)
707720
ereport(ERROR,
708721
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
709-
errmsg("cannot use publication column list for relation \"%s.%s\"",
722+
errmsg("cannot use column list for relation \"%s.%s\" in publication \"%s\"",
710723
get_namespace_name(RelationGetNamespace(pri->relation)),
711-
RelationGetRelationName(pri->relation)),
712-
errdetail("Column list cannot be specified if any schema is part of the publication or specified in the list."));
724+
RelationGetRelationName(pri->relation), pubname),
725+
errdetail("Column lists cannot be specified in publications containing FOR TABLES IN SCHEMA elements."));
713726

714727
/*
715728
* If the publication doesn't publish changes via the root partitioned
716729
* table, the partition's column list will be used. So disallow using
717-
* the column list on partitioned table in this case.
730+
* a column list on the partitioned table in this case.
718731
*/
719732
if (!pubviaroot &&
720733
pri->relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
721734
ereport(ERROR,
722735
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
723-
errmsg("cannot use publication column list for relation \"%s\"",
724-
RelationGetRelationName(pri->relation)),
725-
errdetail("Column list cannot be used for a partitioned table when %s is false.",
736+
errmsg("cannot use column list for relation \"%s.%s\" in publication \"%s\"",
737+
get_namespace_name(RelationGetNamespace(pri->relation)),
738+
RelationGetRelationName(pri->relation), pubname),
739+
errdetail("Column lists cannot be specified for partitioned tables when %s is false.",
726740
"publish_via_partition_root")));
727741
}
728742
}
@@ -765,12 +779,10 @@ CreatePublication(ParseState *pstate, CreatePublicationStmt *stmt)
765779
puboid = GetSysCacheOid1(PUBLICATIONNAME, Anum_pg_publication_oid,
766780
CStringGetDatum(stmt->pubname));
767781
if (OidIsValid(puboid))
768-
{
769782
ereport(ERROR,
770783
(errcode(ERRCODE_DUPLICATE_OBJECT),
771784
errmsg("publication \"%s\" already exists",
772785
stmt->pubname)));
773-
}
774786

775787
/* Form a tuple. */
776788
memset(values, 0, sizeof(values));
@@ -840,7 +852,7 @@ CreatePublication(ParseState *pstate, CreatePublicationStmt *stmt)
840852
TransformPubWhereClauses(rels, pstate->p_sourcetext,
841853
publish_via_partition_root);
842854

843-
CheckPubRelationColumnList(rels, pstate->p_sourcetext,
855+
CheckPubRelationColumnList(stmt->pubname, rels,
844856
schemaidlist != NIL,
845857
publish_via_partition_root);
846858

@@ -864,12 +876,10 @@ CreatePublication(ParseState *pstate, CreatePublicationStmt *stmt)
864876
InvokeObjectPostCreateHook(PublicationRelationId, puboid, 0);
865877

866878
if (wal_level != WAL_LEVEL_LOGICAL)
867-
{
868879
ereport(WARNING,
869880
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
870881
errmsg("wal_level is insufficient to publish logical changes"),
871-
errhint("Set wal_level to logical before creating subscriptions.")));
872-
}
882+
errhint("Set wal_level to \"logical\" before creating subscriptions.")));
873883

874884
return myself;
875885
}
@@ -1110,7 +1120,7 @@ AlterPublicationTables(AlterPublicationStmt *stmt, HeapTuple tup,
11101120

11111121
publish_schema |= is_schema_publication(pubid);
11121122

1113-
CheckPubRelationColumnList(rels, queryString, publish_schema,
1123+
CheckPubRelationColumnList(stmt->pubname, rels, publish_schema,
11141124
pubform->pubviaroot);
11151125

11161126
PublicationAddTables(pubid, rels, false, stmt);
@@ -1126,7 +1136,7 @@ AlterPublicationTables(AlterPublicationStmt *stmt, HeapTuple tup,
11261136

11271137
TransformPubWhereClauses(rels, queryString, pubform->pubviaroot);
11281138

1129-
CheckPubRelationColumnList(rels, queryString, publish_schema,
1139+
CheckPubRelationColumnList(stmt->pubname, rels, publish_schema,
11301140
pubform->pubviaroot);
11311141

11321142
/*
@@ -1299,8 +1309,9 @@ AlterPublicationSchemas(AlterPublicationStmt *stmt,
12991309
if (!heap_attisnull(coltuple, Anum_pg_publication_rel_prattrs, NULL))
13001310
ereport(ERROR,
13011311
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1302-
errmsg("cannot add schema to the publication"),
1303-
errdetail("Schema cannot be added if any table that specifies column list is already part of the publication."));
1312+
errmsg("cannot add schema to publication \"%s\"",
1313+
stmt->pubname),
1314+
errdetail("Schemas cannot be added if any tables that specify a column list are already part of the publication."));
13041315

13051316
ReleaseSysCache(coltuple);
13061317
}

src/test/regress/expected/publication.out

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ ALTER PUBLICATION testpub_default SET (publish = update);
2424
CREATE PUBLICATION testpub_xxx WITH (foo);
2525
ERROR: unrecognized publication parameter: "foo"
2626
CREATE PUBLICATION testpub_xxx WITH (publish = 'cluster, vacuum');
27-
ERROR: unrecognized "publish" value: "cluster"
27+
ERROR: unrecognized value for publication option "publish": "cluster"
2828
CREATE PUBLICATION testpub_xxx WITH (publish_via_partition_root = 'true', publish_via_partition_root = '0');
2929
ERROR: conflicting or redundant options
3030
LINE 1: ...ub_xxx WITH (publish_via_partition_root = 'true', publish_vi...
@@ -853,32 +853,32 @@ DETAIL: Column list used by the publication does not cover the replica identity
853853
SET client_min_messages = 'ERROR';
854854
-- failure - cannot use column list and schema together
855855
CREATE PUBLICATION testpub_tbl9 FOR TABLES IN SCHEMA public, TABLE public.testpub_tbl7(a);
856-
ERROR: cannot use publication column list for relation "public.testpub_tbl7"
857-
DETAIL: Column list cannot be specified if any schema is part of the publication or specified in the list.
856+
ERROR: cannot use column list for relation "public.testpub_tbl7" in publication "testpub_tbl9"
857+
DETAIL: Column lists cannot be specified in publications containing FOR TABLES IN SCHEMA elements.
858858
-- ok - only publish schema
859859
CREATE PUBLICATION testpub_tbl9 FOR TABLES IN SCHEMA public;
860860
-- failure - add a table with column list when there is already a schema in the
861861
-- publication
862862
ALTER PUBLICATION testpub_tbl9 ADD TABLE public.testpub_tbl7(a);
863-
ERROR: cannot use publication column list for relation "public.testpub_tbl7"
864-
DETAIL: Column list cannot be specified if any schema is part of the publication or specified in the list.
863+
ERROR: cannot use column list for relation "public.testpub_tbl7" in publication "testpub_tbl9"
864+
DETAIL: Column lists cannot be specified in publications containing FOR TABLES IN SCHEMA elements.
865865
-- ok - only publish table with column list
866866
ALTER PUBLICATION testpub_tbl9 SET TABLE public.testpub_tbl7(a);
867867
-- failure - specify a schema when there is already a column list in the
868868
-- publication
869869
ALTER PUBLICATION testpub_tbl9 ADD TABLES IN SCHEMA public;
870-
ERROR: cannot add schema to the publication
871-
DETAIL: Schema cannot be added if any table that specifies column list is already part of the publication.
870+
ERROR: cannot add schema to publication "testpub_tbl9"
871+
DETAIL: Schemas cannot be added if any tables that specify a column list are already part of the publication.
872872
-- failure - cannot SET column list and schema together
873873
ALTER PUBLICATION testpub_tbl9 SET TABLES IN SCHEMA public, TABLE public.testpub_tbl7(a);
874-
ERROR: cannot use publication column list for relation "public.testpub_tbl7"
875-
DETAIL: Column list cannot be specified if any schema is part of the publication or specified in the list.
874+
ERROR: cannot use column list for relation "public.testpub_tbl7" in publication "testpub_tbl9"
875+
DETAIL: Column lists cannot be specified in publications containing FOR TABLES IN SCHEMA elements.
876876
-- ok - drop table
877877
ALTER PUBLICATION testpub_tbl9 DROP TABLE public.testpub_tbl7;
878878
-- failure - cannot ADD column list and schema together
879879
ALTER PUBLICATION testpub_tbl9 ADD TABLES IN SCHEMA public, TABLE public.testpub_tbl7(a);
880-
ERROR: cannot use publication column list for relation "public.testpub_tbl7"
881-
DETAIL: Column list cannot be specified if any schema is part of the publication or specified in the list.
880+
ERROR: cannot use column list for relation "public.testpub_tbl7" in publication "testpub_tbl9"
881+
DETAIL: Column lists cannot be specified in publications containing FOR TABLES IN SCHEMA elements.
882882
RESET client_min_messages;
883883
DROP TABLE testpub_tbl5, testpub_tbl6, testpub_tbl7, testpub_tbl8, testpub_tbl8_1;
884884
DROP PUBLICATION testpub_table_ins, testpub_fortable, testpub_fortable_insert, testpub_col_list, testpub_tbl9;
@@ -1009,8 +1009,8 @@ UPDATE rf_tbl_abcd_nopk SET a = 1;
10091009
ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=0);
10101010
-- fail - cannot use column list for partitioned table
10111011
ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk (a);
1012-
ERROR: cannot use publication column list for relation "rf_tbl_abcd_part_pk"
1013-
DETAIL: Column list cannot be used for a partitioned table when publish_via_partition_root is false.
1012+
ERROR: cannot use column list for relation "public.rf_tbl_abcd_part_pk" in publication "testpub6"
1013+
DETAIL: Column lists cannot be specified for partitioned tables when publish_via_partition_root is false.
10141014
-- ok - can use column list for partition
10151015
ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk_1 (a);
10161016
-- ok - "a" is a PK col

0 commit comments

Comments
 (0)