#include "utils/syscache.h"
#include "utils/varlena.h"
+
/*
* Information used to validate the columns in the row filter expression. See
* contain_invalid_rfcolumn_walker for details.
AlterPublicationStmt *stmt);
static void PublicationDropSchemas(Oid pubid, List *schemas, bool missing_ok);
+
static void
parse_publication_options(ParseState *pstate,
List *options,
if (!SplitIdentifierString(publish, ',', &publish_list))
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("invalid list syntax for \"publish\" option")));
+ errmsg("invalid list syntax in parameter \"%s\"",
+ "publish")));
/* Process the option list. */
foreach(lc, publish_list)
else
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("unrecognized \"publish\" value: \"%s\"", publish_opt)));
+ errmsg("unrecognized value for publication option \"%s\": \"%s\"",
+ "publish", publish_opt)));
}
}
else if (strcmp(defel->defname, "publish_via_partition_root") == 0)
}
/*
- * Check if the node contains any unallowed object. See
+ * Check if the node contains any disallowed object. Subroutine for
* check_simple_rowfilter_expr_walker.
*
- * Returns the error detail message in errdetail_msg for unallowed expressions.
+ * If a disallowed object is found, *errdetail_msg is set to a (possibly
+ * translated) message to use as errdetail. If none, *errdetail_msg is not
+ * modified.
*/
static void
expr_allowed_in_node(Node *node, ParseState *pstate, char **errdetail_msg)
/*
- * Check the publication column lists expression for all relations in the list.
+ * Given a list of tables that are going to be added to a publication,
+ * verify that they fulfill the necessary preconditions, namely: no tables
+ * have a column list if any schema is published; and partitioned tables do
+ * not have column lists if publish_via_partition_root is not set.
+ *
+ * 'publish_schema' indicates that the publication contains any TABLES IN
+ * SCHEMA elements (newly added in this command, or preexisting).
+ * 'pubviaroot' is the value of publish_via_partition_root.
*/
static void
-CheckPubRelationColumnList(List *tables, const char *queryString,
+CheckPubRelationColumnList(char *pubname, List *tables,
bool publish_schema, bool pubviaroot)
{
ListCell *lc;
if (publish_schema)
ereport(ERROR,
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("cannot use publication column list for relation \"%s.%s\"",
+ errmsg("cannot use column list for relation \"%s.%s\" in publication \"%s\"",
get_namespace_name(RelationGetNamespace(pri->relation)),
- RelationGetRelationName(pri->relation)),
- errdetail("Column list cannot be specified if any schema is part of the publication or specified in the list."));
+ RelationGetRelationName(pri->relation), pubname),
+ errdetail("Column lists cannot be specified in publications containing FOR TABLES IN SCHEMA elements."));
/*
* If the publication doesn't publish changes via the root partitioned
* table, the partition's column list will be used. So disallow using
- * the column list on partitioned table in this case.
+ * a column list on the partitioned table in this case.
*/
if (!pubviaroot &&
pri->relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("cannot use publication column list for relation \"%s\"",
- RelationGetRelationName(pri->relation)),
- errdetail("Column list cannot be used for a partitioned table when %s is false.",
+ errmsg("cannot use column list for relation \"%s.%s\" in publication \"%s\"",
+ get_namespace_name(RelationGetNamespace(pri->relation)),
+ RelationGetRelationName(pri->relation), pubname),
+ errdetail("Column lists cannot be specified for partitioned tables when %s is false.",
"publish_via_partition_root")));
}
}
puboid = GetSysCacheOid1(PUBLICATIONNAME, Anum_pg_publication_oid,
CStringGetDatum(stmt->pubname));
if (OidIsValid(puboid))
- {
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("publication \"%s\" already exists",
stmt->pubname)));
- }
/* Form a tuple. */
memset(values, 0, sizeof(values));
TransformPubWhereClauses(rels, pstate->p_sourcetext,
publish_via_partition_root);
- CheckPubRelationColumnList(rels, pstate->p_sourcetext,
+ CheckPubRelationColumnList(stmt->pubname, rels,
schemaidlist != NIL,
publish_via_partition_root);
InvokeObjectPostCreateHook(PublicationRelationId, puboid, 0);
if (wal_level != WAL_LEVEL_LOGICAL)
- {
ereport(WARNING,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("wal_level is insufficient to publish logical changes"),
- errhint("Set wal_level to logical before creating subscriptions.")));
- }
+ errhint("Set wal_level to \"logical\" before creating subscriptions.")));
return myself;
}
publish_schema |= is_schema_publication(pubid);
- CheckPubRelationColumnList(rels, queryString, publish_schema,
+ CheckPubRelationColumnList(stmt->pubname, rels, publish_schema,
pubform->pubviaroot);
PublicationAddTables(pubid, rels, false, stmt);
TransformPubWhereClauses(rels, queryString, pubform->pubviaroot);
- CheckPubRelationColumnList(rels, queryString, publish_schema,
+ CheckPubRelationColumnList(stmt->pubname, rels, publish_schema,
pubform->pubviaroot);
/*
if (!heap_attisnull(coltuple, Anum_pg_publication_rel_prattrs, NULL))
ereport(ERROR,
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("cannot add schema to the publication"),
- errdetail("Schema cannot be added if any table that specifies column list is already part of the publication."));
+ errmsg("cannot add schema to publication \"%s\"",
+ stmt->pubname),
+ errdetail("Schemas cannot be added if any tables that specify a column list are already part of the publication."));
ReleaseSysCache(coltuple);
}
CREATE PUBLICATION testpub_xxx WITH (foo);
ERROR: unrecognized publication parameter: "foo"
CREATE PUBLICATION testpub_xxx WITH (publish = 'cluster, vacuum');
-ERROR: unrecognized "publish" value: "cluster"
+ERROR: unrecognized value for publication option "publish": "cluster"
CREATE PUBLICATION testpub_xxx WITH (publish_via_partition_root = 'true', publish_via_partition_root = '0');
ERROR: conflicting or redundant options
LINE 1: ...ub_xxx WITH (publish_via_partition_root = 'true', publish_vi...
SET client_min_messages = 'ERROR';
-- failure - cannot use column list and schema together
CREATE PUBLICATION testpub_tbl9 FOR TABLES IN SCHEMA public, TABLE public.testpub_tbl7(a);
-ERROR: cannot use publication column list for relation "public.testpub_tbl7"
-DETAIL: Column list cannot be specified if any schema is part of the publication or specified in the list.
+ERROR: cannot use column list for relation "public.testpub_tbl7" in publication "testpub_tbl9"
+DETAIL: Column lists cannot be specified in publications containing FOR TABLES IN SCHEMA elements.
-- ok - only publish schema
CREATE PUBLICATION testpub_tbl9 FOR TABLES IN SCHEMA public;
-- failure - add a table with column list when there is already a schema in the
-- publication
ALTER PUBLICATION testpub_tbl9 ADD TABLE public.testpub_tbl7(a);
-ERROR: cannot use publication column list for relation "public.testpub_tbl7"
-DETAIL: Column list cannot be specified if any schema is part of the publication or specified in the list.
+ERROR: cannot use column list for relation "public.testpub_tbl7" in publication "testpub_tbl9"
+DETAIL: Column lists cannot be specified in publications containing FOR TABLES IN SCHEMA elements.
-- ok - only publish table with column list
ALTER PUBLICATION testpub_tbl9 SET TABLE public.testpub_tbl7(a);
-- failure - specify a schema when there is already a column list in the
-- publication
ALTER PUBLICATION testpub_tbl9 ADD TABLES IN SCHEMA public;
-ERROR: cannot add schema to the publication
-DETAIL: Schema cannot be added if any table that specifies column list is already part of the publication.
+ERROR: cannot add schema to publication "testpub_tbl9"
+DETAIL: Schemas cannot be added if any tables that specify a column list are already part of the publication.
-- failure - cannot SET column list and schema together
ALTER PUBLICATION testpub_tbl9 SET TABLES IN SCHEMA public, TABLE public.testpub_tbl7(a);
-ERROR: cannot use publication column list for relation "public.testpub_tbl7"
-DETAIL: Column list cannot be specified if any schema is part of the publication or specified in the list.
+ERROR: cannot use column list for relation "public.testpub_tbl7" in publication "testpub_tbl9"
+DETAIL: Column lists cannot be specified in publications containing FOR TABLES IN SCHEMA elements.
-- ok - drop table
ALTER PUBLICATION testpub_tbl9 DROP TABLE public.testpub_tbl7;
-- failure - cannot ADD column list and schema together
ALTER PUBLICATION testpub_tbl9 ADD TABLES IN SCHEMA public, TABLE public.testpub_tbl7(a);
-ERROR: cannot use publication column list for relation "public.testpub_tbl7"
-DETAIL: Column list cannot be specified if any schema is part of the publication or specified in the list.
+ERROR: cannot use column list for relation "public.testpub_tbl7" in publication "testpub_tbl9"
+DETAIL: Column lists cannot be specified in publications containing FOR TABLES IN SCHEMA elements.
RESET client_min_messages;
DROP TABLE testpub_tbl5, testpub_tbl6, testpub_tbl7, testpub_tbl8, testpub_tbl8_1;
DROP PUBLICATION testpub_table_ins, testpub_fortable, testpub_fortable_insert, testpub_col_list, testpub_tbl9;
ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=0);
-- fail - cannot use column list for partitioned table
ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk (a);
-ERROR: cannot use publication column list for relation "rf_tbl_abcd_part_pk"
-DETAIL: Column list cannot be used for a partitioned table when publish_via_partition_root is false.
+ERROR: cannot use column list for relation "public.rf_tbl_abcd_part_pk" in publication "testpub6"
+DETAIL: Column lists cannot be specified for partitioned tables when publish_via_partition_root is false.
-- ok - can use column list for partition
ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk_1 (a);
-- ok - "a" is a PK col