diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c index 65710afd24..f74908401c 100644 --- a/src/backend/commands/subscriptioncmds.c +++ b/src/backend/commands/subscriptioncmds.c @@ -902,6 +902,7 @@ AlterSubscription_refresh(Subscription *sub, CopyData copy_data, qsort(subrel_local_oids, list_length(subrel_states), sizeof(Oid), oid_cmp); + /* Check whether we can allow copy of newly added relations. */ check_pub_table_subscribed(wrconn, sub->publications, copy_data, sub->origin, subrel_local_oids, list_length(subrel_states)); @@ -1858,10 +1859,16 @@ AlterSubscriptionOwner_oid(Oid subid, Oid newOwnerId) /* * Check and throw an error if the publisher has subscribed to the same table * from some other publisher. This check is required only if copydata is ON and - * the origin is local for ALTER SUBSCRIPTION ... REFRESH statement. This check - * need not be peformed on the tables that are already added as incremental - * sync for ready tables will happen through WAL and the origin of the data can - * be identified from the WAL records. + * the origin is local for CREATE SUBSCRIPTION and + * ALTER SUBSCRIPTION ... REFRESH statements to avoid replicating remote data + * from the publisher. + * + * This check need not be performed on the tables that are already added as + * incremental sync for such tables will happen through WAL and the origin of + * the data can be identified from the WAL records. + * + * subrel_local_oids contains the list of relation oids that are already + * present on the subscriber. */ static void check_pub_table_subscribed(WalReceiverConn *wrconn, List *publications, @@ -1911,6 +1918,7 @@ check_pub_table_subscribed(WalReceiverConn *wrconn, List *publications, relname = TextDatumGetCString(slot_getattr(slot, 2, &isnull)); Assert(!isnull); + /* Skip already added tables */ if (subrel_count) { RangeVar *rv; @@ -1930,11 +1938,6 @@ check_pub_table_subscribed(WalReceiverConn *wrconn, List *publications, ExecClearTuple(slot); - /* - * No need to throw an error for the tables that were already added, - * as the walsender will send the changes from WAL in case of tables - * in ready state. - */ if (!isnewtable) { pfree(nspname); @@ -1952,14 +1955,14 @@ check_pub_table_subscribed(WalReceiverConn *wrconn, List *publications, * XXX: For simplicity, we don't check whether the table has any data * or not. If the table doesn't have any data then we don't need to * distinguish between local and non-local data so we can avoid - * throwing error in that case. + * throwing an error in that case. */ ereport(ERROR, - errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - errmsg("table: \"%s.%s\" might have replicated data in the publisher", - nspname, relname), - errdetail("CREATE/ALTER SUBSCRIPTION with origin = local and copy_data = on is not allowed when the publisher might have replicated data."), - errhint("Use CREATE/ALTER SUBSCRIPTION with copy_data = off/force.")); + errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("could not replicate table \"%s.%s\"", + nspname, relname), + errdetail("CREATE/ALTER SUBSCRIPTION with origin = local and copy_data = on is not allowed when the publisher has subscribed same table."), + errhint("Use CREATE/ALTER SUBSCRIPTION with copy_data = off/force.")); } ExecDropSingleTupleTableSlot(slot);