MariaDB Data Types
MariaDB has data types that do not exist in MySQL: UUID, INET4, INET6 and
VECTOR, plus a JSON type that is an alias for LONGTEXT rather than a
native binary type. On the wire these columns are sent as standard string and
blob types, so a client cannot distinguish, for example, a UUID column from a
CHAR column, unless the server also sends its extended type metadata.
When MySQL2 connects to a MariaDB server that supports it (MariaDB 10.5 and
above), it automatically negotiates the MARIADB_CLIENT_EXTENDED_METADATA
capability, and each column definition then carries the MariaDB type
information. No configuration is needed.
Extended column metadata
Every field object exposes two additional properties when the server provides them:
extendedTypeName: the MariaDB data type name, e.g.uuid,inet4,inet6, or a geometry subtype such aspoint.extendedFormat: the value format, e.g.jsonfor JSON columns.
const [rows, fields] = await connection.query(
'SELECT id, addr FROM hosts LIMIT 1'
);
console.log(fields[1].extendedTypeName);
// 'inet6'
Both properties are also available on the field object passed to a custom
typeCast function, which makes it possible to
apply custom conversions to MariaDB-specific types:
const [rows] = await connection.query({
sql: 'SELECT * FROM sessions',
typeCast: (field, next) => {
if (field.extendedTypeName === 'uuid') {
return field.string()?.toUpperCase();
}
return next();
},
});
On MySQL servers (and MariaDB older than 10.5) both properties are
undefined.
UUID, INET4 and INET6
Values are returned as strings, exactly as MariaDB formats them:
const [rows] = await connection.query('SELECT u, i4, i6 FROM t');
// rows[0].u === '123e4567-e89b-12d3-a456-426614174000'
// rows[0].i4 === '203.0.113.7'
// rows[0].i6 === '2001:db8::1'
To insert values, bind them as strings: MariaDB converts them to the compact internal representation on the server:
await connection.execute('INSERT INTO t (u, i4, i6) VALUES (?, ?, ?)', [
'123e4567-e89b-12d3-a456-426614174000',
'203.0.113.7',
'2001:db8::1',
]);
JSON
MariaDB JSON columns (and JSON function results such as JSON_OBJECT()) are
identified through the extended metadata and parsed into objects by default,
matching the behavior of MySQL's native JSON type:
const [rows] = await connection.query('SELECT j FROM t');
// rows[0].j is an object, e.g. { tag: 'x', nums: [1, 2, 3] }
To receive JSON values as raw strings instead, use the jsonStrings
connection option:
const connection = mysql.createConnection({
// ...
jsonStrings: true,
});
Objects bound as parameters are automatically serialized with
JSON.stringify():
await connection.execute('INSERT INTO t (j) VALUES (?)', [
{ tag: 'x', nums: [1, 2, 3] },
]);
Before this feature, MariaDB JSON columns were returned as plain strings. If
your application depends on the previous behavior, set jsonStrings: true.
VECTOR
The MariaDB protocol does not tag VECTOR columns with extended metadata (as
of MariaDB 11.8), so MySQL2 returns them as a Buffer containing the raw
little-endian IEEE 754 float32 values, the same bytes MariaDB stores. This
differs from MySQL 9 VECTOR columns, which have their own wire type and are
returned as an array of numbers.
Converting the returned Buffer to numbers:
const [rows] = await connection.query('SELECT v FROM embeddings LIMIT 1');
const buffer = rows[0].v;
const floats = Array.from(
new Float32Array(
buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.length)
)
);
// [1.5, -2.25, 3.75]
Alternatively, select the text representation directly:
const [rows] = await connection.query(
'SELECT VEC_ToText(v) AS v FROM embeddings LIMIT 1'
);
// rows[0].v === '[1.5,-2.25,3.75]'
To insert a vector, bind a Buffer with the packed float32 values (or use
VEC_FromText() with a JSON-style string):
const vector = [1.5, -2.25, 3.75];
const buffer = Buffer.alloc(vector.length * 4);
vector.forEach((value, i) => buffer.writeFloatLE(value, i * 4));
await connection.execute('INSERT INTO embeddings (v) VALUES (?)', [buffer]);