#1 2015-02-24 14:29:09

vaclav
Member
Registered: 2015-02-24
Posts: 4

FillPrepare doesn't work correctly for WIN32* collation

Hello Arnaud,
for very specific strings (like 'd:') the FillPrepare doesn't work correctly under WIN32CASE or WIN32NOCASE collation. The result of the following program is TRUE, but when activating

aModel.SetCustomCollationForAllRawUTF8('WIN32NOCASE');

the result is FALSE.
Maybe it could be connected with SQL WHERE ':(...):' query envelope. But I need the Name field values like 'd:', i.e. folder names.
Thank you in advance for any idea!

program Demo;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  SynCommons,
  mORMot,
  mORMotSQlite3,
  SynSQLite3,
  SynSQLite3Static;

const
  aDatabase = 'D:\demo.db3';

type
  TSQLFolder = class(TSQLRecord)
  private
    fName: RawUTF8;
  published
    property Name: RawUTF8 index 1024 read fName write fName;
  end;

var
  aModel: TSQLModel;
  aServer: TSQLRestServerDB;
  aFolder: TSQLFolder;

begin
  DeleteFile(aDatabase);
  aModel := TSQLModel.Create([TSQLFolder]);
  try
    //aModel.SetCustomCollationForAllRawUTF8('WIN32NOCASE'); // the same for WIN32CASE
    aServer := TSQLRestServerDB.Create(aModel, aDatabase);
    aFolder := TSQLFolder.Create;
    try
      aServer.CreateMissingTables;
      aFolder.Name := StringToUTF8('d:');
      aServer.Add(aFolder, True);
      aFolder.FillPrepare(aServer, 'Name = ?', [StringToUTF8('d:')]);
      Write(aFolder.FillOne);
      Readln;
    finally
      aFolder.Free;
      aServer.Free;
    end;
  finally
    aModel.Free;
  end;
end.

Last edited by vaclav (2015-03-22 20:33:05)

Offline

#2 2015-03-22 20:31:36

vaclav
Member
Registered: 2015-02-24
Posts: 4

Re: FillPrepare doesn't work correctly for WIN32* collation

The solution seems to be making changes in SynSQLite3.pas (CompareStringW needs unicode character count, not bytes count):

function Utf16SQLCompCase(...)
begin
  ...
  result := CompareStringW(GetThreadLocale, 0, S1, S1len div 2, S2, S2Len div 2) - 2;
  ...
end;
function Utf16SQLCompNoCase(...)
begin
  ...
  result := CompareStringW(GetThreadLocale, NORM_IGNORECASE, S1, S1len div 2, S2, S2Len div 2) - 2;
  ...
end;

Please, could you verify my thoughts and implement the correction?

Offline

#3 2015-03-23 07:58:23

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,655
Website

Re: FillPrepare doesn't work correctly for WIN32* collation

Should be fixed by http://synopse.info/fossil/info/63e68170ff

Thanks for the feedback!
smile

Offline

Board footer

Powered by FluxBB