On Mon, Aug 05, 2019 at 03:08:40PM +0200, Michael Weiser wrote:
> On Mon, Jul 01, 2019 at 03:56:28PM +0200, Michael Weiser wrote:
> > I've run into a problem where floats loose their fractions on the way
> > from the database to a perl script using DBD::Pg. A minimal reproducer:
>
> Am I wrong on this list with my question or was there just too much or
> too little or too specific information at once? :)
>
> I'd appreciate any advice since I'm totally lost how to proceed here.
It's the right list. The issue was complex enough to require some
uninterrupted study time.
> > # LANG=C perl ~/t.pl
> > FOO: 1.1:1.100000 C
> > 1.1
> > # LANG=de_DE.UTF-8 perl ~/t.pl
> > FOO: 1.1:1,000000 de_DE.UTF-8
> > 1
> > - so far only macOS's system perl seems to be affected. A perl 5.29.9
> > compiled myself on the same system does not exhibit the problem and
> > neither does a Debian testing box.
I can reproduce it on RHEL 7 with DBD::Pg git head. That strtod() call is a
somewhat-recent addition (added in DBD::Pg 3.6.0, from 2017). What is the
output of these two commands with each of those Perl installations?
perl -MDBD::Pg -e 'print $DBD::Pg::VERSION, "\n"'
LANG=de_DE.UTF-8 perl -MPOSIX -e 'use strict; use warnings;
setlocale(LC_NUMERIC, ""); print join " ", strtod("1.1"), "\n"'
Your symptoms are consistent with using DBD::Pg >= 3.6.0 with the macOS system
perl and DBD::Pg < 3.6.0 in the other configurations. Other explanations are
possible, though.
> > - Is it at all valid to tweak LC_NUMERIC using POSIX::setlocale() when
> > using DBD::Pg?
Yes.
> > - Could the macOS system perl at runtime (without recompilation) be
> > convinced to use another strtod() implementation/behaviour? (... which
> > doesn't involve mucking about with LD_PRELOAD/DYLD_INSERT_LIBRARIES :)
No, not without doing a hack worse than those vars.
> > - Could this reliably be fixed by switching to a non-locale-aware strtod()
> > implementation in DBD::Pg? Based on the protocol specification
> >
> > (https://www.postgresql.org/docs/current/protocol-overview.html#PROTOCOL-FORMAT-CODES)
> > I suspect that the on-wire representation could be similarly affected by
> > server-side locale settings:
>
> > The text representation of values is whatever strings are
> > produced and accepted by the input/output conversion functions
> > for the particular data type.
PostgreSQL always prints ".", not a locale-specific radix character. A
locale-ignorant strtod() would suffice in DBD::Pg.