Skip to content

Commit 9576742

Browse files
authored
feat: fully support VECTOR type results
1 parent 3659488 commit 9576742

File tree

6 files changed

+73
-2
lines changed

6 files changed

+73
-2
lines changed

.github/workflows/ci-mysql.yml

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ jobs:
2424
'mysql:8.0.18',
2525
'mysql:8.0.22',
2626
'mysql:8.0.33',
27+
'mysql:9.0.1',
2728
'mysql:latest',
2829
]
2930
use-compression: [0, 1]

lib/packets/packet.js

+10
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,16 @@ class Packet {
608608
return parseGeometry();
609609
}
610610

611+
parseVector() {
612+
const bufLen = this.readLengthCodedNumber();
613+
const vectorEnd = this.offset + bufLen;
614+
const result = [];
615+
while (this.offset < vectorEnd && this.offset < this.end) {
616+
result.push(this.readFloat());
617+
}
618+
return result;
619+
}
620+
611621
parseDate(timezone) {
612622
const strLen = this.readLengthCodedNumber();
613623
if (strLen === null) {

lib/parsers/binary_parser.js

+2
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ function readCodeFor(field, config, options, fieldNum) {
5555
return 'packet.readLengthCodedString("ascii");';
5656
case Types.GEOMETRY:
5757
return 'packet.parseGeometryValue();';
58+
case Types.VECTOR:
59+
return 'packet.parseVector()';
5860
case Types.JSON:
5961
// Since for JSON columns mysql always returns charset 63 (BINARY),
6062
// we have to handle it according to JSON specs and use "utf8",

lib/parsers/text_parser.js

+2
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ function readCodeFor(type, charset, encodingExpr, config, options) {
5959
return 'packet.readLengthCodedString("ascii")';
6060
case Types.GEOMETRY:
6161
return 'packet.parseGeometryValue()';
62+
case Types.VECTOR:
63+
return 'packet.parseVector()';
6264
case Types.JSON:
6365
// Since for JSON columns mysql always returns charset 63 (BINARY),
6466
// we have to handle it according to JSON specs and use "utf8",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import { test, assert, describe } from 'poku';
2+
import { createRequire } from 'node:module';
3+
4+
const require = createRequire(import.meta.url);
5+
const common = require('../../../common.test.cjs');
6+
7+
const sql = `SELECT TO_VECTOR("[1.05, -17.8, 32, 123.456]") as test`;
8+
const expectedArray = [1.05, -17.8, 32, 123.456];
9+
const epsilon = 1e-6;
10+
11+
const compareFloat = (a, b) => Math.abs((a - b) / a) < epsilon;
12+
const compareFLoatsArray = (a, b) => a.every((v, i) => compareFloat(v, b[i]));
13+
14+
(async () => {
15+
const connection = common.createConnection().promise();
16+
17+
const mySqlVersion = await common.getMysqlVersion(connection);
18+
19+
if (mySqlVersion.major < 9) {
20+
console.log(
21+
`Skipping the test, required mysql version is 9 and above, actual version is ${mySqlVersion.major}`,
22+
);
23+
await connection.end();
24+
return;
25+
}
26+
27+
await test(async () => {
28+
describe(
29+
'Execute PS with vector response is parsed correctly',
30+
common.describeOptions,
31+
);
32+
33+
const [_rows] = await connection.execute(sql);
34+
assert.equal(
35+
compareFLoatsArray(_rows[0].test, expectedArray),
36+
true,
37+
`${_rows[0].test} should be equal to ${expectedArray}`,
38+
);
39+
});
40+
41+
await test(async () => {
42+
describe(
43+
'Select returning vector is parsed correctly',
44+
common.describeOptions,
45+
);
46+
47+
const [_rows] = await connection.query(sql);
48+
assert.equal(
49+
compareFLoatsArray(_rows[0].test, expectedArray),
50+
true,
51+
`${_rows[0].test} should be equal to ${expectedArray}`,
52+
);
53+
});
54+
55+
await connection.end();
56+
})();

test/esm/regressions/2052.test.mjs

+2-2
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ test(async () => {
104104

105105
if (major === 9) return false;
106106
if (major === 8 && minor === 4 && patch === 1) return false;
107-
if (major === 8 && minor === 0 && patch === 38) return false;
107+
if (major === 8 && minor === 0 && patch >= 38) return false;
108108

109109
if (major > 8) {
110110
return true;
@@ -125,7 +125,7 @@ test(async () => {
125125
async () =>
126126
new Promise((resolve, reject) => {
127127
describe(
128-
'E2E Prepare result with number of parameters incorrectly reported by the server',
128+
`E2E Prepare result with number of parameters incorrectly reported by the server`,
129129
common.describeOptions,
130130
);
131131

0 commit comments

Comments
 (0)