View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0030853 | FPC | Compiler | public | 2016-11-03 15:59 | 2021-01-06 09:35 |
Reporter | Vladimir K | Assigned To | Marco van de Voort | ||
Priority | normal | Severity | minor | Reproducibility | always |
Status | feedback | Resolution | reopened | ||
Platform | 64 | OS | Windows | ||
Product Version | 3.0.0 | ||||
Fixed in Version | 3.1.1 | ||||
Summary | 0030853: VarToBcd for value 0 issue | ||||
Description | VarToBcd returns for value 0 structure filled with 0 (Precision, SignSpecialPlaces and Fraction) while Delphi returns Precision 10 and SignSpecialPlaces 2. It looks insignificant until BCD value sent to ASE (Sybase) and fails with message "Domain error during implicit conversion of NUMERIC value '' to a DECIMAL field". | ||||
Steps To Reproduce | var v: Variant; bcd: TBcd; begin v := 0; bcd := VarToBcd(v); | ||||
Additional Information | For now avoidable by fix after conversion if (bcd.Precision = 0) and (bcd.SignSpecialPlaces = 0) then begin bcd.Precision := 10; bcd.SignSpecialPlaces := 2; end; | ||||
Tags | FmtBCD | ||||
Fixed in Revision | 38333 | ||||
FPCOldBugId | |||||
FPCTarget | |||||
Attached Files |
|
|
|
|
Checked with Delphi, indeed. Fix committed. |
|
I checked with Delphi 7 and there is Precision=18 and SignSpecialPlaces=4. May be it would be best to look why ASE returns error ... @Vladimir: can you provide more information about database components you use and small code sample which can reproduce mentioned error. |
|
Delphi7 returns (Precision SignSpecialPlaces): value 0: VarToBcd: 18 4 value 0: DoubleToBcd: 8 2 value 0: IntegerToBcd: 8 2 value 1: IntegerToBcd: 1 0 (so for value 0 various BCD functions returns various results (two various internal representations for same 0 value) ... IMO pretty inconsistent, but not wrong; Probably newer versions of Delphi will return other results so we can not take here Delphi as strong standard (AFAIK FmtBCD unit was changed among Delphi version)) While FPC: value 0: VarToBcd: 0 0 value 0: DoubleToBcd: 0 0 value 0: IntegerToBcd: 0 0 value 1: IntegerToBcd: 1 0 In all cases back-conversion BcdToStr() for 0 value returns '0'. IMO problem is not in internal representation of value 0 (which may be correct), but how this value is later handled by "database" layer, which sends it to ASE server. Fix povided by Marco is hot-fix for given particular VarToBCD situation, but does not handle for example IntegerToBcd or DoubleToBcd conversions of value 0. IMO we need more details from "Vladimir K" to identify root of problem. I have suspection that "Vladimir K" uses 3rd party "database" layer, because TMSSQLConnection and TODBCConnection should handle 0 BCD values correctly. |
|
IMO we must say if we want to distinguish NullBcd (here null means undefined or unknown value) and "ZeroBcd". I have attached patch, which introduces "ZeroBCD" with Precision=1, SignSpecialScale=0 and Fraction=all 0. It is not perfect solution, but in this case - if "database" layer is sensitive to NullBCD (all zeroes in TBCD) - this should help. "Vladimir K" can you test with this patch: fmtbcd.pp.1 ? IMO it does not give sense to represent 0 in TBCD with Precisions 8,10 or 18 and/or scales of 2 or 4 (as we see it in Delphi), because 0 is integer (with zero decimal digits) so there is no sense have "Scale" other than 0. And also "Precision" should be only 0 or 1 (as there is only 0/1 significant digit before decimal point) fmtbcd.pp.1.diff (1,565 bytes)
--- fmtbcd.pp.ori Fri Aug 09 13:34:11 2019 +++ fmtbcd.pp Fri Aug 09 13:38:49 2019 @@ -797,10 +797,12 @@ {$endif} function __get_null : tBCD; Inline; + function __get_zero : tBCD; Inline; function __get_one : tBCD; Inline; PROPERTY NullBCD : tBCD Read __get_null; + ZeroBCD : tBCD Read __get_zero; OneBCD : tBCD Read __get_one; //{$define __lo_bh := 1 * ( -( MaxFmtBCDFractionSize * 1 + 2 ) ) } @@ -887,16 +889,20 @@ OneBCD_ : tBCD; function __get_null : tBCD; Inline; - begin __get_null := NullBCD_; - end; + end; - function __get_one : tBCD; Inline; + function __get_zero : tBCD; Inline; + begin + __get_zero := NullBCD_; + __get_zero.Precision := 1; + end; + function __get_one : tBCD; Inline; begin __get_one := OneBCD_; - end; + end; type range_digits = 1..maxfmtbcdfractionsize; @@ -1584,7 +1590,7 @@ begin _SELECT _WHEN aValue = 0 - _THEN result := NullBCD; + _THEN result := ZeroBCD; _WHEN aValue = 1 _THEN result := OneBCD; _WHEN aValue = low ( myInttype ) @@ -4129,12 +4135,6 @@ not_implemented; else { array or something like that } not_implemented; - end; - // peephole, avoids problems with databases, mantis #30853 - if (Result.Precision = 0) and (Result.SignSpecialPlaces = 0) then - begin - Result.Precision := 10; - Result.SignSpecialPlaces := 2; end; end; |
|
@Marco: you have assigned this bug to me, but I have no commit rights to unit FmtBCD. As far as here is no more reaction from original bug reporter, I can not investigate reasons of problems in deep. I would like to have applied my last patch - fmtbcd.pp.1.diff - which fixes reported problem in "Steps To Reproduce". Thank you |
Date Modified | Username | Field | Change |
---|---|---|---|
2016-11-03 15:59 | Vladimir K | New Issue | |
2018-02-24 21:55 | Marco van de Voort | File Added: bug30853.pp | |
2018-02-24 21:55 | Marco van de Voort | Fixed in Revision | => 38333 |
2018-02-24 21:55 | Marco van de Voort | Note Added: 0106596 | |
2018-02-24 21:55 | Marco van de Voort | Status | new => resolved |
2018-02-24 21:55 | Marco van de Voort | Fixed in Version | => 3.1.1 |
2018-02-24 21:55 | Marco van de Voort | Resolution | open => fixed |
2018-02-24 21:55 | Marco van de Voort | Assigned To | => Marco van de Voort |
2018-05-29 13:54 | LacaK | Note Added: 0108573 | |
2018-05-29 13:54 | LacaK | Status | resolved => feedback |
2018-05-29 13:54 | LacaK | Resolution | fixed => reopened |
2019-08-09 12:30 | LacaK | Note Added: 0117611 | |
2019-08-09 12:30 | LacaK | Note Edited: 0117611 | View Revisions |
2019-08-09 12:40 | LacaK | Note Edited: 0117611 | View Revisions |
2019-08-09 12:46 | LacaK | Note Edited: 0117611 | View Revisions |
2019-08-09 13:39 | Marco van de Voort | Assigned To | Marco van de Voort => LacaK |
2019-08-09 13:52 | LacaK | File Added: fmtbcd.pp.1.diff | |
2019-08-09 13:52 | LacaK | Note Added: 0117612 | |
2019-08-09 14:21 | LacaK | Note Edited: 0117612 | View Revisions |
2021-01-03 10:19 | LacaK | Tag Attached: FmtBCD | |
2021-01-06 09:32 | LacaK | Assigned To | LacaK => Marco van de Voort |
2021-01-06 09:35 | LacaK | Note Added: 0128118 |