diesel/sql_types/mod.rs
1//! Types which represent a SQL data type.
2//!
3//! The structs in this module are *only* used as markers to represent a SQL type.
4//! They should never be used in your structs.
5//! If you'd like to know the rust types which can be used for a given SQL type,
6//! see the documentation for that SQL type.
7//! Additional types may be provided by other crates.
8//!
9//! To see which SQL type can be used with a given Rust type,
10//! see the "Implementors" section of [`FromSql`].
11//!
12//! [`FromSql`]: super::deserialize::FromSql
13//!
14//! Any backend specific types are re-exported through this module
15
16mod fold;
17pub mod ops;
18mod ord;
19
20pub use self::fold::Foldable;
21pub use self::ord::SqlOrd;
22
23use crate::expression::TypedExpressionType;
24use crate::query_builder::QueryId;
25
26/// The boolean SQL type.
27///
28/// On backends without a native boolean type,
29/// this is emulated with the smallest supported integer.
30///
31/// ### [`ToSql`](crate::serialize::ToSql) impls
32///
33/// - [`bool`][bool]
34///
35/// ### [`FromSql`](crate::deserialize::FromSql) impls
36///
37/// - [`bool`][bool]
38///
39/// [bool]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
40#[derive(Debug, Clone, Copy, Default, QueryId, SqlType)]
41#[diesel(postgres_type(oid = 16, array_oid = 1000))]
42#[diesel(sqlite_type(name = "Integer"))]
43#[diesel(mysql_type(name = "Tiny"))]
44pub struct Bool;
45
46/// The tiny integer SQL type.
47///
48/// This is only available on MySQL.
49/// Keep in mind that `diesel print-schema` will see `TINYINT(1)` as `Bool`,
50/// not `TinyInt`.
51///
52/// ### [`ToSql`](crate::serialize::ToSql) impls
53///
54/// - [`i8`][i8]
55///
56/// ### [`FromSql`](crate::deserialize::FromSql) impls
57///
58/// - [`i8`][i8]
59///
60/// [i8]: https://doc.rust-lang.org/nightly/std/primitive.i8.html
61#[derive(Debug, Clone, Copy, Default, QueryId, SqlType)]
62#[diesel(mysql_type(name = "Tiny"))]
63pub struct TinyInt;
64#[doc(hidden)]
65pub type Tinyint = TinyInt;
66
67/// The small integer SQL type.
68///
69/// ### [`ToSql`](crate::serialize::ToSql) impls
70///
71/// - [`i16`][i16]
72///
73/// ### [`FromSql`](crate::deserialize::FromSql) impls
74///
75/// - [`i16`][i16]
76///
77/// [i16]: https://doc.rust-lang.org/nightly/std/primitive.i16.html
78#[derive(Debug, Clone, Copy, Default, QueryId, SqlType)]
79#[diesel(postgres_type(oid = 21, array_oid = 1005))]
80#[diesel(sqlite_type(name = "SmallInt"))]
81#[diesel(mysql_type(name = "Short"))]
82pub struct SmallInt;
83#[doc(hidden)]
84pub type Int2 = SmallInt;
85#[doc(hidden)]
86pub type Smallint = SmallInt;
87
88/// The integer SQL type.
89///
90/// ### [`ToSql`](crate::serialize::ToSql) impls
91///
92/// - [`i32`][i32]
93///
94/// ### [`FromSql`](crate::deserialize::FromSql) impls
95///
96/// - [`i32`][i32]
97///
98/// [i32]: https://doc.rust-lang.org/nightly/std/primitive.i32.html
99#[derive(Debug, Clone, Copy, Default, QueryId, SqlType)]
100#[diesel(postgres_type(oid = 23, array_oid = 1007))]
101#[diesel(sqlite_type(name = "Integer"))]
102#[diesel(mysql_type(name = "Long"))]
103pub struct Integer;
104#[doc(hidden)]
105pub type Int4 = Integer;
106
107/// The big integer SQL type.
108///
109/// ### [`ToSql`](crate::serialize::ToSql) impls
110///
111/// - [`i64`][i64]
112///
113/// ### [`FromSql`](crate::deserialize::FromSql) impls
114///
115/// - [`i64`][i64]
116///
117/// [i64]: https://doc.rust-lang.org/nightly/std/primitive.i64.html
118#[derive(Debug, Clone, Copy, Default, QueryId, SqlType)]
119#[diesel(postgres_type(oid = 20, array_oid = 1016))]
120#[diesel(sqlite_type(name = "Long"))]
121#[diesel(mysql_type(name = "LongLong"))]
122pub struct BigInt;
123#[doc(hidden)]
124pub type Int8 = BigInt;
125#[doc(hidden)]
126pub type Bigint = BigInt;
127
128/// The float SQL type.
129///
130/// ### [`ToSql`](crate::serialize::ToSql) impls
131///
132/// - [`f32`][f32]
133///
134/// ### [`FromSql`](crate::deserialize::FromSql) impls
135///
136/// - [`f32`][f32]
137///
138/// [f32]: https://doc.rust-lang.org/nightly/std/primitive.f32.html
139#[derive(Debug, Clone, Copy, Default, QueryId, SqlType)]
140#[diesel(postgres_type(oid = 700, array_oid = 1021))]
141#[diesel(sqlite_type(name = "Float"))]
142#[diesel(mysql_type(name = "Float"))]
143pub struct Float;
144#[doc(hidden)]
145pub type Float4 = Float;
146
147/// The double precision float SQL type.
148///
149/// ### [`ToSql`](crate::serialize::ToSql) impls
150///
151/// - [`f64`][f64]
152///
153/// ### [`FromSql`](crate::deserialize::FromSql) impls
154///
155/// - [`f64`][f64]
156///
157/// [f64]: https://doc.rust-lang.org/nightly/std/primitive.f64.html
158#[derive(Debug, Clone, Copy, Default, QueryId, SqlType)]
159#[diesel(postgres_type(oid = 701, array_oid = 1022))]
160#[diesel(sqlite_type(name = "Double"))]
161#[diesel(mysql_type(name = "Double"))]
162pub struct Double;
163#[doc(hidden)]
164pub type Float8 = Double;
165
166/// The arbitrary precision numeric SQL type.
167///
168/// This type is only supported on PostgreSQL and MySQL.
169/// On SQLite, [`Double`] should be used instead.
170///
171/// ### [`ToSql`](crate::serialize::ToSql) impls
172///
173/// - [`bigdecimal::BigDecimal`] with `feature = ["numeric"]`
174///
175/// ### [`FromSql`](crate::deserialize::FromSql) impls
176///
177/// - [`bigdecimal::BigDecimal`] with `feature = ["numeric"]`
178///
179/// [`bigdecimal::BigDecimal`]: /bigdecimal/struct.BigDecimal.html
180#[derive(Debug, Clone, Copy, Default, QueryId, SqlType)]
181#[diesel(postgres_type(oid = 1700, array_oid = 1231))]
182#[diesel(mysql_type(name = "Numeric"))]
183#[diesel(sqlite_type(name = "Double"))]
184pub struct Numeric;
185
186/// Alias for `Numeric`
187pub type Decimal = Numeric;
188
189/// The text SQL type.
190///
191/// On all backends strings must be valid UTF-8.
192/// On PostgreSQL strings must not include nul bytes.
193///
194/// Schema inference will treat all variants of `TEXT` as this type (e.g.
195/// `VARCHAR`, `MEDIUMTEXT`, etc).
196///
197/// ### [`ToSql`](crate::serialize::ToSql) impls
198///
199/// - [`String`]
200/// - [`&str`][str]
201///
202/// ### [`FromSql`](crate::deserialize::FromSql) impls
203///
204/// - [`String`]
205///
206/// [str]: https://doc.rust-lang.org/nightly/std/primitive.str.html
207#[derive(Debug, Clone, Copy, Default, QueryId, SqlType)]
208#[diesel(postgres_type(oid = 25, array_oid = 1009))]
209#[diesel(sqlite_type(name = "Text"))]
210#[diesel(mysql_type(name = "String"))]
211pub struct Text;
212
213/// The SQL `VARCHAR` type
214///
215/// This type is generally interchangeable with `TEXT`, so Diesel has this as an
216/// alias rather than a separate type (Diesel does not currently support
217/// implicit coercions).
218///
219/// One notable exception to this is with arrays on PG. `TEXT[]` cannot be
220/// coerced to `VARCHAR[]`. It is recommended that you always use `TEXT[]` if
221/// you need a string array on PG.
222pub type VarChar = Text;
223#[doc(hidden)]
224pub type Varchar = VarChar;
225#[doc(hidden)]
226pub type Char = Text;
227#[doc(hidden)]
228pub type Tinytext = Text;
229#[doc(hidden)]
230pub type Mediumtext = Text;
231#[doc(hidden)]
232pub type Longtext = Text;
233
234/// The binary SQL type.
235///
236/// Schema inference will treat all variants of `BLOB` as this type (e.g.
237/// `VARBINARY`, `MEDIUMBLOB`, etc).
238///
239/// ### [`ToSql`](crate::serialize::ToSql) impls
240///
241/// - [`Vec<u8>`][Vec]
242/// - [`&[u8]`][slice]
243///
244/// ### [`FromSql`](crate::deserialize::FromSql) impls
245///
246/// - [`Vec<u8>`][Vec]
247///
248/// [Vec]: std::vec::Vec
249/// [slice]: https://doc.rust-lang.org/nightly/std/primitive.slice.html
250#[derive(Debug, Clone, Copy, Default, QueryId, SqlType)]
251#[diesel(postgres_type(oid = 17, array_oid = 1001))]
252#[diesel(sqlite_type(name = "Binary"))]
253#[diesel(mysql_type(name = "Blob"))]
254pub struct Binary;
255
256#[doc(hidden)]
257pub type Tinyblob = Binary;
258#[doc(hidden)]
259pub type Blob = Binary;
260#[doc(hidden)]
261pub type Mediumblob = Binary;
262#[doc(hidden)]
263pub type Longblob = Binary;
264#[doc(hidden)]
265pub type Varbinary = Binary;
266#[doc(hidden)]
267pub type Bit = Binary;
268
269/// The date SQL type.
270///
271/// ### [`ToSql`](crate::serialize::ToSql) impls
272///
273/// - [`chrono::NaiveDate`][NaiveDate] with `feature = "chrono"`
274/// - [`time::Date`][Date] with `feature = "time"`
275///
276/// ### [`FromSql`](crate::deserialize::FromSql) impls
277///
278/// - [`chrono::NaiveDate`][NaiveDate] with `feature = "chrono"`
279/// - [`time::Date`][Date] with `feature = "time"`
280///
281/// [NaiveDate]: https://docs.rs/chrono/*/chrono/naive/struct.NaiveDate.html
282/// [Date]: https://docs.rs/time/0.3.9/time/struct.Date.html
283#[derive(Debug, Clone, Copy, Default, QueryId, SqlType)]
284#[diesel(postgres_type(oid = 1082, array_oid = 1182))]
285#[diesel(sqlite_type(name = "Text"))]
286#[diesel(mysql_type(name = "Date"))]
287pub struct Date;
288
289/// The interval SQL type.
290///
291/// This type is currently only implemented for PostgreSQL.
292///
293/// ### [`ToSql`](crate::serialize::ToSql) impls
294///
295/// - [`PgInterval`] which can be constructed using [`IntervalDsl`]
296/// - [`chrono::Duration`][Duration] with `feature = "chrono"`
297///
298/// ### [`FromSql`](crate::deserialize::FromSql) impls
299///
300/// - [`PgInterval`] which can be constructed using [`IntervalDsl`]
301/// - [`chrono::Duration`][Duration] with `feature = "chrono"`
302/// (There might be some information loss due to special behavior for literal `month` (or longer) intervals;
303/// Please read official documentation of [PostgreSQL Interval].)
304///
305/// [`PgInterval`]: ../pg/data_types/struct.PgInterval.html
306/// [`IntervalDsl`]: ../pg/expression/extensions/trait.IntervalDsl.html
307/// [Duration]: https://docs.rs/chrono/*/chrono/type.Duration.html
308/// [PostgreSQL Interval]: https://www.postgresql.org/docs/current/datatype-datetime.html#DATATYPE-INTERVAL-INPUT
309#[derive(Debug, Clone, Copy, Default, QueryId, SqlType)]
310#[diesel(postgres_type(oid = 1186, array_oid = 1187))]
311pub struct Interval;
312
313/// The time SQL type.
314///
315/// ### [`ToSql`](crate::serialize::ToSql) impls
316///
317/// - [`chrono::NaiveTime`][NaiveTime] with `feature = "chrono"`
318/// - [`time::Time`][Time] with `feature = "time"`
319///
320/// ### [`FromSql`](crate::deserialize::FromSql) impls
321///
322/// - [`chrono::NaiveTime`][NaiveTime] with `feature = "chrono"`
323/// - [`time::Time`][Time] with `feature = "time"`
324///
325/// [NaiveTime]: /chrono/naive/time/struct.NaiveTime.html
326/// [Time]: /time/struct.Time.html
327#[derive(Debug, Clone, Copy, Default, QueryId, SqlType)]
328#[diesel(postgres_type(oid = 1083, array_oid = 1183))]
329#[diesel(sqlite_type(name = "Text"))]
330#[diesel(mysql_type(name = "Time"))]
331pub struct Time;
332
333/// The timestamp SQL type.
334///
335/// ### [`ToSql`](crate::serialize::ToSql) impls
336///
337/// - [`std::time::SystemTime`][SystemTime] (PG only)
338/// - [`chrono::NaiveDateTime`][NaiveDateTime] with `feature = "chrono"`
339/// - [`time::PrimitiveDateTime`] with `feature = "time"`
340/// - [`time::OffsetDateTime`] with `feature = "time"` (MySQL only)
341///
342/// ### [`FromSql`](crate::deserialize::FromSql) impls
343///
344/// - [`std::time::SystemTime`][SystemTime] (PG only)
345/// - [`chrono::NaiveDateTime`][NaiveDateTime] with `feature = "chrono"`
346/// - [`time::PrimitiveDateTime`] with `feature = "time"`
347/// - [`time::OffsetDateTime`] with `feature = "time"` (MySQL only)
348///
349/// [SystemTime]: std::time::SystemTime
350#[cfg_attr(
351 feature = "chrono",
352 doc = " [NaiveDateTime]: chrono::naive::NaiveDateTime"
353)]
354#[cfg_attr(
355 not(feature = "chrono"),
356 doc = " [NaiveDateTime]: https://docs.rs/chrono/*/chrono/naive/struct.NaiveDateTime.html"
357)]
358#[cfg_attr(
359 feature = "time",
360 doc = " [`time::PrimitiveDateTime`]: time::PrimitiveDateTime"
361)]
362#[cfg_attr(
363 not(feature = "time"),
364 doc = " [`time::PrimitiveDateTime`]: https://docs.rs/time/0.3.9/time/struct.PrimitiveDateTime.html"
365)]
366#[cfg_attr(
367 feature = "time",
368 doc = " [`time::OffsetDateTime`]: time::OffsetDateTime"
369)]
370#[cfg_attr(
371 not(feature = "time"),
372 doc = " [`time::OffsetDateTime`]: https://docs.rs/time/0.3.9/time/struct.OffsetDateTime.html"
373)]
374/// [Timespec]: /time/struct.Timespec.html
375#[derive(Debug, Clone, Copy, Default, QueryId, SqlType)]
376#[diesel(postgres_type(oid = 1114, array_oid = 1115))]
377#[diesel(sqlite_type(name = "Text"))]
378#[diesel(mysql_type(name = "Timestamp"))]
379pub struct Timestamp;
380
381/// The JSON SQL type. This type can only be used with `feature =
382/// "serde_json"`
383///
384/// For postgresql you should normally prefer [`Jsonb`](struct.Jsonb.html) instead,
385/// for the reasons discussed there.
386///
387/// ### [`ToSql`] impls
388///
389/// - [`serde_json::Value`]
390///
391/// ### [`FromSql`] impls
392///
393/// - [`serde_json::Value`]
394///
395/// [`ToSql`]: /serialize/trait.ToSql.html
396/// [`FromSql`]: /deserialize/trait.FromSql.html
397/// [`serde_json::Value`]: /../serde_json/value/enum.Value.html
398#[derive(Debug, Clone, Copy, Default, QueryId, SqlType)]
399#[diesel(postgres_type(oid = 114, array_oid = 199))]
400#[diesel(mysql_type(name = "String"))]
401pub struct Json;
402
403/// The nullable SQL type.
404///
405/// This wraps another SQL type to indicate that it can be null.
406/// By default all values are assumed to be `NOT NULL`.
407///
408/// ### [`ToSql`](crate::serialize::ToSql) impls
409///
410/// - Any `T` which implements `ToSql<ST>`
411/// - `Option<T>` for any `T` which implements `ToSql<ST>`
412///
413/// ### [`FromSql`](crate::deserialize::FromSql) impls
414///
415/// - `Option<T>` for any `T` which implements `FromSql<ST>`
416#[derive(Debug, Clone, Copy, Default)]
417pub struct Nullable<ST>(ST);
418
419impl<ST> SqlType for Nullable<ST>
420where
421 ST: SqlType,
422{
423 type IsNull = is_nullable::IsNullable;
424}
425
426#[doc(inline)]
427#[cfg(feature = "postgres_backend")]
428pub use crate::pg::sql_types::*;
429
430#[doc(inline)]
431#[cfg(feature = "mysql_backend")]
432pub use crate::mysql::sql_types::{Datetime, Unsigned};
433
434#[doc(inline)]
435#[cfg(feature = "sqlite")]
436pub use crate::sqlite::sql_types::Timestamptz as TimestamptzSqlite;
437
438/// Indicates that a SQL type exists for a backend.
439///
440/// This trait can be derived using the [`SqlType` derive](derive@SqlType)
441///
442/// # Example
443///
444/// ```rust
445/// #[derive(diesel::sql_types::SqlType)]
446/// #[diesel(postgres_type(oid = 23, array_oid = 1007))]
447/// #[diesel(sqlite_type(name = "Integer"))]
448/// #[diesel(mysql_type(name = "Long"))]
449/// pub struct Integer;
450/// ```
451pub trait HasSqlType<ST>: TypeMetadata {
452 /// Fetch the metadata for the given type
453 ///
454 /// This method may use `lookup` to do dynamic runtime lookup. Implementors
455 /// of this method should not do dynamic lookup unless absolutely necessary
456 fn metadata(lookup: &mut Self::MetadataLookup) -> Self::TypeMetadata;
457}
458
459/// Information about how a backend stores metadata about given SQL types
460pub trait TypeMetadata {
461 /// The actual type used to represent metadata.
462 ///
463 /// On PostgreSQL, this is the type's OID.
464 /// On MySQL and SQLite, this is an enum representing all storage classes
465 /// they support.
466 type TypeMetadata;
467 /// The type used for runtime lookup of metadata.
468 ///
469 /// For most backends, which don't support user defined types, this will
470 /// be `()`.
471 type MetadataLookup: ?Sized;
472}
473
474/// Converts a type which may or may not be nullable into its nullable
475/// representation.
476pub trait IntoNullable {
477 /// The nullable representation of this type.
478 ///
479 /// For all types except `Nullable`, this will be `Nullable<Self>`.
480 type Nullable;
481}
482
483impl<T> IntoNullable for T
484where
485 T: SqlType<IsNull = is_nullable::NotNull> + SingleValue,
486{
487 type Nullable = Nullable<T>;
488}
489
490impl<T> IntoNullable for Nullable<T>
491where
492 T: SqlType,
493{
494 type Nullable = Self;
495}
496
497/// Converts a type which may or may not be nullable into its not nullable
498/// representation.
499pub trait IntoNotNullable {
500 /// The not nullable representation of this type.
501 ///
502 /// For `Nullable<T>`, this will be `T` otherwise the type itself
503 type NotNullable;
504}
505
506impl<T> IntoNotNullable for T
507where
508 T: SqlType<IsNull = is_nullable::NotNull>,
509{
510 type NotNullable = T;
511}
512
513impl<T> IntoNotNullable for Nullable<T>
514where
515 T: SqlType,
516{
517 type NotNullable = T;
518}
519
520/// A marker trait indicating that a SQL type represents a single value, as
521/// opposed to a list of values.
522///
523/// This trait should generally be implemented for all SQL types with the
524/// exception of Rust tuples. If a column could have this as its type, this
525/// trait should be implemented.
526///
527/// # Deriving
528///
529/// This trait is automatically implemented by [`#[derive(SqlType)]`](derive@SqlType)
530///
531pub trait SingleValue: SqlType {}
532
533impl<T: SqlType + SingleValue> SingleValue for Nullable<T> {}
534
535#[doc(inline)]
536pub use diesel_derives::DieselNumericOps;
537#[doc(inline)]
538pub use diesel_derives::SqlType;
539
540/// A marker trait for SQL types
541///
542/// # Deriving
543///
544/// This trait is automatically implemented by [`#[derive(SqlType)]`](derive@SqlType)
545/// which sets `IsNull` to [`is_nullable::NotNull`]
546///
547pub trait SqlType: 'static {
548 /// Is this type nullable?
549 ///
550 /// This type should always be one of the structs in the ['is_nullable`]
551 /// module. See the documentation of those structs for more details.
552 ///
553 /// ['is_nullable`]: is_nullable
554 type IsNull: OneIsNullable<is_nullable::IsNullable> + OneIsNullable<is_nullable::NotNull>;
555}
556
557/// Is one value of `IsNull` nullable?
558///
559/// You should never implement this trait.
560pub trait OneIsNullable<Other> {
561 /// See the trait documentation
562 type Out: OneIsNullable<is_nullable::IsNullable> + OneIsNullable<is_nullable::NotNull>;
563}
564
565/// Are both values of `IsNull` are nullable?
566pub trait AllAreNullable<Other> {
567 /// See the trait documentation
568 type Out: AllAreNullable<is_nullable::NotNull> + AllAreNullable<is_nullable::IsNullable>;
569}
570
571/// A type level constructor for maybe nullable types
572///
573/// Constructs either `Nullable<O>` (for `Self` == `is_nullable::IsNullable`)
574/// or `O` (for `Self` == `is_nullable::NotNull`)
575pub trait MaybeNullableType<O> {
576 /// See the trait documentation
577 type Out: SqlType + TypedExpressionType;
578}
579
580/// Possible values for `SqlType::IsNullable`
581pub mod is_nullable {
582 use super::*;
583
584 /// No, this type cannot be null as it is marked as `NOT NULL` at database level
585 ///
586 /// This should be chosen for basically all manual impls of `SqlType`
587 /// beside implementing your own `Nullable<>` wrapper type
588 #[derive(Debug, Clone, Copy)]
589 pub struct NotNull;
590
591 /// Yes, this type can be null
592 ///
593 /// The only diesel provided `SqlType` that uses this value is [`Nullable<T>`]
594 ///
595 /// [`Nullable<T>`]: Nullable
596 #[derive(Debug, Clone, Copy)]
597 pub struct IsNullable;
598
599 impl OneIsNullable<NotNull> for NotNull {
600 type Out = NotNull;
601 }
602
603 impl OneIsNullable<IsNullable> for NotNull {
604 type Out = IsNullable;
605 }
606
607 impl OneIsNullable<NotNull> for IsNullable {
608 type Out = IsNullable;
609 }
610
611 impl OneIsNullable<IsNullable> for IsNullable {
612 type Out = IsNullable;
613 }
614
615 impl AllAreNullable<NotNull> for NotNull {
616 type Out = NotNull;
617 }
618
619 impl AllAreNullable<IsNullable> for NotNull {
620 type Out = NotNull;
621 }
622
623 impl AllAreNullable<NotNull> for IsNullable {
624 type Out = NotNull;
625 }
626
627 impl AllAreNullable<IsNullable> for IsNullable {
628 type Out = IsNullable;
629 }
630
631 impl<O> MaybeNullableType<O> for NotNull
632 where
633 O: SqlType + TypedExpressionType,
634 {
635 type Out = O;
636 }
637
638 impl<O> MaybeNullableType<O> for IsNullable
639 where
640 O: SqlType,
641 Nullable<O>: TypedExpressionType,
642 {
643 type Out = Nullable<O>;
644 }
645
646 /// Represents the output type of [`MaybeNullableType`]
647 pub type MaybeNullable<N, T> = <N as MaybeNullableType<T>>::Out;
648
649 /// Represents the output type of [`OneIsNullable`]
650 /// for two given SQL types
651 pub type IsOneNullable<S1, S2> =
652 <IsSqlTypeNullable<S1> as OneIsNullable<IsSqlTypeNullable<S2>>>::Out;
653
654 /// Represents the output type of [`AllAreNullable`]
655 /// for two given SQL types
656 pub type AreAllNullable<S1, S2> =
657 <IsSqlTypeNullable<S1> as AllAreNullable<IsSqlTypeNullable<S2>>>::Out;
658
659 /// Represents if the SQL type is nullable or not
660 pub type IsSqlTypeNullable<T> = <T as SqlType>::IsNull;
661}
662
663/// A marker trait for accepting expressions of the type `Bool` and
664/// `Nullable<Bool>` in the same place
665#[diagnostic::on_unimplemented(
666 message = "`{Self}` is neither `diesel::sql_types::Bool` nor `diesel::sql_types::Nullable<Bool>`",
667 note = "try to provide an expression that produces one of the expected sql types"
668)]
669pub trait BoolOrNullableBool {}
670
671impl BoolOrNullableBool for Bool {}
672impl BoolOrNullableBool for Nullable<Bool> {}
673
674#[doc(inline)]
675pub use crate::expression::expression_types::Untyped;