Skip to content

Add release cached stmts command to flush DiskANN prepared statements without disconnect#295

Open
rolf-moz wants to merge 2 commits intoasg017:mainfrom
rolf-moz:add-release-cached-stmts-command
Open

Add release cached stmts command to flush DiskANN prepared statements without disconnect#295
rolf-moz wants to merge 2 commits intoasg017:mainfrom
rolf-moz:add-release-cached-stmts-command

Conversation

@rolf-moz
Copy link
Copy Markdown

@rolf-moz rolf-moz commented May 5, 2026

@asg017 I'm seeing some errors with Diskann because there are some prepared statements pending when we are closing the connection.

Is it advisable to have a flush command, or should I suppress these errors?

Attached is a flush implementation. As with my other patch, I heavily relied on Claude code since I don't know this codebase well.

Summary

Adds a new index-type-agnostic command dispatched via the existing FTS5-style
command column on vec0:

INSERT INTO vec_history(vec_history) VALUES('release-cached-stmts');

It calls vec0_free_resources(p) directly, finalizing the cached
sqlite3_stmt* handles vec0 keeps on the vtab (stmtRowidsInsertRowid,
stmtDiskannNodeRead, stmtVectorsInsert, etc.). They're re-prepared lazily
on the next operation.

Why

The vec0 cache is currently only finalized in xDisconnect / xDestroy /
xRename. That's a problem for some embedders. Firefox's mozStorage, for
example, calls sqlite3_close() on shutdown, which fails (and asserts in
debug builds) while any sqlite3_stmt* is still alive on the connection.
Workarounds today are either:
- a no-op ALTER TABLE rename pair — bumps the schema cookie and writes to
shadow tables, also invalidates host-side prepared-statement caches; or
- close + reopen the connection — heavy hammer.


Test plan
tests/test-release-cached-stmts.py:
- Command succeeds on a flat vec0 and data remains queryable after.
- Command is a no-op when no statements are cached yet.
- Command works on a DiskANN-indexed table (the original motivating case).
- Unknown subcommands still produce the existing unknown vec0 command error.

rolf-moz added 2 commits May 5, 2026 12:21
Hosts that embed sqlite-vec sometimes need to finalize vec0's cached
prepared statements without renaming or destroying the table. The cache
(stmtRowidsInsertRowid, stmtDiskannNodeRead, stmtVectorsInsert, etc.) is
otherwise only finalized in xDisconnect / xDestroy / xRename, which is
too late or too heavy for some use cases.

Concrete motivating case: Firefox's mozStorage calls sqlite3_close() on
shutdown, which fails (and asserts in debug builds) while any
sqlite3_stmt* is still alive on the connection — including vec0's. The
existing workarounds are either an ALTER TABLE rename pair (bumps the
schema cookie and writes to shadow tables) or closing/reopening the
connection (heavy hammer).

Adds a new index-type-agnostic command dispatched via the existing
FTS5-style command column:

  INSERT INTO vec_history(vec_history) VALUES('release-cached-stmts');

This calls vec0_free_resources(p) directly. Cached statements are
re-prepared lazily on next use.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant