Skip to content

Commit

Permalink
feat: fully support VECTOR type results
Browse files Browse the repository at this point in the history
  • Loading branch information
sidorares committed Jul 27, 2024
1 parent 3659488 commit 9576742
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 2 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ci-mysql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ jobs:
'mysql:8.0.18',
'mysql:8.0.22',
'mysql:8.0.33',
'mysql:9.0.1',
'mysql:latest',
]
use-compression: [0, 1]
Expand Down
10 changes: 10 additions & 0 deletions lib/packets/packet.js
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,16 @@ class Packet {
return parseGeometry();
}

parseVector() {
const bufLen = this.readLengthCodedNumber();
const vectorEnd = this.offset + bufLen;
const result = [];
while (this.offset < vectorEnd && this.offset < this.end) {
result.push(this.readFloat());
}
return result;
}

parseDate(timezone) {
const strLen = this.readLengthCodedNumber();
if (strLen === null) {
Expand Down
2 changes: 2 additions & 0 deletions lib/parsers/binary_parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ function readCodeFor(field, config, options, fieldNum) {
return 'packet.readLengthCodedString("ascii");';
case Types.GEOMETRY:
return 'packet.parseGeometryValue();';
case Types.VECTOR:
return 'packet.parseVector()';
case Types.JSON:
// Since for JSON columns mysql always returns charset 63 (BINARY),
// we have to handle it according to JSON specs and use "utf8",
Expand Down
2 changes: 2 additions & 0 deletions lib/parsers/text_parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ function readCodeFor(type, charset, encodingExpr, config, options) {
return 'packet.readLengthCodedString("ascii")';
case Types.GEOMETRY:
return 'packet.parseGeometryValue()';
case Types.VECTOR:
return 'packet.parseVector()';
case Types.JSON:
// Since for JSON columns mysql always returns charset 63 (BINARY),
// we have to handle it according to JSON specs and use "utf8",
Expand Down
56 changes: 56 additions & 0 deletions test/esm/integration/connection/test-vector.test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { test, assert, describe } from 'poku';
import { createRequire } from 'node:module';

const require = createRequire(import.meta.url);
const common = require('../../../common.test.cjs');

const sql = `SELECT TO_VECTOR("[1.05, -17.8, 32, 123.456]") as test`;
const expectedArray = [1.05, -17.8, 32, 123.456];
const epsilon = 1e-6;

const compareFloat = (a, b) => Math.abs((a - b) / a) < epsilon;
const compareFLoatsArray = (a, b) => a.every((v, i) => compareFloat(v, b[i]));

(async () => {
const connection = common.createConnection().promise();

const mySqlVersion = await common.getMysqlVersion(connection);

if (mySqlVersion.major < 9) {
console.log(
`Skipping the test, required mysql version is 9 and above, actual version is ${mySqlVersion.major}`,
);
await connection.end();
return;
}

await test(async () => {
describe(
'Execute PS with vector response is parsed correctly',
common.describeOptions,
);

const [_rows] = await connection.execute(sql);
assert.equal(
compareFLoatsArray(_rows[0].test, expectedArray),
true,
`${_rows[0].test} should be equal to ${expectedArray}`,
);
});

await test(async () => {
describe(
'Select returning vector is parsed correctly',
common.describeOptions,
);

const [_rows] = await connection.query(sql);
assert.equal(
compareFLoatsArray(_rows[0].test, expectedArray),
true,
`${_rows[0].test} should be equal to ${expectedArray}`,
);
});

await connection.end();
})();
4 changes: 2 additions & 2 deletions test/esm/regressions/2052.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ test(async () => {

if (major === 9) return false;
if (major === 8 && minor === 4 && patch === 1) return false;
if (major === 8 && minor === 0 && patch === 38) return false;
if (major === 8 && minor === 0 && patch >= 38) return false;

if (major > 8) {
return true;
Expand All @@ -125,7 +125,7 @@ test(async () => {
async () =>
new Promise((resolve, reject) => {
describe(
'E2E Prepare result with number of parameters incorrectly reported by the server',
`E2E Prepare result with number of parameters incorrectly reported by the server`,
common.describeOptions,
);

Expand Down

0 comments on commit 9576742

Please sign in to comment.