Skip to content

node:sqlite read-only statements may report nonzero change counts #59764

@turbocrime

Description

@turbocrime

Version

v24.7.0

Platform

Darwin cut.local 24.5.0 Darwin Kernel Version 24.5.0: Tue Apr 22 19:54:43 PDT 2025; root:xnu-11417.121.6~2/RELEASE_ARM64_T8132 arm64

Subsystem

sqlite

What steps will reproduce the bug?

Several repro cases here https://github.com/turbocrime/node-sqlite-changes-repro

import { DatabaseSync } from "node:sqlite";

const db = new DatabaseSync(":memory:");
db.exec("CREATE TABLE test_table (id INTEGER, name TEXT)");

const insertResult = db.prepare("INSERT INTO test_table VALUES (1, 'test1')").run();

const selectResult = db.prepare("SELECT * FROM test_table").run();

console.log(selectResult.changes);
// Expected: 0, Actual: 1

db.close();

How often does it reproduce? Is there a required condition?

Reproduces when:

  • One or more read-only statements directly follow an effectful statement reporting nonzero changes

Does not reproduce when:

  • A read-only statement is the first operation in the session
  • A read-only statement follows an effectful statement reporting zero changes
  • An effectful statement reports any number of changes

What is the expected behavior? Why is that the expected behavior?

Some SQL statements never modify any rows. Those statements should always report 0 changes.

What do you see instead?

Read-only operations report the change count from the most recent effectful statement.

Additional information

Tests of the sqlite module seem to expect this behavior:

test('executes a query and returns change metadata', (t) => {
const db = new DatabaseSync(nextDb());
t.after(() => { db.close(); });
const setup = db.exec(`
CREATE TABLE storage(key TEXT, val TEXT);
INSERT INTO storage (key, val) VALUES ('foo', 'bar');
`);
t.assert.strictEqual(setup, undefined);
const stmt = db.prepare('SELECT * FROM storage');
t.assert.deepStrictEqual(stmt.run(), { changes: 1, lastInsertRowid: 1 });
});

Metadata

Metadata

Assignees

No one assigned

    Labels

    sqliteIssues and PRs related to the SQLite subsystem.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions