Unix Technical Forum

Fixes for MONEY type using locale

This is a discussion on Fixes for MONEY type using locale within the Pgsql Patches forums, part of the PostgreSQL category; --> In looking at the use of the thousands separator in formatting.c and psql/print.c, I now see similar problems with ...


Go Back   Unix Technical Forum > Database Server Software > PostgreSQL > Pgsql Patches

FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 04-19-2008, 07:23 AM
Bruce Momjian
 
Posts: n/a
Default Fixes for MONEY type using locale

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. +


---------------------------(end of broadcast)---------------------------
TIP 9: In versions below 8.0, the planner will ignore your desire to
choose an index scan if your joining column's datatypes do not
match

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #2 (permalink)  
Old 04-19-2008, 07:23 AM
D'Arcy J.M. Cain
 
Posts: n/a
Default Re: Fixes for MONEY type using locale

On Fri, 23 Nov 2007 15:59:29 -0500 (EST)
Bruce Momjian <bruce@momjian.us> wrote:
> 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];


Good question. This has been in the code since day one. I had to go
back to the book it came from (Software Solutions in C - ISBN
0-12-632360-7) to see what I wrote back in 1994. Here is what the text
says about that.

"The next part may look a little strange, but the previous code is a
little simpler if we just put a comma at the end of the string when
there are no decimal points and strip it off here. Otherwise we would
have to adjust the comma_position variable and test in the main loop
for the special case."

The if block has a second statement though which is effectively this;

buf[LAST_PAREN] = ' ';

This is followed by;

"The Two assignments deal with the case where there is a trailing
parenthesis without having to do another test."

So that's what I know now. I'm not sure what the edge case is. For
one thing it would only be triggered in locales with no places after
the decimal point. I'll try to work up some test later.

--
D'Arcy J.M. Cain <darcy@druid.net> | Democracy is three wolves
http://www.druid.net/darcy/ | and a sheep voting on
+1 416 425 1212 (DoD#0082) (eNTP) | what's for dinner.

---------------------------(end of broadcast)---------------------------
TIP 2: Don't 'kill -9' the postmaster

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #3 (permalink)  
Old 04-19-2008, 07:23 AM
Bruce Momjian
 
Posts: n/a
Default Re: Fixes for MONEY type using locale


Patch applied. I will email on this LAST_DIGIT issue separately.

---------------------------------------------------------------------------

Bruce Momjian wrote:
> 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. +



>
> ---------------------------(end of broadcast)---------------------------
> TIP 9: In versions below 8.0, the planner will ignore your desire to
> choose an index scan if your joining column's datatypes do not
> match


--
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. +

---------------------------(end of broadcast)---------------------------
TIP 4: Have you searched our list archives?

http://archives.postgresql.org

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #4 (permalink)  
Old 04-19-2008, 07:23 AM
Bruce Momjian
 
Posts: n/a
Default Re: Fixes for MONEY type using locale

D'Arcy J.M. Cain wrote:
> On Fri, 23 Nov 2007 15:59:29 -0500 (EST)
> Bruce Momjian <bruce@momjian.us> wrote:
> > 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];

>
> Good question. This has been in the code since day one. I had to go
> back to the book it came from (Software Solutions in C - ISBN
> 0-12-632360-7) to see what I wrote back in 1994. Here is what the text
> says about that.
>
> "The next part may look a little strange, but the previous code is a
> little simpler if we just put a comma at the end of the string when
> there are no decimal points and strip it off here. Otherwise we would
> have to adjust the comma_position variable and test in the main loop
> for the special case."
>
> The if block has a second statement though which is effectively this;
>
> buf[LAST_PAREN] = ' ';
>
> This is followed by;
>
> "The Two assignments deal with the case where there is a trailing
> parenthesis without having to do another test."
>
> So that's what I know now. I'm not sure what the edge case is. For
> one thing it would only be triggered in locales with no places after
> the decimal point. I'll try to work up some test later.


Your summary is helpful. I ran some tests with points == 0 and number
of digits % mon_group == 0 and did see the trailing ssymbol before that
code, and it removed after. What they are doing is setting
buf[LAST_PAREN] to the NUL byte above the ssymbol code, and then at this
point they just trim off the ssymbol. (Perhaps the original code put the
parentheses in earlier and had to do this trick to shift in the
parentheses, but we do it after this block.)

What I did was to hard-code the \0 in there and add a comment about what
it is doing --- patch attached and applied.

I am confused about two other items with MONEY. First, why can't
anything but a string be cast to this type?

test=> select 871234872319489323::money;
ERROR: cannot cast type bigint to money
LINE 1: select 871234872319489323::money;
^
test=> select 871234872::money;
ERROR: cannot cast type integer to money
LINE 1: select 871234872::money;
^
test=> select 87123487231.3::money;
ERROR: cannot cast type numeric to money
LINE 1: select 87123487231.3::money;
^

Without such castings, how is this data type used? I did a \dC and saw
no entries for MONEY.

And second, why are there no regression tests for MONEY. I see it used
only once in the rules test.

--
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. +


---------------------------(end of broadcast)---------------------------
TIP 4: Have you searched our list archives?

http://archives.postgresql.org

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #5 (permalink)  
Old 04-19-2008, 07:23 AM
D'Arcy J.M. Cain
 
Posts: n/a
Default Re: Fixes for MONEY type using locale

On Sat, 24 Nov 2007 11:27:38 -0500 (EST)
Bruce Momjian <bruce@momjian.us> wrote:
> I am confused about two other items with MONEY. First, why can't
> anything but a string be cast to this type?
>
> test=> select 871234872319489323::money;
> ERROR: cannot cast type bigint to money
> LINE 1: select 871234872319489323::money;
> ^
> test=> select 871234872::money;
> ERROR: cannot cast type integer to money
> LINE 1: select 871234872::money;
> ^
> test=> select 87123487231.3::money;
> ERROR: cannot cast type numeric to money
> LINE 1: select 87123487231.3::money;
> ^


I agree. I wasn't the one that added the meta information.

> And second, why are there no regression tests for MONEY. I see it used
> only once in the rules test.


I think that scrappy added this into the code before we were so
vigorous about creating regression tests for everything. I agree that
there should be something. I personally unit test all my own code and
I am a big test booster.

I will look at adding something in.

--
D'Arcy J.M. Cain <darcy@druid.net> | Democracy is three wolves
http://www.druid.net/darcy/ | and a sheep voting on
+1 416 425 1212 (DoD#0082) (eNTP) | what's for dinner.

---------------------------(end of broadcast)---------------------------
TIP 7: You can help support the PostgreSQL project by donating at

http://www.postgresql.org/about/donate

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #6 (permalink)  
Old 04-19-2008, 07:23 AM
D'Arcy J.M. Cain
 
Posts: n/a
Default Re: Fixes for MONEY type using locale

On Sat, 24 Nov 2007 11:27:38 -0500 (EST)
Bruce Momjian <bruce@momjian.us> wrote:
> And second, why are there no regression tests for MONEY. I see it used
> only once in the rules test.


I will be committing some regression tests as soon as I finish testing.

--
D'Arcy J.M. Cain <darcy@druid.net> | Democracy is three wolves
http://www.druid.net/darcy/ | and a sheep voting on
+1 416 425 1212 (DoD#0082) (eNTP) | what's for dinner.

---------------------------(end of broadcast)---------------------------
TIP 4: Have you searched our list archives?

http://archives.postgresql.org

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Forum Jump


All times are GMT. The time now is 04:56 PM.


Powered by vBulletin® Version 3.6.5
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.2.0
www.UnixAdminTalk.com