1//! Types which represent various database backends
23use crate::query_builder::QueryBuilder;
4use crate::sql_types::{self, HasSqlType, TypeMetadata};
56#[cfg_attr(
7 not(any(
8 feature = "postgres_backend",
9 feature = "mysql_backend",
10 feature = "sqlite",
11 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
12)),
13 allow(unused_imports)
14)]
15#[doc(inline)]
16#[doc(inline)]
pub use self::private::{DieselReserveSpecialization, TrustedBackend};#[diesel_derives::__diesel_public_if(
17 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
18)]19pub(crate) use self::private::{DieselReserveSpecialization, TrustedBackend};
2021/// A database backend
22///
23/// This trait represents the concept of a backend (e.g. "MySQL" vs "SQLite").
24/// It is separate from a [`Connection`](crate::connection::Connection)
25/// to that backend.
26/// One backend may have multiple concrete connection implementations.
27///
28/// # Implementing a custom backend
29///
30/// Implementing a custom backend requires enabling the
31/// `i-implement-a-third-party-backend-and-opt-into-breaking-changes` crate feature
32/// to get access to all necessary type and trait implementations.
33///
34/// Implementations of this trait should not assume details about how the
35/// connection is implemented.
36/// For example, the `Pg` backend does not assume that `libpq` is being used.
37/// Implementations of this trait can and should care about details of the wire
38/// protocol used to communicate with the database.
39///
40/// Implementing support for a new backend is a complex topic and depends on the
41/// details how the newly implemented backend may communicate with diesel. As of this,
42/// we cannot provide concrete examples here and only present a general outline of
43/// the required steps. Existing backend implementations provide a good starting point
44/// to see how certain things are solved for other backend implementations.
45///
46/// Types implementing `Backend` should generally be zero sized structs.
47///
48/// To implement the `Backend` trait, you need to:
49///
50/// * Specify how a query should be build from string parts by providing a [`QueryBuilder`]
51/// matching your backend
52/// * Specify the bind value format used by your database connection library by providing
53/// a [`BindCollector`](crate::query_builder::bind_collector::BindCollector) matching your backend
54/// * Specify how values are received from the database by providing a corresponding raw value
55/// definition
56/// * Control sql dialect specific parts of diesels query dsl implementation by providing a
57/// matching [`SqlDialect`] implementation
58/// * Implement [`TypeMetadata`] to specify how your backend identifies types
59/// * Specify support for common datatypes by implementing [`HasSqlType`] for the following sql types:
60/// + [`SmallInt`](sql_types::SmallInt)
61/// + [`Integer`](sql_types::Integer)
62/// + [`BigInt`](sql_types::BigInt)
63/// + [`Float`](sql_types::Float)
64/// + [`Double`](sql_types::Double)
65/// + [`Text`](sql_types::Text)
66/// + [`Binary`](sql_types::Binary)
67/// + [`Date`](sql_types::Date)
68/// + [`Time`](sql_types::Time)
69/// + [`Timestamp`](sql_types::Timestamp)
70///
71/// Additionally to the listed required trait bounds you may want to implement
72#[cfg_attr(
73 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
74 doc = "[`DieselReserveSpecialization`]"
75)]
76#[cfg_attr(
77 not(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"),
78 doc = "`DieselReserveSpecialization`"
79)]
80/// to opt in existing wild card [`QueryFragment`] impls for large parts of the dsl.
81///
82/// [`QueryFragment`]: crate::query_builder::QueryFragment
83pub trait Backend84where
85Self: Sized + SqlDialect + TypeMetadata,
86Self: HasSqlType<sql_types::SmallInt>,
87Self: HasSqlType<sql_types::Integer>,
88Self: HasSqlType<sql_types::BigInt>,
89Self: HasSqlType<sql_types::Float>,
90Self: HasSqlType<sql_types::Double>,
91Self: HasSqlType<sql_types::Text>,
92Self: HasSqlType<sql_types::Binary>,
93Self: HasSqlType<sql_types::Date>,
94Self: HasSqlType<sql_types::Time>,
95Self: HasSqlType<sql_types::Timestamp>,
96{
97/// The concrete [`QueryBuilder`] implementation for this backend.
98type QueryBuilder: QueryBuilder<Self>;
99100/// The actual type given to [`FromSql`], with lifetimes applied. This type
101 /// should not be used directly.
102 ///
103 /// [`FromSql`]: crate::deserialize::FromSql
104type RawValue<'a>;
105106/// The concrete [`BindCollector`](crate::query_builder::bind_collector::BindCollector)
107 /// implementation for this backend.
108 ///
109 /// Most backends should use [`RawBytesBindCollector`].
110 ///
111 /// [`RawBytesBindCollector`]: crate::query_builder::bind_collector::RawBytesBindCollector
112type BindCollector<'a>: crate::query_builder::bind_collector::BindCollector<'a, Self> + 'a;
113}
114115#[doc(hidden)]
116#[cfg(all(feature = "with-deprecated", not(feature = "without-deprecated")))]
117#[deprecated(note = "Use `Backend::RawValue` directly")]
118pub type RawValue<'a, DB> = <DB as Backend>::RawValue<'a>;
119120#[doc(hidden)]
121#[cfg(all(feature = "with-deprecated", not(feature = "without-deprecated")))]
122#[deprecated(note = "Use `Backend::BindCollector` directly")]
123pub type BindCollector<'a, DB> = <DB as Backend>::BindCollector<'a>;
124125/// This trait provides various options to configure the
126/// generated SQL for a specific backend.
127///
128/// Accessing anything from this trait is considered to be part of the
129/// public API. Implementing this trait is not considered to be part of
130/// diesel's public API, as future versions of diesel may add additional
131/// associated constants here.
132///
133/// Each associated type is used to configure the behaviour
134/// of one or more [`QueryFragment`](crate::query_builder::QueryFragment)
135/// implementations by providing
136/// a custom `QueryFragment<YourBackend, YourSpecialSyntaxType>` implementation
137/// to specialize on generic `QueryFragment<DB, DB::AssociatedType>` implementations.
138#[cfg_attr(
139 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
140 doc = "See the [`sql_dialect`] module for options provided by diesel out of the box."
141)]
142pub trait SqlDialect: self::private::TrustedBackend {
143/// Configures how this backend supports `RETURNING` clauses
144 ///
145 /// This allows backends to opt in `RETURNING` clause support and to
146 /// provide a custom [`QueryFragment`](crate::query_builder::QueryFragment)
147#[cfg_attr(
148 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
149 doc = "implementation for [`ReturningClause`](crate::query_builder::ReturningClause)"
150)]
151 #[cfg_attr(
152 not(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"),
153 doc = "implementation for `ReturningClause`"
154)]
155///
156#[cfg_attr(
157 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
158 doc = "See [`sql_dialect::returning_clause`] for provided default implementations"
159)]
160type ReturningClause;
161/// Configures how this backend supports `ON CONFLICT` clauses
162 ///
163 /// This allows backends to opt in `ON CONFLICT` clause support
164#[cfg_attr(
165 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
166 doc = "See [`sql_dialect::on_conflict_clause`] for provided default implementations"
167)]
168type OnConflictClause;
169/// Configures how this backend handles the bare `DEFAULT` keyword for
170 /// inserting the default value in a `INSERT INTO` `VALUES` clause
171 ///
172 /// This allows backends to opt in support for `DEFAULT` value expressions
173 /// for insert statements
174#[cfg_attr(
175 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
176 doc = "See [`sql_dialect::default_keyword_for_insert`] for provided default implementations"
177)]
178type InsertWithDefaultKeyword;
179/// Configures how this backend handles Batch insert statements
180 ///
181 /// This allows backends to provide a custom [`QueryFragment`](crate::query_builder::QueryFragment)
182#[cfg_attr(
183 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
184 doc = "implementation for [`BatchInsert`](crate::query_builder::BatchInsert)"
185)]
186 #[cfg_attr(
187 not(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"),
188 doc = "implementation for `BatchInsert`"
189)]
190///
191#[cfg_attr(
192 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
193 doc = "See [`sql_dialect::batch_insert_support`] for provided default implementations"
194)]
195type BatchInsertSupport;
196/// Configures how this backend handles the Concat clauses in
197 /// select statements.
198 ///
199 /// This allows backends to provide a custom [`QueryFragment`](crate::query_builder::QueryFragment)
200#[cfg_attr(
201 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
202 doc = "implementation for [`Concat`](crate::expression::Concat)"
203)]
204 #[cfg_attr(
205 not(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"),
206 doc = "implementation for `Concat`"
207)]
208///
209#[cfg_attr(
210 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
211 doc = "See [`sql_dialect::concat_clause`] for provided default implementations"
212)]
213type ConcatClause;
214/// Configures how this backend handles the `DEFAULT VALUES` clause for
215 /// insert statements.
216 ///
217 /// This allows backends to provide a custom [`QueryFragment`](crate::query_builder::QueryFragment)
218#[cfg_attr(
219 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
220 doc = "implementation for [`DefaultValues`](crate::query_builder::DefaultValues)"
221)]
222 #[cfg_attr(
223 not(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"),
224 doc = "implementation for `DefaultValues`"
225)]
226///
227#[cfg_attr(
228 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
229 doc = "See [`sql_dialect::default_value_clause`] for provided default implementations"
230)]
231type DefaultValueClauseForInsert;
232/// Configures how this backend handles empty `FROM` clauses for select statements.
233 ///
234 /// This allows backends to provide a custom [`QueryFragment`](crate::query_builder::QueryFragment)
235#[cfg_attr(
236 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
237 doc = "implementation for [`NoFromClause`](crate::query_builder::NoFromClause)"
238)]
239 #[cfg_attr(
240 not(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"),
241 doc = "implementation for `NoFromClause`"
242)]
243///
244#[cfg_attr(
245 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
246 doc = "See [`sql_dialect::from_clause_syntax`] for provided default implementations"
247)]
248type EmptyFromClauseSyntax;
249/// Configures how this backend handles `EXISTS()` expressions.
250 ///
251 /// This allows backends to provide a custom [`QueryFragment`](crate::query_builder::QueryFragment)
252#[cfg_attr(
253 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
254 doc = "implementation for [`Exists`](crate::expression::exists::Exists)"
255)]
256 #[cfg_attr(
257 not(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"),
258 doc = "implementation for `Exists`"
259)]
260///
261#[cfg_attr(
262 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
263 doc = "See [`sql_dialect::exists_syntax`] for provided default implementations"
264)]
265type ExistsSyntax;
266267/// Configures how this backend handles `IN()` and `NOT IN()` expressions.
268 ///
269 /// This allows backends to provide custom [`QueryFragment`](crate::query_builder::QueryFragment)
270#[cfg_attr(
271 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
272 doc = "implementations for [`In`](crate::expression::array_comparison::In),
273 [`NotIn`](crate::expression::array_comparison::NotIn) and
274 [`Many`](crate::expression::array_comparison::Many)"
275)]
276 #[cfg_attr(
277 not(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"),
278 doc = "implementations for `In`, `NotIn` and `Many`"
279)]
280///
281#[cfg_attr(
282 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
283 doc = "See [`sql_dialect::array_comparison`] for provided default implementations"
284)]
285type ArrayComparison;
286287/// Configures how this backend structures `SELECT` queries
288 ///
289 /// This allows backends to provide custom [`QueryFragment`](crate::query_builder::QueryFragment)
290 /// implementations for
291#[cfg_attr(
292 not(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"),
293 doc = "`SelectStatement` and `BoxedSelectStatement`"
294)]
295 #[cfg_attr(
296 not(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"),
297 doc = "[`SelectStatement`](crate::query_builder::SelectStatement) and
298 [`BoxedSelectStatement`](crate::query_builder::BoxedSelectStatement)"
299)]
300///
301#[cfg_attr(
302 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
303 doc = "See [`sql_dialect::select_statement_syntax`] for provided default implementations"
304)]
305type SelectStatementSyntax;
306307/// Configures how this backend structures `SELECT` queries
308 ///
309 /// This allows backends to provide custom [`QueryFragment`](crate::query_builder::QueryFragment)
310 /// implementations for [`Alias<T>`](crate::query_source::Alias)
311#[cfg_attr(
312 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
313 doc = "See [`sql_dialect::alias_syntax`] for provided default implementations"
314)]
315type AliasSyntax;
316317/// Configures how this backend support the `GROUP` frame unit for window functions
318#[cfg_attr(
319 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
320 doc = "See [`sql_dialect::window_frame_clause_group_support`] for provided default implementations"
321)]
322type WindowFrameClauseGroupSupport;
323324/// Configures how this backend supports frame exclusion clauses
325#[cfg_attr(
326 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
327 doc = "See [`sql_dialect::window_frame_exclusion_support`] for provided default implementations"
328)]
329type WindowFrameExclusionSupport;
330331/// Configures how this backend supports aggregate function expressions
332#[cfg_attr(
333 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
334 doc = "See [`sql_dialect::window_frame_clause_group_support`] for provided default implementations"
335)]
336type AggregateFunctionExpressions;
337338/// Configures whether built-in window functions require order clauses for this backend or not
339#[cfg_attr(
340 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
341 doc = "See [`sql_dialect::built_in_window_function_require_order`] for provided default implementations"
342)]
343type BuiltInWindowFunctionRequireOrder;
344}
345346/// This module contains all options provided by diesel to configure the [`SqlDialect`] trait.
347// This module is only public behind the unstable feature flag, as we may want to change SqlDialect
348// implementations of existing backends because of:
349// * The backend gained support for previously unsupported SQL operations
350// * The backend fixed/introduced a bug that requires special handling
351// * We got some edge case wrong with sharing the implementation between backends
352//
353// By not exposing these types publicly we are able to change the exact definitions later on
354// as users cannot write trait bounds that ensure that a specific type is used in place of
355// an existing associated type.
356#[doc =
" This module contains all options provided by diesel to configure the [`SqlDialect`] trait."]
pub mod sql_dialect {
use super::SqlDialect;
#[doc = " This module contains all diesel provided reusable options to"]
#[doc = " configure [`SqlDialect::OnConflictClause`]"]
pub mod on_conflict_clause {
/// A marker trait indicating if a `ON CONFLICT` clause is supported or not
///
/// If you use a custom type to specify specialized support for `ON CONFLICT` clauses
/// implementing this trait opts into reusing diesels existing `ON CONFLICT`
/// `QueryFragment` implementations
pub trait SupportsOnConflictClause { }
/// A marker trait indicating if a `ON CONFLICT (...) DO UPDATE ... [WHERE ...]` clause is supported or not
pub trait SupportsOnConflictClauseWhere { }
/// A marker trait indicating whether the on conflict clause implementation
/// is mostly like postgresql
pub trait PgLikeOnConflictClause: SupportsOnConflictClause { }
/// This marker type indicates that `ON CONFLICT` clauses are not supported for this backend
pub struct DoesNotSupportOnConflictClause;
#[automatically_derived]
impl ::core::fmt::Debug for DoesNotSupportOnConflictClause {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter)
-> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
"DoesNotSupportOnConflictClause")
}
}
#[automatically_derived]
impl ::core::marker::Copy for DoesNotSupportOnConflictClause { }
#[automatically_derived]
impl ::core::clone::Clone for DoesNotSupportOnConflictClause {
#[inline]
fn clone(&self) -> DoesNotSupportOnConflictClause { *self }
}
}
#[doc = " This module contains all reusable options to configure"]
#[doc = " [`SqlDialect::ReturningClause`]"]
pub mod returning_clause {
/// A marker trait indicating if a `RETURNING` clause is supported or not
///
/// If you use a custom type to specify specialized support for `RETURNING` clauses
/// implementing this trait opts in supporting `RETURNING` clause syntax
pub trait SupportsReturningClause { }
/// Indicates that a backend provides support for `RETURNING` clauses
/// using the postgresql `RETURNING` syntax
pub struct PgLikeReturningClause;
#[automatically_derived]
impl ::core::fmt::Debug for PgLikeReturningClause {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter)
-> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "PgLikeReturningClause")
}
}
#[automatically_derived]
impl ::core::marker::Copy for PgLikeReturningClause { }
#[automatically_derived]
impl ::core::clone::Clone for PgLikeReturningClause {
#[inline]
fn clone(&self) -> PgLikeReturningClause { *self }
}
/// Indicates that a backend does not support `RETURNING` clauses
pub struct DoesNotSupportReturningClause;
#[automatically_derived]
impl ::core::fmt::Debug for DoesNotSupportReturningClause {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter)
-> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
"DoesNotSupportReturningClause")
}
}
#[automatically_derived]
impl ::core::marker::Copy for DoesNotSupportReturningClause { }
#[automatically_derived]
impl ::core::clone::Clone for DoesNotSupportReturningClause {
#[inline]
fn clone(&self) -> DoesNotSupportReturningClause { *self }
}
impl SupportsReturningClause for PgLikeReturningClause {}
}
#[doc = " This module contains all reusable options to configure"]
#[doc = " [`SqlDialect::InsertWithDefaultKeyword`]"]
pub mod default_keyword_for_insert {
/// A marker trait indicating if a `DEFAULT` like expression
/// is supported as part of `INSERT INTO` clauses to indicate
/// that a default value should be inserted at a specific position
///
/// If you use a custom type to specify specialized support for `DEFAULT`
/// expressions implementing this trait opts in support for `DEFAULT`
/// value expressions for inserts. Otherwise diesel will emulate this
/// behaviour.
pub trait SupportsDefaultKeyword { }
/// Indicates that a backend support `DEFAULT` value expressions
/// for `INSERT INTO` statements based on the ISO SQL standard
pub struct IsoSqlDefaultKeyword;
#[automatically_derived]
impl ::core::fmt::Debug for IsoSqlDefaultKeyword {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter)
-> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "IsoSqlDefaultKeyword")
}
}
#[automatically_derived]
impl ::core::marker::Copy for IsoSqlDefaultKeyword { }
#[automatically_derived]
impl ::core::clone::Clone for IsoSqlDefaultKeyword {
#[inline]
fn clone(&self) -> IsoSqlDefaultKeyword { *self }
}
/// Indicates that a backend does not support `DEFAULT` value
/// expressions for `INSERT INTO` statements
pub struct DoesNotSupportDefaultKeyword;
#[automatically_derived]
impl ::core::fmt::Debug for DoesNotSupportDefaultKeyword {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter)
-> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
"DoesNotSupportDefaultKeyword")
}
}
#[automatically_derived]
impl ::core::marker::Copy for DoesNotSupportDefaultKeyword { }
#[automatically_derived]
impl ::core::clone::Clone for DoesNotSupportDefaultKeyword {
#[inline]
fn clone(&self) -> DoesNotSupportDefaultKeyword { *self }
}
impl SupportsDefaultKeyword for IsoSqlDefaultKeyword {}
}
#[doc = " This module contains all reusable options to configure"]
#[doc = " [`SqlDialect::BatchInsertSupport`]"]
pub mod batch_insert_support {
/// A marker trait indicating if batch insert statements
/// are supported for this backend or not
pub trait SupportsBatchInsert { }
/// Indicates that this backend does not support batch
/// insert statements.
/// In this case diesel will emulate batch insert support
/// by inserting each row on its own
pub struct DoesNotSupportBatchInsert;
#[automatically_derived]
impl ::core::fmt::Debug for DoesNotSupportBatchInsert {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter)
-> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
"DoesNotSupportBatchInsert")
}
}
#[automatically_derived]
impl ::core::marker::Copy for DoesNotSupportBatchInsert { }
#[automatically_derived]
impl ::core::clone::Clone for DoesNotSupportBatchInsert {
#[inline]
fn clone(&self) -> DoesNotSupportBatchInsert { *self }
}
/// Indicates that this backend supports postgres style
/// batch insert statements to insert multiple rows using one
/// insert statement
pub struct PostgresLikeBatchInsertSupport;
#[automatically_derived]
impl ::core::fmt::Debug for PostgresLikeBatchInsertSupport {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter)
-> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
"PostgresLikeBatchInsertSupport")
}
}
#[automatically_derived]
impl ::core::marker::Copy for PostgresLikeBatchInsertSupport { }
#[automatically_derived]
impl ::core::clone::Clone for PostgresLikeBatchInsertSupport {
#[inline]
fn clone(&self) -> PostgresLikeBatchInsertSupport { *self }
}
impl SupportsBatchInsert for PostgresLikeBatchInsertSupport {}
}
#[doc = " This module contains all reusable options to configure"]
#[doc = " [`SqlDialect::ConcatClause`]"]
pub mod concat_clause {
/// Indicates that this backend uses the
/// `||` operator to select a concatenation
/// of two variables or strings
pub struct ConcatWithPipesClause;
#[automatically_derived]
impl ::core::fmt::Debug for ConcatWithPipesClause {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter)
-> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "ConcatWithPipesClause")
}
}
#[automatically_derived]
impl ::core::clone::Clone for ConcatWithPipesClause {
#[inline]
fn clone(&self) -> ConcatWithPipesClause { *self }
}
#[automatically_derived]
impl ::core::marker::Copy for ConcatWithPipesClause { }
}
#[doc = " This module contains all reusable options to configure"]
#[doc = " [`SqlDialect::DefaultValueClauseForInsert`]"]
pub mod default_value_clause {
/// Indicates that this backend uses the
/// `DEFAULT VALUES` syntax to specify
/// that a row consisting only of default
/// values should be inserted
pub struct AnsiDefaultValueClause;
#[automatically_derived]
impl ::core::fmt::Debug for AnsiDefaultValueClause {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter)
-> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "AnsiDefaultValueClause")
}
}
#[automatically_derived]
impl ::core::clone::Clone for AnsiDefaultValueClause {
#[inline]
fn clone(&self) -> AnsiDefaultValueClause { *self }
}
#[automatically_derived]
impl ::core::marker::Copy for AnsiDefaultValueClause { }
}
#[doc = " This module contains all reusable options to configure"]
#[doc = " [`SqlDialect::EmptyFromClauseSyntax`]"]
pub mod from_clause_syntax {
/// Indicates that this backend skips
/// the `FROM` clause in `SELECT` statements
/// if no table/view is queried
pub struct AnsiSqlFromClauseSyntax;
#[automatically_derived]
impl ::core::fmt::Debug for AnsiSqlFromClauseSyntax {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter)
-> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
"AnsiSqlFromClauseSyntax")
}
}
#[automatically_derived]
impl ::core::marker::Copy for AnsiSqlFromClauseSyntax { }
#[automatically_derived]
impl ::core::clone::Clone for AnsiSqlFromClauseSyntax {
#[inline]
fn clone(&self) -> AnsiSqlFromClauseSyntax { *self }
}
}
#[doc = " This module contains all reusable options to configure"]
#[doc = " [`SqlDialect::ExistsSyntax`]"]
pub mod exists_syntax {
/// Indicates that this backend
/// treats `EXIST()` as function
/// like expression
pub struct AnsiSqlExistsSyntax;
#[automatically_derived]
impl ::core::fmt::Debug for AnsiSqlExistsSyntax {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter)
-> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "AnsiSqlExistsSyntax")
}
}
#[automatically_derived]
impl ::core::marker::Copy for AnsiSqlExistsSyntax { }
#[automatically_derived]
impl ::core::clone::Clone for AnsiSqlExistsSyntax {
#[inline]
fn clone(&self) -> AnsiSqlExistsSyntax { *self }
}
}
#[doc = " This module contains all reusable options to configure"]
#[doc = " [`SqlDialect::ArrayComparison`]"]
pub mod array_comparison {
/// Indicates that this backend requires a single bind
/// per array element in `IN()` and `NOT IN()` expression
pub struct AnsiSqlArrayComparison;
#[automatically_derived]
impl ::core::fmt::Debug for AnsiSqlArrayComparison {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter)
-> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "AnsiSqlArrayComparison")
}
}
#[automatically_derived]
impl ::core::marker::Copy for AnsiSqlArrayComparison { }
#[automatically_derived]
impl ::core::clone::Clone for AnsiSqlArrayComparison {
#[inline]
fn clone(&self) -> AnsiSqlArrayComparison { *self }
}
}
#[doc = " This module contains all reusable options to configure"]
#[doc = " [`SqlDialect::SelectStatementSyntax`]"]
pub mod select_statement_syntax {
/// Indicates that this backend uses the default
/// ANSI select statement structure
pub struct AnsiSqlSelectStatement;
#[automatically_derived]
impl ::core::fmt::Debug for AnsiSqlSelectStatement {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter)
-> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "AnsiSqlSelectStatement")
}
}
#[automatically_derived]
impl ::core::marker::Copy for AnsiSqlSelectStatement { }
#[automatically_derived]
impl ::core::clone::Clone for AnsiSqlSelectStatement {
#[inline]
fn clone(&self) -> AnsiSqlSelectStatement { *self }
}
}
#[doc = " This module contains all reusable options to configure"]
#[doc = " [`SqlDialect::AliasSyntax`]"]
pub mod alias_syntax {
/// Indicates that this backend uses `table AS alias` for
/// defining table aliases
pub struct AsAliasSyntax;
#[automatically_derived]
impl ::core::fmt::Debug for AsAliasSyntax {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter)
-> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "AsAliasSyntax")
}
}
#[automatically_derived]
impl ::core::marker::Copy for AsAliasSyntax { }
#[automatically_derived]
impl ::core::clone::Clone for AsAliasSyntax {
#[inline]
fn clone(&self) -> AsAliasSyntax { *self }
}
}
#[doc =
" This module contains all reusable options to configure [`SqlDialect::WindowFrameClauseGroupSupport`]"]
pub mod window_frame_clause_group_support {
/// Indicates that this backend does not support the `GROUPS` frame unit
pub struct NoGroupWindowFrameUnit;
#[automatically_derived]
impl ::core::fmt::Debug for NoGroupWindowFrameUnit {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter)
-> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "NoGroupWindowFrameUnit")
}
}
#[automatically_derived]
impl ::core::marker::Copy for NoGroupWindowFrameUnit { }
#[automatically_derived]
impl ::core::clone::Clone for NoGroupWindowFrameUnit {
#[inline]
fn clone(&self) -> NoGroupWindowFrameUnit { *self }
}
/// Indicates that this backend does support the `GROUPS` frame unit as specified by the standard
pub struct IsoGroupWindowFrameUnit;
#[automatically_derived]
impl ::core::fmt::Debug for IsoGroupWindowFrameUnit {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter)
-> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
"IsoGroupWindowFrameUnit")
}
}
#[automatically_derived]
impl ::core::marker::Copy for IsoGroupWindowFrameUnit { }
#[automatically_derived]
impl ::core::clone::Clone for IsoGroupWindowFrameUnit {
#[inline]
fn clone(&self) -> IsoGroupWindowFrameUnit { *self }
}
}
#[doc =
" This module contains all reusable options to configure [`SqlDialect::AggregateFunctionExpressions`]"]
pub mod aggregate_function_expressions {
/// Indicates that this backend does not support aggregate function expressions
pub struct NoAggregateFunctionExpressions;
#[automatically_derived]
impl ::core::fmt::Debug for NoAggregateFunctionExpressions {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter)
-> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
"NoAggregateFunctionExpressions")
}
}
#[automatically_derived]
impl ::core::marker::Copy for NoAggregateFunctionExpressions { }
#[automatically_derived]
impl ::core::clone::Clone for NoAggregateFunctionExpressions {
#[inline]
fn clone(&self) -> NoAggregateFunctionExpressions { *self }
}
/// Indicates that this backend supports aggregate function expressions similar to PostgreSQL
pub struct PostgresLikeAggregateFunctionExpressions;
#[automatically_derived]
impl ::core::fmt::Debug for PostgresLikeAggregateFunctionExpressions {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter)
-> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
"PostgresLikeAggregateFunctionExpressions")
}
}
#[automatically_derived]
impl ::core::marker::Copy for PostgresLikeAggregateFunctionExpressions
{
}
#[automatically_derived]
impl ::core::clone::Clone for PostgresLikeAggregateFunctionExpressions
{
#[inline]
fn clone(&self) -> PostgresLikeAggregateFunctionExpressions {
*self
}
}
}
#[doc =
" This module contains all reusable options to configure [`SqlDialect::WindowFrameExclusionSupport`]"]
pub mod window_frame_exclusion_support {
/// Indicates that this backend support frame exclusion clauses
/// for window functions
pub struct FrameExclusionSupport;
#[automatically_derived]
impl ::core::fmt::Debug for FrameExclusionSupport {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter)
-> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "FrameExclusionSupport")
}
}
#[automatically_derived]
impl ::core::marker::Copy for FrameExclusionSupport { }
#[automatically_derived]
impl ::core::clone::Clone for FrameExclusionSupport {
#[inline]
fn clone(&self) -> FrameExclusionSupport { *self }
}
/// Indicates that this backend does not support frame exclusion clauses
/// for window functions
pub struct NoFrameFrameExclusionSupport;
#[automatically_derived]
impl ::core::fmt::Debug for NoFrameFrameExclusionSupport {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter)
-> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
"NoFrameFrameExclusionSupport")
}
}
#[automatically_derived]
impl ::core::marker::Copy for NoFrameFrameExclusionSupport { }
#[automatically_derived]
impl ::core::clone::Clone for NoFrameFrameExclusionSupport {
#[inline]
fn clone(&self) -> NoFrameFrameExclusionSupport { *self }
}
}
#[doc =
" This module contains all reusable options to configure [`SqlDialect::BuiltInWindowFunctionRequireOrder`]"]
pub mod built_in_window_function_require_order {
/// Indicates that this backend doesn't require any order clause
/// for built-in window functions
pub struct NoOrderRequired;
#[automatically_derived]
impl ::core::fmt::Debug for NoOrderRequired {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter)
-> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "NoOrderRequired")
}
}
#[automatically_derived]
impl ::core::marker::Copy for NoOrderRequired { }
#[automatically_derived]
impl ::core::clone::Clone for NoOrderRequired {
#[inline]
fn clone(&self) -> NoOrderRequired { *self }
}
}
}#[diesel_derives::__diesel_public_if(
357 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
358)]359pub(crate) mod sql_dialect {
360#![cfg_attr(
361 not(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"),
362// Otherwise there are false positives
363 // because the lint seems to believe that these pub statements
364 // are not required, but they are required through the various backend impls
365allow(unreachable_pub)
366 )]
367 #[cfg(doc)]
368use super::SqlDialect;
369370/// This module contains all diesel provided reusable options to
371 /// configure [`SqlDialect::OnConflictClause`]
372#[diesel_derives::__diesel_public_if(
373 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
374)]
375pub mod on_conflict_clause {
376/// A marker trait indicating if a `ON CONFLICT` clause is supported or not
377 ///
378 /// If you use a custom type to specify specialized support for `ON CONFLICT` clauses
379 /// implementing this trait opts into reusing diesels existing `ON CONFLICT`
380 /// `QueryFragment` implementations
381pub trait SupportsOnConflictClause {}
382383/// A marker trait indicating if a `ON CONFLICT (...) DO UPDATE ... [WHERE ...]` clause is supported or not
384pub trait SupportsOnConflictClauseWhere {}
385386/// A marker trait indicating whether the on conflict clause implementation
387 /// is mostly like postgresql
388pub trait PgLikeOnConflictClause: SupportsOnConflictClause {}
389390/// This marker type indicates that `ON CONFLICT` clauses are not supported for this backend
391#[derive(Debug, Copy, Clone)]
392pub struct DoesNotSupportOnConflictClause;
393 }
394395/// This module contains all reusable options to configure
396 /// [`SqlDialect::ReturningClause`]
397#[diesel_derives::__diesel_public_if(
398 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
399)]
400pub mod returning_clause {
401/// A marker trait indicating if a `RETURNING` clause is supported or not
402 ///
403 /// If you use a custom type to specify specialized support for `RETURNING` clauses
404 /// implementing this trait opts in supporting `RETURNING` clause syntax
405pub trait SupportsReturningClause {}
406407/// Indicates that a backend provides support for `RETURNING` clauses
408 /// using the postgresql `RETURNING` syntax
409#[derive(Debug, Copy, Clone)]
410pub struct PgLikeReturningClause;
411412/// Indicates that a backend does not support `RETURNING` clauses
413#[derive(Debug, Copy, Clone)]
414pub struct DoesNotSupportReturningClause;
415416impl SupportsReturningClausefor PgLikeReturningClause {}
417 }
418419/// This module contains all reusable options to configure
420 /// [`SqlDialect::InsertWithDefaultKeyword`]
421#[diesel_derives::__diesel_public_if(
422 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
423)]
424pub mod default_keyword_for_insert {
425/// A marker trait indicating if a `DEFAULT` like expression
426 /// is supported as part of `INSERT INTO` clauses to indicate
427 /// that a default value should be inserted at a specific position
428 ///
429 /// If you use a custom type to specify specialized support for `DEFAULT`
430 /// expressions implementing this trait opts in support for `DEFAULT`
431 /// value expressions for inserts. Otherwise diesel will emulate this
432 /// behaviour.
433pub trait SupportsDefaultKeyword {}
434435/// Indicates that a backend support `DEFAULT` value expressions
436 /// for `INSERT INTO` statements based on the ISO SQL standard
437#[derive(Debug, Copy, Clone)]
438pub struct IsoSqlDefaultKeyword;
439440/// Indicates that a backend does not support `DEFAULT` value
441 /// expressions for `INSERT INTO` statements
442#[derive(Debug, Copy, Clone)]
443pub struct DoesNotSupportDefaultKeyword;
444445impl SupportsDefaultKeywordfor IsoSqlDefaultKeyword {}
446 }
447448/// This module contains all reusable options to configure
449 /// [`SqlDialect::BatchInsertSupport`]
450#[diesel_derives::__diesel_public_if(
451 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
452)]
453pub mod batch_insert_support {
454/// A marker trait indicating if batch insert statements
455 /// are supported for this backend or not
456pub trait SupportsBatchInsert {}
457458/// Indicates that this backend does not support batch
459 /// insert statements.
460 /// In this case diesel will emulate batch insert support
461 /// by inserting each row on its own
462#[derive(Debug, Copy, Clone)]
463pub struct DoesNotSupportBatchInsert;
464465/// Indicates that this backend supports postgres style
466 /// batch insert statements to insert multiple rows using one
467 /// insert statement
468#[derive(Debug, Copy, Clone)]
469pub struct PostgresLikeBatchInsertSupport;
470471impl SupportsBatchInsertfor PostgresLikeBatchInsertSupport {}
472 }
473/// This module contains all reusable options to configure
474 /// [`SqlDialect::ConcatClause`]
475#[diesel_derives::__diesel_public_if(
476 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
477)]
478pub mod concat_clause {
479480/// Indicates that this backend uses the
481 /// `||` operator to select a concatenation
482 /// of two variables or strings
483#[derive(Debug, Clone, Copy)]
484pub struct ConcatWithPipesClause;
485 }
486487/// This module contains all reusable options to configure
488 /// [`SqlDialect::DefaultValueClauseForInsert`]
489#[diesel_derives::__diesel_public_if(
490 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
491)]
492pub mod default_value_clause {
493494/// Indicates that this backend uses the
495 /// `DEFAULT VALUES` syntax to specify
496 /// that a row consisting only of default
497 /// values should be inserted
498#[derive(Debug, Clone, Copy)]
499pub struct AnsiDefaultValueClause;
500 }
501502/// This module contains all reusable options to configure
503 /// [`SqlDialect::EmptyFromClauseSyntax`]
504#[diesel_derives::__diesel_public_if(
505 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
506)]
507pub(crate) mod from_clause_syntax {
508509/// Indicates that this backend skips
510 /// the `FROM` clause in `SELECT` statements
511 /// if no table/view is queried
512#[derive(Debug, Copy, Clone)]
513pub struct AnsiSqlFromClauseSyntax;
514 }
515516/// This module contains all reusable options to configure
517 /// [`SqlDialect::ExistsSyntax`]
518#[diesel_derives::__diesel_public_if(
519 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
520)]
521pub mod exists_syntax {
522523/// Indicates that this backend
524 /// treats `EXIST()` as function
525 /// like expression
526#[derive(Debug, Copy, Clone)]
527pub struct AnsiSqlExistsSyntax;
528 }
529530/// This module contains all reusable options to configure
531 /// [`SqlDialect::ArrayComparison`]
532#[diesel_derives::__diesel_public_if(
533 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
534)]
535pub mod array_comparison {
536537/// Indicates that this backend requires a single bind
538 /// per array element in `IN()` and `NOT IN()` expression
539#[derive(Debug, Copy, Clone)]
540pub struct AnsiSqlArrayComparison;
541 }
542543/// This module contains all reusable options to configure
544 /// [`SqlDialect::SelectStatementSyntax`]
545#[diesel_derives::__diesel_public_if(
546 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
547)]
548pub mod select_statement_syntax {
549/// Indicates that this backend uses the default
550 /// ANSI select statement structure
551#[derive(Debug, Copy, Clone)]
552pub struct AnsiSqlSelectStatement;
553 }
554555/// This module contains all reusable options to configure
556 /// [`SqlDialect::AliasSyntax`]
557#[diesel_derives::__diesel_public_if(
558 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
559)]
560pub mod alias_syntax {
561/// Indicates that this backend uses `table AS alias` for
562 /// defining table aliases
563#[derive(Debug, Copy, Clone)]
564pub struct AsAliasSyntax;
565 }
566567/// This module contains all reusable options to configure [`SqlDialect::WindowFrameClauseGroupSupport`]
568#[diesel_derives::__diesel_public_if(
569 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
570)]
571pub mod window_frame_clause_group_support {
572/// Indicates that this backend does not support the `GROUPS` frame unit
573#[derive(Debug, Copy, Clone)]
574pub struct NoGroupWindowFrameUnit;
575576/// Indicates that this backend does support the `GROUPS` frame unit as specified by the standard
577#[derive(Debug, Copy, Clone)]
578pub struct IsoGroupWindowFrameUnit;
579 }
580581/// This module contains all reusable options to configure [`SqlDialect::AggregateFunctionExpressions`]
582#[diesel_derives::__diesel_public_if(
583 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
584)]
585pub mod aggregate_function_expressions {
586/// Indicates that this backend does not support aggregate function expressions
587#[derive(Debug, Copy, Clone)]
588pub struct NoAggregateFunctionExpressions;
589590/// Indicates that this backend supports aggregate function expressions similar to PostgreSQL
591#[derive(Debug, Copy, Clone)]
592pub struct PostgresLikeAggregateFunctionExpressions;
593 }
594595/// This module contains all reusable options to configure [`SqlDialect::WindowFrameExclusionSupport`]
596#[diesel_derives::__diesel_public_if(
597 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
598)]
599pub mod window_frame_exclusion_support {
600/// Indicates that this backend support frame exclusion clauses
601 /// for window functions
602#[derive(Debug, Copy, Clone)]
603pub struct FrameExclusionSupport;
604605/// Indicates that this backend does not support frame exclusion clauses
606 /// for window functions
607#[derive(Debug, Copy, Clone)]
608pub struct NoFrameFrameExclusionSupport;
609 }
610/// This module contains all reusable options to configure [`SqlDialect::BuiltInWindowFunctionRequireOrder`]
611#[diesel_derives::__diesel_public_if(
612 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
613)]
614pub mod built_in_window_function_require_order {
615/// Indicates that this backend doesn't require any order clause
616 /// for built-in window functions
617#[derive(Debug, Copy, Clone)]
618pub struct NoOrderRequired;
619 }
620}
621622// These traits are not part of the public API
623// because we want to replace them by with an associated type
624// in the child trait later if GAT's are finally stable
625pub(crate) mod private {
626627/// This is a marker trait which indicates that
628 /// diesel may specialize a certain [`QueryFragment`]
629 /// impl in a later version. If you as a user encounter, where rustc
630 /// suggests adding this a bound to a type implementing `Backend`
631 /// consider adding the following bound instead
632 /// `YourQueryType: QueryFragment<DB>` (the concrete bound
633 /// is likely mentioned by rustc as part of a `note: …`)
634 ///
635 /// For any user implementing a custom backend: You likely want to implement
636 /// this trait for your custom backend type to opt in the existing [`QueryFragment`] impls in diesel.
637 /// As indicated by the `i-implement-a-third-party-backend-and-opt-into-breaking-changes` feature
638 /// diesel reserves the right to specialize any generic [`QueryFragment`](crate::query_builder::QueryFragment)
639 /// impl via [`SqlDialect`](super::SqlDialect) in a later minor version release
640 ///
641 /// [`QueryFragment`]: crate::query_builder::QueryFragment
642#[cfg_attr(
643 diesel_docsrs,
644 doc(cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"))
645 )]
646pub trait DieselReserveSpecialization {}
647648/// This trait just indicates that none implements
649 /// [`SqlDialect`](super::SqlDialect) without enabling the
650 /// `i-implement-a-third-party-backend-and-opt-into-breaking-changes`
651 /// feature flag.
652#[cfg_attr(
653 diesel_docsrs,
654 doc(cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"))
655 )]
656pub trait TrustedBackend {}
657}