From e3c6814f5a33b54af88c2846721e7d8ef5c26b81 Mon Sep 17 00:00:00 2001 From: Max Freudenberg <67329240+maxfreu@users.noreply.github.com> Date: Wed, 22 May 2024 05:04:46 +0200 Subject: [PATCH] relax bind! Vector{UInt8} -> AbstractVector{UInt8} (#340) * relax bind! Vector{UInt8} -> AbstractVector{UInt8} This allows zero-copy writes e.g. for ReinterpretArrays. * special case for ReinterpretArray * fix size calculation, add tests * pass pointer of ReinterpA. to ccall * replace pointer by Ref --------- Co-authored-by: Max Freudenberg --- src/SQLite.jl | 10 ++++++++++ test/runtests.jl | 18 ++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/SQLite.jl b/src/SQLite.jl index 6525c84..814fb23 100644 --- a/src/SQLite.jl +++ b/src/SQLite.jl @@ -356,6 +356,16 @@ function bind!(stmt::Stmt, i::Integer, val::Vector{UInt8}) C.SQLITE_STATIC, ) end +function bind!(stmt::Stmt, i::Integer, val::Base.ReinterpretArray{UInt8, 1, T, <:DenseVector{T}, false}) where T + stmt.params[i] = val + @CHECK stmt.db C.sqlite3_bind_blob( + _get_stmt_handle(stmt), + i, + Ref(val, 1), + sizeof(eltype(val)) * length(val), + C.SQLITE_STATIC, + ) +end # Fallback is BLOB and defaults to serializing the julia value # internal wrapper mutable struct to, in-effect, mark something which has been serialized diff --git a/test/runtests.jl b/test/runtests.jl index 9c78383..b2a8927 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -906,6 +906,24 @@ end close(db) rm(dbfile) end + + @testset "ReinterpretArray" begin + binddb = SQLite.DB() + DBInterface.execute( + binddb, + "CREATE TABLE temp (b BLOB)", + ) + DBInterface.execute( + binddb, + "INSERT INTO temp VALUES (?)", + [reinterpret(UInt8, [0x6f46, 0x426f, 0x7261]),], + ) + rr = DBInterface.execute(rowtable, binddb, "SELECT b FROM temp") + @test length(rr) == 1 + r = first(rr) + @test r.b == codeunits("FooBar") + @test typeof.(Tuple(r)) == (Vector{UInt8},) + end end # @testset struct UnknownSchemaTable end