diff --git a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c index 5ddc9e812e70..51a240ea6d8b 100644 --- a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c +++ b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c @@ -180,17 +180,6 @@ libpqrcv_connect(const char *conninfo, bool replication, bool logical, /* Tell the publisher to translate to our encoding */ keys[++i] = "client_encoding"; vals[i] = GetDatabaseEncodingName(); - - /* - * Force assorted GUC parameters to settings that ensure that the - * publisher will output data values in a form that is unambiguous - * to the subscriber. (We don't want to modify the subscriber's - * GUC settings, since that might surprise user-defined code - * running in the subscriber, such as triggers.) This should - * match what pg_dump does. - */ - keys[++i] = "options"; - vals[i] = "-c datestyle=ISO -c intervalstyle=postgres -c extra_float_digits=3"; } else { @@ -256,6 +245,38 @@ libpqrcv_connect(const char *conninfo, bool replication, bool logical, PQclear(res); } + /* + * Force assorted GUC parameters to settings that ensure that the + * publisher will output data values in a form that is unambiguous to the + * subscriber. (We don't want to modify the subscriber's GUC settings, + * since that might surprise user-defined code running in the subscriber, + * such as triggers.) This should match what pg_dump does. + */ + if (replication && logical) + { + const char *params[] = + {"datestyle", "intervalstyle", "extra_float_digits"}; + const char *values[] = {"ISO", "postgres", "3"}; + + for (int j = 0; j < lengthof(params); j++) + { + char sql[100]; + PGresult *res; + + sprintf(sql, "SET %s = %s", params[j], values[j]); + res = libpqsrv_exec(conn->streamConn, sql, + WAIT_EVENT_LIBPQWALRECEIVER_RECEIVE); + if (PQresultStatus(res) != PGRES_COMMAND_OK) + { + PQclear(res); + *err = psprintf(_("could not set %s: %s"), + params[j], pchomp(PQerrorMessage(conn->streamConn))); + goto bad_connection; + } + PQclear(res); + } + } + conn->logical = logical; return conn; diff --git a/src/test/subscription/t/001_rep_changes.pl b/src/test/subscription/t/001_rep_changes.pl index 430c1246d14c..9d08ae8b6413 100644 --- a/src/test/subscription/t/001_rep_changes.pl +++ b/src/test/subscription/t/001_rep_changes.pl @@ -438,17 +438,34 @@ 22.22|bar|2), 'update works with dropped subscriber column'); +# Verify that GUC settings supplied in the CONNECTION string take effect on +# the publisher's walsender. We do this by enabling log_disconnections in +# the CONNECTION string later and checking that the publisher's log contains a +# disconnection message. +# +# First, confirm that no such disconnection message appears before enabling +# log_disconnections. +$logfile = slurp_file($node_publisher->logfile, $log_location); +unlike( + $logfile, + qr/disconnection: session time:/, + 'log_disconnections has not been enabled yet'); + # check that change of connection string and/or publication list causes # restart of subscription workers. We check the state along with # application_name to ensure that the walsender is (re)started. # # Not all of these are registered as tests as we need to poll for a change # but the test suite will fail nonetheless when something goes wrong. +# +# Enable log_disconnections as the change of connection string, +# which is also for the above mentioned test of GUC settings passed through +# CONNECTION. my $oldpid = $node_publisher->safe_psql('postgres', "SELECT pid FROM pg_stat_replication WHERE application_name = 'tap_sub' AND state = 'streaming';" ); $node_subscriber->safe_psql('postgres', - "ALTER SUBSCRIPTION tap_sub CONNECTION '$publisher_connstr sslmode=disable'" + "ALTER SUBSCRIPTION tap_sub CONNECTION '$publisher_connstr options=''-c log_disconnections=on'''" ); $node_publisher->poll_query_until('postgres', "SELECT pid != $oldpid FROM pg_stat_replication WHERE application_name = 'tap_sub' AND state = 'streaming';" @@ -552,6 +569,15 @@ or die "Timed out while waiting for apply to restart after renaming SUBSCRIPTION"; +# Check that the expected disconnection message appears, +# which shows that log_disconnections=on from the CONNECTION string +# was correctly passed through to and honored by the walsender. +$logfile = slurp_file($node_publisher->logfile, $log_location); +like( + $logfile, + qr/disconnection: session time:/, + 'log_disconnections in CONNECTION string had effect on publisher\'s walsender'); + # check all the cleanup $node_subscriber->safe_psql('postgres', "DROP SUBSCRIPTION tap_sub_renamed");