Fwd: [Bug] Logical Replication failing if the DateStyle is different in Publisher & Subscriber

Started by Sadhuprasad Patroabout 4 years ago35 messages
#1Sadhuprasad Patro
b.sadhu@gmail.com

Hi All,

Publisher 'DateStyle' is set as "SQL, MDY", whereas in Subscriber as
"SQL, DMY", the logical replication is not working...

From Publisher:
postgres=# INSERT INTO calendar VALUES ('07-18-1036', '1'), ('05-15-1135', '1');
INSERT 0 2

Getting below error in the subscriber log file,
2021-10-14 00:59:23.067 PDT [38262] ERROR: date/time field value out
of range: "07/18/1036"
2021-10-14 00:59:23.067 PDT [38262] HINT: Perhaps you need a
different "datestyle" setting.

Is this an expected behavior?

Thanks & Regards
SadhuPrasad
http://www.EnterpriseDB.com/

#2Dilip Kumar
dilipbalaut@gmail.com
In reply to: Sadhuprasad Patro (#1)
Re: [Bug] Logical Replication failing if the DateStyle is different in Publisher & Subscriber

On Thu, Oct 14, 2021 at 3:48 PM Sadhuprasad Patro <b.sadhu@gmail.com> wrote:

Hi All,

Publisher 'DateStyle' is set as "SQL, MDY", whereas in Subscriber as
"SQL, DMY", the logical replication is not working...

From Publisher:
postgres=# INSERT INTO calendar VALUES ('07-18-1036', '1'), ('05-15-1135', '1');
INSERT 0 2

Getting below error in the subscriber log file,
2021-10-14 00:59:23.067 PDT [38262] ERROR: date/time field value out
of range: "07/18/1036"
2021-10-14 00:59:23.067 PDT [38262] HINT: Perhaps you need a
different "datestyle" setting.

Is this an expected behavior?

Looks like a problem to me, I think for fixing this, on logical
replication connection always set subscriber's DateStlyle, with that
the walsender will always send the data in the same DateStyle that
worker understands and then we are good.

--
Regards,
Dilip Kumar
EnterpriseDB: http://www.enterprisedb.com

#3Japin Li
japinli@hotmail.com
In reply to: Dilip Kumar (#2)
1 attachment(s)
Re: [Bug] Logical Replication failing if the DateStyle is different in Publisher & Subscriber

On Thu, 14 Oct 2021 at 19:49, Dilip Kumar <dilipbalaut@gmail.com> wrote:

On Thu, Oct 14, 2021 at 3:48 PM Sadhuprasad Patro <b.sadhu@gmail.com> wrote:

Hi All,

Publisher 'DateStyle' is set as "SQL, MDY", whereas in Subscriber as
"SQL, DMY", the logical replication is not working...

From Publisher:
postgres=# INSERT INTO calendar VALUES ('07-18-1036', '1'), ('05-15-1135', '1');
INSERT 0 2

Getting below error in the subscriber log file,
2021-10-14 00:59:23.067 PDT [38262] ERROR: date/time field value out
of range: "07/18/1036"
2021-10-14 00:59:23.067 PDT [38262] HINT: Perhaps you need a
different "datestyle" setting.

Is this an expected behavior?

Looks like a problem to me, I think for fixing this, on logical
replication connection always set subscriber's DateStlyle, with that
the walsender will always send the data in the same DateStyle that
worker understands and then we are good.

Right! Attached fix it.

--
Regrads,
Japin Li.
ChengDu WenWu Information Technology Co.,Ltd.

Attachments:

fix-logical-replication-failing-when-in-different-datestyle.patchtext/x-patchDownload
diff --git a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
index 5c6e56a5b2..81cf9e30d7 100644
--- a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
+++ b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
@@ -30,6 +30,7 @@
 #include "pqexpbuffer.h"
 #include "replication/walreceiver.h"
 #include "utils/builtins.h"
+#include "utils/guc.h"
 #include "utils/memutils.h"
 #include "utils/pg_lsn.h"
 #include "utils/tuplestore.h"
@@ -218,6 +219,7 @@ libpqrcv_connect(const char *conninfo, bool logical, const char *appname,
 	if (logical)
 	{
 		PGresult   *res;
+		const char *datestyle;
 
 		res = libpqrcv_PQexec(conn->streamConn,
 							  ALWAYS_SECURE_SEARCH_PATH_SQL);
@@ -229,6 +231,23 @@ libpqrcv_connect(const char *conninfo, bool logical, const char *appname,
 							pchomp(PQerrorMessage(conn->streamConn)))));
 		}
 		PQclear(res);
+
+		datestyle = GetConfigOption("datestyle", true, true);
+		if (datestyle != NULL) {
+			char *sql;
+
+			sql = psprintf("SELECT pg_catalog.set_config('datestyle', '%s', false);", datestyle);
+			res = libpqrcv_PQexec(conn->streamConn, sql);
+			if (PQresultStatus(res) != PGRES_TUPLES_OK)
+			{
+				PQclear(res);
+				ereport(ERROR,
+						(errmsg("could not set datestyle: %s",
+								pchomp(PQerrorMessage(conn->streamConn)))));
+			}
+			PQclear(res);
+			pfree(sql);
+		}
 	}
 
 	conn->logical = logical;
#4Japin Li
japinli@hotmail.com
In reply to: Japin Li (#3)
1 attachment(s)
Re: [Bug] Logical Replication failing if the DateStyle is different in Publisher & Subscriber

On Sat, 16 Oct 2021 at 22:42, Japin Li <japinli@hotmail.com> wrote:

On Thu, 14 Oct 2021 at 19:49, Dilip Kumar <dilipbalaut@gmail.com> wrote:

On Thu, Oct 14, 2021 at 3:48 PM Sadhuprasad Patro <b.sadhu@gmail.com> wrote:

Hi All,

Publisher 'DateStyle' is set as "SQL, MDY", whereas in Subscriber as
"SQL, DMY", the logical replication is not working...

From Publisher:
postgres=# INSERT INTO calendar VALUES ('07-18-1036', '1'), ('05-15-1135', '1');
INSERT 0 2

Getting below error in the subscriber log file,
2021-10-14 00:59:23.067 PDT [38262] ERROR: date/time field value out
of range: "07/18/1036"
2021-10-14 00:59:23.067 PDT [38262] HINT: Perhaps you need a
different "datestyle" setting.

Is this an expected behavior?

Looks like a problem to me, I think for fixing this, on logical
replication connection always set subscriber's DateStlyle, with that
the walsender will always send the data in the same DateStyle that
worker understands and then we are good.

Right! Attached fix it.

Add a test case in subscription/t/100_bugs.pl. Please consider the v2 patch
for review.

--
Regrads,
Japin Li.
ChengDu WenWu Information Technology Co.,Ltd.

Attachments:

v2-fix-logical-replication-failing-when-in-different-datestyle.patchtext/x-patchDownload
diff --git a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
index 5c6e56a5b2..81cf9e30d7 100644
--- a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
+++ b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
@@ -30,6 +30,7 @@
 #include "pqexpbuffer.h"
 #include "replication/walreceiver.h"
 #include "utils/builtins.h"
+#include "utils/guc.h"
 #include "utils/memutils.h"
 #include "utils/pg_lsn.h"
 #include "utils/tuplestore.h"
@@ -218,6 +219,7 @@ libpqrcv_connect(const char *conninfo, bool logical, const char *appname,
 	if (logical)
 	{
 		PGresult   *res;
+		const char *datestyle;
 
 		res = libpqrcv_PQexec(conn->streamConn,
 							  ALWAYS_SECURE_SEARCH_PATH_SQL);
@@ -229,6 +231,23 @@ libpqrcv_connect(const char *conninfo, bool logical, const char *appname,
 							pchomp(PQerrorMessage(conn->streamConn)))));
 		}
 		PQclear(res);
+
+		datestyle = GetConfigOption("datestyle", true, true);
+		if (datestyle != NULL) {
+			char *sql;
+
+			sql = psprintf("SELECT pg_catalog.set_config('datestyle', '%s', false);", datestyle);
+			res = libpqrcv_PQexec(conn->streamConn, sql);
+			if (PQresultStatus(res) != PGRES_TUPLES_OK)
+			{
+				PQclear(res);
+				ereport(ERROR,
+						(errmsg("could not set datestyle: %s",
+								pchomp(PQerrorMessage(conn->streamConn)))));
+			}
+			PQclear(res);
+			pfree(sql);
+		}
 	}
 
 	conn->logical = logical;
diff --git a/src/test/subscription/t/100_bugs.pl b/src/test/subscription/t/100_bugs.pl
index baa4a90771..a88a61df41 100644
--- a/src/test/subscription/t/100_bugs.pl
+++ b/src/test/subscription/t/100_bugs.pl
@@ -6,7 +6,7 @@ use strict;
 use warnings;
 use PostgresNode;
 use TestLib;
-use Test::More tests => 5;
+use Test::More tests => 6;
 
 # Bug #15114
 
@@ -224,3 +224,44 @@ $node_sub->safe_psql('postgres', "DROP TABLE tab1");
 $node_pub->stop('fast');
 $node_pub_sub->stop('fast');
 $node_sub->stop('fast');
