* Add PgBindIter for encoding and use it as the implementation encoding &[T]
* Implement suggestions from review
* Add docs to PgBindIter and test to ensure it works for owned and borrowed types
* Use extension trait for iterators to allow code to flow better. Make struct private. Don't reference unneeded generic T. Make doc tests compile.
* Fix doc function
* Fix doc test to actually compile
* Use Cell<Option<I>> instead of Clone bound
* fix(mysql): validate parameter count for prepared statements
Add validation to ensure the number of provided parameters matches the
expected count for MySQL prepared statements.
This prevents protocol errors by returning an error if the counts do not match before sending
the statement for execution.
* refactor(mysql): use err_protocol macro for error creation
Replace direct Error::Protocol(format!()) calls with err_protocol!
macro in MySQL connection executor.
* test(mysql): add parameter count validation tests
- Add test for too few parameters provided to query
- Add test for too many parameters provided to query
- Add test for parameters provided when none expected
- All tests verify Error::Protocol is returned for mismatches
Covers cases for issue #3774 parameter validation fix.
The `try_from` field attribute in `FromRow` uses `__spec_error` to generate a column decode error. The `spec_error` is currently gated behind the macros feature flag only, but should also be available when using only `derive`.
* Postgres: force generic plan when describing statement with args
* cargo fmt
* Postgres: set plan_cache_mode in transaction
* Postgres: only set force_generic_plan for versions that support it
* Postgres: reduce database calls in query macro's
* Postgres: set generic execution plan only in query macro
* Escape PostgreSQL options
* Use raw string literals in test case
Co-authored-by: Austin Bonander <austin.bonander@gmail.com>
* Document escaping behavior for options
* Remove heap allocations for options formatting
* Use an actual config option for the test case
---------
Co-authored-by: Austin Bonander <austin.bonander@gmail.com>
* feat: create `sqlx.toml` format
* feat: add support for ignored_chars config to sqlx_core::migrate
* chore: test ignored_chars with `U+FEFF` (ZWNBSP/BOM)
https://en.wikipedia.org/wiki/Byte_order_mark
* refactor: make `Config` always compiled
simplifies usage while still making parsing optional for less generated code
* refactor: add origin information to `Column`
* feat(macros): implement `type_override` and `column_override` from `sqlx.toml`
* refactor(sqlx.toml): make all keys kebab-case, create `macros.preferred-crates`
* feat: make macros aware of `macros.preferred-crates`
* feat: make `sqlx-cli` aware of `database-url-var`
* feat: teach macros about `migrate.table-name`, `migrations-dir`
* feat: teach macros about `migrate.ignored-chars`
* chore: delete unused source file `sqlx-cli/src/migration.rs`
* feat: teach `sqlx-cli` about `migrate.defaults`
* feat: teach `sqlx-cli` about `migrate.migrations-dir`
* feat: teach `sqlx-cli` about `migrate.table-name`
* feat: introduce `migrate.create-schemas`
* WIP feat: create multi-tenant database example
* fix(postgres): don't fetch `ColumnOrigin` for transparently-prepared statements
* feat: progress on axum-multi-tenant example
* feat(config): better errors for mislabeled fields
* WIP feat: filling out axum-multi-tenant example
* feat: multi-tenant example
No longer Axum-based because filling out the request routes would have distracted from the purpose of the example.
* chore(ci): test multi-tenant example
* fixup after merge
* fix(ci): enable `sqlx-toml` in CLI build for examples
* fix: CI, README for `multi-tenant`
* fix: clippy warnings
* fix: multi-tenant README
* fix: sequential versioning inference for migrations
* fix: migration versioning with explicit overrides
* fix: only warn on ambiguous crates if the invocation relies on it
* fix: remove unused imports
* fix: doctest
* fix: `sqlx mig add` behavior and tests
* fix: restore original type-checking order
* fix: deprecation warning in `tests/postgres/macros.rs`
* feat: create postgres/multi-database example
* fix: examples/postgres/multi-database
* fix: cargo fmt
* chore: add tests for config `migrate.defaults`
* fix: sqlx-cli/tests/add.rs
* feat(cli): add `--config` override to all relevant commands
* chore: run `sqlx mig add` test with `RUST_BACKTRACE=1`
* fix: properly canonicalize config path for `sqlx mig add` test
* fix: get `sqlx mig add` test passing
* fix(cli): test `migrate.ignored-chars`, fix bugs
* feat: create `macros.preferred-crates` example
* fix(examples): use workspace `sqlx`
* fix: examples
* fix(sqlite): unexpected feature flags in `type_checking.rs`
* fix: run `cargo fmt`
* fix: more example fixes
* fix(ci): preferred-crates setup
* fix(examples): enable default-features for workspace `sqlx`
* fix(examples): issues in `preferred-crates`
* chore: adjust error message for missing param type in `query!()`
* doc: mention new `sqlx.toml` configuration
* chore: add `CHANGELOG` entry
Normally I generate these when cutting the release, but I wanted to take time to editorialize this one.
* doc: fix new example titles
* refactor: make `sqlx-toml` feature non-default, improve errors
* refactor: eliminate panics in `Config` read path
* chore: remove unused `axum` dependency from new examples
* fix(config): restore fallback to default config for macros
* chore(config): remove use of `once_cell` (to match `main`)
Previously, `TextRow::decode_with` would read a length-encoded field size
and attempt to advance the buffer by that amount. If the server sent a
malformed packet containing a length value larger than the remaining data
in the buffer, the call to `buf.advance(size)` would panic.
eg:
```
thread 'main' panicked at /home/user/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.10.1/src/bytes.rs:711:9:
cannot advance past remaining: 8590116092 <= 0
stack backtrace:
0: 0x56119b657e00 - <std::sys::backtrace::BacktraceLock::print::DisplayBacktrace as core::fmt::Display>::fmt::h6d42cc84fc840290
1: 0x56119b67edd3 - core::fmt::write::h5af61a909e3ec64d
2: 0x56119b653ee3 - std::io::Write::write_fmt::h5a7b54aa6e4a315d
3: 0x56119b657c52 - std::sys::backtrace::BacktraceLock::print::h555579e7396c26ac
4: 0x56119b658cef - std::panicking::default_hook::{{closure}}::h9128866118196224
5: 0x56119b658b5a - std::panicking::default_hook::h52e9e7314e0255f6
6: 0x56119b659712 - std::panicking::rust_panic_with_hook::h541791bcc774ef34
7: 0x56119b65949a - std::panicking::begin_panic_handler::{{closure}}::h6479a2f0137c7d19
8: 0x56119b658319 - std::sys::backtrace::__rust_end_short_backtrace::ha04e7c0fc61ded91
9: 0x56119b65912d - rust_begin_unwind
10: 0x56119b67c390 - core::panicking::panic_fmt::h5764ee7030b7a73d
11: 0x56119b572b18 - <sqlx_mysql::protocol::text::row::TextRow as sqlx_core::io::decode::ProtocolDecode<&[sqlx_mysql::column::MySqlColumn]>>::decode_with::h17ac8b44140b5469
12: 0x56119b42df1f - sqlx_mysql::connection::executor::<impl sqlx_mysql::connection::MySqlConnection>::run::{{closure}}::{{closure}}::{{closure}}::h4874a0f73925d55a
```
This commit introduces a bounds check immediately after reading the field length from a packet.
This panic condition was specifically observed when executing a TiDB
`BATCH ON ... DELETE` statement via `pool.execute()`. It sends an OK packet immediately followed by
a full result set describing the batch status (column defs, row data, EOF).
Observed TiDB response sequence for `BATCH DML` via `COM_QUERY`:
1. OK Packet (seq=1, `SERVER_MORE_RESULTS_EXISTS` = false)
2. Column Count Packet (seq=1, non-standard, protocol violation)
3. Column Definition Packet (seq=2)
4. Column Definition Packet (seq=3)
5. Text Row Data Packet (seq=4)
6. EOF Packet (seq=5, `SERVER_MORE_RESULTS_EXISTS` = false)
This differs from standard MySQL DML response (OK/ERR packet only) and
causes `sqlx` using `execute()` to attempt parsing the unexpected result
set packets after the initial OK packet.
* feat: Implement `get_transaction_depth` for drivers
* test: Verify `get_transaction_depth()` on postgres
* Refactor: `TransactionManager` delegation without BC
SQLite implementation is currently WIP
* Fix: Avoid breaking changes on `AnyConnectionBackend`
* Refactor: Remove verbose `SqliteConnection` typing
* Feat: Implementation for SQLite
I have included `AtomicUsize` in `WorkerSharedState`. Ideally, it is not desirable to execute `load` and `fetch_add` in two separate steps, but we decided to allow it here since there is only one thread writing. To prevent writing from other threads, the field itself was made private, and a getter method was provided with `pub(crate)`.
* Refactor: Same approach for `cached_statements_size`
ref: a66787d36d62876b55475ef2326d17bade817aed
* Fix: Add missing `is_in_transaction` for backend
* Doc: Remove verbose "synchronously" word
* Fix: Remove useless `mut` qualifier
* feat: add Connection::begin_with
This patch completes the plumbing of an optional statement from these methods to
`TransactionManager::begin` without any validation of the provided statement.
There is a new `Error::InvalidSavePoint` which is triggered by any attempt to
call `Connection::begin_with` when we are already inside of a transaction.
* feat: add Pool::begin_with and Pool::try_begin_with
* feat: add Error::BeginFailed and validate that custom "begin" statements are successful
* chore: add tests of Error::BeginFailed
* chore: add tests of Error::InvalidSavePointStatement
* chore: test begin_with works for all SQLite "BEGIN" statements
* chore: improve comment on Connection::begin_with
* feat: add default impl of `Connection::begin_with`
This makes the new method a non-breaking change.
* refactor: combine if statement + unwrap_or_else into one match
* feat: use in-memory SQLite DB to avoid conflicts across tests run in parallel
* feedback: remove public wrapper for sqlite3_txn_state
Move the wrapper directly into the test that uses it instead.
* fix: cache Status on MySqlConnection
* fix: compilation errors
* fix: format
* fix: postgres test
* refactor: delete `Connection::get_transaction_depth`
* fix: tests
---------
Co-authored-by: mpyw <ryosuke_i_628@yahoo.co.jp>
Co-authored-by: Duncan Fairbanks <duncanfairbanks6@gmail.com>
* feat: add polygon
* test: paths for pgpoints in polygon test
* fix: import typo
* chore(Sqlite): remove ci.db from repo (#3768)
* fix: CI
* Fix breakage from Rustup 1.28 <https://blog.rust-lang.org/2025/03/02/Rustup-1.28.0.html>
* Let `Swatinem/rust-cache` generate cache keys
* fix(ci): upgrade Ubuntu image to 24.04
For some reason the `cargo +beta clippy` step is failing because `libsqlite3-sys` starts requiring Glibc >= 2.39 but I don't have time to figure out why and I can't reproduce it in a clean environment.
---------
Co-authored-by: joeydewaal <99046430+joeydewaal@users.noreply.github.com>
Co-authored-by: Austin Bonander <austin.bonander@gmail.com>