JuliaDatabases / SQLite.jl

A Julia interface to the SQLite library
https://juliadatabases.org/SQLite.jl/stable
Other
223 stars 78 forks source link

Binding signed/unsigned integer causes different results #313

Open rongcuid opened 1 year ago

rongcuid commented 1 year ago

For instance a query like so:

SELECT * FROM table WHERE x = ?

Binding 0x1000 (which is UInt16) and Int(0x1000) yield different results.

metab0t commented 1 year ago

Please give a reproducible example.

rongcuid commented 1 year ago
db = SQLite.DB()
DBInterface.execute(db, "CREATE TABLE t(x INTEGER)")
DBInterface.execute(db, "INSERT INTO t(x) VALUES (1000)")

Then:

julia> using DataFrames

julia> DBInterface.execute(db, "SELECT * FROM t WHERE x  = 1000") |> DataFrame
1×1 DataFrame
 Row │ x     
     │ Int64 
─────┼───────
   1 │  1000

julia> DBInterface.execute(db, "SELECT * FROM t WHERE x  = ?", (1000,)) |> DataFrame
1×1 DataFrame
 Row │ x     
     │ Int64 
─────┼───────
   1 │  1000

julia> DBInterface.execute(db, "SELECT * FROM t WHERE x  = ?", (UInt16(1000),)) |> DataFrame
0×1 DataFrame
 Row │ x      
     │ Int64? 
─────┴────────
julia> DBInterface.execute(db, "SELECT * FROM t WHERE x  = ?", (UInt32(1000),)) |> DataFrame
0×1 DataFrame
 Row │ x      
     │ Int64? 
─────┴────────

julia> DBInterface.execute(db, "SELECT * FROM t WHERE x  = ?", (UInt64(1000),)) |> DataFrame
0×1 DataFrame
 Row │ x      
     │ Int64? 
─────┴────────
quinnj commented 1 year ago

I think this is because we don't have a direct dispatch for UInt types, so they go through the fallback which does the full serialize(x) and bound as blobs. We should probably have a fallback for Integer that converts to Int64 and does the bind, though that may mean we get a weird truncation issue for some UInt64. Or maybe we explicitly error and say you can only bind signed integers since sqlite doesn't ahve explicit bind functions for unsigned.

Zentrik commented 2 months ago

This also seems to be an issue if you load a DataFrame with UInt64s in it into a database. Everything works fine on Julia, but sqlite3 and other libraries see a string.