Skip to content

fix(codegen): make dynamic-slice queries compile on sqlx 0.9 - #50

Merged
jrandolf merged 1 commit into
mainfrom
fix/sqlx-0.9-dynamic-slice
Sep 26, 2026
Merged

jrandolf merged 1 commit into
mainfrom
fix/sqlx-0.9-dynamic-slice

Conversation

@jrandolf

@jrandolf jrandolf commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

Implements the first part of the stack proposed in Discussion #47. Thanks to @iamralch for finding the bug and writing the fix. This carries their commit unchanged from iamralch#3.

Problem

The workspace targets sqlx 0.9, but a sqlc.slice() query that cannot use the = ANY($1) fast path emits sqlx::query_as(&sql) for its run-time SQL. sqlx 0.9 only accepts a &'static str directly, so that output does not compile. Reproduced against sqlx 0.9.0 with the code main currently generates for tests/e2e/cases/dynamic_slice:

error[E0277]: dynamic SQL strings should be audited for possible injections
  --> src/queries.rs:74:62

The e2e fixtures pinned sqlx 0.8, and no example had a non-ANY slice, so nothing compiled this output against the version the workspace declares.

Change

  • The nine dynamic-SQL call sites in query.rs and batch.rs now pass sqlx::AssertSqlSafe(sql).
  • The e2e fixtures move from sqlx 0.8 to 0.9.
  • The README states the supported sqlx version.
  • Only the two dynamic-slice snapshots change.

Why AssertSqlSafe is sound

The run-time string starts from the generated const SQL and changes in only two ways: placeholders are renumbered to $n (or expanded to ?), and an empty slice becomes NULL. Only the slice's length is decided at run time. Every value still goes through .bind(), so no caller data reaches the SQL text.

Support note

Generated code that contains a dynamic slice now needs sqlx 0.9. It no longer compiles against 0.8. Static queries are unchanged and still compile on both versions. The workspace already declared 0.9. If we treat dropping 0.8 for dynamic slices as breaking, retitle with ! before squashing so release-please records it.

Verification

  • cargo fmt --check, cargo clippy --workspace --all-features --all-targets -D warnings, and cargo package --locked are clean.
  • 88 lib tests and 30 codegen snapshot tests pass.
  • The e2e suite passes against PostgreSQL with sqlx 0.9.
  • An extra check (not committed) compiled every dynamic-slice command on sqlx 0.9 and ran it against PostgreSQL 17 with correct results: :one, :many (including an empty slice), :exec, :execrows, :execresult, :execlastid, :batchexec, :batchone and :batchmany.

The MySQL and SQLite parts of the stack (iamralch#1, iamralch#2) are not included. Review follows in the Discussion.

`sqlc.slice()` parameters that cannot use `= ANY($1)` build their SQL at run
time, and the generated code passed the result as `sqlx::query_as(&sql)`. sqlx
0.9 replaced the `&'q str` parameter with `impl SqlSafeStr`, which is only
implemented for `&'static str` — so every such query fails to compile against
the sqlx version this workspace already declares:

    error[E0277]: dynamic SQL strings should be audited for possible injections

Run-time SQL now goes through `sqlx::AssertSqlSafe`, the escape hatch 0.9 added
for exactly this case. The strings are assembled by the generator from the query
text and a placeholder count — no user input reaches them — so the assertion is
sound.

This went unnoticed because nothing exercised the combination: the e2e fixtures
pinned sqlx 0.8, and no example has a `sqlc.slice()` query that misses the
`= ANY($1)` fast path. The fixtures move to 0.9 so the suite now covers the same
version the workspace does.

`AssertSqlSafe` does not exist in 0.8, so generated code cannot support both;
0.9 is now the floor, and the README says so. Only the two dynamic-slice
snapshots change — every other query still passes a `&'static str` const.
@jrandolf
jrandolf force-pushed the fix/sqlx-0.9-dynamic-slice branch from 4ba81ad to e22eada Compare September 26, 2026 01:46
@jrandolf
jrandolf merged commit 2b69750 into main Sep 26, 2026
25 checks passed
@jrandolf
jrandolf deleted the fix/sqlx-0.9-dynamic-slice branch September 26, 2026 01:54
jrandolf added a commit that referenced this pull request Sep 26, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.2.7](v0.2.6...v0.2.7)
(2026-09-26)


### Bug Fixes

* **codegen:** Make dynamic-slice queries compile on sqlx 0.9
([#50](#50))
([2b69750](2b69750))
* **deps:** Update rustls security fix
([b31da6c](b31da6c))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants