Page 1 of 1

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

Posted: 20.03.2020, 14:25
by DPStano
CompareExtended_Equals from ZDbcCache will return an incorrect result for the "same" numbers

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

Posted: 23.03.2020, 14:51
by marsupilami
Could you post some example code please?

Best regards, Jan

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

Posted: 25.03.2020, 17:43
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);

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

Posted: 26.03.2020, 09:29
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

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

Posted: 26.03.2020, 17:40
by DPStano
thx for info, will switch to TBCDFields in future