Page 1 of 2

Bug in DataSet-Filter?

Posted: Mon 09 Sep 2013 13:31
by a-s-z
Hi,

I want to filter a DataSet locally, so I use DataSet.Filter.

When setting FilterOptions to foNoPartialCompare, using LIKE is not possible anymore.

I think this is a bug in Odac, since the Delphi reference says that setting foNoPartialCompare will affect matching only for strings ending with "*". Like search using "%" and "_" should work regardless of FilterOptions.

Best regards,
Andre

Re: Bug in DataSet-Filter?

Posted: Mon 09 Sep 2013 14:26
by AlexP
Hello,

In the standard Delphi filter you can use the '*' character only; the '_' and '%' characters are implemented by us, and the foNoPartialCompare option also affects their behaviour.

Re: Bug in DataSet-Filter?

Posted: Mon 09 Sep 2013 15:13
by a-s-z
Hi Alex,
AlexP wrote:In the standard Delphi filter you can use the '*' character only; the '_' and '%' characters are implemented by us, and the foNoPartialCompare option also affects their behaviour.
Well, the behavior depends on the class you are using. When using TClientDataSet, usage of '%' and '_' is possible. :wink:
It is a pity that the documentation does not correspond to implementation of the base class TDataSet.

So I know Odac is better than standard TDataSet :), but does it make sense to use this option like it is implemented now? In my opinion the option foNoPartialCompare should not affect usage of '%' and '_' in LIKE operator in any form. This would be a real enhancement, because now it is not possible to filter for literal '*', when I want to use LIKE. In addition it would be great to add the possibility to escape '%' and '_' (e.g. using '\'), so you could filter for these chars too.

Is it possible to use LIKE and filter literal '*' at the same time in Odac, using other syntax or options?

Best regards,
Andre

Re: Bug in DataSet-Filter?

Posted: Tue 10 Sep 2013 08:01
by AlexP
Hello,

We have modified the behaviour of our DataSet. Now, when using LIKE[NOT LIKE], the NoPartialCompare option will not be taken into account, comparison will be performed similarly to ClientDataSet

Re: Bug in DataSet-Filter?

Posted: Tue 10 Sep 2013 09:53
by a-s-z
Hi Alex,
AlexP wrote:We have modified the behaviour of our DataSet. Now, when using LIKE[NOT LIKE], the NoPartialCompare option will not be taken into account, comparison will be performed similarly to ClientDataSet
Great news, thanks. Is it possible to escape '%' and '_' too?
When will next version be available?
Will http://forums.devart.com/viewtopic.php?f=5&t=27581 get fixed in next version too?

Re: Bug in DataSet-Filter?

Posted: Wed 11 Sep 2013 12:23
by AlexP
Hello,

Yes, character escaping is also supported. The next version will be released after the official XE5 release.

Re: Bug in DataSet-Filter?

Posted: Wed 11 Sep 2013 13:47
by a-s-z
Hi Alex,
AlexP wrote:Yes, character escaping is also supported. The next version will be released after the official XE5 release.
OK, XE5 is released today :) (http://www.embarcadero.com/press-releas ... os-support), so I am glad to see next release soon :D

Is it possible to add function MatchesMask to interface part of unit, so we can use it in out application?

Best regards,
Andre

Re: Bug in DataSet-Filter?

Posted: Thu 12 Sep 2013 11:58
by AlexP
Hello,

We plan to release the new version next week.
The MatchesMask method is used inside one method only, and there is no need to move it out

Re: Bug in DataSet-Filter?

Posted: Mon 23 Sep 2013 07:56
by a-s-z
Hi Alex,
AlexP wrote:We have modified the behaviour of our DataSet. Now, when using LIKE[NOT LIKE], the NoPartialCompare option will not be taken into account, comparison will be performed similarly to ClientDataSet
I have looked into the new version and it seems that behavior of LIKE when using NoPartialCompare is a little bit weird, because the star is not ignored at all. You must escape it with a backslash to make the filter work. :?:

The star should be recognized only when option NoPartialCompare is not set and then only at the end of the pattern. Please test this behavior against TClientDataSet.

Best Regards,
Andre

Re: Bug in DataSet-Filter?

Posted: Mon 23 Sep 2013 10:02
by AlexP
Hello,

Unfortunately, we cannot make the filter behaviour fully similar to ClientDataSet, since it will change the current behaviour, and users using filtering in our components will encounter problems when updating to new product versions.

Re: Bug in DataSet-Filter?

Posted: Mon 23 Sep 2013 14:28
by a-s-z
Hi Alex,
AlexP wrote:Unfortunately, we cannot make the filter behaviour fully similar to ClientDataSet, since it will change the current behaviour, and users using filtering in our components will encounter problems when updating to new product versions.
I have a patch using a global variable in MemData.pas to change the behavior. Should I send it to you, or can I post it here?

Please note that current ODAC code will access Mask[0] when Mask[1] = '_'. My code will fix this error.

Best regards,
Andre

Re: Bug in DataSet-Filter?

Posted: Tue 24 Sep 2013 09:14
by AlexP
Hello,

Please provide your code - we will try to include it to the new version if it doesn't change the current behaviour

Re: Bug in DataSet-Filter?

Posted: Tue 24 Sep 2013 10:18
by a-s-z
Hi Alex,
AlexP wrote:Please provide your code - we will try to include it to the new version if it doesn't change the current behaviour
Here we go :)
  • % and _ will be recognized only for LIKE
  • Any char can be escaped with \
  • With 'OldFilterAsteriskBehavior=False', * will match only at end of string and foNoPartialCompare not set.
  • With 'OldFilterAsteriskBehavior=True', * will act like % (also for equality operator)

Code: Select all

diff -ur NewFilterBehavior.orig/Source/MemData.pas ODAC for RAD Studio XE2/Source/MemData.pas
--- NewFilterBehavior.orig/Source/MemData.pas	2013-09-12 19:48:14.000000000 +0200
+++ ODAC for RAD Studio XE2/Source/MemData.pas	2013-09-23 15:30:37.033885200 +0200
@@ -1432,6 +1432,9 @@
 function AddCRUnicode(Source, Dest: IntPtr; Count: integer): integer; overload;
 function RemoveCRUnicode(Source, Dest: IntPtr; DestLen, Count: integer): integer; overload;
 
+var
+  OldFilterAsteriskBehavior: Boolean = True;
+
 implementation
 
 uses
@@ -5299,12 +5302,29 @@
   type
     TMatchesResult = (mrFalse,mrTrue,mrEnd);
 
+    function IsLikeNode: Boolean;
+    begin
+      Result := Node.NodeType in [ntLike, ntNotLike];
+    end;
+    function CheckWildcardAst(MaskIndex: integer): Boolean;
+    begin
+      Result := Mask[MaskIndex] = WildcardAst;
+      if Result then
+      begin
+        if OldFilterAsteriskBehavior then
+          Result := True
+        else if FilterNoPartialCompare then
+          Result := False
+        else
+          Result := MaskIndex = Length(Mask);
+      end;
+    end;
     function SubMatchesMask(StIndex, MaskIndex: integer): TMatchesResult;
     begin
       while (MaskIndex <= Length(Mask)) and
         ((StIndex <= Length(St)) or
-        ((Mask[MaskIndex] = WildcardAst) or (Mask[MaskIndex] = WildcardPct))) do begin
-        if (Mask[MaskIndex] = WildcardAst) or (Mask[MaskIndex] = WildcardPct) then begin
+        ((Mask[MaskIndex] = WildcardAst) or (IsLikeNode and (Mask[MaskIndex] = WildcardPct)))) do begin
+        if (CheckWildcardAst(MaskIndex)) or (IsLikeNode and (Mask[MaskIndex] = WildcardPct)) then begin
           if MaskIndex = Length(Mask) then begin  //-
             Result := mrTrue;                     // Speed up
             Exit;                                 // with mask '*'
@@ -5331,7 +5351,7 @@
         else begin
           if Mask[MaskIndex] = '\' then
             Inc(MaskIndex);
-          if (St[StIndex] = Mask[MaskIndex]) or ((Mask[MaskIndex] = WildcardOne) and (Mask[MaskIndex - 1] <> '\'))
+          if (St[StIndex] = Mask[MaskIndex]) or (IsLikeNode and (Mask[MaskIndex] = WildcardOne) and ((MaskIndex = 1) or (Mask[MaskIndex - 1] <> '\')))
           then begin
             Inc(StIndex);
             Inc(MaskIndex);
Best regards,
Andre

Re: Bug in DataSet-Filter?

Posted: Wed 25 Sep 2013 12:19
by AlexP
Hello,
% and _ will be recognized only for LIKE
Any char can be escaped with \
this will be modification of the current behaviour, we cannot apply such a fix
With 'OldFilterAsteriskBehavior=False', * will match only at end of string and foNoPartialCompare not set.
With 'OldFilterAsteriskBehavior=True', * will act like % (also for equality operator)
We will consider the possibility to add these changes.

Re: Bug in DataSet-Filter?

Posted: Wed 25 Sep 2013 12:51
by a-s-z
Hi Alex,
AlexP wrote:
% and _ will be recognized only for LIKE
Any char can be escaped with \
this will be modification of the current behaviour, we cannot apply such a fix
With 'OldFilterAsteriskBehavior=False', * will match only at end of string and foNoPartialCompare not set.
With 'OldFilterAsteriskBehavior=True', * will act like % (also for equality operator)
We will consider the possibility to add these changes.
Well, the handling of the escape char (introduced in 9.1.3) is a change in behavior too, so I do not see a problem. :shock:
But if you want to maintain the behavior of 9.1.3 you can replace

Code: Select all

Result := Node.NodeType in [ntLike, ntNotLike];
in function IsLikeNode by

Code: Select all

Result := (Node.NodeType in [ntLike, ntNotLike]) or OldFilterAsteriskBehavior;
Best regards,
Andre