[fpc-devel] SQLite and ftFmtBCD
Joost van der Sluis
joost at cnoc.nl
Tue May 10 13:18:45 CEST 2011
On Tue, 2011-05-10 at 12:39 +0200, LacaK wrote:
> Hi Joost (and others also ;-),
>
> I comment your question about
> http://bugs.freepascal.org/view.php?id=18809 here.
> (because I do not know what comment here and what in bug tracker)
>
> I see problem in fact, that AsString returns number formated using
> locale specific DecimalSeparator.
> So if FmtBCD param will hold value "123456789,123456789" then this value
> will be written into SQLite3 database.
>
> Which is IMO not very good, becuase SQL standard and also SQLite
> expects, that numeric values will always have point as decimal separator.
True.
> So my suggestion is in case of ftFMTBCD param use something like:
>
> ftFmtBCD: begin
> str1:= BCDToStr(P.AsFMTBCD, SQLFormatSettings); //this depend on bug 18807
> checkerror(sqlite3_bind_text(fstatement,I,pcharstr(str1), length(str1), at freebindstring));
> end;
I'll look at this solution. I'm a little bit confused about
SQLFormatSettings and why it was implemented as it is now. I'll have to
investigate this.
> or better:
> ftFmtBCD: begin
> if P.AsFMTBCD.Precision > 15 then //we are out of REAL range, so we must bind as BLOB
> begin
> str1:=BCDTOStr(P.AsFMTBCD, SQLFormatSettings);
> checkerror(sqlite3_bind_blob(fstatement,I,pcharstr(str1), length(str1), @freebindstring));
> end
> else
> begin
> do1=P.AsFloat
> checkerror(sqlite3_bind_double(fstatement,I,do1));
> end;
> end;
This is wrong. There are some values which can't be written as floats,
but have precision<15.
> ----------------------
> Other questions:
> > " Isn't it better to use '4' instead of 255/0 as default value for
> the scale?"
> SQL standard says, that if scale is ommited then scale is 0 ... imho it
> is better to follow standard
But this particular piece of code is used when an invalid value is
supplied, like 'DECIMAL(10,A)'. The case that the value is omitted is
handled elsewhere.
> > " Isn't it better to map to a ftInteger/ftLargeInt field when size1=0?"
> Yes IMHO it is better, at least because ftLargeInt (int64) can hold more
> significant digits (left to decimal point) than ftBCD (currency)
> But what if user defines NUMERIC(30,0) then we have two options:
> 1. say "sorry" SQLite does not support this, so we map to ftLargeInt
Nah...
> 2. or map to ftFmtBCD if (scale>4) or (precision>18)
>
> if precision>18 then ftFmtBCD
> else if scale=0 then ftLargeInt
> else if scale<=4 then ftBCD
> else ftFmtBCD
Can you create a patch which does this?
Joost
More information about the fpc-devel
mailing list