Summary
When perry cannot run cargo at compile time it prints
auto-optimize: failed to spawn cargo (No such file or directory (os error 2)), using prebuilt libraries
and links perry-stdlib's bundled mysql2 module (crates/perry-stdlib/src/mysql2/) instead of perry-ext-mysql2 — silently: the same note: serving mysql2 from the bundled native binding perry-ext-mysql2 line is printed either way, and the only tell is nm out | grep js_mysql2_handle_method_dispatch (present only for the ext). The two implementations behave differently in ways that break real programs. Found while reproducing #9356 on perrymaster (main f1e9c37, MySQL 8.0.46).
Divergences (bundled build; the ext build passes all of these)
pool.query(sql) with no bind values is sent as a prepared statement, so statements MySQL refuses to prepare fail:
pool.query("begin") → Query failed: error returned from database: 1295 (HY000): This command is not supported in the prepared statement protocol yet
(strace shows COM_STMT_PREPARE for a plain pool.query("SELECT …") too.) Node's mysql2 and perry-ext-mysql2 use the text protocol for query() without values.
- Server errors reject with a value whose
.message is undefined (String(e) still renders the text), so catch (e) { e.message } and every logger that reads it print undefined.
- Dynamic dispatch of the string form crashes: with the static type lost (
const client: any = pool; await client.query("SELECT 6 AS x")) the process dumps core (timeout: the monitored command dumped core). The options-object form (client.query({ sql, rowsAsArray: true }, []), drizzle's shape) works.
Reproduction
/root/claude-9356/repro/probe.ts on perrymaster: compile once without ~/.cargo/bin on PATH (bundled build) and once with it (ext build) and run both; DB user perry9356.
Suggested direction
Either make the fallback loud (fail the compile when the well-known wrapper cannot be built, or at least print which implementation was linked), or bring the bundled module up to the ext's behaviour (sqlx::raw_sql for no-value query(), MysqlPromiseError-style rejections, string-form dispatch).
Summary
When
perrycannot run cargo at compile time it printsand links perry-stdlib's bundled
mysql2module (crates/perry-stdlib/src/mysql2/) instead ofperry-ext-mysql2— silently: the samenote: serving mysql2 from the bundled native binding perry-ext-mysql2line is printed either way, and the only tell isnm out | grep js_mysql2_handle_method_dispatch(present only for the ext). The two implementations behave differently in ways that break real programs. Found while reproducing #9356 on perrymaster (main f1e9c37, MySQL 8.0.46).Divergences (bundled build; the ext build passes all of these)
pool.query(sql)with no bind values is sent as a prepared statement, so statements MySQL refuses to prepare fail:straceshowsCOM_STMT_PREPAREfor a plainpool.query("SELECT …")too.) Node's mysql2 and perry-ext-mysql2 use the text protocol forquery()without values..messageisundefined(String(e)still renders the text), socatch (e) { e.message }and every logger that reads it printundefined.const client: any = pool; await client.query("SELECT 6 AS x")) the process dumps core (timeout: the monitored command dumped core). The options-object form (client.query({ sql, rowsAsArray: true }, []), drizzle's shape) works.Reproduction
/root/claude-9356/repro/probe.tson perrymaster: compile once without~/.cargo/binonPATH(bundled build) and once with it (ext build) and run both; DB userperry9356.Suggested direction
Either make the fallback loud (fail the compile when the well-known wrapper cannot be built, or at least print which implementation was linked), or bring the bundled module up to the ext's behaviour (
sqlx::raw_sqlfor no-valuequery(),MysqlPromiseError-style rejections, string-form dispatch).