@@ -271,57 +271,60 @@ void tvector_from_string(vsql::MaybeParams<TVectorParams> &p,
271271// Decode: N * bpe bytes binary -> "[v1,v2,...,vN]" string.
272272// TVECTOR -> STRING
273273// Dimension and element type are read from type parameters.
274- bool tvector_to_string (const TVectorParams &p,
275- vsql::Span<const unsigned char > data,
276- vsql::Span<char > out, size_t *out_len) {
274+ void tvector_to_string (vsql::CustomArgWith<TVectorParams> in,
275+ vsql::StringResult out) {
276+ const TVectorParams &p = in.params ();
277+ auto data = in.value ();
277278 const size_t bpe = p.bytes_per_elem ;
278- if (data.size () != static_cast <size_t >(p.dimension ) * bpe) return true ;
279+ if (data.size () != static_cast <size_t >(p.dimension ) * bpe) return ;
279280
281+ auto buf = out.buffer ();
280282 size_t pos = 0 ;
281- if (pos >= out .size ()) return true ;
282- out [pos++] = ' [' ;
283+ if (pos >= buf .size ()) return ;
284+ buf [pos++] = ' [' ;
283285
284286 for (size_t i = 0 ; i < static_cast <size_t >(p.dimension ); i++) {
285287 if (i > 0 ) {
286- if (pos >= out .size ()) return true ;
287- out [pos++] = ' ,' ;
288+ if (pos >= buf .size ()) return ;
289+ buf [pos++] = ' ,' ;
288290 }
289291 int written;
290292 if (bpe == 8 ) {
291293 double val = load_double (data.data () + i * bpe);
292- written = snprintf (out .data () + pos, out .size () - pos, " %.17g" , val);
294+ written = snprintf (buf .data () + pos, buf .size () - pos, " %.17g" , val);
293295 } else {
294296 float val = load_float (data.data () + i * bpe);
295- written = snprintf (out .data () + pos, out .size () - pos, " %g" , val);
297+ written = snprintf (buf .data () + pos, buf .size () - pos, " %g" , val);
296298 }
297- if (written < 0 || pos + static_cast <size_t >(written) >= out.size ())
298- return true ;
299+ if (written < 0 || pos + static_cast <size_t >(written) >= buf.size ()) return ;
299300 pos += static_cast <size_t >(written);
300301 }
301302
302- if (pos >= out .size ()) return true ;
303- out [pos++] = ' ]' ;
303+ if (pos >= buf .size ()) return ;
304+ buf [pos++] = ' ]' ;
304305
305- *out_len = pos;
306- return false ;
306+ out.set_length (pos);
307307}
308308
309309// Compare: (TVECTOR, TVECTOR) -> INT for ORDER BY, indexes.
310310// Lexicographic element-by-element comparison.
311311// TODO(villagesql-performance): we can also consider having templated versions
312312// of these functions instead of using branches, then selecting the version to
313313// use with one branch.
314- int tvector_compare (const TVectorParams &p, vsql::Span<const unsigned char > a,
315- vsql::Span<const unsigned char > b) {
314+ int tvector_compare (vsql::CustomArgWith<TVectorParams> a,
315+ vsql::CustomArgWith<TVectorParams> b) {
316+ const TVectorParams &p = a.params ();
317+ const unsigned char *da = a.value ().data ();
318+ const unsigned char *db = b.value ().data ();
316319 for (int64_t i = 0 ; i < p.dimension ; i++) {
317320 if (p.bytes_per_elem == 8 ) {
318- double v1 = load_double (a. data () + i * p.bytes_per_elem );
319- double v2 = load_double (b. data () + i * p.bytes_per_elem );
321+ double v1 = load_double (da + i * p.bytes_per_elem );
322+ double v2 = load_double (db + i * p.bytes_per_elem );
320323 if (v1 < v2) return -1 ;
321324 if (v1 > v2) return 1 ;
322325 } else {
323- float v1 = load_float (a. data () + i * p.bytes_per_elem );
324- float v2 = load_float (b. data () + i * p.bytes_per_elem );
326+ float v1 = load_float (da + i * p.bytes_per_elem );
327+ float v2 = load_float (db + i * p.bytes_per_elem );
325328 if (v1 < v2) return -1 ;
326329 if (v1 > v2) return 1 ;
327330 }
0 commit comments