ZeosLib can't correctly compare Extended value when creating update query

The forum for ZeosLib 7.2 Report problems. Ask for help, post proposals for the new version and Zeoslib 7.2 features here. This is a forum that will be edited once the 7.2.x version goes into RC/stable!!

My personal intention for 7.2 is to speed up the internals as optimal a possible for all IDE's. Hope you can help?! Have fun with testing 7.2
Post Reply
DPStano
Junior Boarder
Junior Boarder
Posts: 39
Joined: 16.05.2016, 09:21

ZeosLib can't correctly compare Extended value when creating update query

Post by DPStano »

CompareExtended_Equals from ZDbcCache will return an incorrect result for the "same" numbers
marsupilami
Platinum Boarder
Platinum Boarder
Posts: 1956
Joined: 17.01.2011, 14:17

Re: ZeosLib can't correctly compare Extended value when creating update query

Post by marsupilami »

Could you post some example code please?

Best regards, Jan
DPStano
Junior Boarder
Junior Boarder
Posts: 39
Joined: 16.05.2016, 09:21

Re: ZeosLib can't correctly compare Extended value when creating update query

Post by DPStano »

it's definitely regression, you can't compare two floats this way, https://floating-point-gui.de/errors/comparison/

just load some decimal number to the dataset, update dataset without changes (Edit and Post) and zeos will create update query that contains your decimal field even field not changed.

I'm hooking that code for now (it's not a universal solution, epsilon it's set for our needs)

Code: Select all

function InterceptCompareExtended_Equals(const Null1, Null2: Boolean; const V1, V2): Integer;
begin
  if Null1 and Null2 then
    Result := 0
  else
    Result := CompareValue(PExtended(V1)^, PExtended(V2)^, 0.000001);
end;

var
  TrampolineGetCompareFunc: function(const Self: TZRowAccessor; ColumnIndex: Integer; const CompareKind: TComparisonKind): TCompareFunc = nil;

function InterceptGetCompareFunc(const Self: TZRowAccessor; ColumnIndex: Integer; const CompareKind: TComparisonKind): TCompareFunc;
begin
  if (Self.GetColumnType(ColumnIndex) = stBigDecimal) and (CompareKind = ckEquals) then
    Result := InterceptCompareExtended_Equals
  else
    Result := TrampolineGetCompareFunc(Self, ColumnIndex, CompareKind);
end;

@TrampolineGetCompareFunc := InterceptCreate(@TZRowAccessor.GetCompareFunc, @InterceptGetCompareFunc);
marsupilami
Platinum Boarder
Platinum Boarder
Posts: 1956
Joined: 17.01.2011, 14:17

Re: ZeosLib can't correctly compare Extended value when creating update query

Post by marsupilami »

Hello :)
DPStano wrote: 25.03.2020, 17:43 it's not a universal solution, epsilon it's set for our needs
This is the main problem - we cannot know a correct epsilon to use. We only could try to generate an epsilon if the database field is a DECIMAL or NUMERIC field.

But then - the current value of a TFlotField or TExtendedField should be determined when we load the data. The question for me is - why should it change if one does a edit / post cycle without touching it? Maybe this has to do with the conversion between a binary representation and a decimal representation. In that case epsilon could be very very small - compared to the values in the float...

Zeos 7.3 supports NUMERIC and DECIMAL fields correctly now by using TBCDField and TFMTBCDField. Maybe this solves your problem?

Best regards,

Jan
DPStano
Junior Boarder
Junior Boarder
Posts: 39
Joined: 16.05.2016, 09:21

Re: ZeosLib can't correctly compare Extended value when creating update query

Post by DPStano »

thx for info, will switch to TBCDFields in future
Post Reply