Skip to content

Commit 26ef106

Browse files
authored
Merge pull request diesel-rs#1990 from mehcode/boxed-send
Add Send bound to BoxedSelectStatement
2 parents 63b404c + 2d24a9c commit 26ef106

6 files changed

Lines changed: 77 additions & 39 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,18 @@ for Rust libraries in [RFC #1105](https://github.com/rust-lang/rfcs/blob/master/
4848
`Mysql::TypeMetadata`, you will need to take the new struct
4949
`MysqlTypeMetadata` instead.
5050

51-
* The minimal officially supported rustc version is now 1.36.0
51+
* The minimal officially supported rustc version is now 1.37.0
5252

5353
* The `RawValue` types for the `Mysql` and `Postgresql` backend where changed
5454
from `[u8]` to distinct opaque types. If you used the concrete `RawValue` type
5555
somewhere you need to change it to `mysql::MysqlValue` or `pg::PgValue`.
5656
For the postgres backend additionally type information where added to the `RawValue`
5757
type. This allows to dynamically deserialize `RawValues` in container types.
58+
5859
* The uuidv07 feature was renamed to uuid, due to the removal of support for older uuid versions
5960

61+
* Boxed queries (constructed from `.into_boxed()`) are now `Send`.
62+
6063
### Fixed
6164

6265
* Many types were incorrectly considered non-aggregate when they should not

diesel/src/macros/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ macro_rules! table {
279279
sql_name = unknown,
280280
name = unknown,
281281
schema = public,
282-
primary_key = (id),
282+
primary_key = id,
283283
}
284284
}
285285
}
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
simple_clause!(NoOrderClause, OrderClause, " ORDER BY ");
22

3-
impl<'a, DB, Expr> Into<Option<Box<dyn QueryFragment<DB> + 'a>>> for OrderClause<Expr>
3+
impl<'a, DB, Expr> Into<Option<Box<dyn QueryFragment<DB> + Send + 'a>>> for OrderClause<Expr>
44
where
55
DB: Backend,
6-
Expr: QueryFragment<DB> + 'a,
6+
Expr: QueryFragment<DB> + Send + 'a,
77
{
8-
fn into(self) -> Option<Box<dyn QueryFragment<DB> + 'a>> {
8+
fn into(self) -> Option<Box<dyn QueryFragment<DB> + Send + 'a>> {
99
Some(Box::new(self.0))
1010
}
1111
}
1212

13-
impl<'a, DB> Into<Option<Box<dyn QueryFragment<DB> + 'a>>> for NoOrderClause
13+
impl<'a, DB> Into<Option<Box<dyn QueryFragment<DB> + Send + 'a>>> for NoOrderClause
1414
where
1515
DB: Backend,
1616
{
17-
fn into(self) -> Option<Box<dyn QueryFragment<DB> + 'a>> {
17+
fn into(self) -> Option<Box<dyn QueryFragment<DB> + Send + 'a>> {
1818
None
1919
}
2020
}

diesel/src/query_builder/select_statement/boxed.rs

Lines changed: 51 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,28 +22,28 @@ use crate::sql_types::{BigInt, Bool, NotNull, Nullable};
2222

2323
#[allow(missing_debug_implementations)]
2424
pub struct BoxedSelectStatement<'a, ST, QS, DB> {
25-
select: Box<dyn QueryFragment<DB> + 'a>,
25+
select: Box<dyn QueryFragment<DB> + Send + 'a>,
2626
from: QS,
27-
distinct: Box<dyn QueryFragment<DB> + 'a>,
27+
distinct: Box<dyn QueryFragment<DB> + Send + 'a>,
2828
where_clause: BoxedWhereClause<'a, DB>,
29-
order: Option<Box<dyn QueryFragment<DB> + 'a>>,
30-
limit: Box<dyn QueryFragment<DB> + 'a>,
31-
offset: Box<dyn QueryFragment<DB> + 'a>,
32-
group_by: Box<dyn QueryFragment<DB> + 'a>,
29+
order: Option<Box<dyn QueryFragment<DB> + Send + 'a>>,
30+
limit: Box<dyn QueryFragment<DB> + Send + 'a>,
31+
offset: Box<dyn QueryFragment<DB> + Send + 'a>,
32+
group_by: Box<dyn QueryFragment<DB> + Send + 'a>,
3333
_marker: PhantomData<ST>,
3434
}
3535

3636
impl<'a, ST, QS, DB> BoxedSelectStatement<'a, ST, QS, DB> {
3737
#[allow(clippy::too_many_arguments)]
3838
pub fn new(
39-
select: Box<dyn QueryFragment<DB> + 'a>,
39+
select: Box<dyn QueryFragment<DB> + Send + 'a>,
4040
from: QS,
41-
distinct: Box<dyn QueryFragment<DB> + 'a>,
41+
distinct: Box<dyn QueryFragment<DB> + Send + 'a>,
4242
where_clause: BoxedWhereClause<'a, DB>,
43-
order: Option<Box<dyn QueryFragment<DB> + 'a>>,
44-
limit: Box<dyn QueryFragment<DB> + 'a>,
45-
offset: Box<dyn QueryFragment<DB> + 'a>,
46-
group_by: Box<dyn QueryFragment<DB> + 'a>,
43+
order: Option<Box<dyn QueryFragment<DB> + Send + 'a>>,
44+
limit: Box<dyn QueryFragment<DB> + Send + 'a>,
45+
offset: Box<dyn QueryFragment<DB> + Send + 'a>,
46+
group_by: Box<dyn QueryFragment<DB> + Send + 'a>,
4747
) -> Self {
4848
BoxedSelectStatement {
4949
select: select,
@@ -164,7 +164,7 @@ where
164164
impl<'a, ST, QS, DB, Selection> SelectDsl<Selection> for BoxedSelectStatement<'a, ST, QS, DB>
165165
where
166166
DB: Backend,
167-
Selection: SelectableExpression<QS> + QueryFragment<DB> + 'a,
167+
Selection: SelectableExpression<QS> + QueryFragment<DB> + Send + 'a,
168168
{
169169
type Output = BoxedSelectStatement<'a, Selection::SqlType, QS, DB>;
170170

@@ -237,7 +237,7 @@ where
237237
impl<'a, ST, QS, DB, Order> OrderDsl<Order> for BoxedSelectStatement<'a, ST, QS, DB>
238238
where
239239
DB: Backend,
240-
Order: QueryFragment<DB> + AppearsOnTable<QS> + 'a,
240+
Order: QueryFragment<DB> + AppearsOnTable<QS> + Send + 'a,
241241
{
242242
type Output = Self;
243243

@@ -250,7 +250,7 @@ where
250250
impl<'a, ST, QS, DB, Order> ThenOrderDsl<Order> for BoxedSelectStatement<'a, ST, QS, DB>
251251
where
252252
DB: Backend + 'a,
253-
Order: QueryFragment<DB> + AppearsOnTable<QS> + 'a,
253+
Order: QueryFragment<DB> + AppearsOnTable<QS> + Send + 'a,
254254
{
255255
type Output = Self;
256256

@@ -266,7 +266,7 @@ where
266266
impl<'a, ST, QS, DB, Expr> GroupByDsl<Expr> for BoxedSelectStatement<'a, ST, QS, DB>
267267
where
268268
DB: Backend,
269-
Expr: QueryFragment<DB> + AppearsOnTable<QS> + 'a,
269+
Expr: QueryFragment<DB> + AppearsOnTable<QS> + Send + 'a,
270270
Self: Query,
271271
{
272272
type Output = Self;
@@ -340,3 +340,38 @@ where
340340
}
341341
}
342342
}
343+
344+
#[cfg(test)]
345+
mod tests {
346+
use crate::backend::Backend;
347+
use crate::prelude::*;
348+
349+
table! {
350+
users {
351+
id -> Integer,
352+
}
353+
}
354+
355+
fn assert_send<T>(_: T)
356+
where
357+
T: Send,
358+
{
359+
}
360+
361+
fn assert_boxed_query_send<B: Backend>() {
362+
assert_send(users::table.into_boxed::<B>());
363+
assert_send(users::table.filter(users::id.eq(10)).into_boxed::<B>());
364+
}
365+
366+
#[test]
367+
fn boxed_is_send() {
368+
#[cfg(feature = "postgres")]
369+
assert_boxed_query_send::<crate::pg::Pg>();
370+
371+
#[cfg(feature = "sqlite")]
372+
assert_boxed_query_send::<crate::sqlite::Sqlite>();
373+
374+
#[cfg(feature = "mysql")]
375+
assert_boxed_query_send::<crate::mysql::Mysql>();
376+
}
377+
}

diesel/src/query_builder/select_statement/dsl_impls.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -344,13 +344,13 @@ impl<'a, F, S, D, W, O, L, Of, G, DB> BoxedDsl<'a, DB>
344344
where
345345
Self: AsQuery,
346346
DB: Backend,
347-
S: QueryFragment<DB> + SelectableExpression<F> + 'a,
348-
D: QueryFragment<DB> + 'a,
347+
S: QueryFragment<DB> + SelectableExpression<F> + Send + 'a,
348+
D: QueryFragment<DB> + Send + 'a,
349349
W: Into<BoxedWhereClause<'a, DB>>,
350-
O: Into<Option<Box<dyn QueryFragment<DB> + 'a>>>,
351-
L: QueryFragment<DB> + 'a,
352-
Of: QueryFragment<DB> + 'a,
353-
G: QueryFragment<DB> + 'a,
350+
O: Into<Option<Box<dyn QueryFragment<DB> + Send + 'a>>>,
351+
L: QueryFragment<DB> + Send + 'a,
352+
Of: QueryFragment<DB> + Send + 'a,
353+
G: QueryFragment<DB> + Send + 'a,
354354
{
355355
type Output = BoxedSelectStatement<'a, S::SqlType, F, DB>;
356356

@@ -374,13 +374,13 @@ where
374374
Self: AsQuery,
375375
DB: Backend,
376376
F: QuerySource,
377-
F::DefaultSelection: QueryFragment<DB> + 'a,
378-
D: QueryFragment<DB> + 'a,
377+
F::DefaultSelection: QueryFragment<DB> + Send + 'a,
378+
D: QueryFragment<DB> + Send + 'a,
379379
W: Into<BoxedWhereClause<'a, DB>>,
380-
O: Into<Option<Box<dyn QueryFragment<DB> + 'a>>>,
381-
L: QueryFragment<DB> + 'a,
382-
Of: QueryFragment<DB> + 'a,
383-
G: QueryFragment<DB> + 'a,
380+
O: Into<Option<Box<dyn QueryFragment<DB> + Send + 'a>>>,
381+
L: QueryFragment<DB> + Send + 'a,
382+
Of: QueryFragment<DB> + Send + 'a,
383+
G: QueryFragment<DB> + Send + 'a,
384384
{
385385
type Output = BoxedSelectStatement<'a, <F::DefaultSelection as Expression>::SqlType, F, DB>;
386386
fn internal_into_boxed(self) -> Self::Output {

diesel/src/query_builder/where_clause.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ where
108108
impl<'a, DB, Predicate> Into<BoxedWhereClause<'a, DB>> for WhereClause<Predicate>
109109
where
110110
DB: Backend,
111-
Predicate: QueryFragment<DB> + 'a,
111+
Predicate: QueryFragment<DB> + Send + 'a,
112112
{
113113
fn into(self) -> BoxedWhereClause<'a, DB> {
114114
BoxedWhereClause::Where(Box::new(self.0))
@@ -125,7 +125,7 @@ impl<QS, Expr> ValidWhereClause<QS> for WhereClause<Expr> where Expr: AppearsOnT
125125

126126
#[allow(missing_debug_implementations)] // We can't...
127127
pub enum BoxedWhereClause<'a, DB> {
128-
Where(Box<dyn QueryFragment<DB> + 'a>),
128+
Where(Box<dyn QueryFragment<DB> + Send + 'a>),
129129
None,
130130
}
131131

@@ -153,7 +153,7 @@ impl<'a, DB> QueryId for BoxedWhereClause<'a, DB> {
153153
impl<'a, DB, Predicate> WhereAnd<Predicate> for BoxedWhereClause<'a, DB>
154154
where
155155
DB: Backend + 'a,
156-
Predicate: QueryFragment<DB> + 'a,
156+
Predicate: QueryFragment<DB> + Send + 'a,
157157
{
158158
type Output = Self;
159159

@@ -170,7 +170,7 @@ where
170170
impl<'a, DB, Predicate> WhereOr<Predicate> for BoxedWhereClause<'a, DB>
171171
where
172172
DB: Backend + 'a,
173-
Predicate: QueryFragment<DB> + 'a,
173+
Predicate: QueryFragment<DB> + Send + 'a,
174174
{
175175
type Output = Self;
176176

0 commit comments

Comments
 (0)