+
+# Verify different datestyle between publisher and subscriber.
+$node_publisher = PostgresNode->new('datestyle_publisher');
+$node_publisher->init(allows_streaming => 'logical');
+$node_publisher->append_conf('postgresql.conf',
+	"datestyle = 'SQL, MDY'");
+$node_publisher->start;
+
+$node_subscriber = PostgresNode->new('datestyle_subscriber');
+$node_subscriber->init(allows_streaming => 'logical');
+$node_subscriber->append_conf('postgresql.conf',
+	"datestyle = 'SQL, DMY'");
+$node_subscriber->start;
+
+$node_publisher->safe_psql('postgres',
+	"CREATE TABLE tab_rep(a date)");
+$node_publisher->safe_psql('postgres',
+	"INSERT INTO tab_rep VALUES ('07-18-2021'), ('05-15-2018')");
+
+$node_subscriber->safe_psql('postgres',
+	"CREATE TABLE tab_rep(a date)");
+
+# Setup logical replication
+my $node_publisher_connstr = $node_publisher->connstr . ' dbname=postgres';
+$node_publisher->safe_psql('postgres',
+	"CREATE PUBLICATION tab_pub FOR ALL TABLES");
+$node_subscriber->safe_psql('postgres',
+	"CREATE SUBSCRIPTION tab_sub CONNECTION '$node_publisher_connstr' PUBLICATION tab_pub");
+
+$node_publisher->wait_for_catchup('tab_sub');
+
+my $result = $node_subscriber->safe_psql('postgres',
+	"SELECT count(*) FROM tab_rep");
+is($result, qq(2), 'failed to replication date from different datestyle');
+
+# Clean up the tables on both publisher and subscriber as we don't need them
+$node_publisher->safe_psql('postgres', 'DROP TABLE tab_rep');
+$node_subscriber->safe_psql('postgres', 'DROP TABLE tab_rep');
+
+$node_publisher->stop('fast');
+$node_subscriber->stop('fast');
#5Sadhuprasad Patro
b.sadhu@gmail.com
In reply to: Japin Li (#4)
Re: [Bug] Logical Replication failing if the DateStyle is different in Publisher & Subscriber

Add a test case in subscription/t/100_bugs.pl. Please consider the v2 patch
for review.

Reviewed and tested the patch, it works fine... There are some
trailing spaces present in the newly added code lines, which needs to
be corrected...
Doing some further testing with different datestyles, will update further...

Thanks & Regards
SadhuPrasad
EnterpriseDB: http://www.enterprisedb.com

#6Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Dilip Kumar (#2)
Re: [Bug] Logical Replication failing if the DateStyle is different in Publisher & Subscriber

On Thu, Oct 14, 2021 at 8:50 PM Dilip Kumar <dilipbalaut@gmail.com> wrote:

On Thu, Oct 14, 2021 at 3:48 PM Sadhuprasad Patro <b.sadhu@gmail.com> wrote:

Hi All,

Publisher 'DateStyle' is set as "SQL, MDY", whereas in Subscriber as
"SQL, DMY", the logical replication is not working...

From Publisher:
postgres=# INSERT INTO calendar VALUES ('07-18-1036', '1'), ('05-15-1135', '1');
INSERT 0 2

Getting below error in the subscriber log file,
2021-10-14 00:59:23.067 PDT [38262] ERROR: date/time field value out
of range: "07/18/1036"
2021-10-14 00:59:23.067 PDT [38262] HINT: Perhaps you need a
different "datestyle" setting.

Is this an expected behavior?

Looks like a problem to me, I think for fixing this, on logical
replication connection always set subscriber's DateStlyle, with that
the walsender will always send the data in the same DateStyle that
worker understands and then we are good.

+1

Probably the same is true for IntervalStyle? If the publisher sets
'sql_standard', the subscriber sets 'postgres', and an interval value
'-1 11:22:33' is inserted, these two nodes have different data:

* Publisher
=# set intervalstyle to 'postgres'; select * from test;
i
-------------------
-1 days -11:22:33
(1 row)

* Subscriber
=# set intervalstyle to 'postgres'; select * from test;
i
-------------------
-1 days +11:22:33
(1 row)

Regards,

--
Masahiko Sawada
EDB: https://www.enterprisedb.com/

#7Tom Lane
tgl@sss.pgh.pa.us
In reply to: Masahiko Sawada (#6)
Re: [Bug] Logical Replication failing if the DateStyle is different in Publisher & Subscriber

Masahiko Sawada <sawada.mshk@gmail.com> writes:

On Thu, Oct 14, 2021 at 8:50 PM Dilip Kumar <dilipbalaut@gmail.com> wrote:

Looks like a problem to me, I think for fixing this, on logical
replication connection always set subscriber's DateStlyle, with that
the walsender will always send the data in the same DateStyle that
worker understands and then we are good.

+1

An alternative that wouldn't require a network round trip is for the
publisher to set its own datestyle to ISO/YMD. I'm pretty sure that
will be interpreted correctly regardless of the receiver's datestyle.

Probably the same is true for IntervalStyle?

Not sure if an equivalent solution applies to intervals ...

regards, tom lane

#8Tom Lane
tgl@sss.pgh.pa.us
In reply to: Tom Lane (#7)
Re: [Bug] Logical Replication failing if the DateStyle is different in Publisher & Subscriber

I wrote:

An alternative that wouldn't require a network round trip is for the
publisher to set its own datestyle to ISO/YMD. I'm pretty sure that
will be interpreted correctly regardless of the receiver's datestyle.

Ah ... see postgres_fdw's set_transmission_modes(). I think we want
to copy that logic not invent some other way to do it.

regards, tom lane

#9Michael Paquier
michael@paquier.xyz
In reply to: Tom Lane (#8)
Re: [Bug] Logical Replication failing if the DateStyle is different in Publisher & Subscriber

On Sun, Oct 17, 2021 at 11:41:35PM -0400, Tom Lane wrote:

Ah ... see postgres_fdw's set_transmission_modes(). I think we want
to copy that logic not invent some other way to do it.

dblink.c has something similar as of applyRemoteGucs(), except that it
does not do extra_float_digits. It would be nice to avoid more
duplication for those things, at least on HEAD. On the top of my
head, don't we have something similar for parallel workers when
passing down GUCs from the leader?
--
Michael

#10Japin Li
japinli@hotmail.com
In reply to: Sadhuprasad Patro (#5)
Re: [Bug] Logical Replication failing if the DateStyle is different in Publisher & Subscriber

On Mon, 18 Oct 2021 at 11:14, Sadhuprasad Patro <b.sadhu@gmail.com> wrote:

Add a test case in subscription/t/100_bugs.pl. Please consider the v2 patch
for review.

Reviewed and tested the patch, it works fine... There are some
trailing spaces present in the newly added code lines, which needs to
be corrected...
Doing some further testing with different datestyles, will update further...

Thanks for your review and test! As Tom Lane said, the postgres_fdw has the similar
things, I will update the patch later.

--
Regrads,
Japin Li.
ChengDu WenWu Information Technology Co.,Ltd.

#11Japin Li
japinli@hotmail.com
In reply to: Michael Paquier (#9)
Re: [Bug] Logical Replication failing if the DateStyle is different in Publisher & Subscriber

On Mon, 18 Oct 2021 at 11:59, Michael Paquier <michael@paquier.xyz> wrote:

On Sun, Oct 17, 2021 at 11:41:35PM -0400, Tom Lane wrote:

Ah ... see postgres_fdw's set_transmission_modes(). I think we want
to copy that logic not invent some other way to do it.

dblink.c has something similar as of applyRemoteGucs(), except that it
does not do extra_float_digits. It would be nice to avoid more
duplication for those things, at least on HEAD. On the top of my
head, don't we have something similar for parallel workers when
passing down GUCs from the leader?

Since it will be used in more than one places. IMO, we can implement it in core.
Any thoughts?

--
Regrads,
Japin Li.
ChengDu WenWu Information Technology Co.,Ltd.

#12Japin Li
japinli@hotmail.com
In reply to: Tom Lane (#8)
Re: [Bug] Logical Replication failing if the DateStyle is different in Publisher & Subscriber

On Mon, 18 Oct 2021 at 11:41, Tom Lane <tgl@sss.pgh.pa.us> wrote:

I wrote:

An alternative that wouldn't require a network round trip is for the
publisher to set its own datestyle to ISO/YMD. I'm pretty sure that
will be interpreted correctly regardless of the receiver's datestyle.

Ah ... see postgres_fdw's set_transmission_modes(). I think we want
to copy that logic not invent some other way to do it.

Thanks for your remention. As Michael Paquier side, dblink also uses the
similar logical. I will read them then update the patch.

--
Regrads,
Japin Li.
ChengDu WenWu Information Technology Co.,Ltd.

#13Tom Lane
tgl@sss.pgh.pa.us
In reply to: Japin Li (#11)
Re: [Bug] Logical Replication failing if the DateStyle is different in Publisher & Subscriber

Japin Li <japinli@hotmail.com> writes:

On Mon, 18 Oct 2021 at 11:59, Michael Paquier <michael@paquier.xyz> wrote:

dblink.c has something similar as of applyRemoteGucs(), except that it
does not do extra_float_digits. It would be nice to avoid more
duplication for those things, at least on HEAD. On the top of my
head, don't we have something similar for parallel workers when
passing down GUCs from the leader?

Since it will be used in more than one places. IMO, we can implement it in core.
Any thoughts?

It's not going to be the same code everywhere. A logrep sender won't
have a need to save-and-restore the settings like postgres_fdw does,
AFAICS. Also, now that I look at it, dblink is doing the opposite
thing of absorbing the sender's values.

It would be good I guess to have some central notion of which
variables ought to be set to what, but I'm not sure how to
mechanize that given the need for different behaviors.

regards, tom lane

#14Japin Li
japinli@hotmail.com
In reply to: Tom Lane (#13)
1 attachment(s)
Re: [Bug] Logical Replication failing if the DateStyle is different in Publisher & Subscriber

On Mon, 18 Oct 2021 at 12:17, Tom Lane <tgl@sss.pgh.pa.us> wrote:

Japin Li <japinli@hotmail.com> writes:

On Mon, 18 Oct 2021 at 11:59, Michael Paquier <michael@paquier.xyz> wrote:

dblink.c has something similar as of applyRemoteGucs(), except that it
does not do extra_float_digits. It would be nice to avoid more
duplication for those things, at least on HEAD. On the top of my
head, don't we have something similar for parallel workers when
passing down GUCs from the leader?

Since it will be used in more than one places. IMO, we can implement it in core.
Any thoughts?

It's not going to be the same code everywhere. A logrep sender won't
have a need to save-and-restore the settings like postgres_fdw does,

Thanks for your explanation. Yeah, we do not need reset the settings in
logical replication.

AFAICS. Also, now that I look at it, dblink is doing the opposite
thing of absorbing the sender's values.

Sorry I misunderstand. You are right, the dblink applies the remote
server's settings to local server.

Attached v3 patch modify the settings on sender as you suggest.

--
Regrads,
Japin Li.
ChengDu WenWu Information Technology Co.,Ltd.

Attachments:

v3-fix-logical-replication-failing-when-in-different-datestyle.patchtext/x-patchDownload
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index e2a76ba055..3c1b2fa85e 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -2223,6 +2223,20 @@ retry1:
 				{
 					am_walsender = true;
 					am_db_walsender = true;
+
+					/*
+					 * Force assorted GUC parameters to settings that ensure
+					 * that we'll output data values in a form that is
+					 * unambiguous to the walreceiver.
+					 */
+					port->guc_options = lappend(port->guc_options,
+												pstrdup("datestyle"));
+					port->guc_options = lappend(port->guc_options,
+												pstrdup("ISO"));
+					port->guc_options = lappend(port->guc_options,
+												pstrdup("intervalstyle"));
+					port->guc_options = lappend(port->guc_options,
+												pstrdup("postgres"));
 				}
 				else if (!parse_bool(valptr, &am_walsender))
 					ereport(FATAL,
diff --git a/src/test/subscription/t/100_bugs.pl b/src/test/subscription/t/100_bugs.pl
index baa4a90771..a88a61df41 100644
--- a/src/test/subscription/t/100_bugs.pl
+++ b/src/test/subscription/t/100_bugs.pl
@@ -6,7 +6,7 @@ use strict;
 use warnings;
 use PostgresNode;
 use TestLib;
-use Test::More tests => 5;
+use Test::More tests => 6;
 
 # Bug #15114
 
@@ -224,3 +224,44 @@ $node_sub->safe_psql('postgres', "DROP TABLE tab1");
 $node_pub->stop('fast');
 $node_pub_sub->stop('fast');
 $node_sub->stop('fast');
+
+# Verify different datestyle between publisher and subscriber.
+$node_publisher = PostgresNode->new('datestyle_publisher');
+$node_publisher->init(allows_streaming => 'logical');
+$node_publisher->append_conf('postgresql.conf',
+	"datestyle = 'SQL, MDY'");
+$node_publisher->start;
+
+$node_subscriber = PostgresNode->new('datestyle_subscriber');
+$node_subscriber->init(allows_streaming => 'logical');
+$node_subscriber->append_conf('postgresql.conf',
+	"datestyle = 'SQL, DMY'");
+$node_subscriber->start;
+
+$node_publisher->safe_psql('postgres',
+	"CREATE TABLE tab_rep(a date)");
+$node_publisher->safe_psql('postgres',
+	"INSERT INTO tab_rep VALUES ('07-18-2021'), ('05-15-2018')");
+
+$node_subscriber->safe_psql('postgres',
+	"CREATE TABLE tab_rep(a date)");
+
+# Setup logical replication
+my $node_publisher_connstr = $node_publisher->connstr . ' dbname=postgres';
+$node_publisher->safe_psql('postgres',
+	"CREATE PUBLICATION tab_pub FOR ALL TABLES");
+$node_subscriber->safe_psql('postgres',
+	"CREATE SUBSCRIPTION tab_sub CONNECTION '$node_publisher_connstr' PUBLICATION tab_pub");
+
+$node_publisher->wait_for_catchup('tab_sub');
+
+my $result = $node_subscriber->safe_psql('postgres',
+	"SELECT count(*) FROM tab_rep");
+is($result, qq(2), 'failed to replication date from different datestyle');
+
+# Clean up the tables on both publisher and subscriber as we don't need them
+$node_publisher->safe_psql('postgres', 'DROP TABLE tab_rep');
+$node_subscriber->safe_psql('postgres', 'DROP TABLE tab_rep');
+
+$node_publisher->stop('fast');
+$node_subscriber->stop('fast');
#15Japin Li
japinli@hotmail.com
In reply to: Masahiko Sawada (#6)
Re: [Bug] Logical Replication failing if the DateStyle is different in Publisher & Subscriber

On Mon, 18 Oct 2021 at 11:26, Masahiko Sawada <sawada.mshk@gmail.com> wrote:

On Thu, Oct 14, 2021 at 8:50 PM Dilip Kumar <dilipbalaut@gmail.com> wrote:

On Thu, Oct 14, 2021 at 3:48 PM Sadhuprasad Patro <b.sadhu@gmail.com> wrote:

Hi All,

Publisher 'DateStyle' is set as "SQL, MDY", whereas in Subscriber as
"SQL, DMY", the logical replication is not working...

From Publisher:
postgres=# INSERT INTO calendar VALUES ('07-18-1036', '1'), ('05-15-1135', '1');
INSERT 0 2

Getting below error in the subscriber log file,
2021-10-14 00:59:23.067 PDT [38262] ERROR: date/time field value out
of range: "07/18/1036"
2021-10-14 00:59:23.067 PDT [38262] HINT: Perhaps you need a
different "datestyle" setting.

Is this an expected behavior?

Looks like a problem to me, I think for fixing this, on logical
replication connection always set subscriber's DateStlyle, with that
the walsender will always send the data in the same DateStyle that
worker understands and then we are good.

+1

Probably the same is true for IntervalStyle? If the publisher sets
'sql_standard', the subscriber sets 'postgres', and an interval value
'-1 11:22:33' is inserted, these two nodes have different data:

* Publisher
=# set intervalstyle to 'postgres'; select * from test;
i
-------------------
-1 days -11:22:33
(1 row)

* Subscriber
=# set intervalstyle to 'postgres'; select * from test;
i
-------------------
-1 days +11:22:33
(1 row)

I attached v3 patch that set IntervalStyle to 'postgres' when the
server backend is walsender, and this problem has gone.

I test that set IntervalStyle to 'sql_standard' on publisher and
'iso_8601' on subscriber, it works fine.

Please try v3 patch and let me know if they work as unexpected.
Thanks in advance.

--
Regrads,
Japin Li.
ChengDu WenWu Information Technology Co.,Ltd.

#16Dilip Kumar
dilipbalaut@gmail.com
In reply to: Japin Li (#15)
Re: [Bug] Logical Replication failing if the DateStyle is different in Publisher & Subscriber

On Mon, Oct 18, 2021 at 1:41 PM Japin Li <japinli@hotmail.com> wrote:

I attached v3 patch that set IntervalStyle to 'postgres' when the
server backend is walsender, and this problem has gone.

I test that set IntervalStyle to 'sql_standard' on publisher and
'iso_8601' on subscriber, it works fine.

Please try v3 patch and let me know if they work as unexpected.
Thanks in advance.

I think the idea of setting the standard DateStyle and the
IntervalStyle on the walsender process looks fine to me. As this will
avoid extra network round trips as Tom mentioned.

--
Regards,
Dilip Kumar
EnterpriseDB: http://www.enterprisedb.com

#17Japin Li
japinli@hotmail.com
In reply to: Dilip Kumar (#16)
1 attachment(s)
Re: [Bug] Logical Replication failing if the DateStyle is different in Publisher & Subscriber

On Mon, 18 Oct 2021 at 17:27, Dilip Kumar <dilipbalaut@gmail.com> wrote:

On Mon, Oct 18, 2021 at 1:41 PM Japin Li <japinli@hotmail.com> wrote:

I attached v3 patch that set IntervalStyle to 'postgres' when the
server backend is walsender, and this problem has gone.

I test that set IntervalStyle to 'sql_standard' on publisher and
'iso_8601' on subscriber, it works fine.

Please try v3 patch and let me know if they work as unexpected.
Thanks in advance.

I think the idea of setting the standard DateStyle and the
IntervalStyle on the walsender process looks fine to me. As this will
avoid extra network round trips as Tom mentioned.

After some test, I find we also should set the extra_float_digits to avoid
precision lossing.

Please consider the v4 patch to review.

--
Regrads,
Japin Li.
ChengDu WenWu Information Technology Co.,Ltd.

Attachments:

v4-fix-logical-replication-failing-when-in-different-datestyle.patchtext/x-patchDownload
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index e2a76ba055..7ae0c7bff2 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -2223,6 +2223,24 @@ retry1:
 				{
 					am_walsender = true;
 					am_db_walsender = true;
+
+					/*
+					 * Force assorted GUC parameters to settings that ensure
+					 * that we'll output data values in a form that is
+					 * unambiguous to the walreceiver.
+					 */
+					port->guc_options = lappend(port->guc_options,
+												pstrdup("datestyle"));
+					port->guc_options = lappend(port->guc_options,
+												pstrdup("ISO"));
+					port->guc_options = lappend(port->guc_options,
+												pstrdup("intervalstyle"));
+					port->guc_options = lappend(port->guc_options,
+												pstrdup("postgres"));
+					port->guc_options = lappend(port->guc_options,
+												pstrdup("extra_float_digits"));
+					port->guc_options = lappend(port->guc_options,
+												pstrdup("3"));
 				}
 				else if (!parse_bool(valptr, &am_walsender))
 					ereport(FATAL,
diff --git a/src/test/subscription/t/100_bugs.pl b/src/test/subscription/t/100_bugs.pl
index baa4a90771..d92ab60d86 100644
--- a/src/test/subscription/t/100_bugs.pl
+++ b/src/test/subscription/t/100_bugs.pl
@@ -6,7 +6,7 @@ use strict;
 use warnings;
 use PostgresNode;
 use TestLib;
-use Test::More tests => 5;
+use Test::More tests => 7;
 
 # Bug #15114
 
@@ -224,3 +224,69 @@ $node_sub->safe_psql('postgres', "DROP TABLE tab1");
 $node_pub->stop('fast');
 $node_pub_sub->stop('fast');
 $node_sub->stop('fast');
+
+# Verify different datestyle between publisher and subscriber.
+$node_publisher = PostgresNode->new('datestyle_publisher');
+$node_publisher->init(allows_streaming => 'logical');
+$node_publisher->append_conf('postgresql.conf',
+	"datestyle = 'SQL, MDY'");
+$node_publisher->append_conf('postgresql.conf',
+	"extra_float_digits = '-4'");
+$node_publisher->start;
+
+$node_subscriber = PostgresNode->new('datestyle_subscriber');
+$node_subscriber->init(allows_streaming => 'logical');
+$node_subscriber->append_conf('postgresql.conf',
+	"datestyle = 'SQL, DMY'");
+$node_subscriber->start;
+
+# Table for datestyle
+$node_publisher->safe_psql('postgres',
+	"CREATE TABLE tab_rep(a date)");
+$node_subscriber->safe_psql('postgres',
+	"CREATE TABLE tab_rep(a date)");
+
+# Table for extra_float_digits
+$node_publisher->safe_psql('postgres',
+	"CREATE TABLE flt_rep(a real, d double precision)");
+$node_subscriber->safe_psql('postgres',
+	"CREATE TABLE flt_rep(a real, d double precision)");
+
+# Setup logical replication
+my $node_publisher_connstr = $node_publisher->connstr . ' dbname=postgres';
+$node_publisher->safe_psql('postgres',
+	"CREATE PUBLICATION tab_pub FOR ALL TABLES");
+$node_subscriber->safe_psql('postgres',
+	"CREATE SUBSCRIPTION tab_sub CONNECTION '$node_publisher_connstr' PUBLICATION tab_pub");
+
+$node_publisher->safe_psql('postgres',
+	"INSERT INTO tab_rep VALUES ('07-18-2021'), ('05-15-2018')");
+
+$node_publisher->wait_for_catchup('tab_sub');
+
+my $result = $node_subscriber->safe_psql('postgres',
+	"SELECT count(*) FROM tab_rep");
+is($result, qq(2), 'failed to replication date from different datestyle');
+
+$node_publisher->safe_psql('postgres',
+	"INSERT INTO flt_rep VALUES (1.2121323, 32.32321232132434)");
+
+$node_publisher->wait_for_catchup('tab_sub');
+
+$result = $node_subscriber->safe_psql('postgres',
+	"SELECT a, d FROM flt_rep");
+is($result, qq(1.2121323|32.32321232132434),
+	'failed to replication floating-point values');
+
+# Clean up the tables on both publisher and subscriber as we don't need them
+$node_publisher->safe_psql('postgres', 'DROP TABLE tab_rep');
+$node_subscriber->safe_psql('postgres', 'DROP TABLE tab_rep');
+$node_publisher->safe_psql('postgres', 'DROP TABLE flt_rep');
+$node_subscriber->safe_psql('postgres', 'DROP TABLE flt_rep');
+
+# Drop subscription/publication as we don't need anymore
+$node_subscriber->safe_psql('postgres', 'DROP SUBSCRIPTION tab_sub');
+$node_publisher->safe_psql('postgres', 'DROP PUBLICATION tab_pub');
+
+$node_publisher->stop('fast');
+$node_subscriber->stop('fast');
#18Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Japin Li (#17)
Re: [Bug] Logical Replication failing if the DateStyle is different in Publisher & Subscriber

On Wed, Oct 20, 2021 at 8:12 PM Japin Li <japinli@hotmail.com> wrote:

On Mon, 18 Oct 2021 at 17:27, Dilip Kumar <dilipbalaut@gmail.com> wrote:

On Mon, Oct 18, 2021 at 1:41 PM Japin Li <japinli@hotmail.com> wrote:

I attached v3 patch that set IntervalStyle to 'postgres' when the
server backend is walsender, and this problem has gone.

I test that set IntervalStyle to 'sql_standard' on publisher and
'iso_8601' on subscriber, it works fine.

Please try v3 patch and let me know if they work as unexpected.
Thanks in advance.

I think the idea of setting the standard DateStyle and the
IntervalStyle on the walsender process looks fine to me. As this will
avoid extra network round trips as Tom mentioned.

After some test, I find we also should set the extra_float_digits to avoid
precision lossing.

Thank you for the patch!

--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -2223,6 +2223,24 @@ retry1:
                                {
                                        am_walsender = true;
                                        am_db_walsender = true;
+
+                                       /*
+                                        * Force assorted GUC
parameters to settings that ensure
+                                        * that we'll output data
values in a form that is
+                                        * unambiguous to the walreceiver.
+                                        */
+                                       port->guc_options =
lappend(port->guc_options,
+
                         pstrdup("datestyle"));
+                                       port->guc_options =
lappend(port->guc_options,
+
                         pstrdup("ISO"));
+                                       port->guc_options =
lappend(port->guc_options,
+
                         pstrdup("intervalstyle"));
+                                       port->guc_options =
lappend(port->guc_options,
+
                         pstrdup("postgres"));
+                                       port->guc_options =
lappend(port->guc_options,
+
                         pstrdup("extra_float_digits"));
+                                       port->guc_options =
lappend(port->guc_options,
+
                         pstrdup("3"));
                                }

I'm concerned that it sets parameters too early since wal senders end
up setting the parameters regardless of logical decoding plugins. It
might be better to force the parameters within the plugin for logical
replication, pgoutput, in order to avoid affecting other plugins? On
the other hand, if we do so, we will need to handle table sync worker
cases separately since they copy data via COPY executed by the wal
sender process. For example, we can have table sync workers set the
parameters.

Regards,

--
Masahiko Sawada
EDB: https://www.enterprisedb.com/

#19Dilip Kumar
dilipbalaut@gmail.com
In reply to: Masahiko Sawada (#18)
Re: [Bug] Logical Replication failing if the DateStyle is different in Publisher & Subscriber

On Thu, Oct 21, 2021 at 11:16 AM Masahiko Sawada <sawada.mshk@gmail.com> wrote:

On Wed, Oct 20, 2021 at 8:12 PM Japin Li <japinli@hotmail.com> wrote:

On Mon, 18 Oct 2021 at 17:27, Dilip Kumar <dilipbalaut@gmail.com> wrote:

On Mon, Oct 18, 2021 at 1:41 PM Japin Li <japinli@hotmail.com> wrote:

I attached v3 patch that set IntervalStyle to 'postgres' when the
server backend is walsender, and this problem has gone.

I test that set IntervalStyle to 'sql_standard' on publisher and
'iso_8601' on subscriber, it works fine.

Please try v3 patch and let me know if they work as unexpected.
Thanks in advance.

I think the idea of setting the standard DateStyle and the
IntervalStyle on the walsender process looks fine to me. As this will
avoid extra network round trips as Tom mentioned.

After some test, I find we also should set the extra_float_digits to avoid
precision lossing.

Thank you for the patch!

--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -2223,6 +2223,24 @@ retry1:
{
am_walsender = true;
am_db_walsender = true;
+
+                                       /*
+                                        * Force assorted GUC
parameters to settings that ensure
+                                        * that we'll output data
values in a form that is
+                                        * unambiguous to the walreceiver.
+                                        */
+                                       port->guc_options =
lappend(port->guc_options,
+
pstrdup("datestyle"));
+                                       port->guc_options =
lappend(port->guc_options,
+
pstrdup("ISO"));
+                                       port->guc_options =
lappend(port->guc_options,
+
pstrdup("intervalstyle"));
+                                       port->guc_options =
lappend(port->guc_options,
+
pstrdup("postgres"));
+                                       port->guc_options =
lappend(port->guc_options,
+
pstrdup("extra_float_digits"));
+                                       port->guc_options =
lappend(port->guc_options,
+
pstrdup("3"));
}

I'm concerned that it sets parameters too early since wal senders end
up setting the parameters regardless of logical decoding plugins. It
might be better to force the parameters within the plugin for logical
replication, pgoutput, in order to avoid affecting other plugins? On
the other hand, if we do so, we will need to handle table sync worker
cases separately since they copy data via COPY executed by the wal
sender process. For example, we can have table sync workers set the
parameters.

You mean table sync worker to set over the replication connection
right? I think that was the first solution where normal workers, as
well as table sync workers, were setting over the replication
connection, but Tom suggested that setting on the walsender is a
better option as we can avoid the network round trip.

If we want to set it over the replication connection then do it for
both as Japin's first patch is doing, otherwise, I am not seeing any
big issue in setting it early in the walsender also. I think it is
good to let walsender always send in the standard format which can be
understood by other node, no?

--
Regards,
Dilip Kumar
EnterpriseDB: http://www.enterprisedb.com

#20Japin Li
japinli@hotmail.com
In reply to: Dilip Kumar (#19)
Re: [Bug] Logical Replication failing if the DateStyle is different in Publisher & Subscriber

On Thu, 21 Oct 2021 at 14:04, Dilip Kumar <dilipbalaut@gmail.com> wrote:

On Thu, Oct 21, 2021 at 11:16 AM Masahiko Sawada <sawada.mshk@gmail.com> wrote:

On Wed, Oct 20, 2021 at 8:12 PM Japin Li <japinli@hotmail.com> wrote:

On Mon, 18 Oct 2021 at 17:27, Dilip Kumar <dilipbalaut@gmail.com> wrote:

On Mon, Oct 18, 2021 at 1:41 PM Japin Li <japinli@hotmail.com> wrote:

I attached v3 patch that set IntervalStyle to 'postgres' when the
server backend is walsender, and this problem has gone.

I test that set IntervalStyle to 'sql_standard' on publisher and
'iso_8601' on subscriber, it works fine.

Please try v3 patch and let me know if they work as unexpected.
Thanks in advance.

I think the idea of setting the standard DateStyle and the
IntervalStyle on the walsender process looks fine to me. As this will
avoid extra network round trips as Tom mentioned.

After some test, I find we also should set the extra_float_digits to avoid
precision lossing.

Thank you for the patch!

--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -2223,6 +2223,24 @@ retry1:
{
am_walsender = true;
am_db_walsender = true;
+
+                                       /*
+                                        * Force assorted GUC
parameters to settings that ensure
+                                        * that we'll output data
values in a form that is
+                                        * unambiguous to the walreceiver.
+                                        */
+                                       port->guc_options =
lappend(port->guc_options,
+
pstrdup("datestyle"));
+                                       port->guc_options =
lappend(port->guc_options,
+
pstrdup("ISO"));
+                                       port->guc_options =
lappend(port->guc_options,
+
pstrdup("intervalstyle"));
+                                       port->guc_options =
lappend(port->guc_options,
+
pstrdup("postgres"));
+                                       port->guc_options =
lappend(port->guc_options,
+
pstrdup("extra_float_digits"));
+                                       port->guc_options =
lappend(port->guc_options,
+
pstrdup("3"));
}

I'm concerned that it sets parameters too early since wal senders end
up setting the parameters regardless of logical decoding plugins. It
might be better to force the parameters within the plugin for logical
replication, pgoutput, in order to avoid affecting other plugins? On
the other hand, if we do so, we will need to handle table sync worker
cases separately since they copy data via COPY executed by the wal
sender process. For example, we can have table sync workers set the
parameters.

You mean table sync worker to set over the replication connection
right? I think that was the first solution where normal workers, as
well as table sync workers, were setting over the replication
connection, but Tom suggested that setting on the walsender is a
better option as we can avoid the network round trip.

If we want to set it over the replication connection then do it for
both as Japin's first patch is doing, otherwise, I am not seeing any
big issue in setting it early in the walsender also. I think it is
good to let walsender always send in the standard format which can be
understood by other node, no?

+1

I inclined to let walsender set the parameters.

--
Regrads,
Japin Li.
ChengDu WenWu Information Technology Co.,Ltd.

#21Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Dilip Kumar (#19)
Re: [Bug] Logical Replication failing if the DateStyle is different in Publisher & Subscriber

On Thu, Oct 21, 2021 at 3:04 PM Dilip Kumar <dilipbalaut@gmail.com> wrote:

On Thu, Oct 21, 2021 at 11:16 AM Masahiko Sawada <sawada.mshk@gmail.com> wrote:

On Wed, Oct 20, 2021 at 8:12 PM Japin Li <japinli@hotmail.com> wrote:

On Mon, 18 Oct 2021 at 17:27, Dilip Kumar <dilipbalaut@gmail.com> wrote:

On Mon, Oct 18, 2021 at 1:41 PM Japin Li <japinli@hotmail.com> wrote:

I attached v3 patch that set IntervalStyle to 'postgres' when the
server backend is walsender, and this problem has gone.

I test that set IntervalStyle to 'sql_standard' on publisher and
'iso_8601' on subscriber, it works fine.

Please try v3 patch and let me know if they work as unexpected.
Thanks in advance.

I think the idea of setting the standard DateStyle and the
IntervalStyle on the walsender process looks fine to me. As this will
avoid extra network round trips as Tom mentioned.

After some test, I find we also should set the extra_float_digits to avoid
precision lossing.

Thank you for the patch!

--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -2223,6 +2223,24 @@ retry1:
{
am_walsender = true;
am_db_walsender = true;
+
+                                       /*
+                                        * Force assorted GUC
parameters to settings that ensure
+                                        * that we'll output data
values in a form that is
+                                        * unambiguous to the walreceiver.
+                                        */
+                                       port->guc_options =
lappend(port->guc_options,
+
pstrdup("datestyle"));
+                                       port->guc_options =
lappend(port->guc_options,
+
pstrdup("ISO"));
+                                       port->guc_options =
lappend(port->guc_options,
+
pstrdup("intervalstyle"));
+                                       port->guc_options =
lappend(port->guc_options,
+
pstrdup("postgres"));
+                                       port->guc_options =
lappend(port->guc_options,
+
pstrdup("extra_float_digits"));
+                                       port->guc_options =
lappend(port->guc_options,
+
pstrdup("3"));
}

I'm concerned that it sets parameters too early since wal senders end
up setting the parameters regardless of logical decoding plugins. It
might be better to force the parameters within the plugin for logical
replication, pgoutput, in order to avoid affecting other plugins? On
the other hand, if we do so, we will need to handle table sync worker
cases separately since they copy data via COPY executed by the wal
sender process. For example, we can have table sync workers set the
parameters.

You mean table sync worker to set over the replication connection
right? I think that was the first solution where normal workers, as
well as table sync workers, were setting over the replication
connection, but Tom suggested that setting on the walsender is a
better option as we can avoid the network round trip.

Right.

BTW I think we can set the parameters from the subscriber side without
additional network round trips by specifying the "options" parameter
in the connection string, no?

If we want to set it over the replication connection then do it for
both as Japin's first patch is doing, otherwise, I am not seeing any
big issue in setting it early in the walsender also. I think it is
good to let walsender always send in the standard format which can be
understood by other node, no?

Yeah, probably the change on HEAD is fine but I'm a bit concerned
about possible issues on back branches like if the user expects to get
date data in the style of DateStyle setting on the server via
pg_recvlogical, this change could break it.

Regards,

--
Masahiko Sawada
EDB: https://www.enterprisedb.com/

#22Japin Li
japinli@hotmail.com
In reply to: Masahiko Sawada (#21)
Re: [Bug] Logical Replication failing if the DateStyle is different in Publisher & Subscriber

On Thu, 21 Oct 2021 at 19:54, Masahiko Sawada <sawada.mshk@gmail.com> wrote:

On Thu, Oct 21, 2021 at 3:04 PM Dilip Kumar <dilipbalaut@gmail.com> wrote:

On Thu, Oct 21, 2021 at 11:16 AM Masahiko Sawada <sawada.mshk@gmail.com> wrote:

On Wed, Oct 20, 2021 at 8:12 PM Japin Li <japinli@hotmail.com> wrote:

On Mon, 18 Oct 2021 at 17:27, Dilip Kumar <dilipbalaut@gmail.com> wrote:

On Mon, Oct 18, 2021 at 1:41 PM Japin Li <japinli@hotmail.com> wrote:

I attached v3 patch that set IntervalStyle to 'postgres' when the
server backend is walsender, and this problem has gone.

I test that set IntervalStyle to 'sql_standard' on publisher and
'iso_8601' on subscriber, it works fine.

Please try v3 patch and let me know if they work as unexpected.
Thanks in advance.

I think the idea of setting the standard DateStyle and the
IntervalStyle on the walsender process looks fine to me. As this will
avoid extra network round trips as Tom mentioned.

After some test, I find we also should set the extra_float_digits to avoid
precision lossing.

I'm concerned that it sets parameters too early since wal senders end
up setting the parameters regardless of logical decoding plugins. It
might be better to force the parameters within the plugin for logical
replication, pgoutput, in order to avoid affecting other plugins? On
the other hand, if we do so, we will need to handle table sync worker
cases separately since they copy data via COPY executed by the wal
sender process. For example, we can have table sync workers set the
parameters.

You mean table sync worker to set over the replication connection
right? I think that was the first solution where normal workers, as
well as table sync workers, were setting over the replication
connection, but Tom suggested that setting on the walsender is a
better option as we can avoid the network round trip.

Right.

BTW I think we can set the parameters from the subscriber side without
additional network round trips by specifying the "options" parameter
in the connection string, no?

Yes, we can. However, each client should be concerned the style for
datestyle, IMO it is boring.

If we want to set it over the replication connection then do it for
both as Japin's first patch is doing, otherwise, I am not seeing any
big issue in setting it early in the walsender also. I think it is
good to let walsender always send in the standard format which can be
understood by other node, no?

Yeah, probably the change on HEAD is fine but I'm a bit concerned
about possible issues on back branches like if the user expects to get
date data in the style of DateStyle setting on the server via
pg_recvlogical, this change could break it.

How it breaks? The user also can specify the "options" to get date data
in the style which they are wanted. Right?

--
Regrads,
Japin Li.
ChengDu WenWu Information Technology Co.,Ltd.

#23Tom Lane
tgl@sss.pgh.pa.us
In reply to: Japin Li (#22)
Re: [Bug] Logical Replication failing if the DateStyle is different in Publisher & Subscriber

Japin Li <japinli@hotmail.com> writes:

On Thu, 21 Oct 2021 at 19:54, Masahiko Sawada <sawada.mshk@gmail.com> wrote:

BTW I think we can set the parameters from the subscriber side without
additional network round trips by specifying the "options" parameter
in the connection string, no?

Yes, we can. However, each client should be concerned the style for
datestyle, IMO it is boring.

There's another issue here: the subscriber can run user-defined code
(in triggers), while AFAIK the sender cannot. People might be surprised
if their triggers run with a datestyle setting different from the
database's prevailing setting. So while I think it should be okay
to set-and-forget the datestyle on the sender side, we could not get
away with that in the subscriber. We'd have to set and unset for
each row, much as (e.g.) postgres_fdw has to do.

regards, tom lane

#24Japin Li
japinli@hotmail.com
In reply to: Tom Lane (#23)
Re: [Bug] Logical Replication failing if the DateStyle is different in Publisher & Subscriber

On Thu, 21 Oct 2021 at 22:46, Tom Lane <tgl@sss.pgh.pa.us> wrote:

Japin Li <japinli@hotmail.com> writes:

On Thu, 21 Oct 2021 at 19:54, Masahiko Sawada <sawada.mshk@gmail.com> wrote:

BTW I think we can set the parameters from the subscriber side without
additional network round trips by specifying the "options" parameter
in the connection string, no?

Yes, we can. However, each client should be concerned the style for
datestyle, IMO it is boring.

There's another issue here: the subscriber can run user-defined code
(in triggers), while AFAIK the sender cannot.

Sorry, I'm not sure about this. Could you give me an example?

People might be surprised
if their triggers run with a datestyle setting different from the
database's prevailing setting. So while I think it should be okay
to set-and-forget the datestyle on the sender side, we could not get
away with that in the subscriber. We'd have to set and unset for
each row, much as (e.g.) postgres_fdw has to do.

Yeah! As Masahiko said, we can avoid the network round trips by specifying
the "options" parameter in the connection string.

If this way is more accepted, I'll update the patch later.

--
Regrads,
Japin Li.
ChengDu WenWu Information Technology Co.,Ltd.

#25Tom Lane
tgl@sss.pgh.pa.us
In reply to: Japin Li (#24)
Re: [Bug] Logical Replication failing if the DateStyle is different in Publisher & Subscriber

Japin Li <japinli@hotmail.com> writes:

On Thu, 21 Oct 2021 at 22:46, Tom Lane <tgl@sss.pgh.pa.us> wrote:

There's another issue here: the subscriber can run user-defined code
(in triggers), while AFAIK the sender cannot.

Sorry, I'm not sure about this. Could you give me an example?

If you're doing logical replication into a table that has triggers,
the replication worker has to execute those triggers.

regards, tom lane

#26Japin Li
japinli@hotmail.com
In reply to: Tom Lane (#25)
Re: [Bug] Logical Replication failing if the DateStyle is different in Publisher & Subscriber

On Thu, 21 Oct 2021 at 23:10, Tom Lane <tgl@sss.pgh.pa.us> wrote:

Japin Li <japinli@hotmail.com> writes:

On Thu, 21 Oct 2021 at 22:46, Tom Lane <tgl@sss.pgh.pa.us> wrote:

There's another issue here: the subscriber can run user-defined code
(in triggers), while AFAIK the sender cannot.

Sorry, I'm not sure about this. Could you give me an example?

If you're doing logical replication into a table that has triggers,
the replication worker has to execute those triggers.

Does that mean we should use the subscriber's settings to set the
replication's parameter (e.g. datestyle)? If we do this, it might
loss precision (for example: extra_float_digits on publisher is 3
and on subscriber is -4), is this accpted?

--
Regrads,
Japin Li.
ChengDu WenWu Information Technology Co.,Ltd.

#27Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Japin Li (#22)
Re: [Bug] Logical Replication failing if the DateStyle is different in Publisher & Subscriber

On Thu, Oct 21, 2021 at 11:18 PM Japin Li <japinli@hotmail.com> wrote:

On Thu, 21 Oct 2021 at 19:54, Masahiko Sawada <sawada.mshk@gmail.com> wrote:

On Thu, Oct 21, 2021 at 3:04 PM Dilip Kumar <dilipbalaut@gmail.com> wrote:

On Thu, Oct 21, 2021 at 11:16 AM Masahiko Sawada <sawada.mshk@gmail.com> wrote:

On Wed, Oct 20, 2021 at 8:12 PM Japin Li <japinli@hotmail.com> wrote:

On Mon, 18 Oct 2021 at 17:27, Dilip Kumar <dilipbalaut@gmail.com> wrote:

On Mon, Oct 18, 2021 at 1:41 PM Japin Li <japinli@hotmail.com> wrote:

I attached v3 patch that set IntervalStyle to 'postgres' when the
server backend is walsender, and this problem has gone.

I test that set IntervalStyle to 'sql_standard' on publisher and
'iso_8601' on subscriber, it works fine.

Please try v3 patch and let me know if they work as unexpected.
Thanks in advance.

I think the idea of setting the standard DateStyle and the
IntervalStyle on the walsender process looks fine to me. As this will
avoid extra network round trips as Tom mentioned.

After some test, I find we also should set the extra_float_digits to avoid
precision lossing.

I'm concerned that it sets parameters too early since wal senders end
up setting the parameters regardless of logical decoding plugins. It
might be better to force the parameters within the plugin for logical
replication, pgoutput, in order to avoid affecting other plugins? On
the other hand, if we do so, we will need to handle table sync worker
cases separately since they copy data via COPY executed by the wal
sender process. For example, we can have table sync workers set the
parameters.

You mean table sync worker to set over the replication connection
right? I think that was the first solution where normal workers, as
well as table sync workers, were setting over the replication
connection, but Tom suggested that setting on the walsender is a
better option as we can avoid the network round trip.

Right.

BTW I think we can set the parameters from the subscriber side without
additional network round trips by specifying the "options" parameter
in the connection string, no?

Yes, we can. However, each client should be concerned the style for
datestyle, IMO it is boring.

If we want to set it over the replication connection then do it for
both as Japin's first patch is doing, otherwise, I am not seeing any
big issue in setting it early in the walsender also. I think it is
good to let walsender always send in the standard format which can be
understood by other node, no?

Yeah, probably the change on HEAD is fine but I'm a bit concerned
about possible issues on back branches like if the user expects to get
date data in the style of DateStyle setting on the server via
pg_recvlogical, this change could break it.

How it breaks?

I don't know the real case but for example, if an application gets
changes via pg_recvlogical with a decoding plugin (say wal2json) from
the database whose DateStyle setting is "SQL, MDY", it expects that
the date values in the streamed data are in the style of "ISO, MDY".
But with this change, it will get date values in the style of "ISO"
which could lead to a parse error in the application.

The user also can specify the "options" to get date data
in the style which they are wanted. Right?

Right. But doesn't it mean breaking the compatibility?

Regards,

--
Masahiko Sawada
EDB: https://www.enterprisedb.com/

#28Japin Li
japinli@hotmail.com
In reply to: Masahiko Sawada (#27)
Re: [Bug] Logical Replication failing if the DateStyle is different in Publisher & Subscriber

On Fri, 22 Oct 2021 at 08:26, Masahiko Sawada <sawada.mshk@gmail.com> wrote:

On Thu, Oct 21, 2021 at 11:18 PM Japin Li <japinli@hotmail.com> wrote:

How it breaks?

I don't know the real case but for example, if an application gets
changes via pg_recvlogical with a decoding plugin (say wal2json) from
the database whose DateStyle setting is "SQL, MDY", it expects that
the date values in the streamed data are in the style of "ISO, MDY".
But with this change, it will get date values in the style of "ISO"
which could lead to a parse error in the application.

The user also can specify the "options" to get date data
in the style which they are wanted. Right?

Right. But doesn't it mean breaking the compatibility?

Yeah, it might be break the compatibility.

In conclusion, this bug has two ways to fix.

In conclusion, this bug has two ways to fix.

1. Set the parameters on publisher, this might be break the compatibility.
2. Set the parameters on subscriber. In my first patch, I try to set the
parameters after establish the connection, it will lead more network
round trips. We can set the parameters when connecting the walsender
using "options".

For the second way, should we set the parameters same as subscriber or
use the parameters (e.g. datestyle = "ISO") likes postgres_fdw
set_transmission_modes()?

Any thoughts?

--
Regrads,
Japin Li.
ChengDu WenWu Information Technology Co.,Ltd.

#29Sadhuprasad Patro
b.sadhu@gmail.com
In reply to: Japin Li (#28)
Re: [Bug] Logical Replication failing if the DateStyle is different in Publisher & Subscriber

On Fri, Oct 22, 2021 at 8:07 AM Japin Li <japinli@hotmail.com> wrote:

On Fri, 22 Oct 2021 at 08:26, Masahiko Sawada <sawada.mshk@gmail.com> wrote:

On Thu, Oct 21, 2021 at 11:18 PM Japin Li <japinli@hotmail.com> wrote:

How it breaks?

I don't know the real case but for example, if an application gets
changes via pg_recvlogical with a decoding plugin (say wal2json) from
the database whose DateStyle setting is "SQL, MDY", it expects that
the date values in the streamed data are in the style of "ISO, MDY".
But with this change, it will get date values in the style of "ISO"
which could lead to a parse error in the application.

The user also can specify the "options" to get date data
in the style which they are wanted. Right?

Right. But doesn't it mean breaking the compatibility?

Yeah, it might be break the compatibility.

In conclusion, this bug has two ways to fix.

In conclusion, this bug has two ways to fix.

1. Set the parameters on publisher, this might be break the compatibility.

Is it not possible to set the parameter on publisher as "ISO, MDY" or
"ISO, YMD", instead of only "ISO"?
DateStyle includes both, so we may set the parameter with date format...

2. Set the parameters on subscriber. In my first patch, I try to set the
parameters after establish the connection, it will lead more network
round trips. We can set the parameters when connecting the walsender
using "options".

For the second way, should we set the parameters same as subscriber or
use the parameters (e.g. datestyle = "ISO") likes postgres_fdw
set_transmission_modes()?

Any thoughts?

IMO, setting the parameter value same as the subscriber is better. It
is always possible that we can set any datestyle in the plugins
itself...

Thanks & Regards
SadhuPrasad
EnterpriseDB: http://www.enterprisedb.com

#30Japin Li
japinli@hotmail.com
In reply to: Sadhuprasad Patro (#29)
1 attachment(s)
Re: [Bug] Logical Replication failing if the DateStyle is different in Publisher & Subscriber

On Fri, 22 Oct 2021 at 15:00, Sadhuprasad Patro <b.sadhu@gmail.com> wrote:

On Fri, Oct 22, 2021 at 8:07 AM Japin Li <japinli@hotmail.com> wrote:

On Fri, 22 Oct 2021 at 08:26, Masahiko Sawada <sawada.mshk@gmail.com> wrote:

On Thu, Oct 21, 2021 at 11:18 PM Japin Li <japinli@hotmail.com> wrote:

How it breaks?

I don't know the real case but for example, if an application gets
changes via pg_recvlogical with a decoding plugin (say wal2json) from
the database whose DateStyle setting is "SQL, MDY", it expects that
the date values in the streamed data are in the style of "ISO, MDY".
But with this change, it will get date values in the style of "ISO"
which could lead to a parse error in the application.

The user also can specify the "options" to get date data
in the style which they are wanted. Right?

Right. But doesn't it mean breaking the compatibility?

Yeah, it might be break the compatibility.

In conclusion, this bug has two ways to fix.

In conclusion, this bug has two ways to fix.

1. Set the parameters on publisher, this might be break the compatibility.

Is it not possible to set the parameter on publisher as "ISO, MDY" or
"ISO, YMD", instead of only "ISO"?
DateStyle includes both, so we may set the parameter with date format...

2. Set the parameters on subscriber. In my first patch, I try to set the
parameters after establish the connection, it will lead more network
round trips. We can set the parameters when connecting the walsender
using "options".

For the second way, should we set the parameters same as subscriber or
use the parameters (e.g. datestyle = "ISO") likes postgres_fdw
set_transmission_modes()?

Any thoughts?

IMO, setting the parameter value same as the subscriber is better. It
is always possible that we can set any datestyle in the plugins
itself...

Attach v5 patch. This patch set the datestyle, intervalstyle and
extra_float_digits parameters when we connect to publisher, this can
avoid the network round trips (compare with the first patch).

OTOH, the patch uses the subscriber's parameters as connecting parameters,
which is more complex. If we use the parameters likes postgres_fdw
set_transmission_mode(), the code will be easier [1]diff --git a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c index 5c6e56a5b2..0d03edd39f 100644 --- a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c +++ b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c @@ -128,8 +128,8 @@ libpqrcv_connect(const char *conninfo, bool logical, const char *appname, { WalReceiverConn *conn; PostgresPollingStatusType status; - const char *keys[5]; - const char *vals[5]; + const char *keys[6]; + const char *vals[6]; int i = 0;.

[1]
diff --git a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
index 5c6e56a5b2..0d03edd39f 100644
--- a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
+++ b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
@@ -128,8 +128,8 @@ libpqrcv_connect(const char *conninfo, bool logical, const char *appname,
 {
 	WalReceiverConn *conn;
 	PostgresPollingStatusType status;
-	const char *keys[5];
-	const char *vals[5];
+	const char *keys[6];
+	const char *vals[6];
 	int			i = 0;
 	/*
@@ -155,6 +155,8 @@ libpqrcv_connect(const char *conninfo, bool logical, const char *appname,
 	{
 		keys[++i] = "client_encoding";
 		vals[i] = GetDatabaseEncodingName();
+		keys[++i] = "options";
+		vals[i] = "-c datestyle=ISO,\\ YMD -c intervalstyle=postgres extra_float_digits=3";
 	}
 	keys[++i] = NULL;
 	vals[i] = NULL;

--
Regrads,
Japin Li.
ChengDu WenWu Information Technology Co.,Ltd.

Attachments:

v5-fix-logical-replication-failing-when-in-different-datestyle.patchtext/x-patchDownload
diff --git a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
index 5c6e56a5b2..c1fb4fd3d4 100644
--- a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
+++ b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
@@ -30,6 +30,7 @@
 #include "pqexpbuffer.h"
 #include "replication/walreceiver.h"
 #include "utils/builtins.h"
+#include "utils/guc.h"
 #include "utils/memutils.h"
 #include "utils/pg_lsn.h"
 #include "utils/tuplestore.h"
@@ -82,6 +83,8 @@ static WalRcvExecResult *libpqrcv_exec(WalReceiverConn *conn,
 									   const int nRetTypes,
 									   const Oid *retTypes);
 static void libpqrcv_disconnect(WalReceiverConn *conn);
+static char *add_backslash(const char *value);
+static char *get_transmission_modes(void);
 
 static WalReceiverFunctionsType PQWalReceiverFunctions = {
 	libpqrcv_connect,
@@ -128,9 +131,10 @@ libpqrcv_connect(const char *conninfo, bool logical, const char *appname,
 {
 	WalReceiverConn *conn;
 	PostgresPollingStatusType status;
-	const char *keys[5];
-	const char *vals[5];
+	const char *keys[6];
+	const char *vals[6];
 	int			i = 0;
+	char	   *options;
 
 	/*
 	 * We use the expand_dbname parameter to process the connection string (or
@@ -155,6 +159,10 @@ libpqrcv_connect(const char *conninfo, bool logical, const char *appname,
 	{
 		keys[++i] = "client_encoding";
 		vals[i] = GetDatabaseEncodingName();
+
+		options = get_transmission_modes();
+		keys[++i] = "options";
+		vals[i] = options;
 	}
 	keys[++i] = NULL;
 	vals[i] = NULL;
@@ -164,6 +172,7 @@ libpqrcv_connect(const char *conninfo, bool logical, const char *appname,
 	conn = palloc0(sizeof(WalReceiverConn));
 	conn->streamConn = PQconnectStartParams(keys, vals,
 											 /* expand_dbname = */ true);
+	pfree(options);
 	if (PQstatus(conn->streamConn) == CONNECTION_BAD)
 	{
 		*err = pchomp(PQerrorMessage(conn->streamConn));
@@ -1153,3 +1162,56 @@ stringlist_to_identifierstr(PGconn *conn, List *strings)
 
 	return res.data;
 }
+
+static char *
+add_backslash(const char *value)
+{
+	const char		*p;
+	StringInfoData	res;
+
+	initStringInfo(&res);
+
+	for (p = value; *p != '\0'; p++)
+	{
+		if (*p == ' ')
+			appendStringInfoChar(&res, '\\');
+
+		appendStringInfoChar(&res, *p);
+	}
+
+	return res.data;
+}
+
+static char *
+get_transmission_modes(void)
+{
+	char	*res;
+	char	*date_style;
+	char	*interval_style;
+	char	*extra_float_digits;
+
+	date_style = (char *) GetConfigOption("datestyle", true, true);
+	if (date_style == NULL)
+		date_style = "ISO, YMD";
+
+	interval_style = (char *) GetConfigOption("interval", true, true);
+	if (interval_style == NULL)
+		interval_style = "postgres";
+
+	extra_float_digits = (char *) GetConfigOption("extra_float_digits", true, true);
+	if (extra_float_digits == NULL)
+		extra_float_digits = "3";
+
+	date_style = add_backslash(date_style);
+	interval_style = add_backslash(interval_style);
+	extra_float_digits = add_backslash(extra_float_digits);
+
+	res = psprintf("-c datestyle=%s -c intervalstyle=%s -c extra_float_digits=%s",
+				   date_style, interval_style, extra_float_digits);
+
+	pfree(date_style);
+	pfree(interval_style);
+	pfree(extra_float_digits);
+
+	return res;
+}
diff --git a/src/test/subscription/t/100_bugs.pl b/src/test/subscription/t/100_bugs.pl
index baa4a90771..d92ab60d86 100644
--- a/src/test/subscription/t/100_bugs.pl
+++ b/src/test/subscription/t/100_bugs.pl
@@ -6,7 +6,7 @@ use strict;
 use warnings;
 use PostgresNode;
 use TestLib;
-use Test::More tests => 5;
+use Test::More tests => 7;
 
 # Bug #15114
 
@@ -224,3 +224,69 @@ $node_sub->safe_psql('postgres', "DROP TABLE tab1");
 $node_pub->stop('fast');
 $node_pub_sub->stop('fast');
 $node_sub->stop('fast');
+
+# Verify different datestyle between publisher and subscriber.
+$node_publisher = PostgresNode->new('datestyle_publisher');
+$node_publisher->init(allows_streaming => 'logical');
+$node_publisher->append_conf('postgresql.conf',
+	"datestyle = 'SQL, MDY'");
+$node_publisher->append_conf('postgresql.conf',
+	"extra_float_digits = '-4'");
+$node_publisher->start;
+
+$node_subscriber = PostgresNode->new('datestyle_subscriber');
+$node_subscriber->init(allows_streaming => 'logical');
+$node_subscriber->append_conf('postgresql.conf',
+	"datestyle = 'SQL, DMY'");
+$node_subscriber->start;
+
+# Table for datestyle
+$node_publisher->safe_psql('postgres',
+	"CREATE TABLE tab_rep(a date)");
+$node_subscriber->safe_psql('postgres',
+	"CREATE TABLE tab_rep(a date)");
+
+# Table for extra_float_digits
+$node_publisher->safe_psql('postgres',
+	"CREATE TABLE flt_rep(a real, d double precision)");
+$node_subscriber->safe_psql('postgres',
+	"CREATE TABLE flt_rep(a real, d double precision)");
+
+# Setup logical replication
+my $node_publisher_connstr = $node_publisher->connstr . ' dbname=postgres';
+$node_publisher->safe_psql('postgres',
+	"CREATE PUBLICATION tab_pub FOR ALL TABLES");
+$node_subscriber->safe_psql('postgres',
+	"CREATE SUBSCRIPTION tab_sub CONNECTION '$node_publisher_connstr' PUBLICATION tab_pub");
+
+$node_publisher->safe_psql('postgres',
+	"INSERT INTO tab_rep VALUES ('07-18-2021'), ('05-15-2018')");
+
+$node_publisher->wait_for_catchup('tab_sub');
+
+my $result = $node_subscriber->safe_psql('postgres',
+	"SELECT count(*) FROM tab_rep");
+is($result, qq(2), 'failed to replication date from different datestyle');
+
+$node_publisher->safe_psql('postgres',
+	"INSERT INTO flt_rep VALUES (1.2121323, 32.32321232132434)");
+
+$node_publisher->wait_for_catchup('tab_sub');
+
+$result = $node_subscriber->safe_psql('postgres',
+	"SELECT a, d FROM flt_rep");
+is($result, qq(1.2121323|32.32321232132434),
+	'failed to replication floating-point values');
+
+# Clean up the tables on both publisher and subscriber as we don't need them
+$node_publisher->safe_psql('postgres', 'DROP TABLE tab_rep');
+$node_subscriber->safe_psql('postgres', 'DROP TABLE tab_rep');
+$node_publisher->safe_psql('postgres', 'DROP TABLE flt_rep');
+$node_subscriber->safe_psql('postgres', 'DROP TABLE flt_rep');
+
+# Drop subscription/publication as we don't need anymore
+$node_subscriber->safe_psql('postgres', 'DROP SUBSCRIPTION tab_sub');
+$node_publisher->safe_psql('postgres', 'DROP PUBLICATION tab_pub');
+
+$node_publisher->stop('fast');
+$node_subscriber->stop('fast');
#31Tom Lane
tgl@sss.pgh.pa.us
In reply to: Japin Li (#30)
Re: [Bug] Logical Replication failing if the DateStyle is different in Publisher & Subscriber

Japin Li <japinli@hotmail.com> writes:

Attach v5 patch. This patch set the datestyle, intervalstyle and
extra_float_digits parameters when we connect to publisher, this can
avoid the network round trips (compare with the first patch).

You could make it a little less confusing by not insisting on a
space in the datestyle. This should work fine:

vals[i] = "-c datestyle=ISO,YMD -c intervalstyle=postgres extra_float_digits=3";

Also, I think some comments would be appropriate.

I don't see any value whatsoever in the more complicated version
of the patch. It's just more code to maintain and more things
to go wrong. And not only at our level, but the DBA's too.
What if the subscriber and publisher are of different PG versions
and have different ideas of the valid values of these settings?

regards, tom lane

#32Japin Li
japinli@hotmail.com
In reply to: Tom Lane (#31)
1 attachment(s)
Re: [Bug] Logical Replication failing if the DateStyle is different in Publisher & Subscriber

On Sat, 23 Oct 2021 at 00:55, Tom Lane <tgl@sss.pgh.pa.us> wrote:

Japin Li <japinli@hotmail.com> writes:

Attach v5 patch. This patch set the datestyle, intervalstyle and
extra_float_digits parameters when we connect to publisher, this can
avoid the network round trips (compare with the first patch).

You could make it a little less confusing by not insisting on a
space in the datestyle. This should work fine:

vals[i] = "-c datestyle=ISO,YMD -c intervalstyle=postgres extra_float_digits=3";

Oh. My apologies. I try this style before, but find it see "ISO," is not valid,
so I add backslash, but it seems like that is my environment doesn't cleanup.

Fixed.

Also, I think some comments would be appropriate.

Add comments for it.

I don't see any value whatsoever in the more complicated version
of the patch. It's just more code to maintain and more things
to go wrong. And not only at our level, but the DBA's too.

Agreed.

What if the subscriber and publisher are of different PG versions
and have different ideas of the valid values of these settings?

Sorry, I'm a bit confused. Do you mean we should provide a choose for user
to set thoses parameters when establish logical replication?

--
Regrads,
Japin Li.
ChengDu WenWu Information Technology Co.,Ltd.

Attachments:

v6-fix-logical-replication-failing-when-in-different-datestyle.patchtext/x-patchDownload
diff --git a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
index 5c6e56a5b2..2c1a598300 100644
--- a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
+++ b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
@@ -128,8 +128,8 @@ libpqrcv_connect(const char *conninfo, bool logical, const char *appname,
 {
 	WalReceiverConn *conn;
 	PostgresPollingStatusType status;
-	const char *keys[5];
-	const char *vals[5];
+	const char *keys[6];
+	const char *vals[6];
 	int			i = 0;
 
 	/*
@@ -155,6 +155,13 @@ libpqrcv_connect(const char *conninfo, bool logical, const char *appname,
 	{
 		keys[++i] = "client_encoding";
 		vals[i] = GetDatabaseEncodingName();
+
+		/*
+		 * Force assorted GUC parameters to settings that ensure that we'll output
+		 * data values in a form that is unambiguous to the publisher.
+		 */
+		keys[++i] = "options";
+		vals[i] = "-c datestyle=ISO,YMD -c intervalstyle=postgres -c extra_float_digits=3";
 	}
 	keys[++i] = NULL;
 	vals[i] = NULL;
diff --git a/src/test/subscription/t/100_bugs.pl b/src/test/subscription/t/100_bugs.pl
index baa4a90771..d92ab60d86 100644
--- a/src/test/subscription/t/100_bugs.pl
+++ b/src/test/subscription/t/100_bugs.pl
@@ -6,7 +6,7 @@ use strict;
 use warnings;
 use PostgresNode;
 use TestLib;
-use Test::More tests => 5;
+use Test::More tests => 7;
 
 # Bug #15114
 
@@ -224,3 +224,69 @@ $node_sub->safe_psql('postgres', "DROP TABLE tab1");
 $node_pub->stop('fast');
 $node_pub_sub->stop('fast');
 $node_sub->stop('fast');
+
+# Verify different datestyle between publisher and subscriber.
+$node_publisher = PostgresNode->new('datestyle_publisher');
+$node_publisher->init(allows_streaming => 'logical');
+$node_publisher->append_conf('postgresql.conf',
+	"datestyle = 'SQL, MDY'");
+$node_publisher->append_conf('postgresql.conf',
+	"extra_float_digits = '-4'");
+$node_publisher->start;
+
+$node_subscriber = PostgresNode->new('datestyle_subscriber');
+$node_subscriber->init(allows_streaming => 'logical');
+$node_subscriber->append_conf('postgresql.conf',
+	"datestyle = 'SQL, DMY'");
+$node_subscriber->start;
+
+# Table for datestyle
+$node_publisher->safe_psql('postgres',
+	"CREATE TABLE tab_rep(a date)");
+$node_subscriber->safe_psql('postgres',
+	"CREATE TABLE tab_rep(a date)");
+
+# Table for extra_float_digits
+$node_publisher->safe_psql('postgres',
+	"CREATE TABLE flt_rep(a real, d double precision)");
+$node_subscriber->safe_psql('postgres',
+	"CREATE TABLE flt_rep(a real, d double precision)");
+
+# Setup logical replication
+my $node_publisher_connstr = $node_publisher->connstr . ' dbname=postgres';
+$node_publisher->safe_psql('postgres',
+	"CREATE PUBLICATION tab_pub FOR ALL TABLES");
+$node_subscriber->safe_psql('postgres',
+	"CREATE SUBSCRIPTION tab_sub CONNECTION '$node_publisher_connstr' PUBLICATION tab_pub");
+
+$node_publisher->safe_psql('postgres',
+	"INSERT INTO tab_rep VALUES ('07-18-2021'), ('05-15-2018')");
+
+$node_publisher->wait_for_catchup('tab_sub');
+
+my $result = $node_subscriber->safe_psql('postgres',
+	"SELECT count(*) FROM tab_rep");
+is($result, qq(2), 'failed to replication date from different datestyle');
+
+$node_publisher->safe_psql('postgres',
+	"INSERT INTO flt_rep VALUES (1.2121323, 32.32321232132434)");
+
+$node_publisher->wait_for_catchup('tab_sub');
+
+$result = $node_subscriber->safe_psql('postgres',
+	"SELECT a, d FROM flt_rep");
+is($result, qq(1.2121323|32.32321232132434),
+	'failed to replication floating-point values');
+
+# Clean up the tables on both publisher and subscriber as we don't need them
+$node_publisher->safe_psql('postgres', 'DROP TABLE tab_rep');
+$node_subscriber->safe_psql('postgres', 'DROP TABLE tab_rep');
+$node_publisher->safe_psql('postgres', 'DROP TABLE flt_rep');
+$node_subscriber->safe_psql('postgres', 'DROP TABLE flt_rep');
+
+# Drop subscription/publication as we don't need anymore
+$node_subscriber->safe_psql('postgres', 'DROP SUBSCRIPTION tab_sub');
+$node_publisher->safe_psql('postgres', 'DROP PUBLICATION tab_pub');
+
+$node_publisher->stop('fast');
+$node_subscriber->stop('fast');
#33Tom Lane
tgl@sss.pgh.pa.us
In reply to: Japin Li (#32)
Re: [Bug] Logical Replication failing if the DateStyle is different in Publisher & Subscriber

Japin Li <japinli@hotmail.com> writes:

On Sat, 23 Oct 2021 at 00:55, Tom Lane <tgl@sss.pgh.pa.us> wrote:

What if the subscriber and publisher are of different PG versions
and have different ideas of the valid values of these settings?

Sorry, I'm a bit confused. Do you mean we should provide a choose for user
to set thoses parameters when establish logical replication?

No, I'm just pointing out that pushing the subscriber's settings
to the publisher wouldn't be guaranteed to work. As long as we
use curated values that we know do what we want on all versions,
I think we're okay.

regards, tom lane

#34Japin Li
japinli@hotmail.com
In reply to: Tom Lane (#33)
Re: [Bug] Logical Replication failing if the DateStyle is different in Publisher & Subscriber

On Sat, 23 Oct 2021 at 02:00, Tom Lane <tgl@sss.pgh.pa.us> wrote:

Japin Li <japinli@hotmail.com> writes:

On Sat, 23 Oct 2021 at 00:55, Tom Lane <tgl@sss.pgh.pa.us> wrote:

What if the subscriber and publisher are of different PG versions
and have different ideas of the valid values of these settings?

Sorry, I'm a bit confused. Do you mean we should provide a choose for user
to set thoses parameters when establish logical replication?

No, I'm just pointing out that pushing the subscriber's settings
to the publisher wouldn't be guaranteed to work. As long as we
use curated values that we know do what we want on all versions,
I think we're okay.

Thanks for your clarification.

--
Regrads,
Japin Li.
ChengDu WenWu Information Technology Co.,Ltd.

#35Tom Lane
tgl@sss.pgh.pa.us
In reply to: Japin Li (#34)
Re: [Bug] Logical Replication failing if the DateStyle is different in Publisher & Subscriber

Pushed with some adjustment of the comments. I also simplified the
datestyle setting to just "ISO", because that's sufficient: that
DateStyle doesn't care about DateOrder. Since the settings are
supposed to match what pg_dump uses, it's just confusing if they don't.

Also, I didn't commit the test case. It was useful for development,
but it seemed entirely too expensive to keep forevermore compared to its
likely future value. It increased the runtime of 100_bugs.pl by about
a third, and I'm afraid the likely future value is nil. The most likely
bug in this area would be introducing some new GUC that we need to set
and forgetting to do so here; but this test case could not expose that.

regards, tom lane