Found while implementing #8696 in the same function, and filed rather than fixed in passing — it is a different declared key with a different remedy.
What happens
buildMysqlConnection computes the TLS option and then returns before it can be used:
functionbuildMysqlConnection(spec: DatasourceConnectionSpec): unknown{constcfg=(spec.config??{})asRecord<string,unknown>;constmysqlSsl=resolveSslOption(spec);// computedconsturl=cfg.urlasstring|undefined;if(url){ ... }// returns without itreturn{
...
...(mysqlSsl!==undefined ? {ssl: mysqlSsl} : {}),// only reachable here};}So a mysql datasource that declares TLS and writes a connection URL gets no ssl option at all. Declared, resolved, dropped — with no diagnostic. The discrete-fields branch of the same arm honours it.
The asymmetry
The postgres arm handles exactly this case on its DSN branch, deliberately and with the reasoning written down:
// TLS still applies: `sslmode` in a DSN and the `ssl` option are separate// channels to `pg`, and a datasource that declares one should get it.return{connectionString: url,
...
...(ssl!==undefined ? { ssl } : {}),};The same argument applies to mysql2: a ?ssl-mode= parameter in the DSN and the client's ssl option are separate channels, so an author who declared the block should get it. Whether TLS is actually negotiated therefore depends on which branch of one arm the datasource happens to take, which is the datasource.pool failure shape #5714 / #7243 closed for a different key.
Why it is not a rider on #8696
#8696 fixes the DSN branch's handling of a bound credential and, once landed, that branch returns an object rather than a bare string — so wiring ssl in becomes a one-line change. It was deliberately not taken there: carrying ssl only when a secret happens to be bound would make TLS conditional on an unrelated declaration, and carrying it unconditionally is a behaviour change for existing rows that deserves its own decision.
That decision is a real one, in the shape the pool-support module already settled twice: wire it, or reject the declaration loudly (unsupportedPoolMessage style) if this branch cannot honour it. packages/spec's MysqlConfigSchema guidance already tells authors that TLS on a URL-shaped mysql datasource is a connection-string concern for the mongo driver — worth reading before choosing, so the answer stays consistent across arms.
Repro sketch
Runtime datasource, driver mysql, config: { url: 'mysql://app@db.internal:3306/app', ssl: true } (or the ssl object form). The knex connection handed to SqlDriver carries no ssl key.
Filed unassigned for triage.
Found while implementing #8696 in the same function, and filed rather than fixed in passing — it is a different declared key with a different remedy.
What happens
buildMysqlConnectioncomputes the TLS option and then returns before it can be used:So a mysql datasource that declares TLS and writes a connection URL gets no
ssloption at all. Declared, resolved, dropped — with no diagnostic. The discrete-fields branch of the same arm honours it.The asymmetry
The postgres arm handles exactly this case on its DSN branch, deliberately and with the reasoning written down:
The same argument applies to mysql2: a
?ssl-mode=parameter in the DSN and the client'sssloption are separate channels, so an author who declared the block should get it. Whether TLS is actually negotiated therefore depends on which branch of one arm the datasource happens to take, which is thedatasource.poolfailure shape #5714 / #7243 closed for a different key.Why it is not a rider on #8696
#8696 fixes the DSN branch's handling of a bound credential and, once landed, that branch returns an object rather than a bare string — so wiring
sslin becomes a one-line change. It was deliberately not taken there: carryingsslonly when a secret happens to be bound would make TLS conditional on an unrelated declaration, and carrying it unconditionally is a behaviour change for existing rows that deserves its own decision.That decision is a real one, in the shape the pool-support module already settled twice: wire it, or reject the declaration loudly (
unsupportedPoolMessagestyle) if this branch cannot honour it.packages/spec'sMysqlConfigSchemaguidance already tells authors that TLS on a URL-shaped mysql datasource is a connection-string concern for the mongo driver — worth reading before choosing, so the answer stays consistent across arms.Repro sketch
Runtime datasource, driver
mysql,config: { url: 'mysql://app@db.internal:3306/app', ssl: true }(or thesslobject form). The knexconnectionhanded toSqlDrivercarries nosslkey.Filed unassigned for triage.