Skip to content

RETURNING emits rows despite FK constraint rollback #5491

@LeMikaelF

Description

@LeMikaelF

Description

When a DML statement with RETURNING fails due to an immediate foreign key constraint violation, RETURNING still emits the rows even though the statement is rolled back. Data integrity is maintained (the rollback works), but the RETURNING output is spurious. Affects INSERT, UPDATE, and DELETE. CHECK constraints correctly suppress output.

Reproducer

PRAGMA foreign_keys = ON;
CREATE TABLE parent(id INTEGER PRIMARY KEY, name TEXT);
CREATE TABLE child(id INTEGER PRIMARY KEY, parent_id INTEGER REFERENCES parent(id), val TEXT);
INSERT INTO parent VALUES(1, 'p1');
INSERT INTO child VALUES(1, 1, 'c1');

-- INSERT FK violation: RETURNING should NOT output anything
INSERT INTO child VALUES(2, 999, 'c2') RETURNING *;
-- Turso: Error + row (2|999|c2) shown
-- SQLite: Error only, no row output

-- DELETE FK violation: same issue
DELETE FROM parent WHERE id = 1 RETURNING *;
-- Turso: Error + row (1|p1) shown
-- SQLite: Error only, no row output

-- UPDATE FK violation: same issue
CREATE TABLE parent2(id INTEGER PRIMARY KEY);
CREATE TABLE child2(id INTEGER PRIMARY KEY, pid INTEGER REFERENCES parent2(id));
INSERT INTO parent2 VALUES(1);
INSERT INTO child2 VALUES(1, 1);
UPDATE child2 SET pid = 999 WHERE id = 1 RETURNING *;
-- Turso: Error + row (1|999) shown
-- SQLite: Error only, no row output

Per SQLite documentation: "If a statement modifies the contents of the database so that an immediate foreign key constraint is in violation at the conclusion the statement, an exception is thrown and the effects of the statement are reverted."

Since the effects are reverted, RETURNING should not emit any rows. The RETURNING rows are buffered into the ephemeral table before the FK check runs, and then emitted even after rollback.


This issue brought to you by Mikaël and Claude Code.

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions