From bb3b571a5799cfeaa3368b05ed0f0b6e66f465fc Mon Sep 17 00:00:00 2001 From: Ryan Leckey Date: Sat, 30 May 2020 02:04:19 -0700 Subject: [PATCH] fix: tweak lifetimes in Executor to limit the scope for the borrow on the query to the single execution --- sqlx-core/src/executor.rs | 36 +++-- sqlx-core/src/mysql/connection/executor.rs | 13 +- sqlx-core/src/pool/executor.rs | 45 +++--- sqlx-core/src/postgres/connection/executor.rs | 16 ++- sqlx-core/src/postgres/listener.rs | 17 ++- sqlx-core/src/query.rs | 136 +++++++++--------- sqlx-core/src/query_as.rs | 67 ++++----- sqlx-core/src/query_scalar.rs | 67 ++++----- sqlx-core/src/sqlite/connection/executor.rs | 13 +- 9 files changed, 227 insertions(+), 183 deletions(-) diff --git a/sqlx-core/src/executor.rs b/sqlx-core/src/executor.rs index 58f84681..9d9ad0ff 100644 --- a/sqlx-core/src/executor.rs +++ b/sqlx-core/src/executor.rs @@ -28,8 +28,9 @@ pub trait Executor<'c>: Send + Debug + Sized { type Database: Database; /// Execute the query and return the total number of rows affected. - fn execute<'q: 'c, E: 'c>(self, query: E) -> BoxFuture<'c, Result> + fn execute<'e, 'q: 'e, E: 'q>(self, query: E) -> BoxFuture<'e, Result> where + 'c: 'e, E: Execute<'q, Self::Database>, { self.execute_many(query) @@ -38,8 +39,9 @@ pub trait Executor<'c>: Send + Debug + Sized { } /// Execute multiple queries and return the rows affected from each query, in a stream. - fn execute_many<'q: 'c, E: 'c>(self, query: E) -> BoxStream<'c, Result> + fn execute_many<'e, 'q: 'e, E: 'q>(self, query: E) -> BoxStream<'e, Result> where + 'c: 'e, E: Execute<'q, Self::Database>, { self.fetch_many(query) @@ -53,11 +55,12 @@ pub trait Executor<'c>: Send + Debug + Sized { } /// Execute the query and return the generated results as a stream. - fn fetch<'q: 'c, E: 'c>( + fn fetch<'e, 'q: 'e, E: 'q>( self, query: E, - ) -> BoxStream<'c, Result<::Row, Error>> + ) -> BoxStream<'e, Result<::Row, Error>> where + 'c: 'e, E: Execute<'q, Self::Database>, { self.fetch_many(query) @@ -72,30 +75,33 @@ pub trait Executor<'c>: Send + Debug + Sized { /// Execute multiple queries and return the generated results as a stream /// from each query, in a stream. - fn fetch_many<'q: 'c, E: 'c>( + fn fetch_many<'e, 'q: 'e, E: 'q>( self, query: E, - ) -> BoxStream<'c, Result::Row>, Error>> + ) -> BoxStream<'e, Result::Row>, Error>> where + 'c: 'e, E: Execute<'q, Self::Database>; /// Execute the query and return all the generated results, collected into a [`Vec`]. - fn fetch_all<'q: 'c, E: 'c>( + fn fetch_all<'e, 'q: 'e, E: 'q>( self, query: E, - ) -> BoxFuture<'c, Result::Row>, Error>> + ) -> BoxFuture<'e, Result::Row>, Error>> where + 'c: 'e, E: Execute<'q, Self::Database>, { self.fetch(query).try_collect().boxed() } /// Execute the query and returns exactly one row. - fn fetch_one<'q: 'c, E: 'c>( + fn fetch_one<'e, 'q: 'e, E: 'q>( self, query: E, - ) -> BoxFuture<'c, Result<::Row, Error>> + ) -> BoxFuture<'e, Result<::Row, Error>> where + 'c: 'e, E: Execute<'q, Self::Database>, { self.fetch_optional(query) @@ -107,11 +113,12 @@ pub trait Executor<'c>: Send + Debug + Sized { } /// Execute the query and returns at most one row. - fn fetch_optional<'q: 'c, E: 'c>( + fn fetch_optional<'e, 'q: 'e, E: 'q>( self, query: E, - ) -> BoxFuture<'c, Result::Row>, Error>> + ) -> BoxFuture<'e, Result::Row>, Error>> where + 'c: 'e, E: Execute<'q, Self::Database>; /// Prepare the SQL query and return type information about its parameters @@ -120,11 +127,12 @@ pub trait Executor<'c>: Send + Debug + Sized { /// This is used by compile-time verification in the query macros to /// power their type inference. #[doc(hidden)] - fn describe<'q: 'c, E: 'c>( + fn describe<'e, 'q: 'e, E: 'q>( self, query: E, - ) -> BoxFuture<'c, Result, Error>> + ) -> BoxFuture<'e, Result, Error>> where + 'c: 'e, E: Execute<'q, Self::Database>; } diff --git a/sqlx-core/src/mysql/connection/executor.rs b/sqlx-core/src/mysql/connection/executor.rs index 34ba7db2..405493fa 100644 --- a/sqlx-core/src/mysql/connection/executor.rs +++ b/sqlx-core/src/mysql/connection/executor.rs @@ -198,11 +198,12 @@ impl MySqlConnection { impl<'c> Executor<'c> for &'c mut MySqlConnection { type Database = MySql; - fn fetch_many<'q: 'c, E: 'c>( + fn fetch_many<'e, 'q: 'e, E: 'q>( self, mut query: E, - ) -> BoxStream<'c, Result, Error>> + ) -> BoxStream<'e, Result, Error>> where + 'c: 'e, E: Execute<'q, Self::Database>, { let s = query.query(); @@ -218,11 +219,12 @@ impl<'c> Executor<'c> for &'c mut MySqlConnection { }) } - fn fetch_optional<'q: 'c, E: 'c>( + fn fetch_optional<'e, 'q: 'e, E: 'q>( self, query: E, - ) -> BoxFuture<'c, Result, Error>> + ) -> BoxFuture<'e, Result, Error>> where + 'c: 'e, E: Execute<'q, Self::Database>, { let mut s = self.fetch_many(query); @@ -239,8 +241,9 @@ impl<'c> Executor<'c> for &'c mut MySqlConnection { } #[doc(hidden)] - fn describe<'q: 'c, E: 'c>(self, query: E) -> BoxFuture<'c, Result, Error>> + fn describe<'e, 'q: 'e, E: 'q>(self, query: E) -> BoxFuture<'e, Result, Error>> where + 'c: 'e, E: Execute<'q, Self::Database>, { let query = query.query(); diff --git a/sqlx-core/src/pool/executor.rs b/sqlx-core/src/pool/executor.rs index a7b11940..f4911560 100644 --- a/sqlx-core/src/pool/executor.rs +++ b/sqlx-core/src/pool/executor.rs @@ -11,22 +11,24 @@ use crate::error::Error; use crate::executor::{Execute, Executor}; use crate::pool::Pool; -impl<'p, C> Executor<'p> for &'p Pool +impl<'p, C> Executor<'p> for &'_ Pool where - C: Connect, + C: 'static + Connect, for<'c> &'c mut C: Executor<'c, Database = C::Database>, { type Database = C::Database; - fn fetch_many<'q, E: 'p>( + fn fetch_many<'e, 'q: 'e, E: 'q>( self, query: E, - ) -> BoxStream<'p, Result::Row>, Error>> + ) -> BoxStream<'e, Result::Row>, Error>> where E: Execute<'q, Self::Database>, { + let pool = self.clone(); + Box::pin(try_stream! { - let mut conn = self.acquire().await?; + let mut conn = pool.acquire().await?; let mut s = conn.fetch_many(query); for v in s.try_next().await? { @@ -35,51 +37,61 @@ where }) } - fn fetch_optional<'q, E: 'p>( + fn fetch_optional<'e, 'q: 'e, E: 'q>( self, query: E, - ) -> BoxFuture<'p, Result::Row>, Error>> + ) -> BoxFuture<'e, Result::Row>, Error>> where E: Execute<'q, Self::Database>, { - Box::pin(async move { self.acquire().await?.fetch_optional(query).await }) + let pool = self.clone(); + + Box::pin(async move { pool.acquire().await?.fetch_optional(query).await }) } #[doc(hidden)] - fn describe<'q, E: 'p>(self, query: E) -> BoxFuture<'p, Result, Error>> + fn describe<'e, 'q: 'e, E: 'q>( + self, + query: E, + ) -> BoxFuture<'e, Result, Error>> where E: Execute<'q, Self::Database>, { - Box::pin(async move { self.acquire().await?.describe(query).await }) + let pool = self.clone(); + + Box::pin(async move { pool.acquire().await?.describe(query).await }) } } // NOTE: required due to lack of lazy normalization +#[allow(unused_macros)] macro_rules! impl_executor_for_pool_connection { ($DB:ident, $C:ident, $R:ident) => { impl<'c> crate::executor::Executor<'c> for &'c mut crate::pool::PoolConnection<$C> { type Database = $DB; #[inline] - fn fetch_many<'q: 'c, E: 'c>( + fn fetch_many<'e, 'q: 'e, E: 'q>( self, query: E, ) -> futures_core::stream::BoxStream< - 'c, + 'e, Result, crate::error::Error>, > where + 'c: 'e, E: crate::executor::Execute<'q, $DB>, { (&mut **self).fetch_many(query) } #[inline] - fn fetch_optional<'q: 'c, E: 'c>( + fn fetch_optional<'e, 'q: 'e, E: 'q>( self, query: E, - ) -> futures_core::future::BoxFuture<'c, Result, crate::error::Error>> + ) -> futures_core::future::BoxFuture<'e, Result, crate::error::Error>> where + 'c: 'e, E: crate::executor::Execute<'q, $DB>, { (&mut **self).fetch_optional(query) @@ -87,14 +99,15 @@ macro_rules! impl_executor_for_pool_connection { #[doc(hidden)] #[inline] - fn describe<'q: 'c, E: 'c>( + fn describe<'e, 'q: 'e, E: 'q>( self, query: E, ) -> futures_core::future::BoxFuture< - 'c, + 'e, Result, crate::error::Error>, > where + 'c: 'e, E: crate::executor::Execute<'q, $DB>, { (&mut **self).describe(query) diff --git a/sqlx-core/src/postgres/connection/executor.rs b/sqlx-core/src/postgres/connection/executor.rs index 7930b054..2b4b6c94 100644 --- a/sqlx-core/src/postgres/connection/executor.rs +++ b/sqlx-core/src/postgres/connection/executor.rs @@ -242,11 +242,12 @@ SELECT oid FROM pg_catalog.pg_type WHERE typname ILIKE $1 impl<'c> Executor<'c> for &'c mut PgConnection { type Database = Postgres; - fn fetch_many<'q: 'c, E: 'c>( + fn fetch_many<'e, 'q: 'e, E: 'q>( self, mut query: E, - ) -> BoxStream<'c, Result, Error>> + ) -> BoxStream<'e, Result, Error>> where + 'c: 'e, E: Execute<'q, Self::Database>, { let s = query.query(); @@ -262,11 +263,12 @@ impl<'c> Executor<'c> for &'c mut PgConnection { }) } - fn fetch_optional<'q: 'c, E: 'c>( + fn fetch_optional<'e, 'q: 'e, E: 'q>( self, mut query: E, - ) -> BoxFuture<'c, Result, Error>> + ) -> BoxFuture<'e, Result, Error>> where + 'c: 'e, E: Execute<'q, Self::Database>, { let s = query.query(); @@ -287,8 +289,12 @@ impl<'c> Executor<'c> for &'c mut PgConnection { } #[doc(hidden)] - fn describe<'q: 'c, E: 'c>(self, query: E) -> BoxFuture<'c, Result, Error>> + fn describe<'e, 'q: 'e, E: 'q>( + self, + query: E, + ) -> BoxFuture<'e, Result, Error>> where + 'c: 'e, E: Execute<'q, Self::Database>, { let s = query.query(); diff --git a/sqlx-core/src/postgres/listener.rs b/sqlx-core/src/postgres/listener.rs index 42343dd8..66868856 100644 --- a/sqlx-core/src/postgres/listener.rs +++ b/sqlx-core/src/postgres/listener.rs @@ -195,26 +195,35 @@ impl PgListener { impl<'c> Executor<'c> for &'c mut PgListener { type Database = Postgres; - fn fetch_many<'q: 'c, E: 'c>(self, query: E) -> BoxStream<'c, Result, Error>> + fn fetch_many<'e, 'q: 'e, E: 'q>( + self, + query: E, + ) -> BoxStream<'e, Result, Error>> where + 'c: 'e, E: Execute<'q, Self::Database>, { self.connection().fetch_many(query) } - fn fetch_optional<'q: 'c, E: 'c>(self, query: E) -> BoxFuture<'c, Result, Error>> + fn fetch_optional<'e, 'q: 'e, E: 'q>( + self, + query: E, + ) -> BoxFuture<'e, Result, Error>> where + 'c: 'e, E: Execute<'q, Self::Database>, { self.connection().fetch_optional(query) } #[doc(hidden)] - fn describe<'q: 'c, E: 'c>( + fn describe<'e, 'q: 'e, E: 'q>( self, query: E, - ) -> BoxFuture<'c, Result, Error>> + ) -> BoxFuture<'e, Result, Error>> where + 'c: 'e, E: Execute<'q, Self::Database>, { self.connection().describe(query) diff --git a/sqlx-core/src/query.rs b/sqlx-core/src/query.rs index d6d540f6..93f4fd1a 100644 --- a/sqlx-core/src/query.rs +++ b/sqlx-core/src/query.rs @@ -2,9 +2,8 @@ use std::marker::PhantomData; use async_stream::try_stream; use either::Either; -use futures_core::future::BoxFuture; use futures_core::stream::BoxStream; -use futures_util::{future, FutureExt, StreamExt, TryFutureExt, TryStreamExt}; +use futures_util::{future, StreamExt, TryFutureExt, TryStreamExt}; use crate::arguments::{Arguments, IntoArguments}; use crate::database::{Database, HasArguments}; @@ -71,7 +70,7 @@ impl<'q, DB: Database> Query<'q, DB, >::Arguments> { impl<'q, DB, A: Send> Query<'q, DB, A> where DB: Database, - A: IntoArguments<'q, DB>, + A: 'q + IntoArguments<'q, DB>, { /// Map each row in the result to another type. /// @@ -104,10 +103,10 @@ where /// Execute the query and return the total number of rows affected. #[inline] - pub async fn execute<'c, E>(self, executor: E) -> Result + pub async fn execute<'e, 'c: 'e, E>(self, executor: E) -> Result where - 'q: 'c, - A: 'c, + 'q: 'e, + A: 'e, E: Executor<'c, Database = DB>, { executor.execute(self).await @@ -115,10 +114,10 @@ where /// Execute multiple queries and return the rows affected from each query, in a stream. #[inline] - pub async fn execute_many<'c, E>(self, executor: E) -> BoxStream<'c, Result> + pub async fn execute_many<'e, 'c: 'e, E>(self, executor: E) -> BoxStream<'e, Result> where - 'q: 'c, - A: 'c, + 'q: 'e, + A: 'e, E: Executor<'c, Database = DB>, { executor.execute_many(self) @@ -126,10 +125,10 @@ where /// Execute the query and return the generated results as a stream. #[inline] - pub fn fetch<'c, E>(self, executor: E) -> BoxStream<'c, Result> + pub fn fetch<'e, 'c: 'e, E>(self, executor: E) -> BoxStream<'e, Result> where - 'q: 'c, - A: 'c, + 'q: 'e, + A: 'e, E: Executor<'c, Database = DB>, { executor.fetch(self) @@ -138,13 +137,13 @@ where /// Execute multiple queries and return the generated results as a stream /// from each query, in a stream. #[inline] - pub fn fetch_many<'c, E>( + pub fn fetch_many<'e, 'c: 'e, E>( self, executor: E, - ) -> BoxStream<'c, Result, Error>> + ) -> BoxStream<'e, Result, Error>> where - 'q: 'c, - A: 'c, + 'q: 'e, + A: 'e, E: Executor<'c, Database = DB>, { executor.fetch_many(self) @@ -152,10 +151,10 @@ where /// Execute the query and return all the generated results, collected into a [`Vec`]. #[inline] - pub async fn fetch_all<'c, E>(self, executor: E) -> Result, Error> + pub async fn fetch_all<'e, 'c: 'e, E>(self, executor: E) -> Result, Error> where - 'q: 'c, - A: 'c, + 'q: 'e, + A: 'e, E: Executor<'c, Database = DB>, { executor.fetch_all(self).await @@ -163,10 +162,10 @@ where /// Execute the query and returns exactly one row. #[inline] - pub async fn fetch_one<'c, E>(self, executor: E) -> Result + pub async fn fetch_one<'e, 'c: 'e, E>(self, executor: E) -> Result where - 'q: 'c, - A: 'c, + 'q: 'e, + A: 'e, E: Executor<'c, Database = DB>, { executor.fetch_one(self).await @@ -174,10 +173,10 @@ where /// Execute the query and returns at most one row. #[inline] - pub async fn fetch_optional<'c, E>(self, executor: E) -> Result, Error> + pub async fn fetch_optional<'e, 'c: 'e, E>(self, executor: E) -> Result, Error> where - 'q: 'c, - A: 'c, + 'q: 'e, + A: 'e, E: Executor<'c, Database = DB>, { executor.fetch_optional(self).await @@ -207,16 +206,14 @@ where O: Send + Unpin, A: 'q + Send + IntoArguments<'q, DB>, { - // FIXME: This is very close 1:1 with [`Executor::fetch`] - // noinspection DuplicatedCode /// Execute the query and return the generated results as a stream. - pub fn fetch<'c, E>(self, executor: E) -> BoxStream<'c, Result> + pub fn fetch<'e, 'c: 'e, E>(self, executor: E) -> BoxStream<'e, Result> where - 'q: 'c, - E: 'c + Executor<'c, Database = DB>, - DB: 'c, - F: 'c, - O: 'c, + 'q: 'e, + E: 'e + Executor<'c, Database = DB>, + DB: 'e, + F: 'e, + O: 'e, { self.fetch_many(executor) .try_filter_map(|step| async move { @@ -230,13 +227,16 @@ where /// Execute multiple queries and return the generated results as a stream /// from each query, in a stream. - pub fn fetch_many<'c, E>(self, executor: E) -> BoxStream<'c, Result, Error>> + pub fn fetch_many<'e, 'c: 'e, E>( + self, + executor: E, + ) -> BoxStream<'e, Result, Error>> where - 'q: 'c, - E: 'c + Executor<'c, Database = DB>, - DB: 'c, - F: 'c, - O: 'c, + 'q: 'e, + E: 'e + Executor<'c, Database = DB>, + DB: 'e, + F: 'e, + O: 'e, { Box::pin(try_stream! { let mut s = executor.fetch_many(self.inner); @@ -253,54 +253,50 @@ where } /// Execute the query and return all the generated results, collected into a [`Vec`]. - #[inline] - pub fn fetch_all<'c, E>(self, executor: E) -> BoxFuture<'c, Result, Error>> + pub async fn fetch_all<'e, 'c: 'e, E>(self, executor: E) -> Result, Error> where - 'q: 'c, - E: 'c + Executor<'c, Database = DB>, - DB: 'c, - F: 'c, - O: 'c, + 'q: 'e, + E: 'e + Executor<'c, Database = DB>, + DB: 'e, + F: 'e, + O: 'e, { - self.fetch(executor).try_collect().boxed() + self.fetch(executor).try_collect().await } - // FIXME: This is very close 1:1 with [`Executor::fetch_one`] - // noinspection DuplicatedCode /// Execute the query and returns exactly one row. - pub fn fetch_one<'c, E>(self, executor: E) -> BoxFuture<'c, Result> + pub async fn fetch_one<'e, 'c: 'e, E>(self, executor: E) -> Result where - 'q: 'c, - E: 'c + Executor<'c, Database = DB>, - DB: 'c, - F: 'c, - O: 'c, + 'q: 'e, + E: 'e + Executor<'c, Database = DB>, + DB: 'e, + F: 'e, + O: 'e, { self.fetch_optional(executor) .and_then(|row| match row { Some(row) => future::ok(row), None => future::err(Error::RowNotFound), }) - .boxed() + .await } /// Execute the query and returns at most one row. - pub fn fetch_optional<'c, E>(self, executor: E) -> BoxFuture<'c, Result, Error>> + pub async fn fetch_optional<'e, 'c: 'e, E>(self, executor: E) -> Result, Error> where - 'q: 'c, - E: 'c + Executor<'c, Database = DB>, - DB: 'c, - F: 'c, - O: 'c, + 'q: 'e, + E: 'e + Executor<'c, Database = DB>, + DB: 'e, + F: 'e, + O: 'e, { - Box::pin(async move { - let row = executor.fetch_optional(self.inner).await?; - if let Some(row) = row { - (self.mapper)(row).map(Some) - } else { - Ok(None) - } - }) + let row = executor.fetch_optional(self.inner).await?; + + if let Some(row) = row { + (self.mapper)(row).map(Some) + } else { + Ok(None) + } } } diff --git a/sqlx-core/src/query_as.rs b/sqlx-core/src/query_as.rs index 3f96ac36..7ecfa719 100644 --- a/sqlx-core/src/query_as.rs +++ b/sqlx-core/src/query_as.rs @@ -24,7 +24,7 @@ pub struct QueryAs<'q, DB: Database, O, A> { impl<'q, DB, O: Send, A: Send> Execute<'q, DB> for QueryAs<'q, DB, O, A> where DB: Database, - A: IntoArguments<'q, DB>, + A: 'q + IntoArguments<'q, DB>, { #[inline] fn query(&self) -> &'q str { @@ -52,17 +52,17 @@ impl<'q, DB: Database, O> QueryAs<'q, DB, O, >::Arguments impl<'q, DB, O, A> QueryAs<'q, DB, O, A> where DB: Database, - A: IntoArguments<'q, DB>, + A: 'q + IntoArguments<'q, DB>, O: Send + Unpin + for<'r> FromRow<'r, DB::Row>, { /// Execute the query and return the generated results as a stream. - pub fn fetch<'c, E>(self, executor: E) -> BoxStream<'c, Result> + pub fn fetch<'e, 'c: 'e, E>(self, executor: E) -> BoxStream<'e, Result> where - 'q: 'c, - E: 'c + Executor<'c, Database = DB>, - DB: 'c, - O: 'c, - A: 'c, + 'q: 'e, + E: 'e + Executor<'c, Database = DB>, + DB: 'e, + O: 'e, + A: 'e, { self.fetch_many(executor) .try_filter_map(|step| async move { Ok(step.right()) }) @@ -71,13 +71,16 @@ where /// Execute multiple queries and return the generated results as a stream /// from each query, in a stream. - pub fn fetch_many<'c, E>(self, executor: E) -> BoxStream<'c, Result, Error>> + pub fn fetch_many<'e, 'c: 'e, E>( + self, + executor: E, + ) -> BoxStream<'e, Result, Error>> where - 'q: 'c, - E: 'c + Executor<'c, Database = DB>, - DB: 'c, - O: 'c, - A: 'c, + 'q: 'e, + E: 'e + Executor<'c, Database = DB>, + DB: 'e, + O: 'e, + A: 'e, { Box::pin(try_stream! { let mut s = executor.fetch_many(self.inner); @@ -95,25 +98,25 @@ where /// Execute the query and return all the generated results, collected into a [`Vec`]. #[inline] - pub async fn fetch_all<'c, E>(self, executor: E) -> Result, Error> + pub async fn fetch_all<'e, 'c: 'e, E>(self, executor: E) -> Result, Error> where - 'q: 'c, - E: 'c + Executor<'c, Database = DB>, - DB: 'c, - A: 'c, - O: 'c, + 'q: 'e, + E: 'e + Executor<'c, Database = DB>, + DB: 'e, + O: 'e, + A: 'e, { self.fetch(executor).try_collect().await } /// Execute the query and returns exactly one row. - pub async fn fetch_one<'c, E>(self, executor: E) -> Result + pub async fn fetch_one<'e, 'c: 'e, E>(self, executor: E) -> Result where - 'q: 'c, - E: 'c + Executor<'c, Database = DB>, - DB: 'c, - O: 'c, - A: 'c, + 'q: 'e, + E: 'e + Executor<'c, Database = DB>, + DB: 'e, + O: 'e, + A: 'e, { self.fetch_optional(executor) .await @@ -121,13 +124,13 @@ where } /// Execute the query and returns at most one row. - pub async fn fetch_optional<'c, E>(self, executor: E) -> Result, Error> + pub async fn fetch_optional<'e, 'c: 'e, E>(self, executor: E) -> Result, Error> where - 'q: 'c, - E: 'c + Executor<'c, Database = DB>, - DB: 'c, - O: 'c, - A: 'c, + 'q: 'e, + E: 'e + Executor<'c, Database = DB>, + DB: 'e, + O: 'e, + A: 'e, { let row = executor.fetch_optional(self.inner).await?; if let Some(row) = row { diff --git a/sqlx-core/src/query_scalar.rs b/sqlx-core/src/query_scalar.rs index 00056c93..474b3a98 100644 --- a/sqlx-core/src/query_scalar.rs +++ b/sqlx-core/src/query_scalar.rs @@ -19,7 +19,7 @@ pub struct QueryScalar<'q, DB: Database, O, A> { impl<'q, DB: Database, O: Send, A: Send> Execute<'q, DB> for QueryScalar<'q, DB, O, A> where - A: IntoArguments<'q, DB>, + A: 'q + IntoArguments<'q, DB>, { #[inline] fn query(&self) -> &'q str { @@ -48,18 +48,18 @@ impl<'q, DB, O, A> QueryScalar<'q, DB, O, A> where DB: Database, O: Send + Unpin, - A: IntoArguments<'q, DB>, + A: 'q + IntoArguments<'q, DB>, (O,): Send + Unpin + for<'r> FromRow<'r, DB::Row>, { /// Execute the query and return the generated results as a stream. #[inline] - pub fn fetch<'c, E>(self, executor: E) -> BoxStream<'c, Result> + pub fn fetch<'e, 'c: 'e, E>(self, executor: E) -> BoxStream<'e, Result> where - 'q: 'c, - E: 'c + Executor<'c, Database = DB>, - DB: 'c, - A: 'c, - O: 'c, + 'q: 'e, + E: 'e + Executor<'c, Database = DB>, + DB: 'e, + A: 'e, + O: 'e, { self.inner.fetch(executor).map_ok(|it| it.0).boxed() } @@ -67,13 +67,16 @@ where /// Execute multiple queries and return the generated results as a stream /// from each query, in a stream. #[inline] - pub fn fetch_many<'c, E>(self, executor: E) -> BoxStream<'c, Result, Error>> + pub fn fetch_many<'e, 'c: 'e, E>( + self, + executor: E, + ) -> BoxStream<'e, Result, Error>> where - 'q: 'c, - E: 'c + Executor<'c, Database = DB>, - DB: 'c, - O: 'c, - A: 'c, + 'q: 'e, + E: 'e + Executor<'c, Database = DB>, + DB: 'e, + A: 'e, + O: 'e, { self.inner .fetch_many(executor) @@ -83,13 +86,13 @@ where /// Execute the query and return all the generated results, collected into a [`Vec`]. #[inline] - pub async fn fetch_all<'c, E>(self, executor: E) -> Result, Error> + pub async fn fetch_all<'e, 'c: 'e, E>(self, executor: E) -> Result, Error> where - 'q: 'c, - E: 'c + Executor<'c, Database = DB>, - DB: 'c, - (O,): 'c, - A: 'c, + 'q: 'e, + E: 'e + Executor<'c, Database = DB>, + DB: 'e, + (O,): 'e, + A: 'e, { self.inner .fetch(executor) @@ -100,26 +103,26 @@ where /// Execute the query and returns exactly one row. #[inline] - pub async fn fetch_one<'c, E>(self, executor: E) -> Result + pub async fn fetch_one<'e, 'c: 'e, E>(self, executor: E) -> Result where - 'q: 'c, - E: 'c + Executor<'c, Database = DB>, - DB: 'c, - O: 'c, - A: 'c, + 'q: 'e, + E: 'e + Executor<'c, Database = DB>, + DB: 'e, + O: 'e, + A: 'e, { self.inner.fetch_one(executor).map_ok(|it| it.0).await } /// Execute the query and returns at most one row. #[inline] - pub async fn fetch_optional<'c, E>(self, executor: E) -> Result, Error> + pub async fn fetch_optional<'e, 'c: 'e, E>(self, executor: E) -> Result, Error> where - 'q: 'c, - E: 'c + Executor<'c, Database = DB>, - DB: 'c, - O: 'c, - A: 'c, + 'q: 'e, + E: 'e + Executor<'c, Database = DB>, + DB: 'e, + O: 'e, + A: 'e, { Ok(self.inner.fetch_optional(executor).await?.map(|it| it.0)) } diff --git a/sqlx-core/src/sqlite/connection/executor.rs b/sqlx-core/src/sqlite/connection/executor.rs index 290bcfb6..ba174ff7 100644 --- a/sqlx-core/src/sqlite/connection/executor.rs +++ b/sqlx-core/src/sqlite/connection/executor.rs @@ -74,11 +74,12 @@ fn emplace_row_metadata( impl<'c> Executor<'c> for &'c mut SqliteConnection { type Database = Sqlite; - fn fetch_many<'q: 'c, E: 'c>( + fn fetch_many<'e, 'q: 'e, E: 'q>( self, mut query: E, - ) -> BoxStream<'c, Result, Error>> + ) -> BoxStream<'e, Result, Error>> where + 'c: 'e, E: Execute<'q, Self::Database>, { let s = query.query(); @@ -148,11 +149,12 @@ impl<'c> Executor<'c> for &'c mut SqliteConnection { }) } - fn fetch_optional<'q: 'c, E: 'c>( + fn fetch_optional<'e, 'q: 'e, E: 'q>( self, query: E, - ) -> BoxFuture<'c, Result, Error>> + ) -> BoxFuture<'e, Result, Error>> where + 'c: 'e, E: Execute<'q, Self::Database>, { let mut s = self.fetch_many(query); @@ -169,8 +171,9 @@ impl<'c> Executor<'c> for &'c mut SqliteConnection { } #[doc(hidden)] - fn describe<'q: 'c, E: 'c>(self, query: E) -> BoxFuture<'c, Result, Error>> + fn describe<'e, 'q: 'e, E: 'q>(self, query: E) -> BoxFuture<'e, Result, Error>> where + 'c: 'e, E: Execute<'q, Self::Database>, { let query = query.query();