Skip to content

Commit 4e802fd

Browse files
committed
Added support for binary decoding
1 parent feaa5dc commit 4e802fd

File tree

5 files changed

+94
-4
lines changed

5 files changed

+94
-4
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 0.1.1 (unreleased)
2+
3+
- Added support for binary decoding
4+
15
## 0.1.0 (2025-06-07)
26

37
- First release

src/halfvec.jl

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,31 @@
1+
using LibPQ
2+
13
struct HalfVector
24
vec::Base.Vector{Float16}
35
end
46

5-
function Base.parse(::Type{HalfVector}, s::String)
7+
function Base.parse(::Type{HalfVector}, pqv::LibPQ.PQBinaryValue{OID}) where {OID}
8+
ptr = LibPQ.data_pointer(pqv)
9+
10+
dim = ntoh(unsafe_load(Ptr{Int16}(ptr)))
11+
ptr += sizeof(Int16)
12+
13+
# TODO check unused
14+
unused = ntoh(unsafe_load(Ptr{Int16}(ptr)))
15+
ptr += sizeof(Int16)
16+
17+
vec = []
18+
for i = 1:dim
19+
v = ntoh(unsafe_load(Ptr{Float16}(ptr)))
20+
ptr += sizeof(Float16)
21+
append!(vec, v)
22+
end
23+
24+
HalfVector(vec)
25+
end
26+
27+
function Base.parse(::Type{HalfVector}, pqv::LibPQ.PQTextValue{OID}) where {OID}
28+
s = unsafe_string(pqv)
629
HalfVector(map(x -> Base.parse(Float16, x), split(s[2:end-1], ",")))
730
end
831

src/sparsevec.jl

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,41 @@
1-
using SparseArrays
1+
using LibPQ, SparseArrays
22

33
struct SparseVector
44
vec::SparseArrays.SparseVector{Float32,Int32}
55
end
66

7-
function Base.parse(::Type{SparseVector}, s::String)
7+
function Base.parse(::Type{SparseVector}, pqv::LibPQ.PQBinaryValue{OID}) where {OID}
8+
ptr = LibPQ.data_pointer(pqv)
9+
10+
dim = ntoh(unsafe_load(Ptr{Int32}(ptr)))
11+
ptr += sizeof(Int32)
12+
13+
nnz = ntoh(unsafe_load(Ptr{Int32}(ptr)))
14+
ptr += sizeof(Int32)
15+
16+
# TODO check unused
17+
unused = ntoh(unsafe_load(Ptr{Int32}(ptr)))
18+
ptr += sizeof(Int32)
19+
20+
indices = []
21+
for i = 1:nnz
22+
v = ntoh(unsafe_load(Ptr{Int32}(ptr)))
23+
ptr += sizeof(Int32)
24+
append!(indices, v + 1)
25+
end
26+
27+
values = []
28+
for i = 1:nnz
29+
v = ntoh(unsafe_load(Ptr{Float32}(ptr)))
30+
ptr += sizeof(Float32)
31+
append!(values, v)
32+
end
33+
34+
SparseVector(sparsevec(indices, values, dim))
35+
end
36+
37+
function Base.parse(::Type{SparseVector}, pqv::LibPQ.PQTextValue{OID}) where {OID}
38+
s = unsafe_string(pqv)
839
elements, dim = rsplit(s, "/"; limit=2)
940
elements = map(e -> split(e, ":"; limit=2), split(elements[2:end-1], ","))
1041
indices = map(v -> Base.parse(Int32, v[1]), elements)

src/vector.jl

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,31 @@
1+
using LibPQ
2+
13
struct Vector
24
vec::Base.Vector{Float32}
35
end
46

5-
function Base.parse(::Type{Vector}, s::String)
7+
function Base.parse(::Type{Vector}, pqv::LibPQ.PQBinaryValue{OID}) where {OID}
8+
ptr = LibPQ.data_pointer(pqv)
9+
10+
dim = ntoh(unsafe_load(Ptr{Int16}(ptr)))
11+
ptr += sizeof(Int16)
12+
13+
# TODO check unused
14+
unused = ntoh(unsafe_load(Ptr{Int16}(ptr)))
15+
ptr += sizeof(Int16)
16+
17+
vec = []
18+
for i = 1:dim
19+
v = ntoh(unsafe_load(Ptr{Float32}(ptr)))
20+
ptr += sizeof(Float32)
21+
append!(vec, v)
22+
end
23+
24+
Vector(vec)
25+
end
26+
27+
function Base.parse(::Type{Vector}, pqv::LibPQ.PQTextValue{OID}) where {OID}
28+
s = unsafe_string(pqv)
629
Vector(map(x -> Base.parse(Float32, x), split(s[2:end-1], ",")))
730
end
831

test/runtests.jl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ Pgvector.register!(conn)
1010

1111
vec = columntable(execute(conn, "SELECT '[1,2,3]'::vector"))[1][1]
1212
@test vec.vec == [1, 2, 3]
13+
14+
vec = columntable(execute(conn, "SELECT '[1,2,3]'::vector", binary_format=true))[1][1]
15+
@test vec.vec == [1, 2, 3]
1316
end
1417

1518
@testset "HalfVector" begin
@@ -18,6 +21,9 @@ end
1821

1922
vec = columntable(execute(conn, "SELECT '[1,2,3]'::halfvec"))[1][1]
2023
@test vec.vec == [1, 2, 3]
24+
25+
vec = columntable(execute(conn, "SELECT '[1,2,3]'::halfvec", binary_format=true))[1][1]
26+
@test vec.vec == [1, 2, 3]
2127
end
2228

2329
@testset "SparseVector" begin
@@ -26,4 +32,7 @@ end
2632

2733
vec = columntable(execute(conn, "SELECT '{1:1,3:2,5:3}/6'::sparsevec"))[1][1]
2834
@test vec.vec == sparsevec([1, 0, 2, 0, 3, 0])
35+
36+
vec = columntable(execute(conn, "SELECT '{1:1,3:2,5:3}/6'::sparsevec", binary_format=true))[1][1]
37+
@test vec.vec == sparsevec([1, 0, 2, 0, 3, 0])
2938
end

0 commit comments

Comments
 (0)