Search code examples
delphidelphi-xedatasnaptclientdataset

Is there a limit for TClientDataSet filter, or is it a bug?


I'm using a TClientDataSet as an in-memory table and must apply a filter with a lot of conditions.

For example, with 400 OR conditions, I get an access violation when I try to enable the filter.

Access violation at address 4DAEDC76 in module 'midas.dll'. Read of address 00000034.

The exception occurs here :

procedure TCustomClientDataSet.AddExprFilter(const Expr: Widestring; Options: TFilterOptions); 
begin 
  if FExprFilter <> nil then FDSCursor.DropFilter(FExprFilter); 
  if Expr <> '' then 
  with TExprParser.Create(Self, Expr, Options, [poExtSyntax], '', nil, FieldTypeMap, True) do 
    try 
      CheckProviderEOF; 
      Check(FDSCursor.AddFilter(FilterData, DataSize, FExprFilter)); // ** AV HERE
    finally 
      Free; 
    end; 
end; 

Is it a bug on component or it's a limitation of the midas.dll ? I tested this behavior on these midas's versions: >= 15 and <= 23

I'm using Delphi XE. Example code:

procedure TForm41.Button1Click(Sender: TObject);
var
  I: Integer;
  FilterStr: string;
begin
  FilterStr := '(vehicleId = -1)';
  //It is just an example, the original code I can have any integer number.
  for I := 0 to 400 do //If I change the limit value to 40 for example, it works. 
    FilterStr := FilterStr + ' or (vehicleId = ' + IntToStr(I) + ')';

  ClientDataSet1.Filter := FilterStr;
  ClientDataSet1.Filtered := True;
  ClientDataSet1.CreateDataSet; //Error here
end;

I already tried to use IN statement, but I get the same error.

I didn't found references about this situation on internet.


Solution

  • I can reproduce this error, including the "Read of address 00000034" in Delphi Seattle. It occurs when more than about 280 terms are in the Filter expression. It's obviously a midas limitation. You need a better way of translating from your problem domain to the desired effect of your filter.

    If you can evaluate your condition in code, then what I would do is to add a boolean fkInternalCalc field to the CDS and set it to True of False depending on the result. Then, filtering the dataset is a simple matter of applying a filter based on the value of the boolean.