Skip to content

Commit 4ccdf52

Browse files
committed
Switched to public constructor for from_string for SparseVector [skip ci]
1 parent f1917e6 commit 4ccdf52

3 files changed

Lines changed: 15 additions & 25 deletions

File tree

include/pgvector/pqxx.hpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#pragma once
88

99
#include <cstddef>
10+
#include <limits>
1011
#include <string_view>
1112
#include <vector>
1213

@@ -182,13 +183,8 @@ template<> struct string_traits<pgvector::SparseVector> {
182183
throw conversion_error{"Malformed sparsevec literal"};
183184
}
184185

186+
std::unordered_map<int, float> map;
185187
int dimensions = pqxx::from_string<int>(text.substr(n + 2), c);
186-
if (dimensions < 0) {
187-
throw conversion_error{"Dimensions cannot be negative"};
188-
}
189-
190-
std::vector<int> indices;
191-
std::vector<float> values;
192188

193189
if (n > 1) {
194190
auto add_element = [&](std::string_view substr) {
@@ -200,12 +196,12 @@ template<> struct string_traits<pgvector::SparseVector> {
200196
int index = pqxx::from_string<int>(substr.substr(0, ne), c);
201197
float value = pqxx::from_string<float>(substr.substr(ne + 1), c);
202198

203-
if (index < 1 || index > dimensions) {
204-
throw conversion_error{"Index out of bounds"};
199+
// check to avoid undefined behavior
200+
if (index > std::numeric_limits<int>::min()) {
201+
index -= 1;
205202
}
206203

207-
indices.push_back(index - 1);
208-
values.push_back(value);
204+
map.insert({index, value});
209205
};
210206

211207
std::string_view inner = text.substr(1, n - 1);
@@ -219,7 +215,11 @@ template<> struct string_traits<pgvector::SparseVector> {
219215
add_element(inner.substr(start));
220216
}
221217

222-
return pgvector::SparseVector{dimensions, std::move(indices), std::move(values)};
218+
try {
219+
return pgvector::SparseVector{map, dimensions};
220+
} catch (const std::invalid_argument& e) {
221+
throw conversion_error{e.what()};
222+
}
223223
}
224224

225225
static std::string_view to_buf(std::span<char> buf, const pgvector::SparseVector& value, ctx c = {}) {

include/pgvector/sparsevec.hpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,6 @@ namespace pgvector {
1919
/// A sparse vector.
2020
class SparseVector {
2121
public:
22-
/// @private
23-
SparseVector(int dimensions, std::vector<int>&& indices, std::vector<float>&& values) {
24-
if (values.size() != indices.size()) {
25-
throw std::invalid_argument{"indices and values must be the same length"};
26-
}
27-
dimensions_ = dimensions;
28-
indices_ = std::move(indices);
29-
values_ = std::move(values);
30-
}
31-
3222
/// Creates a sparse vector from a dense vector.
3323
explicit SparseVector(const std::vector<float>& value) : SparseVector(std::span<const float>{value}) {}
3424

test/pqxx_test.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ void test_sparsevec_from_string() {
246246

247247
assert_exception<pqxx::conversion_error>([] {
248248
auto _ = pqxx::from_string<pgvector::SparseVector>("{}/-1");
249-
}, "Dimensions cannot be negative");
249+
}, "sparsevec must have at least 1 dimension");
250250

251251
assert_exception<pqxx::conversion_error>([] {
252252
auto _ = pqxx::from_string<pgvector::SparseVector>("{:}/1");
@@ -258,15 +258,15 @@ void test_sparsevec_from_string() {
258258

259259
assert_exception<pqxx::conversion_error>([] {
260260
auto _ = pqxx::from_string<pgvector::SparseVector>("{0:1}/1");
261-
}, "Index out of bounds");
261+
}, "sparsevec index out of bounds");
262262

263263
assert_exception<pqxx::conversion_error>([] {
264264
auto _ = pqxx::from_string<pgvector::SparseVector>("{-2147483648:1}/1");
265-
}, "Index out of bounds");
265+
}, "sparsevec index out of bounds");
266266

267267
assert_exception<pqxx::conversion_error>([] {
268268
auto _ = pqxx::from_string<pgvector::SparseVector>("{2:1}/1");
269-
}, "Index out of bounds");
269+
}, "sparsevec index out of bounds");
270270

271271
assert_exception<pqxx::conversion_error>([] {
272272
auto _ = pqxx::from_string<pgvector::SparseVector>("{1:4e38}/1");

0 commit comments

Comments
 (0)