Skip to content

Commit b6d08e8

Browse files
Special VDFs to use CustomArg/Result (#515)
Refs #504 Next step - update external repos. Then remove old signatures/update comments.
1 parent 1b366e4 commit b6d08e8

10 files changed

Lines changed: 274 additions & 169 deletions

File tree

mysql-test/suite/villagesql/std_data/bad_type_funcs.cc

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,23 +34,14 @@ void f1_impl(std::string_view from, vsql::CustomResult out) {
3434
}
3535

3636
// Generic TO_STRING function
37-
bool f2_impl(vsql::Span<const unsigned char> buf,
38-
vsql::Span<char> to, size_t *to_length) {
39-
(void)buf;
40-
41-
if (to.size() < 4) {
42-
return true;
43-
}
44-
45-
strcpy(to.data(), "val");
46-
*to_length = 3;
47-
return false;
37+
void f2_impl(vsql::CustomArg in, vsql::StringResult out) {
38+
(void)in;
39+
out.set("val");
4840
}
4941

5042
// Generic COMPARE function
51-
int f3_impl(vsql::Span<const unsigned char> a,
52-
vsql::Span<const unsigned char> b) {
53-
return memcmp(a.data(), b.data(), 16);
43+
int f3_impl(vsql::CustomArg a, vsql::CustomArg b) {
44+
return memcmp(a.value().data(), b.value().data(), 16);
5445
}
5546

5647
static constexpr const char kTestBadTypeName[] = "TESTBADTYPE";

mysql-test/suite/villagesql/std_data/complex3_encode.cc

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -37,25 +37,13 @@ void complex3_from_string(std::string_view from, vsql::CustomResult out) {
3737
}
3838

3939
// TO_STRING: always return "(0,0)"
40-
bool complex3_to_string(vsql::Span<const unsigned char> buf,
41-
vsql::Span<char> to, size_t *to_length) {
42-
(void)buf; // Unused - always return "(0,0)"
43-
44-
const char *result = "(0,0)";
45-
size_t len = strlen(result);
46-
47-
if (to.size() < len + 1) {
48-
return true; // Error
49-
}
50-
51-
memcpy(to.data(), result, len);
52-
*to_length = len;
53-
return false; // Success
40+
void complex3_to_string(vsql::CustomArg in, vsql::StringResult out) {
41+
(void)in; // Unused - always return "(0,0)"
42+
out.set("(0,0)");
5443
}
5544

5645
// COMPARE: always returns 0 (equal)
57-
int complex3_compare(vsql::Span<const unsigned char> a,
58-
vsql::Span<const unsigned char> b) {
46+
int complex3_compare(vsql::CustomArg a, vsql::CustomArg b) {
5947
(void)a;
6048
(void)b;
6149
return 0;

mysql-test/suite/villagesql/std_data/missing_params_fn.cc

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,20 +43,21 @@ void faketype_encode(vsql::MaybeParams<FakeParams> &, std::string_view from,
4343
out.set_length(n);
4444
}
4545

46-
bool faketype_decode(vsql::Span<const unsigned char> data,
47-
vsql::Span<char> out, size_t *out_len) {
48-
size_t n = data.size() < out.size() ? data.size() : out.size();
49-
memcpy(out.data(), data.data(), n);
50-
*out_len = n;
51-
return false;
46+
void faketype_decode(vsql::CustomArg in, vsql::StringResult out) {
47+
auto data = in.value();
48+
auto buf = out.buffer();
49+
size_t n = data.size() < buf.size() ? data.size() : buf.size();
50+
memcpy(buf.data(), data.data(), n);
51+
out.set_length(n);
5252
}
5353

54-
int faketype_compare(vsql::Span<const unsigned char> a,
55-
vsql::Span<const unsigned char> b) {
56-
size_t n = a.size() < b.size() ? a.size() : b.size();
57-
int r = memcmp(a.data(), b.data(), n);
54+
int faketype_compare(vsql::CustomArg a, vsql::CustomArg b) {
55+
auto va = a.value();
56+
auto vb = b.value();
57+
size_t n = va.size() < vb.size() ? va.size() : vb.size();
58+
int r = memcmp(va.data(), vb.data(), n);
5859
if (r != 0) return r;
59-
return static_cast<int>(a.size()) - static_cast<int>(b.size());
60+
return static_cast<int>(va.size()) - static_cast<int>(vb.size());
6061
}
6162

6263
static constexpr const char kFakeTypeName[] = "FAKETYPE";

mysql-test/suite/villagesql/std_data/no_default_type.cc

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,19 +41,16 @@ void no_default_encode(std::string_view from, vsql::CustomResult out) {
4141
out.set_length(static_cast<size_t>(kLen));
4242
}
4343

44-
bool no_default_decode(vsql::Span<const unsigned char> buffer,
45-
vsql::Span<char> out, size_t *out_len) {
46-
if (buffer.size() < static_cast<size_t>(kLen)) return true;
47-
int written = snprintf(out.data(), out.size(), "(%u)", buffer[0]);
48-
if (written < 0) return true;
49-
*out_len = static_cast<size_t>(written);
50-
return false;
44+
void no_default_decode(vsql::CustomArg in, vsql::StringResult out) {
45+
auto buffer = in.value();
46+
if (buffer.size() < static_cast<size_t>(kLen)) return; // default ERROR
47+
auto buf = out.buffer();
48+
int written = snprintf(buf.data(), buf.size(), "(%u)", buffer[0]);
49+
if (written < 0) return;
50+
out.set_length(static_cast<size_t>(written));
5151
}
5252

53-
int no_default_compare(vsql::Span<const unsigned char>,
54-
vsql::Span<const unsigned char>) {
55-
return 0;
56-
}
53+
int no_default_compare(vsql::CustomArg, vsql::CustomArg) { return 0; }
5754

5855
static constexpr const char kNoDefaultTypeName[] = "NO_DEFAULT_TYPE";
5956

mysql-test/suite/villagesql/std_data/testtype_full.cc

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,18 +39,18 @@ void encode_testtype(std::string_view from, vsql::CustomResult out) {
3939
out.set_length(kTestTypeLen);
4040
}
4141

42-
bool decode_testtype_full(vsql::Span<const unsigned char> from,
43-
vsql::Span<char> to, size_t *to_length) {
42+
void decode_testtype_full(vsql::CustomArg in, vsql::StringResult out) {
43+
auto from = in.value();
4444
double real, imag;
4545
memcpy(&real, from.data(), 8);
4646
memcpy(&imag, from.data() + 8, 8);
47-
*to_length = snprintf(to.data(), to.size(), "(%.17g,%.17g)", real, imag);
48-
return false;
47+
auto to = out.buffer();
48+
size_t len = snprintf(to.data(), to.size(), "(%.17g,%.17g)", real, imag);
49+
out.set_length(len);
4950
}
5051

51-
int cmp_testtype(vsql::Span<const unsigned char> l,
52-
vsql::Span<const unsigned char> r) {
53-
return memcmp(l.data(), r.data(), kTestTypeLen);
52+
int cmp_testtype(vsql::CustomArg l, vsql::CustomArg r) {
53+
return memcmp(l.value().data(), r.value().data(), kTestTypeLen);
5454
}
5555

5656
static constexpr const char kTestTypeName[] = "TESTTYPE";

mysql-test/suite/villagesql/std_data/testtype_short.cc

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,18 +39,18 @@ void encode_testtype(std::string_view from, vsql::CustomResult out) {
3939
out.set_length(kTestTypeLen);
4040
}
4141

42-
bool decode_testtype_short(vsql::Span<const unsigned char> from,
43-
vsql::Span<char> to, size_t *to_length) {
42+
void decode_testtype_short(vsql::CustomArg in, vsql::StringResult out) {
43+
auto from = in.value();
4444
double real, imag;
4545
memcpy(&real, from.data(), 8);
4646
memcpy(&imag, from.data() + 8, 8);
47-
*to_length = snprintf(to.data(), to.size(), "(%.6g,%.6g)", real, imag);
48-
return false;
47+
auto to = out.buffer();
48+
size_t len = snprintf(to.data(), to.size(), "(%.6g,%.6g)", real, imag);
49+
out.set_length(len);
4950
}
5051

51-
int cmp_testtype(vsql::Span<const unsigned char> a,
52-
vsql::Span<const unsigned char> b) {
53-
return memcmp(a.data(), b.data(), kTestTypeLen);
52+
int cmp_testtype(vsql::CustomArg a, vsql::CustomArg b) {
53+
return memcmp(a.value().data(), b.value().data(), kTestTypeLen);
5454
}
5555

5656
static constexpr const char kTestTypeName[] = "TESTTYPE";

villagesql/examples/vsql-complex/src/complex.cc

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -135,22 +135,23 @@ void complex2_from_string(std::string_view from, vsql::CustomResult out) {
135135

136136
// Decode: 16 bytes -> "(real,imag)" string
137137
// COMPLEX -> STRING
138-
bool complex_to_string(vsql::Span<const unsigned char> data,
139-
vsql::Span<char> out, size_t *out_len) {
140-
if (data.size() != kComplexSize) return true;
138+
void complex_to_string(CustomArg in, StringResult out) {
139+
auto data = in.value();
140+
if (data.size() != kComplexSize) return; // wrapper default ERROR
141141
Complex cx = load_complex(data.data());
142-
int written = snprintf(out.data(), out.size(), "(%g,%g)", cx.re, cx.im);
143-
if (written < 0 || static_cast<size_t>(written) >= out.size()) return true;
144-
*out_len = static_cast<size_t>(written);
145-
return false;
142+
auto buf = out.buffer();
143+
int written = snprintf(buf.data(), buf.size(), "(%g,%g)", cx.re, cx.im);
144+
if (written < 0 || static_cast<size_t>(written) >= buf.size()) return;
145+
out.set_length(static_cast<size_t>(written));
146146
}
147147

148148
// Compare: (COMPLEX, COMPLEX) -> INT for ORDER BY, indexes
149-
int complex_compare(vsql::Span<const unsigned char> a,
150-
vsql::Span<const unsigned char> b) {
151-
if (a.size() != kComplexSize || b.size() != kComplexSize) return 0;
152-
Complex lhs = load_complex(a.data());
153-
Complex rhs = load_complex(b.data());
149+
int complex_compare(CustomArg a, CustomArg b) {
150+
auto da = a.value();
151+
auto db = b.value();
152+
if (da.size() != kComplexSize || db.size() != kComplexSize) return 0;
153+
Complex lhs = load_complex(da.data());
154+
Complex rhs = load_complex(db.data());
154155

155156
// Compare real parts first
156157
if (lhs.re < rhs.re) return -1;
@@ -165,7 +166,8 @@ int complex_compare(vsql::Span<const unsigned char> a,
165166
// Canonicalizes -0 to +0 before hashing so that -0.0 and +0.0 hash to the
166167
// same bucket. This allows COMPLEX2 to preserve -0 in storage while still
167168
// working correctly with hash joins and EXCEPT operations.
168-
size_t complex2_hash(vsql::Span<const unsigned char> data) {
169+
size_t complex2_hash(CustomArg in) {
170+
auto data = in.value();
169171
if (data.size() != kComplexSize) return 0;
170172
Complex cx = load_complex(data.data());
171173
cx.canonicalize();

villagesql/examples/vsql-simple/src/extension.cc

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,18 +42,17 @@ void bytearray_from_string(std::string_view from, CustomResult out) {
4242
}
4343

4444
// to_string: binary -> string (copy 8 bytes)
45-
bool bytearray_to_string(Span<const unsigned char> data, Span<char> out,
46-
size_t *out_len) {
47-
if (data.size() < kBytearrayLen || out.size() < kBytearrayLen) return true;
48-
memcpy(out.data(), data.data(), kBytearrayLen);
49-
*out_len = kBytearrayLen;
50-
return false; // success
45+
void bytearray_to_string(CustomArg in, StringResult out) {
46+
auto data = in.value();
47+
auto buf = out.buffer();
48+
if (data.size() < kBytearrayLen || buf.size() < kBytearrayLen) return;
49+
memcpy(buf.data(), data.data(), kBytearrayLen);
50+
out.set_length(kBytearrayLen);
5151
}
5252

5353
// Compare: lexicographic byte comparison
54-
int bytearray_compare(Span<const unsigned char> a,
55-
Span<const unsigned char> b) {
56-
return memcmp(a.data(), b.data(), kBytearrayLen);
54+
int bytearray_compare(CustomArg a, CustomArg b) {
55+
return memcmp(a.value().data(), b.value().data(), kBytearrayLen);
5756
}
5857

5958
// ROT13: apply ROT13 cipher to ASCII letters

villagesql/examples/vsql-tvector/src/tvector.cc

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)