Page 1 of 1

Duplicate result when using locate, loPartialKey and Filter

Posted: 23.04.2008, 18:06
by gto
Hello there

I found a bug when using a simple query and an edit field that looks for the typed word using locate, loPartialKey and filtered=true. Some rows of the result appear twice.

Image

There's a connection to a firebird database, a query with "select * from table" and filtered=true, and a DataSource, all linked to the a default DBGrid.

The only typed code is under Edit1Change:

Code: Select all

if edit1.text <> '' then
   ZQuery1.Locate('USUARIO' ,edit1.text, [loPartialKey]);
The problem occurs when you look for various (3-4..) keys, which have found something, and then look for a last match key. When it matched, you select the grid and start to press down in the keyboard, until the bottom of DBGrid. When you reach the bottom, press down one more time, and the first and last line of DBGrid will have the same value (duplicated).

A very strange bug, and an old one, since 6.5.1 as I remember. I've tested with and without a bogus filter (1=1), and the results are the same.

Should I register a bug in mantis?

Thks

Posted: 24.04.2008, 02:07
by cipto_kh
Yep, I also think this is a bug, should register to mantis.

Could you also give an example program in mantis by using Firebird standart example of employee.fdb database?

Posted: 24.04.2008, 13:27
by gto
Just posted the bug into mantis:

http://zeosbugs.firmos.at/view.php?id=108

Any help is welcome!

Thanks!

Posted: 12.05.2008, 19:37
by gto
Hello guys!

News from the front: Just found that the procedure doing this problem is TZAbstractRODataset.MoveRecNo!

After a closer look into TZAbstractRODataset.Locate method, which calls MoveRecNo, I've found that the bug root are a bit different than I related:

Everytime, when TZAbstractRODataset find some row using locate, it fires a MoveRecNo to position the cursor over it.

Then, MoveRecNo uses the Resync procedure, which reset the cursor position. MoveRecNo uses a integer var to save this position and then re-set it when Resync is done.

The problem is: This procedure isn't enough to tell the TZAbstractRODataset that the cursor is postitioned over this row. When I scrolled down the DBGrid and the components tried to search for the next record (off the screen/scroll limit), it was taking the search result cursor, and not the current cursor (in this case, I scrolled by hand down the bottom of DBGrid).

Well, I solved it calling UpdateCursorPos by the end of MoveRecNo , right after re-setting the CurrentRow position.

Don't know if it's a good practice, but I'll wait for your comments! :)

Thanks!

UPDATE:

My version of the funcion MoveRecNo:

Code: Select all

procedure TZAbstractRODataset.MoveRecNo(Value: Integer);
var
  PreviousCurrentRow: Integer;
begin
  Value := Max(1, Value);
  if Value < CurrentRow then
    CheckBiDirectional;

  if FetchRows(Value) then
    CurrentRow := Value
  else CurrentRow := CurrentRows.Count;

  PreviousCurrentRow := CurrentRow;//Resync moves the current row away
  try
    if not (State in [dsInactive]) then Resync([]);
  finally
    CurrentRow := PreviousCurrentRow;
  end;
  UpdateCursorPos;
end;

Posted: 19.05.2008, 17:18
by dragos
This also fixes a bug with a TDBLookupComboBox whose data comes from a TZQuery's dataset where scrolling up/down would - under some conditions - seem as if all entries are duplicates.

Thanks gto!

Posted: 19.05.2008, 19:39
by gto
Oh thanks for testing!

I'm glad to see it worked beyond my test site... nice!

I guess we can ask mdaems to put this change on the SVN tree :)

Thank you!

Posted: 19.05.2008, 23:30
by mdaems
Done already! SVN rev. 368 on 13/05/2008. Will be merged into trunk next time merge happens.

Mark

Posted: 20.05.2008, 13:09
by gto
mdaems wrote:Done already! SVN rev. 368 on 13/05/2008. Will be merged into trunk next time merge happens.

Mark
Thank you Mark! :mrgreen: