ReviewOS

stacks/bun-query-builder

fix(hooks): MySQL query events report [object Promise] instead of SQL

#1142
Closed glennmichael123 opened this 9 days ago ·
9 days ago

Reproduction

With Bun 1.4.1, MySQL 8.4.5 and published bun-query-builder 0.2.69, QueryEvent.sql is the literal string [object Promise] for ordinary INSERT, SELECT and UPDATE builders. The queries execute successfully.

Register hooks.onQueryStart, then execute these against a disposable MySQL table:

await db.insertInto('hook_probe').values({ id: 1, value: 10 }).execute()
await db.selectFrom('hook_probe').where('id', '=', 1).selectAll().execute()
await db.updateTable('hook_probe').set({ value: 11 }).where('id', '=', 1).execute()

Observed events:

insert: [object Promise]
select: [object Promise]
update: [object Promise]

Expected: parameterized SQL text describing each executed statement. Checking only typeof event.sql === 'string' misses this regression because the placeholder is itself a string.

Owning layer and impact

Reproduced directly through the installed package without Stacks imports. runWithHooks() obtains its text from computeSqlText(q), which uses String(q). The native Bun MySQL query does not expose its SQL through this conversion. The SQLite wrapper supplies its own toString(), so existing SQLite hook tests pass.

This prevents log filtering, query diagnostics and tracing consumers from identifying executed SQL. It was discovered while adding a deterministic concurrent session-revocation check to Stacks; a hook filtering by event.sql.includes('sessions') never matched.

Related coverage work: https://github.com/stacksjs/stacks/issues/2607, shipped in https://github.com/stacksjs/stacks/commit/792c0e496ea1fc99e25f7ac847eaf3d9376da1c8. That commit tests the session behavior; it does not fix this upstream diagnostic contract.

The fix belongs in query metadata capture/rendering in this package. It must retain parameterized text rather than interpolate values or reconstruct SQL from an opaque Promise. No query execution failure or session-revocation bypass was observed in this investigation. Tagged/subquery, transaction, error/slow-hook and PostgreSQL paths need coverage when fixing this.

9 days ago

Fixed in e8d66ca.

  • Native query creation now retains parameterized SQL and ordered bindings without replacing the driver query or its transaction connection.
  • Composed selects and onlyTrashed now use the normal builder SQL state instead of uncaptured native helpers.
  • Added real MySQL and PostgreSQL CI regressions covering CRUD, composition, transaction rollback, reserved connections, errors, slow events and tracing spans.
  • CI test job passed: 2,181 tests, zero failures. Verified that both new native-driver cases passed, not skipped. Lint/typecheck/build also passed: run 34689748311.
  • An isolated candidate build also passed Stacks' MySQL session-refresh/concurrent-revocation fixture, including a hook that identifies session SQL and its bindings.

This is an upstream source fix. npm 0.2.69 remains unchanged until the next release; no workaround or dependency replacement was added to Stacks.

Sign in to comment on this issue.