The following bug has been logged online:
Bug reference: 4845
Logged by: Itagaki Takahiro
Email address: itagaki.takahiro@oss.ntt.co.jp
PostgreSQL version: 8.4dev, 8.3.7
Operating system: Windows XP
Description: cash_in is broken for lc_monetary = 'ja'
Details:
The type input function for money is broken
if lc_monetary is set to zero-precision locale.
Since Japanese "yen" has no decimal fractions,
lconv.frac_digits is 0 when lc_monetary = 'ja'.
I tested the bug in 8.3.7 and 8.4dev, but probably
we need to port it to older versions.
=# SET lc_monetary = 'en';
=# SELECT '$123'::money;
money
---------
$123.00
(1 row)
=# SET lc_monetary = 'ja';
=# SELECT E'\\123'::money;
money
-------
\0 <== should be \123.
(1 row)
[Patch attached]
Index: src/backend/utils/adt/cash.c
===================================================================
--- src/backend/utils/adt/cash.c (HEAD)
+++ src/backend/utils/adt/cash.c (fixed)
@@ -193,7 +193,7 @@
{
/* we look for digits as int8 as we have less */
/* than the required number of decimal places */
- if (isdigit((unsigned char) *s) && dec < fpoint)
+ if (isdigit((unsigned char) *s) && (!seen_dot || dec < fpoint))
{
value = (value * 10) + *s - '0';
@@ -236,7 +236,7 @@
result = value * sgn;
#ifdef CASHDEBUG
- printf("cashin- result is %d\n", result);
+ printf("cashin- result is " INT64_FORMAT "\n", result);
#endif
PG_RETURN_CASH(result);