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