You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This bug is similar to #235 and #383, but is not fixed by the changes in #383.
The crash is the same: Query.run(query: Insert) successfully runs the insert, but sqlite3_last_insert_rowid returns 0 afterwards, which means that Connection.lastInsertRowid returns nil, and Query.run crashes when it force-unwraps that nil.
publicfunc run(query:Insert)throws->Int64{letexpression= query.expression
returntrysync{tryself.run(expression.template, expression.bindings)// This succeedsreturnself.lastInsertRowid! // This crashes}}
The rowid is an alias for a declared integer primary key column in the table, and the insert sets the primary key to 0. As documented: "If the table has a column of type INTEGER PRIMARY KEY then that column is another alias for the rowid."
The table has been created with WITHOUT ROWID. As documented: "Inserts into WITHOUT ROWID tables are not recorded."
To reproduce the first crash, you can do something like this:
lettblTest=Table("test")letcolIndex=Expression<Int>("index")
db.run(tblTest.create(){ t in
t.column(colIndex, primaryKey: true)})
db.run(tblTest.insert(colIndex <-0))
In #383, @stephencelis said "My take: the main insert() method shouldn't return an optional." I think that is OK, but it's at odds with the assumption inside Connection.lastInsertRowid that sqlite3_last_insert_rowid() == 0 always means "not set". I think that, since rowid can be an alias to a user-defined column, it's lastInsertRowid that is wrong, and it should always return the integer that it gets, even if that is 0.
Technically that's a breaking API change; I don't know if you have a policy about that.
The text was updated successfully, but these errors were encountered:
This bug is similar to #235 and #383, but is not fixed by the changes in #383.
The crash is the same:
Query.run(query: Insert)
successfully runs the insert, butsqlite3_last_insert_rowid
returns 0 afterwards, which means thatConnection.lastInsertRowid
returns nil, andQuery.run
crashes when it force-unwraps that nil.This can happen in two situations according to the SQLite last_insert_row_id documentation. The first is the one that I hit:
WITHOUT ROWID
. As documented: "Inserts into WITHOUT ROWID tables are not recorded."To reproduce the first crash, you can do something like this:
In #383, @stephencelis said "My take: the main insert() method shouldn't return an optional." I think that is OK, but it's at odds with the assumption inside
Connection.lastInsertRowid
thatsqlite3_last_insert_rowid() == 0
always means "not set". I think that, since rowid can be an alias to a user-defined column, it'slastInsertRowid
that is wrong, and it should always return the integer that it gets, even if that is 0.Technically that's a breaking API change; I don't know if you have a policy about that.
The text was updated successfully, but these errors were encountered: