diesel/query_builder/
from_clause.rs
1use super::{AstPass, QueryFragment, QueryId};
2use crate::backend::Backend;
3use crate::query_source::AppearsInFromClause;
4use crate::{QueryResult, QuerySource};
5
6#[cfg_attr(
12 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
13 cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")
14)]
15#[derive(Debug, Clone, Copy, QueryId)]
16pub struct NoFromClause;
17
18impl<DB> QueryFragment<DB> for NoFromClause
19where
20 Self: QueryFragment<DB, DB::EmptyFromClauseSyntax>,
21 DB: Backend,
22{
23 fn walk_ast<'b>(&'b self, pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
24 <Self as QueryFragment<DB, DB::EmptyFromClauseSyntax>>::walk_ast(self, pass)
25 }
26}
27
28impl<DB> QueryFragment<DB, crate::backend::sql_dialect::from_clause_syntax::AnsiSqlFromClauseSyntax>
29 for NoFromClause
30where
31 DB: Backend<EmptyFromClauseSyntax = crate::backend::sql_dialect::from_clause_syntax::AnsiSqlFromClauseSyntax>,
32{
33 fn walk_ast<'b>(&'b self, _pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
34 Ok(())
35 }
36}
37
38pub trait AsQuerySource {
39 type QuerySource: QuerySource;
40
41 fn as_query_source(&self) -> &Self::QuerySource;
42}
43
44impl<QS> AsQuerySource for QS
45where
46 QS: QuerySource,
47{
48 type QuerySource = Self;
49
50 fn as_query_source(&self) -> &Self::QuerySource {
51 self
52 }
53}
54
55#[doc(hidden)]
56pub struct FromClause<F: QuerySource> {
57 pub(crate) source: F,
58 pub(crate) from_clause: F::FromClause,
59}
60
61impl<F> AsQuerySource for FromClause<F>
62where
63 F: QuerySource,
64{
65 type QuerySource = F;
66
67 fn as_query_source(&self) -> &Self::QuerySource {
68 &self.source
69 }
70}
71
72impl<F> QueryId for FromClause<F>
73where
74 F: QuerySource + QueryId,
75{
76 type QueryId = F::QueryId;
77
78 const HAS_STATIC_QUERY_ID: bool = F::HAS_STATIC_QUERY_ID;
79}
80
81impl<F> Copy for FromClause<F>
82where
83 F: QuerySource + Copy,
84 F::FromClause: Copy,
85{
86}
87
88impl<F> Clone for FromClause<F>
89where
90 F: QuerySource + Clone,
91 F::FromClause: Clone,
92{
93 fn clone(&self) -> Self {
94 Self {
95 source: self.source.clone(),
96 from_clause: self.from_clause.clone(),
97 }
98 }
99}
100
101impl<F> std::fmt::Debug for FromClause<F>
102where
103 F: QuerySource,
104 F::FromClause: std::fmt::Debug,
105{
106 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
107 f.debug_struct("FromClause")
108 .field("from_clause", &self.from_clause)
109 .finish()
110 }
111}
112
113impl<F: QuerySource> FromClause<F> {
114 pub(crate) fn new(qs: F) -> Self {
115 Self {
116 from_clause: qs.from_clause(),
117 source: qs,
118 }
119 }
120}
121
122impl<DB, F> QueryFragment<DB> for FromClause<F>
123where
124 F: QuerySource,
125 DB: Backend,
126 F::FromClause: QueryFragment<DB>,
127{
128 fn walk_ast<'b>(&'b self, mut pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
129 pass.push_sql(" FROM ");
130 self.from_clause.walk_ast(pass)
131 }
132}
133
134impl<QS1, QS2> AppearsInFromClause<QS1> for FromClause<QS2>
135where
136 QS1: QuerySource,
137 QS2: QuerySource,
138 QS2: AppearsInFromClause<QS1>,
139{
140 type Count = <QS2 as AppearsInFromClause<QS1>>::Count;
141}