On 2015-04-09 07:57 PM, Simon Slavin wrote: > On 9 Apr 2015, at 6:04pm, Gustav Melno <knarks at online.de> wrote: > >> Thanks for the help. Adding a trailing underscore helped also. I'm still >> wondering why insertion worked at all because defining oid as column name >> with the type VARCHAR should result in an error on execution. > The three names for the integer primary key column (oid, rowid, _rowid_) work > only if the table doesn't have a defined column of that name. This allows > compatibility with people who didn't know that they were had special meanings > for SQLite. Clever, isn't it ?
Except it clearly did not work like that in the OP's case. He had defined "oid" in his table, but then when he inserted into column oid, the value either went to the rowid column or somehow messed up the rowid enough to cause a constraint failure. I'm starting to think this might be a bug. I've checked it like this (Copy paste this to a file and feed to an sqlite parser): -- 2015-04-09 20:34:18.791 | [Info] Script Initialized, Started executing... -- ================================================================================================ CREATE TABLE idTest( -- Table with every row id reference id INTEGER PRIMARY KEY, col1 TEXT, oid INTEGER, rowid INTEGER, _rowid_ INTEGER ); CREATE TABLE fkTest( -- table to test the Foreign Key id INTEGER PRIMARY KEY, Data TEXT, FOREIGN KEY (id) REFERENCES idTest(id) ON UPDATE CASCADE ON DELETE CASCADE -- changes and deletes must cascade ); INSERT INTO idTest (col1, oid, rowid, _rowid_) VALUES ('TestA', 10, 100, 1000), ('TestA', 20, 200, 2000), ('TestA', 30, 300, 3000) ; INSERT INTO idTest (col1, oid) VALUES ('TestB', 'aaa'); INSERT INTO fkTest (id, Data) VALUES (last_insert_rowid(), 'FK 1'); INSERT INTO idTest (col1, oid) VALUES ('TestC', 20); INSERT INTO fkTest (id, Data) VALUES (last_insert_rowid(), 'FK 2'); -- So far all happens as expected and works perfectly... SELECT * FROM idTest; -- id | col1 | oid | rowid | _rowid_ -- ------------ | ------- | ----- | ----- | ------- -- 1 | TestA | 10 | 100 | 1000 -- 2 | TestA | 20 | 200 | 2000 -- 3 | TestA | 30 | 300 | 3000 -- 4 | TestB | aaa | | -- 5 | TestC | 20 | | SELECT F.*, I.* FROM fkTest AS F LEFT JOIN idTest AS I ON F.id=I.id; -- id | Data | id | col1 | oid | rowid | _rowid_ -- ------------ | ------ | ------------ | ------- | ----- | ----- | ------- -- 4 | FK 1 | 4 | TestB | aaa | | -- 5 | FK 2 | 5 | TestC | 20 | | -- Here the problem happens. this statement should in SQL terms succeed and update the fkTest -- table - here I am NOT using oid as the OP did, I am using the correct reference but it still fails. -- And - it works if I remove the rowid references from the first table create. UPDATE idTest SET id = 40 WHERE id = 4; -- 2015-04-09 20:34:18.807 | [ERROR] FOREIGN KEY constraint failed -- Script Stats: Total Script Execution Time: 0d 00h 00m and 00.029s -- Total Script Query Time: 0d 00h 00m and 00.005s -- Total Database Rows Changed: 8 -- Total Virtual-Machine Steps: 396 -- Last executed Item Index: 12 -- Last Script Error: Script Failed in Item 11: FOREIGN KEY constraint failed -- ------------------------------------------------------------------------------------------------ I won't add more test script outputs, but it fails for a DELETE request too. I think including rowid / oid / _rowid_ in a table works normally since the correct values ended up in the correct columns, but somehow including those aliases confuses the FK check mechanism.