1use crate::backend::{Backend, DieselReserveSpecialization};
12use crate::dsl::AsExprOf;
13use crate::expression::IntoSql;
14use crate::expression::subselect::{ValidSubselect, ValidSubselectGrouping};
15use crate::expression::{MixedAggregates, NonAggregate};
16use crate::query_builder::insert_statement::InsertFromSelect;
17use crate::query_builder::limit_clause::{LimitClause, NoLimitClause};
18use crate::query_builder::limit_offset_clause::LimitOffsetClause;
19use crate::query_builder::offset_clause::{NoOffsetClause, OffsetClause};
20use crate::query_builder::order_clause::{NoOrderClause, OrderClause};
21use crate::query_builder::{AsQuery, AstPass, Query, QueryFragment, QueryId, SelectQuery};
22use crate::query_dsl::RunQueryDslSupport;
23use crate::query_dsl::methods::*;
24use crate::query_dsl::positional_order_dsl::{IntoPositionalOrderExpr, PositionalOrderDsl};
25use crate::sql_types::BigInt;
26use crate::{CombineDsl, Insertable, QueryDsl, QueryResult, Table};
27
28#[derive(#[automatically_derived]
impl<Combinator: ::core::fmt::Debug, Rule: ::core::fmt::Debug,
Source: ::core::fmt::Debug, Rhs: ::core::fmt::Debug,
Order: ::core::fmt::Debug, LimitOffset: ::core::fmt::Debug>
::core::fmt::Debug for
CombinationClause<Combinator, Rule, Source, Rhs, Order, LimitOffset> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
let names: &'static _ =
&["combinator", "duplicate_rule", "source", "rhs", "order",
"limit_offset"];
let values: &[&dyn ::core::fmt::Debug] =
&[&self.combinator, &self.duplicate_rule, &self.source, &self.rhs,
&self.order, &&self.limit_offset];
::core::fmt::Formatter::debug_struct_fields_finish(f,
"CombinationClause", names, values)
}
}Debug, #[automatically_derived]
impl<Combinator: ::core::marker::Copy, Rule: ::core::marker::Copy,
Source: ::core::marker::Copy, Rhs: ::core::marker::Copy,
Order: ::core::marker::Copy, LimitOffset: ::core::marker::Copy>
::core::marker::Copy for
CombinationClause<Combinator, Rule, Source, Rhs, Order, LimitOffset> {
}Copy, #[automatically_derived]
impl<Combinator: ::core::clone::Clone, Rule: ::core::clone::Clone,
Source: ::core::clone::Clone, Rhs: ::core::clone::Clone,
Order: ::core::clone::Clone, LimitOffset: ::core::clone::Clone>
::core::clone::Clone for
CombinationClause<Combinator, Rule, Source, Rhs, Order, LimitOffset> {
#[inline]
fn clone(&self) -> Self {
Self {
combinator: ::core::clone::Clone::clone(&self.combinator),
duplicate_rule: ::core::clone::Clone::clone(&self.duplicate_rule),
source: ::core::clone::Clone::clone(&self.source),
rhs: ::core::clone::Clone::clone(&self.rhs),
order: ::core::clone::Clone::clone(&self.order),
limit_offset: ::core::clone::Clone::clone(&self.limit_offset),
}
}
}Clone, const _: () =
{
use diesel;
#[allow(non_camel_case_types)]
impl<Combinator: diesel::query_builder::QueryId,
Rule: diesel::query_builder::QueryId,
Source: diesel::query_builder::QueryId,
Rhs: diesel::query_builder::QueryId,
Order: diesel::query_builder::QueryId,
LimitOffset: diesel::query_builder::QueryId>
diesel::query_builder::QueryId for
CombinationClause<Combinator, Rule, Source, Rhs, Order,
LimitOffset> {
type QueryId =
CombinationClause<<Combinator as
diesel::query_builder::QueryId>::QueryId,
<Rule as diesel::query_builder::QueryId>::QueryId,
<Source as diesel::query_builder::QueryId>::QueryId,
<Rhs as diesel::query_builder::QueryId>::QueryId,
<Order as diesel::query_builder::QueryId>::QueryId,
<LimitOffset as diesel::query_builder::QueryId>::QueryId>;
const HAS_STATIC_QUERY_ID: bool =
<Combinator as
diesel::query_builder::QueryId>::HAS_STATIC_QUERY_ID &&
<Rule as
diesel::query_builder::QueryId>::HAS_STATIC_QUERY_ID &&
<Source as
diesel::query_builder::QueryId>::HAS_STATIC_QUERY_ID &&
<Rhs as diesel::query_builder::QueryId>::HAS_STATIC_QUERY_ID
&&
<Order as
diesel::query_builder::QueryId>::HAS_STATIC_QUERY_ID &&
<LimitOffset as
diesel::query_builder::QueryId>::HAS_STATIC_QUERY_ID &&
true;
const IS_WINDOW_FUNCTION: bool =
<Combinator as
diesel::query_builder::QueryId>::IS_WINDOW_FUNCTION ||
<Rule as diesel::query_builder::QueryId>::IS_WINDOW_FUNCTION
||
<Source as
diesel::query_builder::QueryId>::IS_WINDOW_FUNCTION ||
<Rhs as diesel::query_builder::QueryId>::IS_WINDOW_FUNCTION
||
<Order as
diesel::query_builder::QueryId>::IS_WINDOW_FUNCTION ||
<LimitOffset as
diesel::query_builder::QueryId>::IS_WINDOW_FUNCTION ||
false;
}
};QueryId)]
29#[must_use = "Queries are only executed when calling `load`, `get_result` or similar."]
30pub struct CombinationClause<
33 Combinator,
34 Rule,
35 Source,
36 Rhs,
37 Order = NoOrderClause,
38 LimitOffset = LimitOffsetClause<NoLimitClause, NoOffsetClause>,
39> {
40 combinator: Combinator,
41 duplicate_rule: Rule,
42 source: ParenthesisWrapper<Source>,
43 rhs: ParenthesisWrapper<Rhs>,
44 order: Order,
46 limit_offset: LimitOffset,
48}
49
50impl<Combinator, Rule, Source, Rhs> CombinationClause<Combinator, Rule, Source, Rhs> {
51 pub(crate) fn new(
53 combinator: Combinator,
54 duplicate_rule: Rule,
55 source: Source,
56 rhs: Rhs,
57 ) -> Self {
58 CombinationClause {
59 combinator,
60 duplicate_rule,
61 source: ParenthesisWrapper { inner: source },
62 rhs: ParenthesisWrapper { inner: rhs },
63 order: NoOrderClause,
64 limit_offset: LimitOffsetClause {
65 limit_clause: NoLimitClause,
66 offset_clause: NoOffsetClause,
67 },
68 }
69 }
70}
71
72impl<Combinator, Rule, Source, Rhs, O, LOf> QueryDsl
73 for CombinationClause<Combinator, Rule, Source, Rhs, O, LOf>
74{
75}
76
77impl<Combinator, Rule, Source, Rhs, O, LOf> Query
78 for CombinationClause<Combinator, Rule, Source, Rhs, O, LOf>
79where
80 Source: Query,
81 Rhs: Query<SqlType = Source::SqlType>,
82{
83 type SqlType = Source::SqlType;
84}
85
86impl<Combinator, Rule, Source, Rhs, O, LOf> SelectQuery
87 for CombinationClause<Combinator, Rule, Source, Rhs, O, LOf>
88where
89 Source: SelectQuery,
90 Rhs: SelectQuery<SqlType = Source::SqlType>,
91{
92 type SqlType = Source::SqlType;
93}
94
95impl<Combinator, Rule, Source, Rhs, O, LOf, QS> ValidSubselect<QS>
96 for CombinationClause<Combinator, Rule, Source, Rhs, O, LOf>
97where
98 Source: ValidSubselect<QS>,
99 Rhs: ValidSubselect<QS>,
100{
101}
102
103impl<Combinator, Rule, Source, Rhs, O, LOf, GB> ValidSubselectGrouping<GB>
104 for CombinationClause<Combinator, Rule, Source, Rhs, O, LOf>
105where
106 Source: ValidSubselectGrouping<GB>,
107 Rhs: ValidSubselectGrouping<GB>,
108 Source::IsAggregate: MixedAggregates<Rhs::IsAggregate>,
109{
110 type IsAggregate = <Source::IsAggregate as MixedAggregates<Rhs::IsAggregate>>::Output;
111}
112
113impl<Combinator, Rule, Source, Rhs, O, LOf> RunQueryDslSupport
114 for CombinationClause<Combinator, Rule, Source, Rhs, O, LOf>
115{
116}
117
118impl<Combinator, Rule, Source, Rhs, O, LOf, T> Insertable<T>
119 for CombinationClause<Combinator, Rule, Source, Rhs, O, LOf>
120where
121 T: Table,
122 T::AllColumns: NonAggregate,
123 Self: Query,
124{
125 type Values = InsertFromSelect<Self, T::AllColumns>;
126
127 fn values(self) -> Self::Values {
128 InsertFromSelect::new(self)
129 }
130}
131
132impl<Combinator, Rule, Source, OriginRhs, O, LOf> CombineDsl
133 for CombinationClause<Combinator, Rule, Source, OriginRhs, O, LOf>
134where
135 Self: Query,
136{
137 type Query = Self;
138
139 fn union<Rhs>(self, rhs: Rhs) -> crate::dsl::Union<Self, Rhs>
140 where
141 Rhs: AsQuery<SqlType = <Self::Query as Query>::SqlType>,
142 {
143 CombinationClause::new(Union, Distinct, self, rhs.as_query())
144 }
145
146 fn union_all<Rhs>(self, rhs: Rhs) -> crate::dsl::UnionAll<Self, Rhs>
147 where
148 Rhs: AsQuery<SqlType = <Self::Query as Query>::SqlType>,
149 {
150 CombinationClause::new(Union, All, self, rhs.as_query())
151 }
152
153 fn intersect<Rhs>(self, rhs: Rhs) -> crate::dsl::Intersect<Self, Rhs>
154 where
155 Rhs: AsQuery<SqlType = <Self::Query as Query>::SqlType>,
156 {
157 CombinationClause::new(Intersect, Distinct, self, rhs.as_query())
158 }
159
160 fn intersect_all<Rhs>(self, rhs: Rhs) -> crate::dsl::IntersectAll<Self, Rhs>
161 where
162 Rhs: AsQuery<SqlType = <Self::Query as Query>::SqlType>,
163 {
164 CombinationClause::new(Intersect, All, self, rhs.as_query())
165 }
166
167 fn except<Rhs>(self, rhs: Rhs) -> crate::dsl::Except<Self, Rhs>
168 where
169 Rhs: AsQuery<SqlType = <Self::Query as Query>::SqlType>,
170 {
171 CombinationClause::new(Except, Distinct, self, rhs.as_query())
172 }
173
174 fn except_all<Rhs>(self, rhs: Rhs) -> crate::dsl::ExceptAll<Self, Rhs>
175 where
176 Rhs: AsQuery<SqlType = <Self::Query as Query>::SqlType>,
177 {
178 CombinationClause::new(Except, All, self, rhs.as_query())
179 }
180}
181
182impl<Combinator, Rule, Source, Rhs, O, LOf, DB: Backend> QueryFragment<DB>
183 for CombinationClause<Combinator, Rule, Source, Rhs, O, LOf>
184where
185 Combinator: QueryFragment<DB>,
186 Rule: QueryFragment<DB>,
187 ParenthesisWrapper<Source>: QueryFragment<DB>,
188 ParenthesisWrapper<Rhs>: QueryFragment<DB>,
189 O: QueryFragment<DB>,
190 LOf: QueryFragment<DB>,
191 DB: Backend + SupportsCombinationClause<Combinator, Rule> + DieselReserveSpecialization,
192{
193 fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
194 self.source.walk_ast(out.reborrow())?;
195 self.combinator.walk_ast(out.reborrow())?;
196 self.duplicate_rule.walk_ast(out.reborrow())?;
197 self.rhs.walk_ast(out.reborrow())?;
198 self.order.walk_ast(out.reborrow())?;
199 self.limit_offset.walk_ast(out)
200 }
201}
202
203impl<ST, Combinator, Rule, Source, Rhs, O, LOf, RawExpr, Expr> PositionalOrderDsl<RawExpr>
204 for CombinationClause<Combinator, Rule, Source, Rhs, O, LOf>
205where
206 Self: SelectQuery<SqlType = ST>,
207 CombinationClause<Combinator, Rule, Source, Rhs, OrderClause<Expr>, LOf>:
208 SelectQuery<SqlType = ST>,
209 RawExpr: IntoPositionalOrderExpr<Output = Expr>,
210{
211 type Output = CombinationClause<Combinator, Rule, Source, Rhs, OrderClause<Expr>, LOf>;
212
213 fn positional_order_by(self, expr: RawExpr) -> Self::Output {
214 let order = OrderClause(expr.into_positional_expr());
215
216 CombinationClause {
217 combinator: self.combinator,
218 duplicate_rule: self.duplicate_rule,
219 source: self.source,
220 rhs: self.rhs,
221 order,
222 limit_offset: self.limit_offset,
223 }
224 }
225}
226
227#[doc(hidden)]
228type Limit = AsExprOf<i64, BigInt>;
229
230impl<ST, Combinator, Rule, Source, Rhs, O, L, Of> LimitDsl
231 for CombinationClause<Combinator, Rule, Source, Rhs, O, LimitOffsetClause<L, Of>>
232where
233 Self: SelectQuery<SqlType = ST>,
234 CombinationClause<Combinator, Rule, Source, Rhs, O, LimitOffsetClause<LimitClause<Limit>, Of>>:
235 SelectQuery<SqlType = ST>,
236{
237 type Output = CombinationClause<
238 Combinator,
239 Rule,
240 Source,
241 Rhs,
242 O,
243 LimitOffsetClause<LimitClause<Limit>, Of>,
244 >;
245
246 fn limit(self, limit: i64) -> Self::Output {
247 let limit_clause = LimitClause(limit.into_sql::<BigInt>());
248 CombinationClause {
249 combinator: self.combinator,
250 duplicate_rule: self.duplicate_rule,
251 source: self.source,
252 rhs: self.rhs,
253 order: self.order,
254 limit_offset: LimitOffsetClause {
255 limit_clause,
256 offset_clause: self.limit_offset.offset_clause,
257 },
258 }
259 }
260}
261
262#[doc(hidden)]
263type Offset = Limit;
264
265impl<ST, Combinator, Rule, Source, Rhs, O, L, Of> OffsetDsl
266 for CombinationClause<Combinator, Rule, Source, Rhs, O, LimitOffsetClause<L, Of>>
267where
268 Self: SelectQuery<SqlType = ST>,
269 CombinationClause<Combinator, Rule, Source, Rhs, O, LimitOffsetClause<L, OffsetClause<Offset>>>:
270 SelectQuery<SqlType = ST>,
271{
272 type Output = CombinationClause<
273 Combinator,
274 Rule,
275 Source,
276 Rhs,
277 O,
278 LimitOffsetClause<L, OffsetClause<Offset>>,
279 >;
280
281 fn offset(self, offset: i64) -> Self::Output {
282 let offset_clause = OffsetClause(offset.into_sql::<BigInt>());
283 CombinationClause {
284 combinator: self.combinator,
285 duplicate_rule: self.duplicate_rule,
286 source: self.source,
287 rhs: self.rhs,
288 order: self.order,
289 limit_offset: LimitOffsetClause {
290 limit_clause: self.limit_offset.limit_clause,
291 offset_clause,
292 },
293 }
294 }
295}
296
297#[derive(#[automatically_derived]
impl ::core::fmt::Debug for Union {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "Union")
}
}Debug, #[automatically_derived]
impl ::core::marker::Copy for Union { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for Union { }
#[automatically_derived]
impl ::core::clone::Clone for Union {
#[inline]
fn clone(&self) -> Self { *self }
}Clone, const _: () =
{
use diesel;
#[allow(non_camel_case_types)]
impl diesel::query_builder::QueryId for Union {
type QueryId = Union<>;
const HAS_STATIC_QUERY_ID: bool = true;
const IS_WINDOW_FUNCTION: bool = false;
}
};QueryId)]
298pub struct Union;
300
301impl<DB> QueryFragment<DB> for Union
302where
303 DB: Backend + DieselReserveSpecialization,
304{
305 fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
306 out.push_sql(" UNION ");
307 Ok(())
308 }
309}
310
311#[derive(#[automatically_derived]
impl ::core::fmt::Debug for Intersect {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "Intersect")
}
}Debug, #[automatically_derived]
impl ::core::marker::Copy for Intersect { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for Intersect { }
#[automatically_derived]
impl ::core::clone::Clone for Intersect {
#[inline]
fn clone(&self) -> Self { *self }
}Clone, const _: () =
{
use diesel;
#[allow(non_camel_case_types)]
impl diesel::query_builder::QueryId for Intersect {
type QueryId = Intersect<>;
const HAS_STATIC_QUERY_ID: bool = true;
const IS_WINDOW_FUNCTION: bool = false;
}
};QueryId)]
312pub struct Intersect;
314
315impl<DB> QueryFragment<DB> for Intersect
316where
317 DB: Backend + DieselReserveSpecialization,
318{
319 fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
320 out.push_sql(" INTERSECT ");
321 Ok(())
322 }
323}
324
325#[derive(#[automatically_derived]
impl ::core::fmt::Debug for Except {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "Except")
}
}Debug, #[automatically_derived]
impl ::core::marker::Copy for Except { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for Except { }
#[automatically_derived]
impl ::core::clone::Clone for Except {
#[inline]
fn clone(&self) -> Self { *self }
}Clone, const _: () =
{
use diesel;
#[allow(non_camel_case_types)]
impl diesel::query_builder::QueryId for Except {
type QueryId = Except<>;
const HAS_STATIC_QUERY_ID: bool = true;
const IS_WINDOW_FUNCTION: bool = false;
}
};QueryId)]
326pub struct Except;
328
329impl<DB> QueryFragment<DB> for Except
330where
331 DB: Backend + DieselReserveSpecialization,
332{
333 fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
334 out.push_sql(" EXCEPT ");
335 Ok(())
336 }
337}
338
339#[derive(#[automatically_derived]
impl ::core::fmt::Debug for Distinct {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "Distinct")
}
}Debug, #[automatically_derived]
impl ::core::marker::Copy for Distinct { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for Distinct { }
#[automatically_derived]
impl ::core::clone::Clone for Distinct {
#[inline]
fn clone(&self) -> Self { *self }
}Clone, const _: () =
{
use diesel;
#[allow(non_camel_case_types)]
impl diesel::query_builder::QueryId for Distinct {
type QueryId = Distinct<>;
const HAS_STATIC_QUERY_ID: bool = true;
const IS_WINDOW_FUNCTION: bool = false;
}
};QueryId)]
340pub struct Distinct;
342
343impl<DB> QueryFragment<DB> for Distinct
344where
345 DB: Backend + DieselReserveSpecialization,
346{
347 fn walk_ast<'b>(&'b self, _: AstPass<'_, 'b, DB>) -> QueryResult<()> {
348 Ok(())
349 }
350}
351
352#[derive(#[automatically_derived]
impl ::core::fmt::Debug for All {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "All")
}
}Debug, #[automatically_derived]
impl ::core::marker::Copy for All { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for All { }
#[automatically_derived]
impl ::core::clone::Clone for All {
#[inline]
fn clone(&self) -> Self { *self }
}Clone, const _: () =
{
use diesel;
#[allow(non_camel_case_types)]
impl diesel::query_builder::QueryId for All {
type QueryId = All<>;
const HAS_STATIC_QUERY_ID: bool = true;
const IS_WINDOW_FUNCTION: bool = false;
}
};QueryId)]
353pub struct All;
355
356impl<DB> QueryFragment<DB> for All
357where
358 DB: Backend + DieselReserveSpecialization,
359{
360 fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
361 out.push_sql("ALL ");
362 Ok(())
363 }
364}
365
366pub trait SupportsCombinationClause<Combinator, Rule> {}
368
369#[derive(#[automatically_derived]
impl<T: ::core::fmt::Debug> ::core::fmt::Debug for ParenthesisWrapper<T> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f,
"ParenthesisWrapper", "inner", &&self.inner)
}
}Debug, #[automatically_derived]
impl<T: ::core::marker::Copy> ::core::marker::Copy for ParenthesisWrapper<T> {
}Copy, #[automatically_derived]
impl<T: ::core::clone::Clone> ::core::clone::Clone for ParenthesisWrapper<T> {
#[inline]
fn clone(&self) -> Self {
Self { inner: ::core::clone::Clone::clone(&self.inner) }
}
}Clone, const _: () =
{
use diesel;
#[allow(non_camel_case_types)]
impl<T: diesel::query_builder::QueryId> diesel::query_builder::QueryId
for ParenthesisWrapper<T> {
type QueryId =
ParenthesisWrapper<<T as
diesel::query_builder::QueryId>::QueryId>;
const HAS_STATIC_QUERY_ID: bool =
<T as diesel::query_builder::QueryId>::HAS_STATIC_QUERY_ID &&
true;
const IS_WINDOW_FUNCTION: bool =
<T as diesel::query_builder::QueryId>::IS_WINDOW_FUNCTION ||
false;
}
};QueryId)]
370#[doc =
" Wrapper used to wrap rhs sql in parenthesis when supported by backend"]
#[non_exhaustive]
pub struct ParenthesisWrapper<T> {
#[doc = " the inner parenthesis definition"]
#[allow(dead_code)]
pub inner: T,
}#[diesel_derives::__diesel_public_if(
372 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
373 public_fields(inner)
374)]
375pub struct ParenthesisWrapper<T> {
376 #[allow(dead_code)]
378 inner: T,
379}
380
381#[cfg(feature = "postgres_backend")]
382mod postgres {
383 use super::*;
384 use crate::pg::Pg;
385
386 impl<T: QueryFragment<Pg>> QueryFragment<Pg> for ParenthesisWrapper<T> {
387 fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, Pg>) -> QueryResult<()> {
388 out.push_sql("(");
389 self.inner.walk_ast(out.reborrow())?;
390 out.push_sql(")");
391 Ok(())
392 }
393 }
394
395 impl SupportsCombinationClause<Union, Distinct> for Pg {}
396 impl SupportsCombinationClause<Union, All> for Pg {}
397 impl SupportsCombinationClause<Intersect, Distinct> for Pg {}
398 impl SupportsCombinationClause<Intersect, All> for Pg {}
399 impl SupportsCombinationClause<Except, Distinct> for Pg {}
400 impl SupportsCombinationClause<Except, All> for Pg {}
401}
402
403#[cfg(any(feature = "mysql_backend", feature = "mariadb_backend"))]
404mod mysql_like {
405 use super::*;
406 use crate::mysql_like::MysqlLikeBackend;
407
408 impl<DB, T> QueryFragment<DB> for ParenthesisWrapper<T>
409 where
410 DB: MysqlLikeBackend,
411 T: QueryFragment<DB>,
412 {
413 fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
414 out.push_sql("(");
415 self.inner.walk_ast(out.reborrow())?;
416 out.push_sql(")");
417 Ok(())
418 }
419 }
420
421 impl<DB: MysqlLikeBackend> SupportsCombinationClause<Union, Distinct> for DB {}
422 impl<DB: MysqlLikeBackend> SupportsCombinationClause<Union, All> for DB {}
423}
424
425#[cfg(feature = "mariadb_backend")]
426mod mariadb {
427 use super::*;
428 use crate::mariadb::Mariadb;
429
430 impl SupportsCombinationClause<Intersect, Distinct> for Mariadb {}
431 impl SupportsCombinationClause<Intersect, All> for Mariadb {}
432 impl SupportsCombinationClause<Except, Distinct> for Mariadb {}
433 impl SupportsCombinationClause<Except, All> for Mariadb {}
434}
435
436#[cfg(feature = "__sqlite-shared")]
437mod sqlite {
438 use super::*;
439 use crate::sqlite::Sqlite;
440
441 impl<T: QueryFragment<Sqlite>> QueryFragment<Sqlite> for ParenthesisWrapper<T> {
442 fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, Sqlite>) -> QueryResult<()> {
443 out.push_sql("SELECT * FROM (");
447 self.inner.walk_ast(out.reborrow())?;
448 out.push_sql(")");
449 Ok(())
450 }
451 }
452
453 impl SupportsCombinationClause<Union, Distinct> for Sqlite {}
454 impl SupportsCombinationClause<Union, All> for Sqlite {}
455 impl SupportsCombinationClause<Intersect, Distinct> for Sqlite {}
456 impl SupportsCombinationClause<Except, Distinct> for Sqlite {}
457}