(Fix) Handle nullability of SQLite rowid alias columns
Does your PR solve an issue?
fixes #3967
Is this a breaking change?
This is a breaking change.
Previously an INTEGER PRIMARY KEY column was wrongly inferred to be nullable, so code using query! will break, as the result will now be an i64 instead of an Option<i64>.
query_as! should be fine though because Option<i64> implements From<i64>
This will apply anywhere someone has used an INTEGER PRIMARY KEY and not overridden the nullability of that column in their queries.
The explain.rs changes look reasonable to me. But I haven't touched sqlx in a long time, so I won't try to guess whether returning None from handle.rs column_nullable could lead to surprises.
I initially assumed that the handle.rs is not needed for the macro magic to work. But I vaguely remember some portion of the query type describe mechanism executed select queries to sniff the results... so maybe that is what forced the handle.rs changes?
column_nullable is only called from sqlx-sqlite/src/connection/describe.rs in function describe.
In that function the explain.rs nullability is used as a fallback.
I couldn't think of a reasonably efficient way to determine if a column was a rowid alias in column_nullable. However in explain.rs, obviously SQLite knows which columns are rowid aliases, and it uses special opcodes in those cases which are easy to recognise and handle.
The requested extra test makes sense. Will add.