Skip to Content.
Sympa Menu

freetds - Last digit truncation of NUMERIC

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: "Eric Deutsch" <edeutsch AT systemsbiology.org>
  • To: freetds AT franklin.oit.unc.edu
  • Subject: Last digit truncation of NUMERIC
  • Date: Fri, 9 Mar 2001 13:36:45 -0500



Regarding the problem of NUMERIC values getting truncated, about
which I posted a few days ago:

After hunting around in the FreeTDS code for a good bit, I think
I have located the source of my problem, although I don't
understand why. I'm hoping someone can help clarify.

To recap, I created a table like this:

CREATE TABLE dbo.dbaccesstests (
test_id int identity,
intfield int,
charfield varchar(50),
numfield numeric(10,0),
floatfield float,
datefield datetime
)

I inserted a few rows, and then SELECTed them back out:

1 | 20 | butter | 12 | 3.1415 | Jan 25 2000 06:00P
2 | 25 | milk | 456 | 2.17 | Jan 22 2001 12:00A
3 | 30 | swamp gas | 8901 | 1.23456789012346 | May 10 1998 10:11P
4 | 35 | pillow | 123456789 | 1.23456789012346 | Mar 09 2001 09:38A

I noticed that in the numeric columns, the last digit was always
missing. Later, I noticed that the same was true for the datetime
strings (the "M" is missing from AM and PM).

I've found the piece of code that it apparently responsible for
this:

ct.c: (line ~490)
case CS_FMT_UNUSED:
if (desttype==SYBCHAR) {
len--;
}
break;

If I add a line: len++; reversing the subtraction here, then the
resulting query returns the correct results:

1 | 20 | butter | 123 | 3.1415 | Jan 25 2000 06:00PM
2 | 25 | milk | 4567 | 2.17 | Jan 22 2001 12:00AM
3 | 30 | swamp gas | 89012 | 1.23456789012346 | May 10 1998 10:11PM
4 | 35 | pillow | 1234567890 | 1.23456789012346 | Mar 09 2001 09:40AM

This appears to solve my problem, but I worry that this breaks
something else. It seems that for the varchar(50) column, the len
variable is indeed one larger than necessary, and this len-- is
beneficial in that reduces len to the correct value. However,
since the string has a trailing NULL, this larger len doesn't
seem to matter, anyway.

Does anyone know what the original purpose of that len-- was, or
otherwise understand the implications of this issue better??

Maybe the right thing to do is make a change like the following:

case CS_FMT_UNUSED:
if (desttype==SYBCHAR
&& (srctype==SYBCHAR || srctype==SYBVARCHAR)) {
len--;
}
/* fprintf(stderr,"** debug: dest='%s', len=%d\n",dest,len); */
break;

This appears to work correctly for all the cases I've tried.

Comments? Does this problem affect anyone else?

thanks,
Eric






Archive powered by MHonArc 2.6.24.

Top of Page