Open manswami23 opened 3 weeks ago
Comparing the signature of the sqlx::raw_sql vs sqlx::query execute methods (where the latter compiles) I did notice one thing.
sqlx::raw_sql execute
pub async fn execute<'e, E>(
self,
executor: E,
) -> crate::Result<<E::Database as Database>::QueryResult>
where
'q: 'e,
E: Executor<'e>,
{
executor.execute(self).await
}
sqlx::query execute
#[inline]
pub async fn execute<'e, 'c: 'e, E>(self, executor: E) -> Result<DB::QueryResult, Error>
where
'q: 'e,
A: 'e,
E: Executor<'c, Database = DB>,
{
executor.execute(self).await
}
I'm still new to Rust, but it seems like the Executor's lifetime in query ('c) is bounded by 'e (what is 'e referring to?). But raw_sql has no such bound. I wonder if the extra bound on the query method somehow makes the lifetime "resolvable" by the compiler, because it seems like the issue with raw_sql is that the compiler for whatever reason doesn't know the lifetime of the connection reference, and so is asking for an Executor trait impl that can apply to any lifetime rather than a specific lifetime.
You can change this line
let res: Result<sqlx::postgres::PgQueryResult, sqlx::Error> = sqlx::raw_sql(raw_query)
.execute(&mut *conn) // Dereference the connection to get a mutable reference
.await;
to
let res: Result<sqlx::postgres::PgQueryResult, sqlx::Error> =
conn.execute(sqlx::raw_sql(raw_query)).await;
then it should compile
Thanks @joeydewaal , that worked. I am curious as to why that worked, since it looks both routes end up invoking the Executor trait's execute function.
Why was the latter able to resolve the Executor trait impl on the PgConnection, but the former approach was unable to?
And along the same lines, why is the following able to compile?
let res: Result<sqlx::postgres::PgQueryResult, sqlx::Error> = sqlx::query(raw_query)
.execute(&mut *conn) // Dereference the connection to get a mutable reference
.await;
Bug Description
Hello,
I am setting up an axum web server with a simple route handler. The handler acquires a connection from the connection pool, and then runs some arbitrary statement. Originally, I was using the sqlx::query_as api, and everything was fine. However, out of curiosity, I tried using sqlx::raw_sql, and my code fails to compile with the following error message:
To me, it looks like both the query_as and raw_sql apis use the Executor trait under the hood. So I'm curious as to why the former can successfully resolve the trait implementation for the PgConnection reference while the latter fails.
Minimal Reproduction
Interestingly, when I invoke raw_sql outside of the handler (e.g. I run it right after creating the connection pool in the main method), there are no issues. So I'm wondering if the reference through the Arc is somehow messing up the lifetime of the PgConnection?
Info
Database: Using Postgres, v17. OS: Windows 10 Rust version: rustc 1.81.0 (eeb90cda1 2024-09-04)