Skip to Content.
Sympa Menu

freetds - Re: Last digit truncation of NUMERIC

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: Brian Bruns <camber AT ais.org>
  • To: TDS Development Group <freetds AT franklin.oit.unc.edu>
  • Subject: Re: Last digit truncation of NUMERIC
  • Date: Mon, 12 Mar 2001 19:21:40 -0500 (EST)


Eric,

I've checked in some changes to CVS to fix this, if you want to try it out
and let me know. The basic problem is that binding with CS_NULL_TERM
returns a length that includes the null, so the length of 'test' would be
5. Most of the convert functions returned the correct amount (5) but a
few including numeric and float returned the size sans null (4 in the
example).

Since CS_FMT_NULLTERM was implemented before CS_UNUSED, it was
historically CS_FMT_UNUSED that decremented the value. Instead I've
switched things around so CS_FMT_NULLTERM increments the value.

This should also fix flt8, and money as well.

Brian

On Fri, 9 Mar 2001, Eric Deutsch wrote:

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