diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c index 750d262fcca..0f54686b699 100644 --- a/src/backend/commands/subscriptioncmds.c +++ b/src/backend/commands/subscriptioncmds.c @@ -848,7 +848,7 @@ CreateSubscription(ParseState *pstate, CreateSubscriptionStmt *stmt, else ereport(WARNING, (errmsg("subscription was created, but is not connected"), - errhint("To initiate replication, you must manually create the replication slot, enable the subscription, and refresh the subscription."))); + errhint("To initiate replication, you must manually create the replication slot, enable the subscription, and alter the subscription to refresh publications."))); table_close(rel, RowExclusiveLock); @@ -1612,8 +1612,8 @@ AlterSubscription(ParseState *pstate, AlterSubscriptionStmt *stmt, errhint("Use ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false)."))); /* - * See ALTER_SUBSCRIPTION_REFRESH for details why this is - * not allowed. + * See ALTER_SUBSCRIPTION_REFRESH_PUBLICATION for details + * why this is not allowed. */ if (sub->twophasestate == LOGICALREP_TWOPHASE_STATE_ENABLED && opts.copy_data) ereport(ERROR, @@ -1667,8 +1667,8 @@ AlterSubscription(ParseState *pstate, AlterSubscriptionStmt *stmt, "ALTER SUBSCRIPTION ... DROP PUBLICATION ... WITH (refresh = false)"))); /* - * See ALTER_SUBSCRIPTION_REFRESH for details why this is - * not allowed. + * See ALTER_SUBSCRIPTION_REFRESH_PUBLICATION for details + * why this is not allowed. */ if (sub->twophasestate == LOGICALREP_TWOPHASE_STATE_ENABLED && opts.copy_data) ereport(ERROR, @@ -1692,12 +1692,13 @@ AlterSubscription(ParseState *pstate, AlterSubscriptionStmt *stmt, break; } - case ALTER_SUBSCRIPTION_REFRESH: + case ALTER_SUBSCRIPTION_REFRESH_PUBLICATION: { if (!sub->enabled) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - errmsg("ALTER SUBSCRIPTION ... REFRESH is not allowed for disabled subscriptions"))); + errmsg("%s is not allowed for disabled subscriptions", + "ALTER SUBSCRIPTION ... REFRESH PUBLICATION"))); parse_subscription_options(pstate, stmt->options, SUBOPT_COPY_DATA, &opts); @@ -1709,8 +1710,8 @@ AlterSubscription(ParseState *pstate, AlterSubscriptionStmt *stmt, * * But, having reached this two-phase commit "enabled" state * we must not allow any subsequent table initialization to - * occur. So the ALTER SUBSCRIPTION ... REFRESH is disallowed - * when the user had requested two_phase = on mode. + * occur. So the ALTER SUBSCRIPTION ... REFRESH PUBLICATION is + * disallowed when the user had requested two_phase = on mode. * * The exception to this restriction is when copy_data = * false, because when copy_data is false the tablesync will @@ -1722,10 +1723,10 @@ AlterSubscription(ParseState *pstate, AlterSubscriptionStmt *stmt, if (sub->twophasestate == LOGICALREP_TWOPHASE_STATE_ENABLED && opts.copy_data) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("ALTER SUBSCRIPTION ... REFRESH with copy_data is not allowed when two_phase is enabled"), - errhint("Use ALTER SUBSCRIPTION ... REFRESH with copy_data = false, or use DROP/CREATE SUBSCRIPTION."))); + errmsg("ALTER SUBSCRIPTION ... REFRESH PUBLICATION with copy_data is not allowed when two_phase is enabled"), + errhint("Use ALTER SUBSCRIPTION ... REFRESH PUBLICATION with copy_data = false, or use DROP/CREATE SUBSCRIPTION."))); - PreventInTransactionBlock(isTopLevel, "ALTER SUBSCRIPTION ... REFRESH"); + PreventInTransactionBlock(isTopLevel, "ALTER SUBSCRIPTION ... REFRESH PUBLICATION"); AlterSubscription_refresh(sub, opts.copy_data, NULL); @@ -2322,17 +2323,17 @@ AlterSubscriptionOwner_oid(Oid subid, Oid newOwnerId) * it's a partitioned table), from some other publishers. This check is * required in the following scenarios: * - * 1) For CREATE SUBSCRIPTION and ALTER SUBSCRIPTION ... REFRESH statements - * with "copy_data = true" and "origin = none": + * 1) For CREATE SUBSCRIPTION and ALTER SUBSCRIPTION ... REFRESH PUBLICATION + * statements with "copy_data = true" and "origin = none": * - Warn the user that data with an origin might have been copied. * - This check is skipped for tables already added, as incremental sync via * WAL allows origin tracking. The list of such tables is in * subrel_local_oids. * - * 2) For CREATE SUBSCRIPTION and ALTER SUBSCRIPTION ... REFRESH statements - * with "retain_dead_tuples = true" and "origin = any", and for ALTER - * SUBSCRIPTION statements that modify retain_dead_tuples or origin, or - * when the publisher's status changes (e.g., due to a connection string + * 2) For CREATE SUBSCRIPTION and ALTER SUBSCRIPTION ... REFRESH PUBLICATION + * statements with "retain_dead_tuples = true" and "origin = any", and for + * ALTER SUBSCRIPTION statements that modify retain_dead_tuples or origin, + * or when the publisher's status changes (e.g., due to a connection string * update): * - Warn the user that only conflict detection info for local changes on * the publisher is retained. Data from other origins may lack sufficient @@ -2390,13 +2391,13 @@ check_publications_origin(WalReceiverConn *wrconn, List *publications, appendStringInfoString(&cmd, ")\n"); /* - * In case of ALTER SUBSCRIPTION ... REFRESH, subrel_local_oids contains - * the list of relation oids that are already present on the subscriber. - * This check should be skipped for these tables if checking for table - * sync scenario. However, when handling the retain_dead_tuples scenario, - * ensure all tables are checked, as some existing tables may now include - * changes from other origins due to newly created subscriptions on the - * publisher. + * In case of ALTER SUBSCRIPTION ... REFRESH PUBLICATION, + * subrel_local_oids contains the list of relation oids that are already + * present on the subscriber. This check should be skipped for these + * tables if checking for table sync scenario. However, when handling the + * retain_dead_tuples scenario, ensure all tables are checked, as some + * existing tables may now include changes from other origins due to newly + * created subscriptions on the publisher. */ if (check_table_sync) { diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 21caf2d43bf..dc0c2886674 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -10987,7 +10987,7 @@ AlterSubscriptionStmt: AlterSubscriptionStmt *n = makeNode(AlterSubscriptionStmt); - n->kind = ALTER_SUBSCRIPTION_REFRESH; + n->kind = ALTER_SUBSCRIPTION_REFRESH_PUBLICATION; n->subname = $3; n->options = $6; $$ = (Node *) n; diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index dc09d1a3f03..4e445fe0cd7 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -4361,7 +4361,7 @@ typedef enum AlterSubscriptionType ALTER_SUBSCRIPTION_SET_PUBLICATION, ALTER_SUBSCRIPTION_ADD_PUBLICATION, ALTER_SUBSCRIPTION_DROP_PUBLICATION, - ALTER_SUBSCRIPTION_REFRESH, + ALTER_SUBSCRIPTION_REFRESH_PUBLICATION, ALTER_SUBSCRIPTION_ENABLED, ALTER_SUBSCRIPTION_SKIP, } AlterSubscriptionType; diff --git a/src/test/regress/expected/object_address.out b/src/test/regress/expected/object_address.out index fc42d418bf1..b026d38dcfb 100644 --- a/src/test/regress/expected/object_address.out +++ b/src/test/regress/expected/object_address.out @@ -50,7 +50,7 @@ CREATE PUBLICATION addr_pub_schema FOR TABLES IN SCHEMA addr_nsp; RESET client_min_messages; CREATE SUBSCRIPTION regress_addr_sub CONNECTION '' PUBLICATION bar WITH (connect = false, slot_name = NONE); WARNING: subscription was created, but is not connected -HINT: To initiate replication, you must manually create the replication slot, enable the subscription, and refresh the subscription. +HINT: To initiate replication, you must manually create the replication slot, enable the subscription, and alter the subscription to refresh publications. CREATE STATISTICS addr_nsp.gentable_stat ON a, b FROM addr_nsp.gentable; -- test some error cases SELECT pg_get_object_address('stone', '{}', '{}'); diff --git a/src/test/regress/expected/subscription.out b/src/test/regress/expected/subscription.out index c7f1266fc2f..327d1e7731f 100644 --- a/src/test/regress/expected/subscription.out +++ b/src/test/regress/expected/subscription.out @@ -31,7 +31,7 @@ ERROR: publication name "foo" used more than once -- ok CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false); WARNING: subscription was created, but is not connected -HINT: To initiate replication, you must manually create the replication slot, enable the subscription, and refresh the subscription. +HINT: To initiate replication, you must manually create the replication slot, enable the subscription, and alter the subscription to refresh publications. COMMENT ON SUBSCRIPTION regress_testsub IS 'test subscription'; SELECT obj_description(s.oid, 'pg_subscription') FROM pg_subscription s; obj_description @@ -102,19 +102,19 @@ ERROR: subscription with slot_name = NONE must also set enabled = false -- ok - with slot_name = NONE CREATE SUBSCRIPTION regress_testsub3 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, connect = false); WARNING: subscription was created, but is not connected -HINT: To initiate replication, you must manually create the replication slot, enable the subscription, and refresh the subscription. +HINT: To initiate replication, you must manually create the replication slot, enable the subscription, and alter the subscription to refresh publications. -- fail ALTER SUBSCRIPTION regress_testsub3 ENABLE; ERROR: cannot enable subscription that does not have a slot name ALTER SUBSCRIPTION regress_testsub3 REFRESH PUBLICATION; -ERROR: ALTER SUBSCRIPTION ... REFRESH is not allowed for disabled subscriptions +ERROR: ALTER SUBSCRIPTION ... REFRESH PUBLICATION is not allowed for disabled subscriptions -- fail - origin must be either none or any CREATE SUBSCRIPTION regress_testsub4 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, connect = false, origin = foo); ERROR: unrecognized origin value: "foo" -- now it works CREATE SUBSCRIPTION regress_testsub4 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, connect = false, origin = none); WARNING: subscription was created, but is not connected -HINT: To initiate replication, you must manually create the replication slot, enable the subscription, and refresh the subscription. +HINT: To initiate replication, you must manually create the replication slot, enable the subscription, and alter the subscription to refresh publications. \dRs+ regress_testsub4 List of subscriptions Name | Owner | Enabled | Publication | Binary | Streaming | Two-phase commit | Disable on error | Origin | Password required | Run as owner? | Failover | Retain dead tuples | Max retention duration | Retention active | Synchronous commit | Conninfo | Skip LSN @@ -253,7 +253,7 @@ ERROR: binary requires a Boolean value -- now it works CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, binary = true); WARNING: subscription was created, but is not connected -HINT: To initiate replication, you must manually create the replication slot, enable the subscription, and refresh the subscription. +HINT: To initiate replication, you must manually create the replication slot, enable the subscription, and alter the subscription to refresh publications. \dRs+ List of subscriptions Name | Owner | Enabled | Publication | Binary | Streaming | Two-phase commit | Disable on error | Origin | Password required | Run as owner? | Failover | Retain dead tuples | Max retention duration | Retention active | Synchronous commit | Conninfo | Skip LSN @@ -277,7 +277,7 @@ ERROR: streaming requires a Boolean value or "parallel" -- now it works CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, streaming = true); WARNING: subscription was created, but is not connected -HINT: To initiate replication, you must manually create the replication slot, enable the subscription, and refresh the subscription. +HINT: To initiate replication, you must manually create the replication slot, enable the subscription, and alter the subscription to refresh publications. \dRs+ List of subscriptions Name | Owner | Enabled | Publication | Binary | Streaming | Two-phase commit | Disable on error | Origin | Password required | Run as owner? | Failover | Retain dead tuples | Max retention duration | Retention active | Synchronous commit | Conninfo | Skip LSN @@ -342,7 +342,7 @@ DROP SUBSCRIPTION regress_testsub; CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION mypub WITH (connect = false, create_slot = false, copy_data = false); WARNING: subscription was created, but is not connected -HINT: To initiate replication, you must manually create the replication slot, enable the subscription, and refresh the subscription. +HINT: To initiate replication, you must manually create the replication slot, enable the subscription, and alter the subscription to refresh publications. ALTER SUBSCRIPTION regress_testsub ENABLE; -- fail - ALTER SUBSCRIPTION with refresh is not allowed in a transaction -- block or function @@ -352,7 +352,7 @@ ERROR: ALTER SUBSCRIPTION with refresh cannot run inside a transaction block END; BEGIN; ALTER SUBSCRIPTION regress_testsub REFRESH PUBLICATION; -ERROR: ALTER SUBSCRIPTION ... REFRESH cannot run inside a transaction block +ERROR: ALTER SUBSCRIPTION ... REFRESH PUBLICATION cannot run inside a transaction block END; CREATE FUNCTION func() RETURNS VOID AS $$ ALTER SUBSCRIPTION regress_testsub SET PUBLICATION mypub WITH (refresh = true) $$ LANGUAGE SQL; @@ -369,7 +369,7 @@ ERROR: two_phase requires a Boolean value -- now it works CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, two_phase = true); WARNING: subscription was created, but is not connected -HINT: To initiate replication, you must manually create the replication slot, enable the subscription, and refresh the subscription. +HINT: To initiate replication, you must manually create the replication slot, enable the subscription, and alter the subscription to refresh publications. \dRs+ List of subscriptions Name | Owner | Enabled | Publication | Binary | Streaming | Two-phase commit | Disable on error | Origin | Password required | Run as owner? | Failover | Retain dead tuples | Max retention duration | Retention active | Synchronous commit | Conninfo | Skip LSN @@ -391,7 +391,7 @@ DROP SUBSCRIPTION regress_testsub; -- two_phase and streaming are compatible. CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, streaming = true, two_phase = true); WARNING: subscription was created, but is not connected -HINT: To initiate replication, you must manually create the replication slot, enable the subscription, and refresh the subscription. +HINT: To initiate replication, you must manually create the replication slot, enable the subscription, and alter the subscription to refresh publications. \dRs+ List of subscriptions Name | Owner | Enabled | Publication | Binary | Streaming | Two-phase commit | Disable on error | Origin | Password required | Run as owner? | Failover | Retain dead tuples | Max retention duration | Retention active | Synchronous commit | Conninfo | Skip LSN @@ -407,7 +407,7 @@ ERROR: disable_on_error requires a Boolean value -- now it works CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, disable_on_error = false); WARNING: subscription was created, but is not connected -HINT: To initiate replication, you must manually create the replication slot, enable the subscription, and refresh the subscription. +HINT: To initiate replication, you must manually create the replication slot, enable the subscription, and alter the subscription to refresh publications. \dRs+ List of subscriptions Name | Owner | Enabled | Publication | Binary | Streaming | Two-phase commit | Disable on error | Origin | Password required | Run as owner? | Failover | Retain dead tuples | Max retention duration | Retention active | Synchronous commit | Conninfo | Skip LSN @@ -431,7 +431,7 @@ ERROR: retain_dead_tuples requires a Boolean value -- ok CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, retain_dead_tuples = false); WARNING: subscription was created, but is not connected -HINT: To initiate replication, you must manually create the replication slot, enable the subscription, and refresh the subscription. +HINT: To initiate replication, you must manually create the replication slot, enable the subscription, and alter the subscription to refresh publications. \dRs+ List of subscriptions Name | Owner | Enabled | Publication | Binary | Streaming | Two-phase commit | Disable on error | Origin | Password required | Run as owner? | Failover | Retain dead tuples | Max retention duration | Retention active | Synchronous commit | Conninfo | Skip LSN @@ -448,7 +448,7 @@ ERROR: max_retention_duration requires an integer value CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, max_retention_duration = 1000); NOTICE: max_retention_duration is ineffective when retain_dead_tuples is disabled WARNING: subscription was created, but is not connected -HINT: To initiate replication, you must manually create the replication slot, enable the subscription, and refresh the subscription. +HINT: To initiate replication, you must manually create the replication slot, enable the subscription, and alter the subscription to refresh publications. \dRs+ List of subscriptions Name | Owner | Enabled | Publication | Binary | Streaming | Two-phase commit | Disable on error | Origin | Password required | Run as owner? | Failover | Retain dead tuples | Max retention duration | Retention active | Synchronous commit | Conninfo | Skip LSN @@ -492,7 +492,7 @@ GRANT CREATE ON DATABASE REGRESSION TO regress_subscription_user3; SET SESSION AUTHORIZATION regress_subscription_user3; CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist password=regress_fakepassword' PUBLICATION testpub WITH (connect = false); WARNING: subscription was created, but is not connected -HINT: To initiate replication, you must manually create the replication slot, enable the subscription, and refresh the subscription. +HINT: To initiate replication, you must manually create the replication slot, enable the subscription, and alter the subscription to refresh publications. -- we cannot give the subscription away to some random user ALTER SUBSCRIPTION regress_testsub OWNER TO regress_subscription_user; ERROR: must be able to SET ROLE "regress_subscription_user"