From 2ef8c1acfd5a1f81020c3eb2916f9dcfaeeec48c Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Wed, 10 Jun 2009 16:31:32 +0000
Subject: [PATCH] Fix cash_in() to behave properly in locales where frac_digits
 is zero, eg Japan.  Report and fix by Itagaki Takahiro.  Also fix CASHDEBUG
 printout format for branches with 64-bit money type, and some minor comment
 cleanup.

Back-patch to 7.4, because it's broken all the way back.
---
 src/backend/utils/adt/cash.c | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/src/backend/utils/adt/cash.c b/src/backend/utils/adt/cash.c
index cd4fc6af092..73d55c5b54f 100644
--- a/src/backend/utils/adt/cash.c
+++ b/src/backend/utils/adt/cash.c
@@ -13,7 +13,7 @@
  * this version handles 64 bit numbers and so can hold values up to
  * $92,233,720,368,547,758.07.
  *
- * $PostgreSQL: pgsql/src/backend/utils/adt/cash.c,v 1.80 2008/06/09 19:58:39 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/cash.c,v 1.81 2009/06/10 16:31:32 tgl Exp $
  */
 
 #include "postgres.h"
@@ -191,23 +191,21 @@ cash_in(PG_FUNCTION_ARGS)
 
 	for (;; s++)
 	{
-		/* we look for digits as int8 as we have less */
+		/* we look for digits as long as we have found 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';
+			value = (value * 10) + (*s - '0');
 
 			if (seen_dot)
 				dec++;
-
 		}
 		/* decimal point? then start counting fractions... */
 		else if (*s == dsymbol && !seen_dot)
 		{
 			seen_dot = 1;
-
 		}
-		/* not "thousands" separator? */
+		/* ignore if "thousands" separator, else we're done */
 		else if (*s != ssymbol)
 		{
 			/* round off */
@@ -236,7 +234,7 @@ cash_in(PG_FUNCTION_ARGS)
 	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);
-- 
GitLab