Skip to content

Commit 8e8ef72

Browse files
glommerclaude
andcommitted
fix: invalidate rusqlite schema cache for attached databases in simulator
The differential simulator's SQLite schema cache workaround (pragma_user_version query) only invalidated the main database's schema. When ALTER TABLE DROP COLUMN was executed on an attached database, other rusqlite connections still saw the old column count, causing false divergences between limbo and rusqlite. Fix by also querying {db_name}.sqlite_master for each attached database, which forces SQLite to re-read the attached database's schema. Discovered via seed: 12173377563160143215 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent e2487bc commit 8e8ef72

File tree

1 file changed

+16
-2
lines changed

1 file changed

+16
-2
lines changed

testing/simulator/runner/execution.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -357,14 +357,15 @@ fn execute_interaction_rusqlite(
357357
stack: &mut Vec<ResultSet>,
358358
) -> turso_core::Result<ExecutionContinuation> {
359359
tracing::info!("");
360+
let attached_dbs = env.attached_dbs.clone();
360361
let SimConnection::SQLiteConnection(conn) = &mut env.connections[interaction.connection_index]
361362
else {
362363
unreachable!()
363364
};
364365
match &interaction.interaction {
365366
InteractionType::Query(query) => {
366367
tracing::debug!("{}", interaction);
367-
let raw_result = execute_query_rusqlite(conn, query);
368+
let raw_result = execute_query_rusqlite(conn, query, &attached_dbs);
368369

369370
let is_constraint_error = matches!(
370371
&raw_result,
@@ -440,10 +441,23 @@ fn execute_interaction_rusqlite(
440441
fn execute_query_rusqlite(
441442
connection: &rusqlite::Connection,
442443
query: &Query,
444+
attached_dbs: &[String],
443445
) -> rusqlite::Result<Vec<Vec<SimValue>>> {
444446
// https://sqlite.org/forum/forumpost/9fe5d047f0
445-
// Due to a bug in sqlite, we need to execute this query to clear the internal stmt cache so that schema changes become visible always to other connections
447+
// Due to a bug in sqlite, we need to execute this query to clear the internal stmt cache so that schema changes become visible always to other connections.
448+
// We must do this for the main database AND all attached databases, otherwise
449+
// schema changes (e.g. DROP COLUMN) on attached databases won't be visible to
450+
// other connections that have the old schema cached.
446451
connection.query_one("SELECT * FROM pragma_user_version()", (), |_| Ok(()))?;
452+
for db_name in attached_dbs {
453+
// Force SQLite to re-read the attached database's schema by querying
454+
// its sqlite_master table. This ensures schema changes (e.g. DROP COLUMN)
455+
// made by other connections are visible.
456+
let _ = connection.execute(
457+
&format!("SELECT sql FROM {db_name}.sqlite_master LIMIT 1"),
458+
(),
459+
);
460+
}
447461
match query {
448462
Query::Select(select) => {
449463
let mut stmt = connection.prepare(select.to_string().as_str())?;

0 commit comments

Comments
 (0)