53
53
#include "utils/syscache.h"
54
54
#include "utils/varlena.h"
55
55
56
+
56
57
/*
57
58
* Information used to validate the columns in the row filter expression. See
58
59
* contain_invalid_rfcolumn_walker for details.
@@ -76,6 +77,7 @@ static void PublicationAddSchemas(Oid pubid, List *schemas, bool if_not_exists,
76
77
AlterPublicationStmt * stmt );
77
78
static void PublicationDropSchemas (Oid pubid , List * schemas , bool missing_ok );
78
79
80
+
79
81
static void
80
82
parse_publication_options (ParseState * pstate ,
81
83
List * options ,
@@ -125,7 +127,8 @@ parse_publication_options(ParseState *pstate,
125
127
if (!SplitIdentifierString (publish , ',' , & publish_list ))
126
128
ereport (ERROR ,
127
129
(errcode (ERRCODE_SYNTAX_ERROR ),
128
- errmsg ("invalid list syntax for \"publish\" option" )));
130
+ errmsg ("invalid list syntax in parameter \"%s\"" ,
131
+ "publish" )));
129
132
130
133
/* Process the option list. */
131
134
foreach (lc , publish_list )
@@ -143,7 +146,8 @@ parse_publication_options(ParseState *pstate,
143
146
else
144
147
ereport (ERROR ,
145
148
(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 )));
147
151
}
148
152
}
149
153
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)
444
448
}
445
449
446
450
/*
447
- * Check if the node contains any unallowed object. See
451
+ * Check if the node contains any disallowed object. Subroutine for
448
452
* check_simple_rowfilter_expr_walker.
449
453
*
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.
451
457
*/
452
458
static void
453
459
expr_allowed_in_node (Node * node , ParseState * pstate , char * * errdetail_msg )
@@ -678,10 +684,17 @@ TransformPubWhereClauses(List *tables, const char *queryString,
678
684
679
685
680
686
/*
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.
682
695
*/
683
696
static void
684
- CheckPubRelationColumnList (List * tables , const char * queryString ,
697
+ CheckPubRelationColumnList (char * pubname , List * tables ,
685
698
bool publish_schema , bool pubviaroot )
686
699
{
687
700
ListCell * lc ;
@@ -706,23 +719,24 @@ CheckPubRelationColumnList(List *tables, const char *queryString,
706
719
if (publish_schema )
707
720
ereport (ERROR ,
708
721
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\"" ,
710
723
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 ." ));
713
726
714
727
/*
715
728
* If the publication doesn't publish changes via the root partitioned
716
729
* 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.
718
731
*/
719
732
if (!pubviaroot &&
720
733
pri -> relation -> rd_rel -> relkind == RELKIND_PARTITIONED_TABLE )
721
734
ereport (ERROR ,
722
735
(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." ,
726
740
"publish_via_partition_root" )));
727
741
}
728
742
}
@@ -765,12 +779,10 @@ CreatePublication(ParseState *pstate, CreatePublicationStmt *stmt)
765
779
puboid = GetSysCacheOid1 (PUBLICATIONNAME , Anum_pg_publication_oid ,
766
780
CStringGetDatum (stmt -> pubname ));
767
781
if (OidIsValid (puboid ))
768
- {
769
782
ereport (ERROR ,
770
783
(errcode (ERRCODE_DUPLICATE_OBJECT ),
771
784
errmsg ("publication \"%s\" already exists" ,
772
785
stmt -> pubname )));
773
- }
774
786
775
787
/* Form a tuple. */
776
788
memset (values , 0 , sizeof (values ));
@@ -840,7 +852,7 @@ CreatePublication(ParseState *pstate, CreatePublicationStmt *stmt)
840
852
TransformPubWhereClauses (rels , pstate -> p_sourcetext ,
841
853
publish_via_partition_root );
842
854
843
- CheckPubRelationColumnList (rels , pstate -> p_sourcetext ,
855
+ CheckPubRelationColumnList (stmt -> pubname , rels ,
844
856
schemaidlist != NIL ,
845
857
publish_via_partition_root );
846
858
@@ -864,12 +876,10 @@ CreatePublication(ParseState *pstate, CreatePublicationStmt *stmt)
864
876
InvokeObjectPostCreateHook (PublicationRelationId , puboid , 0 );
865
877
866
878
if (wal_level != WAL_LEVEL_LOGICAL )
867
- {
868
879
ereport (WARNING ,
869
880
(errcode (ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE ),
870
881
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." )));
873
883
874
884
return myself ;
875
885
}
@@ -1110,7 +1120,7 @@ AlterPublicationTables(AlterPublicationStmt *stmt, HeapTuple tup,
1110
1120
1111
1121
publish_schema |= is_schema_publication (pubid );
1112
1122
1113
- CheckPubRelationColumnList (rels , queryString , publish_schema ,
1123
+ CheckPubRelationColumnList (stmt -> pubname , rels , publish_schema ,
1114
1124
pubform -> pubviaroot );
1115
1125
1116
1126
PublicationAddTables (pubid , rels , false, stmt );
@@ -1126,7 +1136,7 @@ AlterPublicationTables(AlterPublicationStmt *stmt, HeapTuple tup,
1126
1136
1127
1137
TransformPubWhereClauses (rels , queryString , pubform -> pubviaroot );
1128
1138
1129
- CheckPubRelationColumnList (rels , queryString , publish_schema ,
1139
+ CheckPubRelationColumnList (stmt -> pubname , rels , publish_schema ,
1130
1140
pubform -> pubviaroot );
1131
1141
1132
1142
/*
@@ -1299,8 +1309,9 @@ AlterPublicationSchemas(AlterPublicationStmt *stmt,
1299
1309
if (!heap_attisnull (coltuple , Anum_pg_publication_rel_prattrs , NULL ))
1300
1310
ereport (ERROR ,
1301
1311
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." ));
1304
1315
1305
1316
ReleaseSysCache (coltuple );
1306
1317
}
0 commit comments