Hi,

as this is my first posting to this list, let me first say thank you for
providing such a great library. It's fun to work with it. I'm intending
to use SQLite in a game engine.

I've encountered some unexpected behavior of foreign keys w.r.t an upsert:
When an entry of the parent table is 'touched' but not deleted or
modified, the child table entry is nevertheless deleted.
Although the foreign key is declared 'ON DELETE CASCADE ON UPDATE
RESTRICT', I did not expect the child entry to be deleted, because the
parent entry was not deleted.

Here is a script that shows the behavior:
-------------------------------------------------------------------------
PRAGMA foreign_keys = ON;

-- Create tables
CREATE TABLE t1 (id char(36), name varchar(40), CONSTRAINT pk_t1 PRIMARY
KEY (id));
CREATE TABLE t2 (id char(36), t1_id char(36), data char(36), CONSTRAINT
pk_t2 PRIMARY KEY (id), CONSTRAINT fk_t1_id FOREIGN KEY (t1_id)
REFERENCES t1(id) ON DELETE CASCADE ON UPDATE RESTRICT DEFERRABLE
INITIALLY DEFERRED);

-- Create table content
INSERT INTO T1 (ID, NAME) VALUES ('A', 'line 1');
INSERT INTO T1 (ID, NAME) VALUES ('B', 'line 2');
INSERT INTO T2 (ID, T1_ID, DATA) VALUES ('T2-A', 'A', 'abc');
INSERT INTO T2 (ID, T1_ID, DATA) VALUES ('T2-B', 'B', 'xyz');

-- Modify one parent entry of foreign key fk_t1_id
REPLACE INTO T1 (ID, NAME) VALUES ('A', 'line 1-new');

-- Although the parent field was not modified, a cascading delete is
triggered:
SELECT *  FROM T2;

-- The cascading delete happens even if the upsert is a no-op:
REPLACE INTO T1 (ID, NAME) VALUES ('B', 'line 2');
SELECT *  FROM T2;
------------------------------------------------------------------------

If I understand correctly, the upsert should behave like UPDATE in the
examples above, but it behaves like a DELETE followed by INSERT instead?


Best,
Michael
_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to