Skip to content

Commit 0a8c1bf

Browse files
authored
Manually preserve cconvert values until sqlite3_step (#308)
Fixes #306. The core issue here is that when we `bind!` some values to an insert statement, the _cconvert_ed value needs to remain valid (i.e. not GC-able) until we execute the insert statement in `sqlite3_step`. In each `SQLite.Stmt`, we have a `params` field for storing these values, but we weren't accounting for the fact that some values, (in the original issue case, InlineStrings), may be `cconvert`ed to a different value when they're actually bound, and it's the cconverted value that we need to store in `params` until the statement is executed.
1 parent 396971f commit 0a8c1bf

File tree

1 file changed

+4
-2
lines changed

1 file changed

+4
-2
lines changed

src/SQLite.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ DB is disconnected or when [`SQLite.finalize_statements!`](@ref) is explicitly c
140140
mutable struct Stmt <: DBInterface.Statement
141141
db::DB
142142
stmt_wrapper::StmtWrapper
143+
# used for holding references to bound statement values via bind!
143144
params::Dict{Int,Any}
144145

145146
function Stmt(db::DB, sql::AbstractString; register::Bool = true)
@@ -311,11 +312,12 @@ function bind!(stmt::Stmt, i::Integer, val::Nothing)
311312
@CHECK stmt.db C.sqlite3_bind_null(_get_stmt_handle(stmt), i)
312313
end
313314
function bind!(stmt::Stmt, i::Integer, val::AbstractString)
314-
stmt.params[i] = val
315+
cval = Base.cconvert(Ptr{Cchar}, val)
316+
stmt.params[i] = cval
315317
@CHECK stmt.db C.sqlite3_bind_text(
316318
_get_stmt_handle(stmt),
317319
i,
318-
val,
320+
cval,
319321
sizeof(val),
320322
C_NULL,
321323
)

0 commit comments

Comments
 (0)