Forum > Databases
[resolved]Debugging SQLQuery.EOF loop with a strange SQLQuery.Next code redirect
indydev:
I will preface this post with the acknowledgement that this problem may not have anything to do with SQLQuery, but I can't track down the problem; hence the post for help.
I am attempting to retrieve data from an SQLite3 database and loading the data into some other List variables for display massaging before the actual display on the form.
For some reason my looping through the messages table causes a jump out of the loop to the beginning of the procedure.
Here is my procedure:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TForm1.BtnLoadClick(Sender: TObject);var SelectedIndex, SessionID, i, j: Integer; QA: TQandA; Role, Content: string;begin try SelectedIndex := Subjects.ItemIndex; // Retrieve the session ID from the selected item SessionID := PtrInt(Subjects.Items.Objects[SelectedIndex]); // Query the database for the session details SQLQuery.Close; // Ensure SQLQuery is closed before setting new SQL text SQLQuery.SQL.Text := 'SELECT * FROM sessions WHERE id = :id'; SQLQuery.Params.ParamByName('id').AsInteger := SessionID; SQLQuery.Open; if SQLQuery.RecordCount = 0 then begin ShowMessage('Session not found.'); SQLQuery.Close; Exit; end; // Assign the session ID to CurrentSessionID CurrentSessionID := SessionID; // Load session details into variables temperature := SQLQuery.FieldByName('temperature').AsFloat; presence_penalty := SQLQuery.FieldByName('presence_penalty').AsFloat; frequency_penalty := SQLQuery.FieldByName('frequency_penalty').AsFloat; max_tokens := SQLQuery.FieldByName('max_tokens').AsInteger; max_Query := SQLQuery.FieldByName('max_tokens_query').AsInteger; top_p := SQLQuery.FieldByName('top_p').AsFloat; SYSTEM_MSG := SQLQuery.FieldByName('system_msg').AsString; image_mode := SQLQuery.FieldByName('is_image_mode').AsBoolean; assistant_id := SQLQuery.FieldByName('tool_choice').AsString; // Load the messages for the session SQLQuery.Close; SQLQuery.SQL.Text := 'SELECT * FROM messages WHERE session_id = :session_id ORDER BY id'; SQLQuery.Params.ParamByName('session_id').AsInteger := SessionID; SQLQuery.Open; QA := TQandA.Create; try while not SQLQuery.EOF and (SQLQuery.FieldByName('session_id').AsInteger = SessionID) do begin Role := SQLQuery.FieldByName('role').AsString; Content := SQLQuery.FieldByName('content').AsString; if Role = 'user' then QA.Question.Add(Content) else if Role = 'assistant' then QA.Response.Add(Content); SQLQuery.Next; // <-- This statement jumps back to line 8 for some reason. end; except on E: Exception do begin ShowMessage('Error processing messages: ' + E.Message); QA.Free; Exit; end; end; // Add the QA object to the Conversation Conversation.Add(QA); // Variable of type TConversationList = specialize TFPGObjectList<TQandA>; SQLQuery.Close; except on E: Exception do ShowMessage('Error loading session: ' + E.Message); end;end;
The important line is 59 where SQLQuery.Next is called. I have stepped through the code and when this line executes it jumps to line 8 and I cannot figure out why.
The above procedure (BtnLoadClick) is called after this procedure:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TForm1.LoadSubjects;var SessionID: PtrInt;begin try SQLQuery.SQL.Text := 'SELECT id, title FROM sessions'; SQLQuery.Open; Subjects.Items.Clear; if SQLQuery.RecordCount <> 0 then while not SQLQuery.EOF do begin SessionID := SQLQuery.FieldByName('id').AsInteger; Subjects.Items.AddObject(SQLQuery.FieldByName('title').AsString, TObject(SessionID)); SQLQuery.Next; end; SQLQuery.Close; except on E: Exception do ShowMessage('Error loading sessions: ' + E.Message); end;end;
Which executes properly. There are some variable assignments in between the two calls, but nothing relating to these two procedures.
Debugging tips welcome.
rvk:
First of all.
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---while not SQLQuery.EOF and (SQLQuery.FieldByName('session_id').AsInteger = SessionID) do
The check for session_id isn't needed because you have a SQL where you only ask for records with that session_id. So you shouldn't get any other. That check is useless.
Second, sometimes the debugger can jump back to the beginning of the procedure when it is at the end. I think it has something to do with the cleanup. If you press f8 again (step through) you should jump to the end again. The procedure won't repeat itself (unless the calling functions calls it again).
indydev:
--- Quote from: rvk on June 12, 2024, 08:19:08 pm ---The check for session_id isn't needed because you have a SQL where you only ask for records with that session_id.
--- End quote ---
Good catch. I didn't even notice it.
--- Quote ---Second, sometimes the debugger can jump back to the beginning of the procedure when it is at the end. I think it has something to do with the cleanup. If you press f8 again (step through) you should jump to the end again. The procedure won't repeat itself (unless the calling functions calls it again).
--- End quote ---
Unfortunately, that isn't the case here. After the jump back (and the jump occurs on the first execution of line 59), It tries to reload SessionID again on line 11. This then produces a memory related error. In the debugger it raises an exception that eventually gets displayed in LazTracer.pas
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---if (length(Msg) div (length(Msg) div 10000))=0 then ;
The division by 0 error is what led me to step through the code to see if I could figure out what was happening.
Thanks for looking it over. Removing unnecessary code is always a good thing.
rvk:
Did it jump at the first call to next?
What happens if you comment out that if/then/else block?
Does it iterate through all the records then?
BTW. The double try/except is not needed either. And there should be a try/finally in there.
But that should not be the issue.
indydev:
If I remove the If else block the error occurs right at the SQL.Next; statement. It is the same message.
I only added the second try except block in the hope I could narrow the error, but stepping is what caught it.
using: Lazarus 2.2.6 (rev lazarus_2_2_6) FPC 3.2.2 x86_64-linux-gtk2
Navigation
[0] Message Index
[#] Next page