TBufDataset is behaving in a very odd way from Release to Debug, and going boom! lazarus / 16-Databases ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2023-09-26 23:00 TBufDataset is behaving in a very odd way from Release to debug, and going boom! Hey Y'all!! I'm playing around with in memory tables. Had a wee Google and found this: How to write in-memory database applications in Lazarus/FPC. So I went and started by playing with TMemDataset: Test Memory Dataset. So, with confidence from the above Lazarus Wiki entry, I proceeded to do the exact same test app but using TBufDataset. Immediately I found myself in trouble because: Build Mode Default: After the first push of the Add Data button inserts 3 rows, no data shows and on a subsequent push of the same button we get an AV right on the first Post, as you can see on image 1.Build Mode Debug: The app does not give us an AV, but the data shown in the DBGrid is rather suspicious, as you can see on image 2. And in image 3 you see the very top of the humongous heaptrc log produced.Build Mode Release: Behaves the same way as Build Mode Default. I'm completely baffled by this whole thing and I come here, very humbled, to ask for your, very appreciated, help. I'm attaching the code of the buggy TestBufferDataset attempt. Many, oh so, many thanks in advance!! EDIT: I forgot to mentions that I tested this on an Ubuntu 20.04 64b with both Lazarus 2.2.6 and main(aka trunk) Cheers, Gus -- Image 1: (https://pasteboard.co/EzyWaNkWt11K.png) Image 2: (https://pasteboard.co/CpAFTaL63Dlc.png) Image 3: (https://pasteboard.co/etyXISEgRjVt.png) ---------------------------------------------------------------------- rvk · 2023-09-27 08:35 Creating the TBufDataset in code seems to work better. I suspect that defining the fields in the Object Inspector is the problem. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TfrmMain.FormCreate(Sender: TObject);//...  bdsAccounts := TBufDataset.Create(nil);  bdsAccounts.FieldDefs.Add('HASH', ftString, 50);  bdsAccounts.FieldDefs.Add('Alias', ftString, 50);  bdsAccounts.FieldDefs.Add('Label', ftString, 50);  bdsAccounts.FieldDefs.Add('Pending', ftCurrency, 0, 15, false, false, 4, 0);  bdsAccounts.FieldDefs.Add('Balance', ftCurrency, 0, 15, false, false, 5, 0);  bdsAccounts.CreateDataset;  bdsAccounts.Open;   dsAccounts.DataSet := bdsAccounts;  dsAccounts.Enabled := true; (On Windows it also gives strange results when doing it design-time.) ---------------------------------------------------------------------- wp · 2023-09-27 08:41 Is there a reason why you did not set the BufDataset's Filename? I am not sure if it is possible at all to use TBufdataset without a file, buf even if it is you will lose all records when the application terminates. Second issue: persistent fields. Once you have persistent fields you cannot access fields by FieldByName[fieldname], but only by their variable name, e.g. bdsAccountsBalance rather than bdsAccounts.FieldByName['Balance']. An annoyance which I already hated in my Delphi times... I deleted the persistent fields from the lfm file, added a Filename to the bdsAccounts dataset and made sure that the dataset is created properly - now the application does not crash any more: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TfrmMain.FormCreate(Sender: TObject);begin  Caption:= Format('%s v%s', [ Application.Title, cVersion ]);  InitShortcuts;  Application.OnHint:= @DisplayHint;  bdsAccounts.FileName := 'test.db';  if not FileExists(bdsAccounts.FileName) then    bdsAccounts.CreateDataset;  bdsAccounts.Open;end; Still... Clear does not seam to work. It clears the dataset in the current session, but when the app starts another time the data are back again. Filtering seems to crash the application still. Well - I would not execute the filter in the OnChange event of the edit control, I would add a button to toggle bdsAccounts.Filtered and use the edit filter text once it is completed. This works, but I don't understand why your code report "Index based on unknown field" while typing the condition... ---------------------------------------------------------------------- paweld · 2023-09-27 08:43 As @rvk wrote define dataset in code and: 1. for DBGrid, you don't need to call BeginUpdate and EndUpdate - everything happens automatically when you change DataSet. when doing a lot of data editing, it is recommended to use DisableControls and EnableCotrols for DataSet  2. using the Clear medtode for a DataSet will clear not only the data but also the field definitions 3. currency has precision to 4 decimal places Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i unit Forms.Main; {$mode objfpc}{$H+} interface uses  Classes, SysUtils, BufDataset, DB, Forms, Controls, Graphics, Dialogs, Menus, ActnList, ComCtrls, StdActns, ExtCtrls, StdCtrls, DBGrids; type   { TfrmMain }   TfrmMain = class(TForm)    actAccountsAddData: TAction;    actAccountsClearData: TAction;    alMain: TActionList;    actFileExit: TFileExit;    btnAccountsAddData: TButton;    btnAccountsClearData: TButton;    bdsAccounts: TBufDataset;    dsAccounts: TDataSource;    dgAccounts: TDBGrid;    edtAccountsFilterByAlias: TEdit;    gbFilter: TGroupBox;    lblFilterByAlias: TLabel;    mnuFile: TMenuItem;    mnuFileExit: TMenuItem;    mmMain: TMainMenu;    panButtons: TPanel;  sbMain: TStatusBar;    procedure FormCreate(Sender: TObject);    procedure alMainUpdate(AAction: TBasicAction; var Handled: Boolean);  procedure actAccountsAddDataExecute(Sender: TObject);    procedure actAccountsClearDataExecute(Sender: TObject);    procedure edtAccountsFilterByAliasChange(Sender: TObject);    procedure FormDestroy(Sender: TObject);  private    procedure InitShortcuts;    procedure DisplayHint(Sender: TObject);    procedure CreateDBDef;  public   end; var  frmMain: TfrmMain; implementation uses  LCLType; const  cVersion = '0.1.0'; {$R *.lfm} { TfrmMain } procedure TfrmMain.FormCreate(Sender: TObject);begin  Caption:= Format('%s v%s', [ Application.Title, cVersion ]);  InitShortcuts;  Application.OnHint:= @DisplayHint;  CreateDBDef;  bdsAccounts.Open;end; procedure TfrmMain.InitShortcuts;begin{$IFDEF UNIX}  actFileExit.ShortCut := KeyToShortCut(VK_Q, [ssCtrl]);{$ENDIF}{$IFDEF WINDOWS}  actFileExit.ShortCut := KeyToShortCut(VK_X, [ssAlt]);{$ENDIF}end; procedure TfrmMain.DisplayHint(Sender: TObject);begin  sbMain.SimpleText:= GetShortHint(Application.Hint);end; procedure TfrmMain.CreateDBDef;var  i: Integer;begin  bdsAccounts.Clear;  bdsAccounts.FieldDefs.Add('HASH', ftString, 50);  bdsAccounts.FieldDefs.Add('Alias', ftString, 50);  bdsAccounts.FieldDefs.Add('Label', ftString, 50);  bdsAccounts.FieldDefs.Add('Pending', ftCurrency);  bdsAccounts.FieldDefs.Add('Balance', ftCurrency);  bdsAccounts.IndexDefs.Add('idx_hash', 'HASH', [ixCaseInsensitive]);  bdsAccounts.CreateDataset;  bdsAccounts.IndexFieldNames := 'HASH';  for i := 0 to bdsAccounts.Fields.Count - 1 do  begin    if bdsAccounts.Fields[i].DataType = ftCurrency then      TNumericField(bdsAccounts.Fields[i]).DisplayFormat:= '#,##0.0000 N';  end;end; procedure TfrmMain.alMainUpdate(AAction: TBasicAction; var Handled: Boolean);begin  if AAction = actAccountsClearData then  begin    actAccountsClearData.Enabled:= bdsAccounts.RecordCount > 0;  Handled:= True;  end;end; procedure TfrmMain.actAccountsAddDataExecute(Sender: TObject);begin  bdsAccounts.Insert;  bdsAccounts.FieldByName('HASH').AsString:= 'N2983096817236';  bdsAccounts.FieldByName('Alias').AsString:= 'Alias 1';  bdsAccounts.FieldByName('Label').AsString:= 'Label 1';  bdsAccounts.FieldByName('Pending').AsCurrency:= 0.0;  bdsAccounts.FieldByName('Balance').AsCurrency:= 1000.0;  bdsAccounts.Append;   bdsAccounts.Insert;  bdsAccounts.FieldByName('HASH').AsString:= 'N2983096817696';  bdsAccounts.FieldByName('Alias').AsString:= 'Alias 2';  bdsAccounts.FieldByName('Label').AsString:= 'Label 2';  bdsAccounts.FieldByName('Pending').AsCurrency:= 0.0;  bdsAccounts.FieldByName('Balance').AsCurrency:= 2000.0;  bdsAccounts.Append;   bdsAccounts.Insert;  bdsAccounts.FieldByName('HASH').AsString:= 'N2983696817236';  bdsAccounts.FieldByName('Alias').AsString:= 'Alias 3';  bdsAccounts.FieldByName('Label').AsString:= 'Label 3';  bdsAccounts.FieldByName('Pending').AsCurrency:= 0.0;  bdsAccounts.FieldByName('Balance').AsCurrency:= 3000.0;  bdsAccounts.Append;   bdsAccounts.Last;   dgAccounts.AutoAdjustColumns;end; procedure TfrmMain.actAccountsClearDataExecute(Sender: TObject);begin  bdsAccounts.DisableControls;  bdsAccounts.First;  while not bdsAccounts.EOF do    bdsAccounts.Delete;  bdsAccounts.EnableControls;end; procedure TfrmMain.edtAccountsFilterByAliasChange(Sender: TObject);begin  if Trim(edtAccountsFilterByAlias.Text) = '' then    bdsAccounts.Filtered := False  else  begin    bdsAccounts.FilterOptions:= [foCaseInsensitive];    bdsAccounts.Filter:= Format('Alias=''*%s*''', [Trim(edtAccountsFilterByAlias.Text)]);    bdsAccounts.Filtered:= True;  end;end; procedure TfrmMain.FormDestroy(Sender: TObject);begin  bdsAccounts.Close;end; end. ---------------------------------------------------------------------- wp · 2023-09-27 09:14 Trying to keep the persistent fields... When they exist they must be used in the following way: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TfrmMain.actAccountsAddDataExecute(Sender: TObject);begin  actAccountsAddData.Enabled:= False;  Application.ProcessMessages;   dgAccounts.BeginUpdate;   bdsAccounts.Append;  bdsAccountsHASH.AsString:= 'N2983096817236';  // instead of bdsAccounts.FieldByName('HASH').AsString := ...  bdsAccountsAlias.AsString:= 'Alias 1';  bdsAccountsLabel.AsString:= 'Label 1';  bdsAccountsPending.AsCurrency:= 0.0;  bdsAccountsBalance.AsCurrency:= 1000.0;  bdsAccounts.Post;   bdsAccounts.Append;  bdsAccountsHASH.AsString:= 'N2983096817696';  bdsAccountsAlias.AsString:= 'Alias 2';  bdsAccountsLabel.AsString:= 'Label 2';  bdsAccountsPending.AsCurrency:= 0.0;  bdsAccountsBalance.AsCurrency:= 2000.0;  bdsAccounts.Post;   bdsAccounts.Append;  bdsAccountsHASH.AsString:= 'N2983696817236';  bdsAccountsAlias.AsString:= 'Alias 3';  bdsAccountsLabel.AsString:= 'Label 3';  bdsAccountsPending.AsCurrency:= 0.0;  bdsAccountsBalance.AsCurrency:= 3000.0;  bdsAccounts.Post;   dgAccounts.AutoAdjustColumns;  dgAccounts.EndUpdate(True);   Application.ProcessMessages;  actAccountsAddData.Enabled:= True;end; After having added a filename to bdsAccounts and creating the dataset at first run (like in my other reply), and pressing "Add data" I do get the same empty rows and the crash at the end, as before. For the next test, I ran the application and closed it immediately afterwards (of course, after having deleted the created database file for a new fresh start). This way an empty database file is created. When I now run it again and click "Add data", the records are added correctly, and the crash at the end does not occur either. ---------------------------------------------------------------------- wp · 2023-09-27 09:25 In order to clear the table replace the bdsAccounts.Clear by the following lines: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   bdsAccounts.First;  while not bdsAccounts.EoF do    bdsAccounts.Delete; ---------------------------------------------------------------------- wp · 2023-09-27 10:10 Returning to the persistent fields... I add some DebugLn instructions to the application after opening the dataset to print the FieldNo of the fields: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TfrmMain.FormCreate(Sender: TObject);var  i: Integer;begin  ...  bdsAccounts.Open;  for i := 0 to bdsAccounts.FieldCount-1 do    DebugLn([bdsAccounts.Fields[i].FieldNo, ', ', bdsAccounts.Fields[i].FieldName]);  end;When application starts for the first time, i.e. without an existing database file, the output always lists FieldNo = 0 - which looks very wrong because FieldNo is an essential ingredient within the database management code. And in fact, when the application is run for the second time (when the database file already exists) the FieldNo values are as expected: 1, 2, 3, ... I copied the bufdsdataset unit from the FPC installation over to my test project (in order to be able to edit it) and added "BindFields(true)" to "TCustomBufDataset.InternalOpen" (before searching for the AutoInc field) - now the issue is gone, and the application works now even without a filename and without CreateDataset. I am not sure whether the position where I added BindFields is the correct one. But I think it is a good hint for a bug report which I will prepare next. [EDIT] Bug report: https://gitlab.com/freepascal.org/fpc/source/-/issues/40450 ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2023-09-27 10:34 Hey WP, First and foremost, thank you so very much for taking the time to suss things out!! Really appreciate it. As a preamble: I was just playing around with things under the impression that TBufDataset was gonna be the same beast as TMemDataset, but with internal changes only, not the polar opposite of it. In this context, I tried to transfer what I learned with TMemDataset, which was easy, simple and worked right out of the box, to TBufDataset and the thing was like nitroglycerine without the stabilising compound that turns it into dynamite. It went boom at the slightest touch. Quote from: wp on September 27, 2023, 10:41:54 amIs there a reason why you did not set the BufDataset's Filename? More than one: The wiki article for TMemDataset did not mention the need for it, but I do realise that the section dedicated to TBufDataset was just focusing on sorting, and nothing more.Again, TMemDataset worked ok without it.My main purpose for this whole endeavour of testing TMemDataset, TBufDataset, TRxMemoryData and ZMSQL is to not rely on, what I'm assuming should only be memory only and volatile by nature, a file or database engine, but to have the Dataset holding the data, a visual component that has way better features than a TStringGrid and some small piece of code to make filter and sorting happen. I want the persistence of the data to be some custom, black box, thing that I can create, re-create and have my mind changed on how to read/write it every time I need to display the data. So, in this context, having a file on the TBufDataset, made no sense and because TMemDataset did not have an issue with it's absence, I guess I made a bad assumption. Quote from: wp on September 27, 2023, 10:41:54 amI am not sure if it is possible at all to use TBufdataset without a file, buf even if it is you will lose all records when the application terminates. That does not have any impact, the data will come and be persisted by other means. Quote from: wp on September 27, 2023, 10:41:54 amSecond issue: persistent fields. Once you have persistent fields you cannot access fields by FieldByName[fieldname], but only by their variable name, e.g. bdsAccountsBalance rather than bdsAccounts.FieldByName['Balance']. An annoyance which I already hated in my Delphi times... Okies, that's going on the notepad for future reference, many, many thanks!! Quote from: wp on September 27, 2023, 10:41:54 amI deleted the persistent fields from the lfm file, added a Filename to the bdsAccounts dataset and made sure that the dataset is created properly - now the application does not crash any more: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TfrmMain.FormCreate(Sender: TObject);begin  Caption:= Format('%s v%s', [ Application.Title, cVersion ]);  InitShortcuts;  Application.OnHint:= @DisplayHint;  bdsAccounts.FileName := 'test.db';  if not FileExists(bdsAccounts.FileName) then    bdsAccounts.CreateDataset;  bdsAccounts.Open;end; These things should either be better documented, or raise an exception if it impacts the more simplistic operation I'm aiming, wouldn't you agree? Quote from: wp on September 27, 2023, 10:41:54 amStill... Clear does not seam to work. It clears the dataset in the current session, but when the app starts another time the data are back again. This Clear was a naive attempt to mimic TMemDataset. Even the Lazarus wiki mentions that a clear is too slow and it provides a quicker solution, a bit hefty on the code, hence me being a bit lazy and tried it the easy and less optimal way. And the loss of data between sessions is of no consequence. Quote from: wp on September 27, 2023, 10:41:54 amFiltering seems to crash the application still. Well - I would not execute the filter in the OnChange event of the edit control, I would add a button to toggle bdsAccounts.Filtered and use the edit filter text once it is completed. This works, but I don't understand why your code report "Index based on unknown field" while typing the condition... The filtering has a blatant error due to my ignorance of the syntax needed. After I posted this, I progressed in doing my tests with TRxMemoryData, and after some head butting with the wall I realized that I need: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i DataSet.Filter:= 'Alias="**"';And with this, it now works. I've always struggled with the many syntaxes(SQL with the Like and the % and never knowing if I should quote the value or not) for this filtering since there is not a place where this is discussed in any docs or examples that I've stumbled upon! There is a blatant lack of documentation on the correct syntax parsed in this Filter property, that's for sure!! Ok, summarising your findings: Have a filename on the respective propertyDo not use the FieldByName wayMaybe not use the Fields, just the FieldDefs. (Is this what you mean by persistent fields?) Am I missing something? Nonetheless, oh so many thanks for the time you've spent on this !!! Cheers, Gus ---------------------------------------------------------------------- rvk · 2023-09-27 10:38 I don't think TBufDataset.Filename is (or should be) mandatory. I used it for in-mem database where there is no need to save to a file. (But I created everything in code.) The problems of using FieldByName when also having persistent fields is new to me. (But I never use persistent fields anyway) ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2023-09-27 10:49 Hey Pawel, First of all, many many thanks for the time you spent on this !!! It is really appreciated !! Quote from: paweld on September 27, 2023, 10:43:07 amAs @rvk wrote define dataset in code and: This for me is a bit hard to swallow. Mainly due to the fact that the component has the functionality to be manipulated via the Designer. If that makes it go boom by design, then probably not allow the manipulation via the IDE? Makes no sense to have it RAD just to explode in your face when used, amirite?! Quote from: paweld on September 27, 2023, 10:43:07 am1. for DBGrid, you don't need to call BeginUpdate and EndUpdate - everything happens automatically when you change DataSet. when doing a lot of data editing, it is recommended to use DisableControls and EnableCotrols for DataSet  That makes quite a lot of sense, thanks very much for the necessary schooling Quote from: paweld on September 27, 2023, 10:43:07 am2. using the Clear medtode for a DataSet will clear not only the data but also the field definitions Yeah, that was a lame ass and lazy attempt on my part  Quote from: paweld on September 27, 2023, 10:43:07 am3. currency has precision to 4 decimal places The default from the Designer is actually 15, witch is even a bit much for what I need: 8. Actually, those fields should be uInt64 and then manipulated to have decimal place between the 9th and 8th from the right. It's a whole thing in crypto not to use Floating point arithmetic due to the loss of data, which in any currency context is not acceptable. And I think that even negative values are not, kinda, used. A transaction is always abs and you can prepend a negative character when displaying on the Sender's side and a plus sign on the Receiver's side. Using uInt64 makes sense, since it's the max a current register is capable of manipulating in one go. And, like previously stated, never use Floating Point arithmetic !! Again, many thanks for adding code to better explain your meaning!! Cheers, Gus ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2023-09-27 10:55 Hey WP, Quote from: wp on September 27, 2023, 11:14:30 amTrying to keep the persistent fields... When they exist they must be used in the following way: Okies, also jotted down on the notepad Quote from: wp on September 27, 2023, 11:14:30 amAfter having added a filename to bdsAccounts and creating the dataset at first run (like in my other reply), and pressing "Add data" I do get the same empty rows and the crash at the end, as before. For the next test, I ran the application and closed it immediately afterwards (of course, after having deleted the created database file for a new fresh start). This way an empty database file is created. When I now run it again and click "Add data", the records are added correctly, and the crash at the end does not occur either. Ok, looks like the key is actually having a file. I think my main problem stems from the fact that: I was completely ignorant of what the CreateDataset did in reality, even if it is one of the option when you Right-Click on it in the DesignerThe whole thing worked fine in TMemDataset Ok, I can amend my previous list to be just: Have a filename on the respective propertyDo not use the FieldByName way Thanks my good friend, this helps a lot!!! Cheers, Gus ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2023-09-27 11:01 Hey WP, Quote from: wp on September 27, 2023, 12:10:56 pmI am not sure whether the position where I added BindFields is the correct one. But I think it is a good hint for a bug report which I will prepare next. This was my hope, that one of you more versed in the guts of these components had the opportunity to chase that eluding bug. Like I said previously to Pawel, it made no sense that the component had all the bells and whistles to work in RAD, to just explode in your face in such a strange way between Default/Release and Debug when you use it. Much, MUCH appreciation for your time, and patience, to get into a bug report !! Cheers, Gus ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2023-09-27 11:20 Hey rvk, Quote from: rvk on September 27, 2023, 12:38:31 pmI don't think TBufDataset.Filename is (or should be) mandatory. I could not agree more with this. After all, the "product" IS advertised as an in memory thingamaboob, so why the mandatory need of a file, right? Quote from: rvk on September 27, 2023, 12:38:31 pmI used it for in-mem database where there is no need to save to a file. (But I created everything in code.) Yeah, I kinda was lazy and used the RAD option that is clearly something that should be supported since it allows us to use it. Quote from: rvk on September 27, 2023, 12:38:31 pmThe problems of using FieldByName when also having persistent fields is new to me. (But I never use persistent fields anyway) Yeah, that also tickles me a bit. But looks like WP has been annoyed by that lill detail ever since his Delphi time, so chalk it to "seniority", I guess? As a disclaimer, my main aim for all this testing was to evaluate a visual thing that I could use instead of the very work intense TStringGrid to achieve data auto refresh, filtering and sorting. Hence me doing the whole thing via the RAD path. I was quite happy with TMemDataset, but a bit sad for the lack of sorting. So after evaluating it, I went on to TBufDatset under the little information provided by the mentioned Wiki entry. Looks like it was a good path, since from the looks of it, there were bugs hiding in the shadows Can not thank you enough for the time and patience you devoted to chasing this alongside me!! Cheers, Gus ---------------------------------------------------------------------- wp · 2023-09-27 11:32 Now that the bugreport has been sent (https://gitlab.com/freepascal.org/fpc/source/-/issues/40450) let me correct my wrong statements made during this thread: TBufDataset does NOT need a filenamePersistent fields DO work (the reason why I don't like them is that it is a pain to rename fields once persistent fields are created).Is is NOT necessary to call CreateDataset for a bufdataset with persistent fields.Gus, do I understand correctly that the Filter works for you. So, I do not need to look into this issue? ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2023-09-27 11:35 Hey WP, Quote from: wp on September 27, 2023, 11:25:12 amIn order to clear the table replace the bdsAccounts.Clear by the following lines: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   bdsAccounts.First;  while not bdsAccounts.EoF do    bdsAccounts.Delete; From the wiki article, this is not the best way to do it, while it is a possibility. They have a 20+ LoC of an example on how to just create a new dataset, fill in the fields and just return it after freeing the old one. Makes sense, and I'll look into it. But to be honest, the need of a clear is just for the that test context. In my particular need, the clear will not be needed... I think Cheers, Gus ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2023-09-27 11:43 Hey WP, Quote from: wp on September 27, 2023, 01:32:05 pmNow that the bugreport has been sent (https://gitlab.com/freepascal.org/fpc/source/-/issues/40450) let me correct my wrong statements made during this thread: TBufDataset does NOT need a filenamePersistent fields DO work (the reason why I don't like them is that it is a pain to rename fields once persistent fields are created).Is is NOT necessary to call CreateDataset for a bufdataset with persistent fields. This is quite awesome to read!! I cannot thank you enough for your time on this!! Quote from: wp on September 27, 2023, 01:32:05 pmGus, do I understand correctly that the Filter works for you. So, I do not need to look into this issue? Yes, that is correct, I made it work in the end. Once I realised that it needed quotations and it was using the star "*" instead of any other symbol for globbing, it works: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Dataset.Filter:= 'Alias="**"';// Then Filter On and a refresh So, yeah, that's sorted and was only an issue due to my ignorance of the particular syntax of the VCL/LCL Dataset's filtering. No need to pursue that further, I guess!! Cheers, Gus