Recent

Author Topic: TlargeIntField set filter error  (Read 933 times)

zhangshelly

  • New Member
  • *
  • Posts: 14
TlargeIntField set filter error
« on: February 04, 2025, 03:43:21 pm »
var
  Fdb:Tbufdataset;
begin
  Fdb:=Tbufdataset.Create(nil);
  Fdb.FieldDefs.Add('prjid',ftlargeint);
  Fdb.FieldDefs.Add('no',ftstring,10);
  Fdb.CreateDataset;
  Fdb.AppendRecord([3556856671915480078,'1']);
  Fdb.AppendRecord([3556856671915480078,'2']);
  Fdb.AppendRecord([3556856671915480017,'3']);
  Fdb.Filter:='prjid=3556856671915480078';                    -- raise Exception
  Fdb.Filtered:=True;   
end; 


zhangshelly

  • New Member
  • *
  • Posts: 14
Re: TlargeIntField set filter error
« Reply #1 on: February 04, 2025, 03:58:04 pm »
var
  Fdb:TmemDataset;
begin
  Fdb:=TmemDataset.Create(nil);
  Fdb.FieldDefs.Add('prjid',ftlargeint);
  Fdb.FieldDefs.Add('no',ftstring,10);
  Fdb.CreateDataset;
  Fdb.AppendRecord([3556856671915480078,'1']);
  Fdb.AppendRecord([3556856671915480078,'2']);
  Fdb.AppendRecord([3556856671915480017,'3']);
  Fdb.Filter:='prjid=3556856671915480078';                   
  Fdb.Filtered:=True;                                           --no filter
end;

cdbc

  • Hero Member
  • *****
  • Posts: 1968
    • http://www.cdbc.dk
Re: TlargeIntField set filter error
« Reply #2 on: February 04, 2025, 04:24:57 pm »
Hi
'ftLargeInt' = int64; NOT QWord. That means, your integer is prolly too large!
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 3.6 up until Jan 2024 from then on it's both above &: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 4.99

zhangshelly

  • New Member
  • *
  • Posts: 14
Re: TlargeIntField set filter error
« Reply #3 on: February 04, 2025, 04:28:32 pm »
it can save  3556856671915480078 as value and display right, only can't  filter
the same code change to Tadodataset in delphi,the result is right

zhangshelly

  • New Member
  • *
  • Posts: 14
Re: TlargeIntField set filter error
« Reply #4 on: February 04, 2025, 04:34:41 pm »
it can save  3556856671915480078 as value and display right, only can't  filter
the same code change to Tadodataset in delphi,the result is right
uses  VirtualTable(unidac) can get right result

  var
  Fdb:TVirtualTable;
begin
  Fdb:=TVirtualTable.Create(nil);
  Fdb.FieldDefs.Add('prjid',ftlargeint);
  Fdb.FieldDefs.Add('no',ftstring,10);
  Fdb.active:=True;
  Fdb.AppendRecord([3556856671915480078,'1']);
  Fdb.AppendRecord([3556856671915480078,'2']);
  Fdb.AppendRecord([3556856671915480017,'3']);
  Fdb.Filter:='prjid=3556856671915480078';
  Fdb.Filtered:=True;
  ds.DataSet:=fdb; 
end;   

BrunoK

  • Hero Member
  • *****
  • Posts: 687
  • Retired programmer
Re: TlargeIntField set filter error
« Reply #5 on: February 04, 2025, 06:07:18 pm »
Probably a bug, see following program.
Code: Pascal  [Select][+][-]
  1. program a;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   Classes,
  7.   SysUtils,
  8.   DB,
  9.   BufDataset;
  10.  
  11. var
  12.   Fdb: Tbufdataset;
  13. begin
  14.   Fdb := Tbufdataset.Create(nil);
  15.   Fdb.FieldDefs.Add('prjid', ftlargeint);
  16.   Fdb.FieldDefs.Add('no', ftstring, 10);
  17.   Fdb.CreateDataset;
  18.   Fdb.AppendRecord([0, '0']);
  19.   Fdb.AppendRecord([High(Int64), '1']);
  20.   Fdb.AppendRecord([3556856671915480078, '2']); // ~bk is within range of ftLargeInt
  21.   Fdb.AppendRecord([3556856671915480017, '3']);
  22.   WriteLn('RecordCount=', Fdb.RecordCount, ' UNFILTERED');
  23.   with Fdb do begin
  24.     First;
  25.     while not EOF do begin
  26.       WriteLn(FieldByName('prjid').AsString, ' ', FieldByName('no').AsString: 4);
  27.       Next;
  28.     end;
  29.   end;
  30.   Fdb.Filter := 'prjid=3556856671915480078'; // 'prjid=0' -> works
  31.   WriteLn('Filtered with ''', Fdb.Filter, '''');
  32.   Fdb.Filtered := True;
  33.   with Fdb do begin
  34.     First;
  35.     while not EOF do begin
  36.       WriteLn(FieldByName('prjid').AsString, ' ', FieldByName('no').AsString: 4);
  37.       Next;
  38.     end;
  39.   end;
  40.  
  41.   ReadLn;
  42. end.

cdbc

  • Hero Member
  • *****
  • Posts: 1968
    • http://www.cdbc.dk
Re: TlargeIntField set filter error
« Reply #6 on: February 04, 2025, 07:02:42 pm »
Hi
@BrunoK: I copy pasted your example and compiled it with trunk and ran it...
Screenshot attached...
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 3.6 up until Jan 2024 from then on it's both above &: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 4.99

BrunoK

  • Hero Member
  • *****
  • Posts: 687
  • Retired programmer
Re: TlargeIntField set filter error
« Reply #7 on: February 04, 2025, 07:22:05 pm »
Hi
@BrunoK: I copy pasted your example and compiled it with trunk and ran it...
Screenshot attached...
Regards Benny

Interesting, will take a look tomorrow. Me is fpc 3.2.2 but with more recent package db from trunk.

zhangshelly

  • New Member
  • *
  • Posts: 14
Re: TlargeIntField set filter error
« Reply #8 on: March 24, 2025, 11:01:42 am »
mey be error locate in   dbf_prscore.pas 

Zvoni

  • Hero Member
  • *****
  • Posts: 2921
Re: TlargeIntField set filter error
« Reply #9 on: March 24, 2025, 12:07:00 pm »
Acc. to the callstack (i can confirm TS' issue): the culprit is a Call to SysUtils.StrToInt in dbf_prscore TCustomExpressionParser.ParseString (line 968 in dbf_prscore for fpc3.2.2 on my installation).

In TS' case we would need a Call to StrToInt64 instead

At first glance i'd consider it a bug, which would need to be reported on bugtracker.

EDIT: I don't have Trunk/Main.
Could someone compare in Trunk/Main " dbf_prscore --> TCustomExpressionParser.ParseString"?
Inside that Procedure there are 2 calls to StrToInt, but my money is on the second one (the first appearance of StrToint has to do with hexadecimal).

EDIT2: Nother stumbling block inside ParseString is probably the whole line 968
Code: Pascal  [Select][+][-]
  1. TempWord := TIntegerConstant.Create(StrToInt(W));  

"TIntegerConstant"

and in dbf_prsdef the Value is an "Integer".
Notabene: in dbf_prsdef there is also a "TLargeIntConstant"......
« Last Edit: March 24, 2025, 12:31:33 pm by Zvoni »
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

BrunoK

  • Hero Member
  • *****
  • Posts: 687
  • Retired programmer
Re: TlargeIntField set filter error
« Reply #10 on: March 24, 2025, 12:38:38 pm »
I submitted a patch in issue :
https://gitlab.com/freepascal.org/fpc/source/-/issues/41139

Maybe you might test it.

Zvoni

  • Hero Member
  • *****
  • Posts: 2921
Re: TlargeIntField set filter error
« Reply #11 on: March 24, 2025, 01:13:12 pm »
I submitted a patch in issue :
https://gitlab.com/freepascal.org/fpc/source/-/issues/41139

Maybe you might test it.
Cannot test (Company-Laptop with restrictions), but just reading the patch, i'd say it looks very good.

The only thing i don't like in your patch, are these 2 lines
Code: Pascal  [Select][+][-]
  1. +      false: Result := TIntegerConstant.Create(lInt64);
  2. ......
  3. +    Result := TIntegerConstant.Create(StrToInt64(aIntStr));
because you pass an Int64 to the "regular" TIntegerConstant, which has an Integer for its Constructor-Argument.
I'd gone for a solution using the "correct" DataType and conversion (StrToInt)

Something along the lines of (Aircode!!)
Code: Pascal  [Select][+][-]
  1. +  function IntegerExprCreate(aIntStr: string): TExprWord;
  2. +  {$ifdef SUPPORT_INT64}
  3. +  var
  4. +    lInt32: Integer;
  5. +    lIsI64: boolean = False;
  6. +    lInt64: Int64;
  7. +  begin
  8. +    lInt64:= StrToInt64(aIntStr);
  9. +    lIsI64 := (lInt64<low(Integer)) or (lInt64>High(Integer));
  10. +    case lIsI64 of
  11. +      false: Begin
  12. +               lInt32:=StrToInt(aIntStr);  //Could be coalesced into one line
  13. +               Result := TIntegerConstant.Create(lInt32);
  14. +             End;
  15. +      true:  Result := TLargeIntConstant.Create(lInt64);
  16. +    end;
  17. +  {$else}
  18. +  begin
  19. +    Result := TIntegerConstant.Create(StrToInt(aIntStr));
  20. +  {$endif}
  21. +  end;
  22. +
« Last Edit: March 24, 2025, 01:41:12 pm by Zvoni »
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

BrunoK

  • Hero Member
  • *****
  • Posts: 687
  • Retired programmer
Re: TlargeIntField set filter error
« Reply #12 on: March 24, 2025, 02:15:40 pm »
because you pass an Int64 to the "regular" TIntegerConstant, which has an Integer for its Constructor-Argument.
I'd gone for a solution using the "correct" DataType and conversion (StrToInt)
The compiler converts the Int64 to Int32 when calling create in its 32 bit version.

Doing a lInt64 = StrToInt64(aIntStr); and then testing  if it is 32 bit or 64 bit seems Ok to me.

Zvoni

  • Hero Member
  • *****
  • Posts: 2921
Re: TlargeIntField set filter error
« Reply #13 on: March 24, 2025, 02:32:17 pm »
because you pass an Int64 to the "regular" TIntegerConstant, which has an Integer for its Constructor-Argument.
I'd gone for a solution using the "correct" DataType and conversion (StrToInt)
The compiler converts the Int64 to Int32 when calling create in its 32 bit version.

Doing a lInt64 = StrToInt64(aIntStr); and then testing  if it is 32 bit or 64 bit seems Ok to me.
No worries.
as i wrote i like your patch.
It's just that i'm a proponent of "use the correct Datatype wherever possible. Don't rely on implicit conversion."
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

BrunoK

  • Hero Member
  • *****
  • Posts: 687
  • Retired programmer
Re: TlargeIntField set filter error
« Reply #14 on: March 24, 2025, 02:48:13 pm »
What takes time is converting a string to an integer value.

Redoing StrToInt to satisfy super correct DataType uselessly slows things. (Of course, not very significant).

What I agree on is that
Code: Pascal  [Select][+][-]
  1. +  {$else}
  2. +  begin
  3. +    Result := TIntegerConstant.Create(StrToInt(aIntStr));
  4. +  {$endif}
Should use StrToInt so an error gets raised early instead of counting on overflow checking of the conversion to the target parameter type.

 

TinyPortal © 2005-2018