KNOWLEDGE BASE
Log In    |    Knowledge Base    |    4D Home
Tech Tip: Reviewing String comparison in 4D v11 SQL
PRODUCT: 4D | VERSION: 11 | PLATFORM: Mac & Win
Published On: February 11, 2009

In the past there has always been at least two ways to perform string comparison in 4D:


In many cases the two techniques could be used interchangeably; however there were times when the results could differ, so one might be preferred over the other. This is all the more evident in 4D v11 SQL so it is a good time to review these techniques.

The most important thing to understand in 4D v11 SQL is that, because Unicode is supported natively, all string comparisons must be compliant with Unicode standards. In particular there are characters that 4D is forced to ignore when checking a string, as described here.

Here is an example that illustrates this issue:

C_TEXT($lhs;$rhs)
$lhs:="A"+Char(0)+"B"
$rhs:="A"+Char(3)+"B"

C_BOOLEAN($b)
$b:= ($lhs=$rhs)

If ($b)
   ALERT("True")
Else
   ALERT("False")
End if


In 4D 2004 $b will evaluate to False because Char(0) is not the same as Char(3). In Unicode Char(0) is reserved and is therefore excluded from the comparison, so in 4D v11 SQL $b evaluates to True.

This is only one example. Diacritic- and case-sensitivity are two other important issues that should be considered.

Fortunately the Position command has been modified in version 11 in such a way as to give the developer complete control over the comparison. Specifically passing the "*" parameter to Position forces it to be sensitive to case, diacritics, and nulls. For example:

C_TEXT($lhs;$rhs)
$lhs:="A"+Char(0)+"B"
$rhs:="A"+Char(3)+"B"

C_LONGINT($pos)
$pos:=Position($lhs;$rhs;*)

If ($pos>0)
   ALERT("True")
Else
   ALERT("False")
End if


The above code evaluates to False because the two "null" characters do not match.

To perform case-insensitive matches (but retain diacritic- and null-sensitivity) simply use the UPPERCASE or LOWERCASE commands to normalize the strings.

Commented by Josh Fletcher on February 18, 2009 at 11:18 AM
Another good tip is to create wrapper Project Methods for the Position command so you can you can have a version for each desired behavior (e.g. Position_Default, Position_CaseSensitive, etc.).