Skip to content

The ODBC backend never populates its statement cache #57

Description

@81reap

Bug Description

The ODBC backend never populates its statement cache, so every query executes through SQLExecDirect.

Depending on the driver used the user impact is ::

  1. statement_cache_capacity (default 100) and Execute::persistent() are silently no-ops on ODBC.
  2. SQLBindParameter followed by SQLExecDirect is valid ODBC, but a driver that only collects bindings on the SQLPrepare/SQLExecute path will send the statement with no parameter values at all.

Minimal Reproduction

(1) I used PostgreSQL as it doesn't have the param pass through issue.

Cargo.toml:

[package]
name = "repro"
version = "0.0.0"
edition = "2021"

[workspace]

[dependencies]
sqlx = { package = "sqlx-oldapi", version = "0.6.56", default-features = false, features = ["runtime-tokio-rustls", "odbc"] }
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }

src/main.rs:

use sqlx::Connection;

#[tokio::main]
async fn main() -> Result<(), sqlx::Error> {
    let url = std::env::var("DATABASE_URL").expect("DATABASE_URL");
    let mut conn = sqlx::OdbcConnection::connect(&url).await?;

    for _ in 0..10 {
        let row: (i32,) = sqlx::query_as("SELECT CAST(? AS INTEGER)")
            .bind(42)
            .fetch_one(&mut conn)
            .await?;
        assert_eq!(row.0, 42);
    }

    println!("cached_statements_size = {}", conn.cached_statements_size());
    Ok(())
}

SOP

$ docker run --rm -d --name pg -e POSTGRES_PASSWORD='Password123!' -e POSTGRES_USER=root -e POSTGRES_DB=test -p 5432:5432 postgres:16

# ODBC backend
$ DATABASE_URL='Driver=/nix/store/1fyjnz2b5h28pdcy9wakcvcq8ywz166g-psqlodbc-18.00.0002/lib/psqlodbcw.so;Server=127.0.0.1;Port=5432;Database=test;UID=root;PWD=Password123!' cargo run
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.09s
     Running `target/debug/repro`
cached_statements_size = 0    # expected :: 1

(2) Is reproducible in SQLPage with SQLPage#1474.

In "index.sql": The following error occurred while executing an SQL statement:
error returned from database: ODBC emitted an error calling 'SQLExecDirect':
State: HY000, Native error: 100, Message: [GizmoData][GizmoSQL] (100) An execution error has occurred: Invalid Input Error: Values were not provided for the following prepared statement parameters: 1, 2. gRPC client debug context: UNKNOWN:Error received from peer ipv6:%5B::1%5D:31337 {grpc_message:"An execution error has occurred: Invalid Input Error: Values were not provided for the following prepared statement parameters: 1, 2", grpc_status:2, created_time:"2026-09-21T16:29:56.6640056+00:00"}. Client context: OK

Info

  • SQLx version: 0.6.56 (sqlx-oldapi, main at f8b378d1)
  • SQLx features enabled: runtime-tokio-rustls, odbc, postgres, any
  • Database server and version: PostgreSQL 16 via psqlODBC 18.00.0002 (also reproduced against GizmoSQL 1.39.0 via gizmosql-odbc 1.1.2, and DuckDB via duckdb-odbc 1.5.5), unixODBC 2.3.14
  • Operating system: NixOS 26.11, Linux 6.18.52 x86_64
  • rustc --version: rustc 1.98.1 (48a229cea 2026-09-01)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions