Skip to content

Commit 4148c8b

Browse files
alvherreHou zj
andcommitted
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy