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