#1 2018-10-01 17:15:24

Joe
Member
Registered: 2014-10-13
Posts: 12

TDynArrayHashed's bug triggered by a re-used TSQLDBZeosStatement

Hello,
today I have encountered a very obscure problem. The way a TDynArrayHashed is used in a TSQLDBZeosStatement a malfunction can be triggered in the fColumn.AddAndMakeUniqueName() method. The array is re-inited with just:

      fColumnCount := 0;
      fColumn.ReHash;

That works fine, but it leaves the fHashFindCount property unchanged, thus it raises further and after several tries with a query of eleven columns it crashes.

If I am correct the cause is a hit of the condition and reset of the fHashCounterTrigger property to zero in TDynArrayHashed.FindHashed() method (the code using the query is fetching values by the names of the columns). The core of the problem lies in the first call to the AddAndMakeUniqueName() method on a statement re-used after the fHashCounterTrigger was set to zero. The TDynArrayHashed.HashAdd does a ReHash (which effectively sets fHashs to nil for an empty array) and tries to write a hash to fHashs afterwards. Also, the Assert() in TDynArrayHashed.HashAdd() is hit, because ReHash clears hash and the following HashFind() finds the column (the data remained there, the Count was already incremented, search goes without a hash).

Either the fHashCounterTrigger should not be set to zero, or the ReHash should be able to prepare fHashs even for an empty array (perhaps calling it from HashAdd() with forAdd = True ?).

Best regards,
Joe

Offline

#2 2018-10-02 07:49:02

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

Re: TDynArrayHashed's bug triggered by a re-used TSQLDBZeosStatement

Could you try

fColumn.Clear;
fColumn.ReHash;

instead?

Offline

#3 2018-10-02 13:13:40

Joe
Member
Registered: 2014-10-13
Posts: 12

Re: TDynArrayHashed's bug triggered by a re-used TSQLDBZeosStatement

I have tried it now, but unfortunately it makes no difference.

Offline

#4 2018-10-12 15:35:40

Joe
Member
Registered: 2014-10-13
Posts: 12

Re: TDynArrayHashed's bug triggered by a re-used TSQLDBZeosStatement

Hello,
after some experimenting I have found out that, it works correctly if I modify the TDynArrayHashed.HashAdd() method in SynCommons.pas:

...
      dec(fCountP^); // ignore latest entry (which is not filled yet)
---    ReHash;
+++    ReHash(True);
    if fCountP<>nil then
...

Best regards,
Joe

Offline

Board footer

Powered by FluxBB