跳到主要内容

Query Attributes

1.2Release Candidate

Query Attributes support is approaching stability.

History
VersionChanges
v3.21.0
Added query attributes support for COM_QUERY and COM_STMT_EXECUTE.

Query attributes let you attach metadata key-value pairs to individual SQL statements. The server can read these values using functions like mysql_query_attribute_string() — without any changes to the SQL text or session state.

Typical use cases include request tracing, audit context, tenant identifiers, and passing out-of-band hints to server-side components or plugins.

MySQL Server Requirements

Requires MySQL 8.0.25+. The component_query_attributes server component must be installed for the server to expose attributes via SQL functions such as mysql_query_attribute_string(). To install it, run INSTALL COMPONENT "file://component_query_attributes" as a privileged user.

How It Works

MySQL2 negotiates the CLIENT_QUERY_ATTRIBUTES capability flag during the handshake (enabled by default). When this capability is active, both connection.query() and connection.execute() encode any attributes you provide into the extended wire protocol for COM_QUERY and COM_STMT_EXECUTE packets.

On the server side, retrieve attribute values inside a query with:

SELECT mysql_query_attribute_string('attribute_name');

Basic Usage

Pass an attributes object in the query options. Each key becomes an attribute name and each value is sent alongside the SQL statement.

import mysql from 'mysql2/promise';

const connection = await mysql.createConnection({
host: 'localhost',
user: 'root',
database: 'test',
});

const [rows] = await connection.query({
sql: `SELECT mysql_query_attribute_string('request_id') AS request_id`,
attributes: {
request_id: 'abc-123',
},
});

console.log(rows); // [ { request_id: 'abc-123' } ]

await connection.end();

With Prepared Statements

Query attributes also work with connection.execute() (prepared statements). Attributes and bind parameters are encoded together in the COM_STMT_EXECUTE packet.

import mysql from 'mysql2/promise';

const connection = await mysql.createConnection({
host: 'localhost',
user: 'root',
database: 'test',
});

const [rows] = await connection.execute({
sql: 'SELECT ? + ? AS sum, mysql_query_attribute_string(?) AS trace_id',
values: [1, 2, 'trace_id'],
attributes: {
trace_id: 'txn-456',
},
});

console.log(rows); // [ { sum: 3, trace_id: 'txn-456' } ]

await connection.end();

Multiple Attributes

You can send any number of attributes per query.

const [rows] = await connection.query({
sql: `
SELECT
mysql_query_attribute_string('user_id') AS user_id,
mysql_query_attribute_string('tenant') AS tenant,
mysql_query_attribute_string('request_time') AS request_time
`,
attributes: {
user_id: 42,
tenant: 'acme-corp',
request_time: new Date(),
},
});

console.log(rows);

With Connection Pools

Attributes are per-query, so they work identically with pools — no special configuration needed.

import mysql from 'mysql2/promise';

const pool = mysql.createPool({
host: 'localhost',
user: 'root',
database: 'test',
});

const [rows] = await pool.query({
sql: `SELECT mysql_query_attribute_string('source') AS source`,
attributes: { source: 'background-worker' },
});

console.log(rows); // [ { source: 'background-worker' } ]

await pool.end();

Supported Attribute Types

Attribute values are serialized from JavaScript to MySQL types using the same rules as bind parameters:

JavaScript TypeMySQL Wire TypeNotes
stringVAR_STRING
numberDOUBLE64-bit floating point
booleanTINYtrue → 1, false → 0
nullNULLServer sees a NULL attribute
DateDATETIME
BufferVAR_STRINGRaw bytes

Passing undefined as an attribute value will throw a TypeError.

TypeScript

The attributes option is fully typed in the QueryOptions interface:

import mysql, { QueryOptions } from 'mysql2/promise';

const connection = await mysql.createConnection({
host: 'localhost',
user: 'root',
database: 'test',
});

const options: QueryOptions = {
sql: `SELECT mysql_query_attribute_string('request_id') AS rid`,
attributes: {
request_id: 'abc-123',
priority: 1,
debug: true,
timestamp: new Date(),
},
};

const [rows] = await connection.query(options);

Disabling Query Attributes

The CLIENT_QUERY_ATTRIBUTES capability is enabled by default. If the server does not support it, query attributes are automatically disabled — no manual configuration is needed. You can also explicitly exclude the flag:

const connection = mysql.createConnection({
host: 'localhost',
user: 'root',
flags: ['-CLIENT_QUERY_ATTRIBUTES'],
});

When the flag is disabled (either automatically or explicitly), any attributes you pass are silently ignored and the standard (non-extended) packet format is used.

Notes

  • Query attributes are per-statement — they are not stored on the connection or session.
  • Attributes are independent of bind parameters (values). You can use both simultaneously.
  • The server must have component_query_attributes installed for mysql_query_attribute_string() to work. Without it, attribute functions are not available.