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.
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!