Skip to main content

diesel/
backend.rs

1//! Types which represent various database backends
2
3use crate::query_builder::QueryBuilder;
4use crate::sql_types::{self, HasSqlType, TypeMetadata};
5
6#[cfg_attr(
7    not(any(
8        feature = "postgres_backend",
9        feature = "mysql_backend",
10        feature = "__sqlite-shared",
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};
20
21/// 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 Backend
84where
85    Self: Sized + SqlDialect + TypeMetadata,
86    Self: HasSqlType<sql_types::SmallInt>,
87    Self: HasSqlType<sql_types::Integer>,
88    Self: HasSqlType<sql_types::BigInt>,
89    Self: HasSqlType<sql_types::Float>,
90    Self: HasSqlType<sql_types::Double>,
91    Self: HasSqlType<sql_types::Text>,
92    Self: HasSqlType<sql_types::Binary>,
93    Self: HasSqlType<sql_types::Date>,
94    Self: HasSqlType<sql_types::Time>,
95    Self: HasSqlType<sql_types::Timestamp>,
96{
97    /// The concrete [`QueryBuilder`] implementation for this backend.
98    type QueryBuilder: QueryBuilder<Self>;
99
100    /// The actual type given to [`FromSql`], with lifetimes applied. This type
101    /// should not be used directly.
102    ///
103    /// [`FromSql`]: crate::deserialize::FromSql
104    type RawValue<'a>;
105
106    /// 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
112    type BindCollector<'a>: crate::query_builder::bind_collector::BindCollector<'a, Self> + 'a;
113}
114
115#[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>;
119
120#[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>;
124
125/// 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::returning::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    )]
160    type 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    )]
168    type 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    )]
178    type 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    )]
195    type BatchInsertSupport;
196    /// Configures how this backend handles Batch update statements
197    ///
198    /// This allows backends to provide a custom [`QueryFragment`](crate::query_builder::QueryFragment)
199    #[cfg_attr(
200        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
201        doc = "implementation for [`BatchUpdate`](crate::query_builder::BatchUpdate)"
202    )]
203    #[cfg_attr(
204        not(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"),
205        doc = "implementation for `BatchUpdate`"
206    )]
207    ///
208    #[cfg_attr(
209        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
210        doc = "See [`sql_dialect::batch_update_support`] for provided default implementations"
211    )]
212    type BatchUpdateSupport;
213    /// Configures how this backend handles the Concat clauses in
214    /// select statements.
215    ///
216    /// This allows backends to provide a custom [`QueryFragment`](crate::query_builder::QueryFragment)
217    #[cfg_attr(
218        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
219        doc = "implementation for [`Concat`](crate::expression::Concat)"
220    )]
221    #[cfg_attr(
222        not(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"),
223        doc = "implementation for `Concat`"
224    )]
225    ///
226    #[cfg_attr(
227        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
228        doc = "See [`sql_dialect::concat_clause`] for provided default implementations"
229    )]
230    type ConcatClause;
231    /// Configures how this backend handles the `DEFAULT VALUES` clause for
232    /// insert 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 [`DefaultValues`](crate::query_builder::DefaultValues)"
238    )]
239    #[cfg_attr(
240        not(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"),
241        doc = "implementation for `DefaultValues`"
242    )]
243    ///
244    #[cfg_attr(
245        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
246        doc = "See [`sql_dialect::default_value_clause`] for provided default implementations"
247    )]
248    type DefaultValueClauseForInsert;
249    /// Configures how this backend handles empty `FROM` clauses for select statements.
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 [`NoFromClause`](crate::query_builder::NoFromClause)"
255    )]
256    #[cfg_attr(
257        not(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"),
258        doc = "implementation for `NoFromClause`"
259    )]
260    ///
261    #[cfg_attr(
262        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
263        doc = "See [`sql_dialect::from_clause_syntax`] for provided default implementations"
264    )]
265    type EmptyFromClauseSyntax;
266    /// Configures how this backend handles `EXISTS()` expressions.
267    ///
268    /// This allows backends to provide a custom [`QueryFragment`](crate::query_builder::QueryFragment)
269    #[cfg_attr(
270        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
271        doc = "implementation for [`Exists`](crate::expression::exists::Exists)"
272    )]
273    #[cfg_attr(
274        not(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"),
275        doc = "implementation for `Exists`"
276    )]
277    ///
278    #[cfg_attr(
279        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
280        doc = "See [`sql_dialect::exists_syntax`] for provided default implementations"
281    )]
282    type ExistsSyntax;
283
284    /// Configures how this backend handles `IN()` and `NOT IN()` expressions.
285    ///
286    /// This allows backends to provide custom [`QueryFragment`](crate::query_builder::QueryFragment)
287    #[cfg_attr(
288        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
289        doc = "implementations for [`In`](crate::expression::array_comparison::In),
290    [`NotIn`](crate::expression::array_comparison::NotIn) and
291    [`Many`](crate::expression::array_comparison::Many)"
292    )]
293    #[cfg_attr(
294        not(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"),
295        doc = "implementations for `In`, `NotIn` and `Many`"
296    )]
297    ///
298    #[cfg_attr(
299        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
300        doc = "See [`sql_dialect::array_comparison`] for provided default implementations"
301    )]
302    type ArrayComparison;
303
304    /// Configures how this backend structures `SELECT` queries
305    ///
306    /// This allows backends to provide custom [`QueryFragment`](crate::query_builder::QueryFragment)
307    /// implementations for
308    #[cfg_attr(
309        not(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"),
310        doc = "`SelectStatement` and `BoxedSelectStatement`"
311    )]
312    #[cfg_attr(
313        not(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"),
314        doc = "[`SelectStatement`](crate::query_builder::SelectStatement) and
315               [`BoxedSelectStatement`](crate::query_builder::BoxedSelectStatement)"
316    )]
317    ///
318    #[cfg_attr(
319        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
320        doc = "See [`sql_dialect::select_statement_syntax`] for provided default implementations"
321    )]
322    type SelectStatementSyntax;
323
324    /// Configures how this backend structures `SELECT` queries
325    ///
326    /// This allows backends to provide custom [`QueryFragment`](crate::query_builder::QueryFragment)
327    /// implementations for [`Alias<T>`](crate::query_source::Alias)
328    #[cfg_attr(
329        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
330        doc = "See [`sql_dialect::alias_syntax`] for provided default implementations"
331    )]
332    type AliasSyntax;
333
334    /// Configures how this backend support the `GROUP` frame unit for window functions
335    #[cfg_attr(
336        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
337        doc = "See [`sql_dialect::window_frame_clause_group_support`] for provided default implementations"
338    )]
339    type WindowFrameClauseGroupSupport;
340
341    /// Configures how this backend supports frame exclusion clauses
342    #[cfg_attr(
343        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
344        doc = "See [`sql_dialect::window_frame_exclusion_support`] for provided default implementations"
345    )]
346    type WindowFrameExclusionSupport;
347
348    /// Configures how this backend supports aggregate function expressions
349    #[cfg_attr(
350        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
351        doc = "See [`sql_dialect::window_frame_clause_group_support`] for provided default implementations"
352    )]
353    type AggregateFunctionExpressions;
354
355    /// Configures whether built-in window functions require order clauses for this backend or not
356    #[cfg_attr(
357        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
358        doc = "See [`sql_dialect::built_in_window_function_require_order`] for provided default implementations"
359    )]
360    type BuiltInWindowFunctionRequireOrder;
361}
362
363/// This module contains all options provided by diesel to configure the [`SqlDialect`] trait.
364// This module is only public behind the unstable feature flag, as we may want to change SqlDialect
365// implementations of existing backends because of:
366// * The backend gained support for previously unsupported SQL operations
367// * The backend fixed/introduced a bug that requires special handling
368// * We got some edge case wrong with sharing the implementation between backends
369//
370// By not exposing these types publicly we are able to change the exact definitions later on
371// as users cannot write trait bounds that ensure that a specific type is used in place of
372// an existing associated type.
373#[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]
        #[doc(hidden)]
        unsafe impl ::core::clone::TrivialClone 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]
        #[doc(hidden)]
        unsafe impl ::core::clone::TrivialClone 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]
        #[doc(hidden)]
        unsafe impl ::core::clone::TrivialClone 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]
        #[doc(hidden)]
        unsafe impl ::core::clone::TrivialClone 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]
        #[doc(hidden)]
        unsafe impl ::core::clone::TrivialClone 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]
        #[doc(hidden)]
        unsafe impl ::core::clone::TrivialClone 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]
        #[doc(hidden)]
        unsafe impl ::core::clone::TrivialClone 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::BatchUpdateSupport`]"]
    pub mod batch_update_support {
        /// A marker trait indicating if batch update statements
        /// are supported for this backend or not
        pub trait SupportsBatchUpdate { }
        /// Indicates that this backend does not support batch
        /// update statements.
        pub struct DoesNotSupportBatchUpdate;
        #[automatically_derived]
        impl ::core::fmt::Debug for DoesNotSupportBatchUpdate {
            #[inline]
            fn fmt(&self, f: &mut ::core::fmt::Formatter)
                -> ::core::fmt::Result {
                ::core::fmt::Formatter::write_str(f,
                    "DoesNotSupportBatchUpdate")
            }
        }
        #[automatically_derived]
        impl ::core::marker::Copy for DoesNotSupportBatchUpdate { }
        #[automatically_derived]
        #[doc(hidden)]
        unsafe impl ::core::clone::TrivialClone for DoesNotSupportBatchUpdate
            {
        }
        #[automatically_derived]
        impl ::core::clone::Clone for DoesNotSupportBatchUpdate {
            #[inline]
            fn clone(&self) -> DoesNotSupportBatchUpdate { *self }
        }
    }
    #[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]
        #[doc(hidden)]
        unsafe impl ::core::clone::TrivialClone for 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]
        #[doc(hidden)]
        unsafe impl ::core::clone::TrivialClone for 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]
        #[doc(hidden)]
        unsafe impl ::core::clone::TrivialClone 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]
        #[doc(hidden)]
        unsafe impl ::core::clone::TrivialClone 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]
        #[doc(hidden)]
        unsafe impl ::core::clone::TrivialClone 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]
        #[doc(hidden)]
        unsafe impl ::core::clone::TrivialClone 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]
        #[doc(hidden)]
        unsafe impl ::core::clone::TrivialClone 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]
        #[doc(hidden)]
        unsafe impl ::core::clone::TrivialClone 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]
        #[doc(hidden)]
        unsafe impl ::core::clone::TrivialClone 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]
        #[doc(hidden)]
        unsafe impl ::core::clone::TrivialClone 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]
        #[doc(hidden)]
        unsafe impl ::core::clone::TrivialClone 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]
        #[doc(hidden)]
        unsafe impl ::core::clone::TrivialClone 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]
        #[doc(hidden)]
        unsafe impl ::core::clone::TrivialClone 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]
        #[doc(hidden)]
        unsafe impl ::core::clone::TrivialClone for NoOrderRequired { }
        #[automatically_derived]
        impl ::core::clone::Clone for NoOrderRequired {
            #[inline]
            fn clone(&self) -> NoOrderRequired { *self }
        }
    }
}#[diesel_derives::__diesel_public_if(
374    feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
375)]
376pub(crate) mod sql_dialect {
377    #![cfg_attr(
378        not(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"),
379        // Otherwise there are false positives
380        // because the lint seems to believe that these pub statements
381        // are not required, but they are required through the various backend impls
382        allow(unreachable_pub)
383    )]
384    #[cfg(doc)]
385    use super::SqlDialect;
386
387    /// This module contains all diesel provided reusable options to
388    /// configure [`SqlDialect::OnConflictClause`]
389    #[diesel_derives::__diesel_public_if(
390        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
391    )]
392    pub mod on_conflict_clause {
393        /// A marker trait indicating if a `ON CONFLICT` clause is supported or not
394        ///
395        /// If you use a custom type to specify specialized support for `ON CONFLICT` clauses
396        /// implementing this trait opts into reusing diesels existing `ON CONFLICT`
397        /// `QueryFragment` implementations
398        pub trait SupportsOnConflictClause {}
399
400        /// A marker trait indicating if a `ON CONFLICT (...) DO UPDATE ... [WHERE ...]` clause is supported or not
401        pub trait SupportsOnConflictClauseWhere {}
402
403        /// A marker trait indicating whether the on conflict clause implementation
404        /// is mostly like postgresql
405        pub trait PgLikeOnConflictClause: SupportsOnConflictClause {}
406
407        /// This marker type indicates that `ON CONFLICT` clauses are not supported for this backend
408        #[derive(Debug, Copy, Clone)]
409        pub struct DoesNotSupportOnConflictClause;
410    }
411
412    /// This module contains all reusable options to configure
413    /// [`SqlDialect::ReturningClause`]
414    #[diesel_derives::__diesel_public_if(
415        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
416    )]
417    pub mod returning_clause {
418        /// A marker trait indicating if a `RETURNING` clause is supported or not
419        ///
420        /// If you use a custom type to specify specialized support for `RETURNING` clauses
421        /// implementing this trait opts in supporting `RETURNING` clause syntax
422        pub trait SupportsReturningClause {}
423
424        /// Indicates that a backend provides support for `RETURNING` clauses
425        /// using the postgresql `RETURNING` syntax
426        #[derive(Debug, Copy, Clone)]
427        pub struct PgLikeReturningClause;
428
429        /// Indicates that a backend does not support `RETURNING` clauses
430        #[derive(Debug, Copy, Clone)]
431        pub struct DoesNotSupportReturningClause;
432
433        impl SupportsReturningClause for PgLikeReturningClause {}
434    }
435
436    /// This module contains all reusable options to configure
437    /// [`SqlDialect::InsertWithDefaultKeyword`]
438    #[diesel_derives::__diesel_public_if(
439        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
440    )]
441    pub mod default_keyword_for_insert {
442        /// A marker trait indicating if a `DEFAULT` like expression
443        /// is supported as part of `INSERT INTO` clauses to indicate
444        /// that a default value should be inserted at a specific position
445        ///
446        /// If you use a custom type to specify specialized support for `DEFAULT`
447        /// expressions implementing this trait opts in support for `DEFAULT`
448        /// value expressions for inserts. Otherwise diesel will emulate this
449        /// behaviour.
450        pub trait SupportsDefaultKeyword {}
451
452        /// Indicates that a backend support `DEFAULT` value expressions
453        /// for `INSERT INTO` statements based on the ISO SQL standard
454        #[derive(Debug, Copy, Clone)]
455        pub struct IsoSqlDefaultKeyword;
456
457        /// Indicates that a backend does not support `DEFAULT` value
458        /// expressions for `INSERT INTO` statements
459        #[derive(Debug, Copy, Clone)]
460        pub struct DoesNotSupportDefaultKeyword;
461
462        impl SupportsDefaultKeyword for IsoSqlDefaultKeyword {}
463    }
464
465    /// This module contains all reusable options to configure
466    /// [`SqlDialect::BatchInsertSupport`]
467    #[diesel_derives::__diesel_public_if(
468        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
469    )]
470    pub mod batch_insert_support {
471        /// A marker trait indicating if batch insert statements
472        /// are supported for this backend or not
473        pub trait SupportsBatchInsert {}
474
475        /// Indicates that this backend does not support batch
476        /// insert statements.
477        /// In this case diesel will emulate batch insert support
478        /// by inserting each row on its own
479        #[derive(Debug, Copy, Clone)]
480        pub struct DoesNotSupportBatchInsert;
481
482        /// Indicates that this backend supports postgres style
483        /// batch insert statements to insert multiple rows using one
484        /// insert statement
485        #[derive(Debug, Copy, Clone)]
486        pub struct PostgresLikeBatchInsertSupport;
487
488        impl SupportsBatchInsert for PostgresLikeBatchInsertSupport {}
489    }
490
491    /// This module contains all reusable options to configure
492    /// [`SqlDialect::BatchUpdateSupport`]
493    #[diesel_derives::__diesel_public_if(
494        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
495    )]
496    pub mod batch_update_support {
497        /// A marker trait indicating if batch update statements
498        /// are supported for this backend or not
499        pub trait SupportsBatchUpdate {}
500
501        /// Indicates that this backend does not support batch
502        /// update statements.
503        #[derive(Debug, Copy, Clone)]
504        pub struct DoesNotSupportBatchUpdate;
505    }
506
507    /// This module contains all reusable options to configure
508    /// [`SqlDialect::ConcatClause`]
509    #[diesel_derives::__diesel_public_if(
510        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
511    )]
512    pub mod concat_clause {
513
514        /// Indicates that this backend uses the
515        /// `||` operator to select a concatenation
516        /// of two variables or strings
517        #[derive(Debug, Clone, Copy)]
518        pub struct ConcatWithPipesClause;
519    }
520
521    /// This module contains all reusable options to configure
522    /// [`SqlDialect::DefaultValueClauseForInsert`]
523    #[diesel_derives::__diesel_public_if(
524        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
525    )]
526    pub mod default_value_clause {
527
528        /// Indicates that this backend uses the
529        /// `DEFAULT VALUES` syntax to specify
530        /// that a row consisting only of default
531        /// values should be inserted
532        #[derive(Debug, Clone, Copy)]
533        pub struct AnsiDefaultValueClause;
534    }
535
536    /// This module contains all reusable options to configure
537    /// [`SqlDialect::EmptyFromClauseSyntax`]
538    #[diesel_derives::__diesel_public_if(
539        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
540    )]
541    pub(crate) mod from_clause_syntax {
542
543        /// Indicates that this backend skips
544        /// the `FROM` clause in `SELECT` statements
545        /// if no table/view is queried
546        #[derive(Debug, Copy, Clone)]
547        pub struct AnsiSqlFromClauseSyntax;
548    }
549
550    /// This module contains all reusable options to configure
551    /// [`SqlDialect::ExistsSyntax`]
552    #[diesel_derives::__diesel_public_if(
553        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
554    )]
555    pub mod exists_syntax {
556
557        /// Indicates that this backend
558        /// treats `EXIST()` as function
559        /// like expression
560        #[derive(Debug, Copy, Clone)]
561        pub struct AnsiSqlExistsSyntax;
562    }
563
564    /// This module contains all reusable options to configure
565    /// [`SqlDialect::ArrayComparison`]
566    #[diesel_derives::__diesel_public_if(
567        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
568    )]
569    pub mod array_comparison {
570
571        /// Indicates that this backend requires a single bind
572        /// per array element in `IN()` and `NOT IN()` expression
573        #[derive(Debug, Copy, Clone)]
574        pub struct AnsiSqlArrayComparison;
575    }
576
577    /// This module contains all reusable options to configure
578    /// [`SqlDialect::SelectStatementSyntax`]
579    #[diesel_derives::__diesel_public_if(
580        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
581    )]
582    pub mod select_statement_syntax {
583        /// Indicates that this backend uses the default
584        /// ANSI select statement structure
585        #[derive(Debug, Copy, Clone)]
586        pub struct AnsiSqlSelectStatement;
587    }
588
589    /// This module contains all reusable options to configure
590    /// [`SqlDialect::AliasSyntax`]
591    #[diesel_derives::__diesel_public_if(
592        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
593    )]
594    pub mod alias_syntax {
595        /// Indicates that this backend uses `table AS alias` for
596        /// defining table aliases
597        #[derive(Debug, Copy, Clone)]
598        pub struct AsAliasSyntax;
599    }
600
601    /// This module contains all reusable options to configure [`SqlDialect::WindowFrameClauseGroupSupport`]
602    #[diesel_derives::__diesel_public_if(
603        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
604    )]
605    pub mod window_frame_clause_group_support {
606        /// Indicates that this backend does not support the `GROUPS` frame unit
607        #[derive(Debug, Copy, Clone)]
608        pub struct NoGroupWindowFrameUnit;
609
610        /// Indicates that this backend does support the `GROUPS` frame unit as specified by the standard
611        #[derive(Debug, Copy, Clone)]
612        pub struct IsoGroupWindowFrameUnit;
613    }
614
615    /// This module contains all reusable options to configure [`SqlDialect::AggregateFunctionExpressions`]
616    #[diesel_derives::__diesel_public_if(
617        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
618    )]
619    pub mod aggregate_function_expressions {
620        /// Indicates that this backend does not support aggregate function expressions
621        #[derive(Debug, Copy, Clone)]
622        pub struct NoAggregateFunctionExpressions;
623
624        /// Indicates that this backend supports aggregate function expressions similar to PostgreSQL
625        #[derive(Debug, Copy, Clone)]
626        pub struct PostgresLikeAggregateFunctionExpressions;
627    }
628
629    /// This module contains all reusable options to configure [`SqlDialect::WindowFrameExclusionSupport`]
630    #[diesel_derives::__diesel_public_if(
631        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
632    )]
633    pub mod window_frame_exclusion_support {
634        /// Indicates that this backend support frame exclusion clauses
635        /// for window functions
636        #[derive(Debug, Copy, Clone)]
637        pub struct FrameExclusionSupport;
638
639        /// Indicates that this backend does not support frame exclusion clauses
640        /// for window functions
641        #[derive(Debug, Copy, Clone)]
642        pub struct NoFrameFrameExclusionSupport;
643    }
644    /// This module contains all reusable options to configure [`SqlDialect::BuiltInWindowFunctionRequireOrder`]
645    #[diesel_derives::__diesel_public_if(
646        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
647    )]
648    pub mod built_in_window_function_require_order {
649        /// Indicates that this backend doesn't require any order clause
650        /// for built-in window functions
651        #[derive(Debug, Copy, Clone)]
652        pub struct NoOrderRequired;
653    }
654}
655
656// These traits are not part of the public API
657// because we want to replace them by with an associated type
658// in the child trait later if GAT's are finally stable
659pub(crate) mod private {
660
661    /// This is a marker trait which indicates that
662    /// diesel may specialize a certain [`QueryFragment`]
663    /// impl in a later version. If you as a user encounter, where rustc
664    /// suggests adding this a bound to a type implementing `Backend`
665    /// consider adding the following bound instead
666    /// `YourQueryType: QueryFragment<DB>` (the concrete bound
667    /// is likely mentioned by rustc as part of a `note: …`)
668    ///
669    /// For any user implementing a custom backend: You likely want to implement
670    /// this trait for your custom backend type to opt in the existing [`QueryFragment`] impls in diesel.
671    /// As indicated by the `i-implement-a-third-party-backend-and-opt-into-breaking-changes` feature
672    /// diesel reserves the right to specialize any generic [`QueryFragment`](crate::query_builder::QueryFragment)
673    /// impl via [`SqlDialect`](super::SqlDialect) in a later minor version release
674    ///
675    /// [`QueryFragment`]: crate::query_builder::QueryFragment
676    #[cfg_attr(
677        diesel_docsrs,
678        doc(cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"))
679    )]
680    pub trait DieselReserveSpecialization {}
681
682    /// This trait just indicates that none implements
683    /// [`SqlDialect`](super::SqlDialect) without enabling the
684    /// `i-implement-a-third-party-backend-and-opt-into-breaking-changes`
685    /// feature flag.
686    #[cfg_attr(
687        diesel_docsrs,
688        doc(cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"))
689    )]
690    pub trait TrustedBackend {}
691}