diesel/expression/
subselect.rs1use core::marker::PhantomData;
2
3use crate::expression::array_comparison::InExpression;
4use crate::expression::*;
5use crate::query_builder::*;
6use crate::query_source::{Never, Once};
7use crate::result::QueryResult;
8
9#[derive(#[automatically_derived]
impl<T: ::core::fmt::Debug, ST: ::core::fmt::Debug> ::core::fmt::Debug for
Subselect<T, ST> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f, "Subselect",
"values", &self.values, "_sql_type", &&self._sql_type)
}
}Debug, #[automatically_derived]
impl<T: ::core::marker::Copy, ST: ::core::marker::Copy> ::core::marker::Copy
for Subselect<T, ST> {
}Copy, #[automatically_derived]
impl<T: ::core::clone::Clone, ST: ::core::clone::Clone> ::core::clone::Clone
for Subselect<T, ST> {
#[inline]
fn clone(&self) -> Self {
Self {
values: ::core::clone::Clone::clone(&self.values),
_sql_type: ::core::clone::Clone::clone(&self._sql_type),
}
}
}Clone, const _: () =
{
use diesel;
#[allow(non_camel_case_types)]
impl<T: diesel::query_builder::QueryId,
ST: diesel::query_builder::QueryId> diesel::query_builder::QueryId
for Subselect<T, ST> {
type QueryId =
Subselect<<T as diesel::query_builder::QueryId>::QueryId,
<ST as diesel::query_builder::QueryId>::QueryId>;
const HAS_STATIC_QUERY_ID: bool =
<T as diesel::query_builder::QueryId>::HAS_STATIC_QUERY_ID &&
<ST as diesel::query_builder::QueryId>::HAS_STATIC_QUERY_ID
&& true;
const IS_WINDOW_FUNCTION: bool =
<T as diesel::query_builder::QueryId>::IS_WINDOW_FUNCTION ||
<ST as diesel::query_builder::QueryId>::IS_WINDOW_FUNCTION
|| false;
}
};QueryId)]
19pub struct Subselect<T, ST> {
20 values: T,
21 _sql_type: PhantomData<ST>,
22}
23
24impl<T, ST> Subselect<T, ST> {
25 pub(crate) fn new(values: T) -> Self {
26 Self {
27 values,
28 _sql_type: PhantomData,
29 }
30 }
31}
32
33impl<T: SelectQuery, ST> Expression for Subselect<T, ST>
34where
35 ST: SqlType + TypedExpressionType,
36{
37 type SqlType = ST;
39}
40
41impl<T, ST: SqlType> InExpression for Subselect<T, ST> {
42 type SqlType = ST;
43 fn is_empty(&self) -> bool {
44 false
45 }
46 fn is_array(&self) -> bool {
47 false
48 }
49}
50
51impl<T, ST, QS> SelectableExpression<QS> for Subselect<T, ST>
52where
53 Subselect<T, ST>: AppearsOnTable<QS>,
54 T: ValidSubselect<QS>,
55{
56}
57
58impl<T, ST, QS> AppearsOnTable<QS> for Subselect<T, ST>
59where
60 Subselect<T, ST>: Expression,
61 T: ValidSubselect<QS>,
62{
63}
64
65impl<T, ST, GB> ValidGrouping<GB> for Subselect<T, ST>
66where
67 T: ValidSubselectGrouping<GB>,
68{
69 type IsAggregate = T::IsAggregate;
70}
71
72impl<T, ST, DB> QueryFragment<DB> for Subselect<T, ST>
73where
74 DB: Backend,
75 T: QueryFragment<DB>,
76{
77 fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
78 self.values.walk_ast(out.reborrow())?;
79 Ok(())
80 }
81}
82
83pub trait ValidSubselect<QS> {}
84
85#[diagnostic::on_unimplemented(
86 message = "`{Self}` cannot be used as a subselect",
87 note = "only select statements and their combinations can be used as subselects"
88)]
89pub trait ValidSubselectGrouping<GB> {
90 type IsAggregate;
91}
92
93#[derive(#[automatically_derived]
impl<GB: ::core::fmt::Debug, From: ::core::fmt::Debug> ::core::fmt::Debug for
SubselectGroupBy<GB, From> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"SubselectGroupBy", &&self.0)
}
}Debug, #[automatically_derived]
impl<GB: ::core::clone::Clone, From: ::core::clone::Clone>
::core::clone::Clone for SubselectGroupBy<GB, From> {
#[inline]
fn clone(&self) -> Self { Self(::core::clone::Clone::clone(&self.0)) }
}Clone, #[automatically_derived]
impl<GB: ::core::marker::Copy, From: ::core::marker::Copy>
::core::marker::Copy for SubselectGroupBy<GB, From> {
}Copy)]
95pub struct SubselectGroupBy<GB, From>(PhantomData<(GB, From)>);
96
97pub trait SubselectFieldGrouping<Field, GB> {
99 type IsAggregate;
101}
102
103impl<Field, GB> SubselectFieldGrouping<Field, GB> for Once {
104 type IsAggregate = is_aggregate::Never;
105}
106
107impl<Field, GB> SubselectFieldGrouping<Field, GB> for Never
108where
109 Field: ValidGrouping<GB>,
110{
111 type IsAggregate = Field::IsAggregate;
112}