fix(state): batch large session cleanup queries below SQLite's variable limit
prune_sessions(), delete_empty_sessions() and prune_empty_ghost_sessions() built one IN (?, ..., ?) clause containing every selected session id (the parent-orphaning UPDATE), so cleaning more than SQLITE_MAX_VARIABLE_NUMBER sessions failed atomically with "too many SQL variables". The per-row DELETE loops that followed are folded into the same 900-id batches. Same single _execute_write() transaction; only the binding is split. Hand-ported from PR #100658 (targeted the pre-decomposition hermes_state.py god file; the methods now live in hermes_state_maintenance.py / hermes_state_sessions.py). The one-pass transcript-directory sweep from that PR is not ported (out of scope for the variable-limit bug). Authored by @Mi55ed; ported under --author.
This commit is contained in:
@@ -1573,16 +1573,14 @@ class SessionSessionsMixin:
|
||||
).fetchall()}
|
||||
if not session_ids:
|
||||
return 0
|
||||
conn.execute(
|
||||
"UPDATE sessions SET parent_session_id = NULL "
|
||||
f"WHERE parent_session_id IN ({_session_ids_placeholders(session_ids)})", list(session_ids),
|
||||
)
|
||||
for sid in session_ids:
|
||||
for chunk in _id_chunks(session_ids):
|
||||
ph = _session_ids_placeholders(chunk)
|
||||
conn.execute(f"UPDATE sessions SET parent_session_id = NULL WHERE parent_session_id IN ({ph})", chunk)
|
||||
# DELETE FROM messages: a row inserted between the SELECT and here
|
||||
# would otherwise dangle (clean FK state).
|
||||
conn.execute("DELETE FROM messages WHERE session_id = ?", (sid,))
|
||||
conn.execute("DELETE FROM sessions WHERE id = ?", (sid,))
|
||||
removed_ids.append(sid)
|
||||
conn.execute(f"DELETE FROM messages WHERE session_id IN ({ph})", chunk)
|
||||
conn.execute(f"DELETE FROM sessions WHERE id IN ({ph})", chunk)
|
||||
removed_ids.extend(chunk)
|
||||
self._delete_unreferenced_system_prompts(conn)
|
||||
return len(session_ids)
|
||||
count = self._execute_write(_do)
|
||||
|
||||
Reference in New Issue
Block a user