Fix cash_in() to behave properly in locales where frac_digits is zero,
authorTom Lane <[email protected]>
Wed, 10 Jun 2009 16:32:02 +0000 (16:32 +0000)
committerTom Lane <[email protected]>
Wed, 10 Jun 2009 16:32:02 +0000 (16:32 +0000)
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

index e5691ad76287fa054423a18222f9988d4d1c70ce..945fe9b58ac38cfe7c268ce8b43f28c4e1fb9121 100644 (file)
@@ -9,7 +9,7 @@
  * workings can be found in the book "Software Solutions in C" by
  * Dale Schumacher, Academic Press, ISBN: 0-12-632360-7.
  *
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/cash.c,v 1.61 2003/09/25 06:58:03 petere Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/cash.c,v 1.61.2.1 2009/06/10 16:32:02 tgl Exp $
  */
 
 #include "postgres.h"
@@ -154,28 +154,22 @@ cash_in(PG_FUNCTION_ARGS)
 
        for (;; s++)
        {
-               /* we look for digits as int4 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... */
                }
+               /* decimal point? then start counting fractions... */
                else if (*s == dsymbol && !seen_dot)
                {
                        seen_dot = 1;
-
-                       /* "thousands" separator? then skip... */
-               }
-               else if (*s == ssymbol)
-               {
-
                }
-               else
+               /* ignore if "thousands" separator, else we're done */
+               else if (*s != ssymbol)
                {
                        /* round off */
                        if (isdigit((unsigned char) *s) && *s >= '5')