Fixes for MONEY type using locale - Mailing list pgsql-patches

From Bruce Momjian
Subject Fixes for MONEY type using locale
Date
Msg-id 200711232059.lANKxTP27953@momjian.us
Whole thread Raw
Responses Re: Fixes for MONEY type using locale  ("D'Arcy J.M. Cain" <darcy@druid.net>)
Re: Fixes for MONEY type using locale  (Bruce Momjian <bruce@momjian.us>)
List pgsql-patches
In looking at the use of the thousands separator in formatting.c and
psql/print.c, I now see similar problems with the MONEY type, namely
that if the thousands separator is "" it is set to "," even if the
decimal separator is ",".

The attached patch fixes this.

I also removed a ssymbol test because ssymbol will never be \0 based on
the code.  Also, what does this do:

    if (buf[LAST_DIGIT] == ',')
        buf[LAST_DIGIT] = buf[LAST_PAREN];

--
  Bruce Momjian  <bruce@momjian.us>        http://momjian.us
  EnterpriseDB                             http://postgres.enterprisedb.com

  + If your life is a hard drive, Christ can be your backup. +
Index: src/backend/utils/adt/cash.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/utils/adt/cash.c,v
retrieving revision 1.75
diff -c -c -r1.75 cash.c
*** src/backend/utils/adt/cash.c    23 Nov 2007 19:54:39 -0000    1.75
--- src/backend/utils/adt/cash.c    23 Nov 2007 20:04:38 -0000
***************
*** 148,154 ****
          fpoint = 2;                /* best guess in this case, I think */

      dsymbol = ((*lconvert->mon_decimal_point != '\0') ? *lconvert->mon_decimal_point : '.');
!     ssymbol = ((*lconvert->mon_thousands_sep != '\0') ? *lconvert->mon_thousands_sep : ',');
      csymbol = ((*lconvert->currency_symbol != '\0') ? lconvert->currency_symbol : "$");
      psymbol = ((*lconvert->positive_sign != '\0') ? *lconvert->positive_sign : '+');
      nsymbol = ((*lconvert->negative_sign != '\0') ? lconvert->negative_sign : "-");
--- 148,158 ----
          fpoint = 2;                /* best guess in this case, I think */

      dsymbol = ((*lconvert->mon_decimal_point != '\0') ? *lconvert->mon_decimal_point : '.');
!     if (*lconvert->mon_thousands_sep != '\0')
!         ssymbol = *lconvert->mon_thousands_sep;
!     else
!         /* ssymbol should not equal dsymbol */
!         ssymbol = (dsymbol != ',') ? ',' : '.';
      csymbol = ((*lconvert->currency_symbol != '\0') ? lconvert->currency_symbol : "$");
      psymbol = ((*lconvert->positive_sign != '\0') ? *lconvert->positive_sign : '+');
      nsymbol = ((*lconvert->negative_sign != '\0') ? lconvert->negative_sign : "-");
***************
*** 293,312 ****
      if (mon_group <= 0 || mon_group > 6)
          mon_group = 3;

-     ssymbol = ((*lconvert->mon_thousands_sep != '\0') ? *lconvert->mon_thousands_sep : ',');
      convention = lconvert->n_sign_posn;
      dsymbol = ((*lconvert->mon_decimal_point != '\0') ? *lconvert->mon_decimal_point : '.');
      csymbol = ((*lconvert->currency_symbol != '\0') ? lconvert->currency_symbol : "$");
      nsymbol = ((*lconvert->negative_sign != '\0') ? lconvert->negative_sign : "-");

      point_pos = LAST_DIGIT - points;

!     /* allow more than three decimal points and separate them */
!     if (ssymbol)
!     {
!         point_pos -= (points - 1) / mon_group;
!         ssymbol_position = point_pos % (mon_group + 1);
!     }

      /* we work with positive amounts and add the minus sign at the end */
      if (value < 0)
--- 297,316 ----
      if (mon_group <= 0 || mon_group > 6)
          mon_group = 3;

      convention = lconvert->n_sign_posn;
      dsymbol = ((*lconvert->mon_decimal_point != '\0') ? *lconvert->mon_decimal_point : '.');
+     if (*lconvert->mon_thousands_sep != '\0')
+         ssymbol = *lconvert->mon_thousands_sep;
+     else
+         /* ssymbol should not equal dsymbol */
+         ssymbol = (dsymbol != ',') ? ',' : '.';
      csymbol = ((*lconvert->currency_symbol != '\0') ? lconvert->currency_symbol : "$");
      nsymbol = ((*lconvert->negative_sign != '\0') ? lconvert->negative_sign : "-");

      point_pos = LAST_DIGIT - points;

!     point_pos -= (points - 1) / mon_group;
!     ssymbol_position = point_pos % (mon_group + 1);

      /* we work with positive amounts and add the minus sign at the end */
      if (value < 0)
***************
*** 333,339 ****
      strncpy((buf + count - strlen(csymbol) + 1), csymbol, strlen(csymbol));
      count -= strlen(csymbol) - 1;

!     if (buf[LAST_DIGIT] == ',')
          buf[LAST_DIGIT] = buf[LAST_PAREN];

      /* see if we need to signify negative amount */
--- 337,344 ----
      strncpy((buf + count - strlen(csymbol) + 1), csymbol, strlen(csymbol));
      count -= strlen(csymbol) - 1;

!     /* XXX What does this do?  It seems to duplicate the last character. */
!     if (buf[LAST_DIGIT] == ssymbol)
          buf[LAST_DIGIT] = buf[LAST_PAREN];

      /* see if we need to signify negative amount */

pgsql-patches by date:

Previous
From: "Marko Kreen"
Date:
Subject: Re: Cleaner API for appendStringInfoVA
Next
From: Bruce Momjian
Date:
Subject: Re: [BUGS] BUG #3769: Fail to make bcc32.mak for libpq