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"))]
401#[diesel(sqlite_type(name = "Text"))]
402pub struct Json;
403
404/// The [`jsonb`] SQL type. This type can only be used with `feature =
405/// "serde_json"`
406///
407/// In SQLite, `jsonb` brings mainly [performance improvements][sqlite-adv] over
408/// regular JSON:
409///
410/// > The advantage of JSONB in SQLite is that it is smaller and faster than
411/// > text JSON - potentially several times faster. There is space in the
412/// > on-disk JSONB format to add enhancements and future versions of SQLite
413/// > might include options to provide O(1) lookup of elements in JSONB, but no
414/// > such capability is currently available.
415///
416/// <div class="warning">
417/// In SQLite, JSONB is intended for internal use by SQLite only. Thus, future
418/// SQLite updates might break our JSONB implementation. And one might have to
419/// wait and then upgrade <code>diesel</code> for those changes to be accounted
420/// for. If you do not want this, prefer the regular
421/// <a href="./struct.Json.html"><code>Json</code></a> type.
422/// </div>
423///
424/// In PostgreSQL, `jsonb` offers [several advantages][pg-adv] over regular JSON:
425///
426/// > There are two JSON data types: `json` and `jsonb`. They accept almost
427/// > identical sets of values as input. The major practical difference
428/// > is one of efficiency. The `json` data type stores an exact copy of
429/// > the input text, which processing functions must reparse on each
430/// > execution; while `jsonb` data is stored in a decomposed binary format
431/// > that makes it slightly slower to input due to added conversion
432/// > overhead, but significantly faster to process, since no reparsing
433/// > is needed. `jsonb` also supports indexing, which can be a significant
434/// > advantage.
435/// >
436/// > ...In general, most applications should prefer to store JSON data as
437/// > `jsonb`, unless there are quite specialized needs, such as legacy
438/// > assumptions about ordering of object keys.
439///
440/// [pg-adv]: https://www.postgresql.org/docs/current/static/datatype-json.html
441/// [sqlite-adv]: https://sqlite.org/draft/jsonb.html
442///
443/// ### [`ToSql`] impls
444///
445/// - [`serde_json::Value`]
446///
447/// ### [`FromSql`] impls
448///
449/// - [`serde_json::Value`]
450///
451/// [`ToSql`]: crate::serialize::ToSql
452/// [`FromSql`]: crate::deserialize::FromSql
453/// [`jsonb`]: https://www.postgresql.org/docs/current/datatype-json.html
454#[cfg_attr(
455 feature = "serde_json",
456 doc = "[`serde_json::Value`]: serde_json::value::Value"
457)]
458#[cfg_attr(
459 not(feature = "serde_json"),
460 doc = "[`serde_json::Value`]: https://docs.rs/serde_json/1.0.64/serde_json/value/enum.Value.html"
461)]
462///
463/// ## Examples
464///
465/// ```rust
466/// # #![allow(dead_code)]
467/// # include!("../doctest_setup.rs");
468/// #
469/// table! {
470/// contacts {
471/// id -> Integer,
472/// name -> Text,
473/// address -> Jsonb,
474/// }
475/// }
476///
477/// # #[cfg(all(
478/// # feature = "serde_json",
479/// # any(
480/// # feature = "postgres_backend",
481/// # all(feature = "sqlite", feature = "returning_clauses_for_sqlite_3_35"),
482/// # )
483/// # ))]
484/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
485/// # use diesel::insert_into;
486/// # use self::contacts::dsl::*;
487/// # let connection = &mut connection_no_data();
488/// # #[cfg(feature = "postgres_backend")]
489/// # diesel::sql_query("CREATE TABLE contacts (
490/// # id SERIAL PRIMARY KEY,
491/// # name VARCHAR NOT NULL,
492/// # address JSONB NOT NULL
493/// # )").execute(connection)?;
494/// # #[cfg(feature = "sqlite")]
495/// # diesel::sql_query("CREATE TABLE contacts (
496/// # id INT PRIMARY KEY,
497/// # name TEXT NOT NULL,
498/// # address BLOB NOT NULL
499/// # )").execute(connection)?;
500/// let santas_address: serde_json::Value = serde_json::from_str(r#"{
501/// "street": "Article Circle Expressway 1",
502/// "city": "North Pole",
503/// "postcode": "99705",
504/// "state": "Alaska"
505/// }"#)?;
506/// let inserted_address = insert_into(contacts)
507/// .values((name.eq("Claus"), address.eq(&santas_address)))
508/// .returning(address)
509/// .get_result::<serde_json::Value>(connection)?;
510/// assert_eq!(santas_address, inserted_address);
511/// # Ok(())
512/// # }
513/// # #[cfg(not(all(
514/// # feature = "serde_json",
515/// # any(
516/// # feature = "postgres_backend",
517/// # all(feature = "sqlite", feature = "returning_clauses_for_sqlite_3_35"),
518/// # )
519/// # )))]
520/// # fn main() {}
521/// ```
522#[derive(Debug, Clone, Copy, Default, QueryId, SqlType)]
523#[diesel(postgres_type(oid = 3802, array_oid = 3807))]
524#[diesel(sqlite_type(name = "Binary"))]
525pub struct Jsonb;
526
527/// The nullable SQL type.
528///
529/// This wraps another SQL type to indicate that it can be null.
530/// By default all values are assumed to be `NOT NULL`.
531///
532/// ### [`ToSql`](crate::serialize::ToSql) impls
533///
534/// - Any `T` which implements `ToSql<ST>`
535/// - `Option<T>` for any `T` which implements `ToSql<ST>`
536///
537/// ### [`FromSql`](crate::deserialize::FromSql) impls
538///
539/// - `Option<T>` for any `T` which implements `FromSql<ST>`
540#[derive(Debug, Clone, Copy, Default)]
541pub struct Nullable<ST>(ST);
542
543impl<ST> SqlType for Nullable<ST>
544where
545 ST: SqlType,
546{
547 type IsNull = is_nullable::IsNullable;
548}
549
550#[doc(inline)]
551#[cfg(feature = "postgres_backend")]
552pub use crate::pg::sql_types::*;
553
554#[doc(inline)]
555#[cfg(feature = "mysql_backend")]
556pub use crate::mysql::sql_types::{Datetime, Unsigned};
557
558#[doc(inline)]
559#[cfg(feature = "sqlite")]
560pub use crate::sqlite::sql_types::Timestamptz as TimestamptzSqlite;
561
562/// Indicates that a SQL type exists for a backend.
563///
564/// This trait can be derived using the [`SqlType` derive](derive@SqlType)
565///
566/// # Example
567///
568/// ```rust
569/// #[derive(diesel::sql_types::SqlType)]
570/// #[diesel(postgres_type(oid = 23, array_oid = 1007))]
571/// #[diesel(sqlite_type(name = "Integer"))]
572/// #[diesel(mysql_type(name = "Long"))]
573/// pub struct Integer;
574/// ```
575pub trait HasSqlType<ST>: TypeMetadata {
576 /// Fetch the metadata for the given type
577 ///
578 /// This method may use `lookup` to do dynamic runtime lookup. Implementors
579 /// of this method should not do dynamic lookup unless absolutely necessary
580 fn metadata(lookup: &mut Self::MetadataLookup) -> Self::TypeMetadata;
581}
582
583/// Information about how a backend stores metadata about given SQL types
584pub trait TypeMetadata {
585 /// The actual type used to represent metadata.
586 ///
587 /// On PostgreSQL, this is the type's OID.
588 /// On MySQL and SQLite, this is an enum representing all storage classes
589 /// they support.
590 type TypeMetadata;
591 /// The type used for runtime lookup of metadata.
592 ///
593 /// For most backends, which don't support user defined types, this will
594 /// be `()`.
595 type MetadataLookup: ?Sized;
596}
597
598/// Converts a type which may or may not be nullable into its nullable
599/// representation.
600pub trait IntoNullable {
601 /// The nullable representation of this type.
602 ///
603 /// For all types except `Nullable`, this will be `Nullable<Self>`.
604 type Nullable;
605}
606
607impl<T> IntoNullable for T
608where
609 T: SqlType<IsNull = is_nullable::NotNull> + SingleValue,
610{
611 type Nullable = Nullable<T>;
612}
613
614impl<T> IntoNullable for Nullable<T>
615where
616 T: SqlType,
617{
618 type Nullable = Self;
619}
620
621/// Converts a type which may or may not be nullable into its not nullable
622/// representation.
623pub trait IntoNotNullable {
624 /// The not nullable representation of this type.
625 ///
626 /// For `Nullable<T>`, this will be `T` otherwise the type itself
627 type NotNullable;
628}
629
630impl<T> IntoNotNullable for T
631where
632 T: SqlType<IsNull = is_nullable::NotNull>,
633{
634 type NotNullable = T;
635}
636
637impl<T> IntoNotNullable for Nullable<T>
638where
639 T: SqlType,
640{
641 type NotNullable = T;
642}
643
644/// A marker trait indicating that a SQL type represents a single value, as
645/// opposed to a list of values.
646///
647/// This trait should generally be implemented for all SQL types with the
648/// exception of Rust tuples. If a column could have this as its type, this
649/// trait should be implemented.
650///
651/// # Deriving
652///
653/// This trait is automatically implemented by [`#[derive(SqlType)]`](derive@SqlType)
654///
655pub trait SingleValue: SqlType {}
656
657impl<T: SqlType + SingleValue> SingleValue for Nullable<T> {}
658
659#[doc(inline)]
660pub use diesel_derives::DieselNumericOps;
661#[doc(inline)]
662pub use diesel_derives::SqlType;
663
664/// A marker trait for SQL types
665///
666/// # Deriving
667///
668/// This trait is automatically implemented by [`#[derive(SqlType)]`](derive@SqlType)
669/// which sets `IsNull` to [`is_nullable::NotNull`]
670///
671pub trait SqlType: 'static {
672 /// Is this type nullable?
673 ///
674 /// This type should always be one of the structs in the ['is_nullable`]
675 /// module. See the documentation of those structs for more details.
676 ///
677 /// ['is_nullable`]: is_nullable
678 type IsNull: OneIsNullable<is_nullable::IsNullable> + OneIsNullable<is_nullable::NotNull>;
679
680 #[doc(hidden)]
681 const IS_ARRAY: bool = false;
682}
683
684/// Is one value of `IsNull` nullable?
685///
686/// You should never implement this trait.
687pub trait OneIsNullable<Other> {
688 /// See the trait documentation
689 type Out: OneIsNullable<is_nullable::IsNullable> + OneIsNullable<is_nullable::NotNull>;
690}
691
692/// Are both values of `IsNull` are nullable?
693pub trait AllAreNullable<Other> {
694 /// See the trait documentation
695 type Out: AllAreNullable<is_nullable::NotNull> + AllAreNullable<is_nullable::IsNullable>;
696}
697
698/// A type level constructor for maybe nullable types
699///
700/// Constructs either `Nullable<O>` (for `Self` == `is_nullable::IsNullable`)
701/// or `O` (for `Self` == `is_nullable::NotNull`)
702pub trait MaybeNullableType<O> {
703 /// See the trait documentation
704 type Out: SqlType + TypedExpressionType;
705}
706
707/// Possible values for `SqlType::IsNullable`
708pub mod is_nullable {
709 use super::*;
710
711 /// No, this type cannot be null as it is marked as `NOT NULL` at database level
712 ///
713 /// This should be chosen for basically all manual impls of `SqlType`
714 /// beside implementing your own `Nullable<>` wrapper type
715 #[derive(Debug, Clone, Copy)]
716 pub struct NotNull;
717
718 /// Yes, this type can be null
719 ///
720 /// The only diesel provided `SqlType` that uses this value is [`Nullable<T>`]
721 ///
722 /// [`Nullable<T>`]: Nullable
723 #[derive(Debug, Clone, Copy)]
724 pub struct IsNullable;
725
726 impl OneIsNullable<NotNull> for NotNull {
727 type Out = NotNull;
728 }
729
730 impl OneIsNullable<IsNullable> for NotNull {
731 type Out = IsNullable;
732 }
733
734 impl OneIsNullable<NotNull> for IsNullable {
735 type Out = IsNullable;
736 }
737
738 impl OneIsNullable<IsNullable> for IsNullable {
739 type Out = IsNullable;
740 }
741
742 impl AllAreNullable<NotNull> for NotNull {
743 type Out = NotNull;
744 }
745
746 impl AllAreNullable<IsNullable> for NotNull {
747 type Out = NotNull;
748 }
749
750 impl AllAreNullable<NotNull> for IsNullable {
751 type Out = NotNull;
752 }
753
754 impl AllAreNullable<IsNullable> for IsNullable {
755 type Out = IsNullable;
756 }
757
758 impl<O> MaybeNullableType<O> for NotNull
759 where
760 O: SqlType + TypedExpressionType,
761 {
762 type Out = O;
763 }
764
765 impl<O> MaybeNullableType<O> for IsNullable
766 where
767 O: SqlType,
768 Nullable<O>: TypedExpressionType,
769 {
770 type Out = Nullable<O>;
771 }
772
773 /// Represents the output type of [`MaybeNullableType`]
774 pub type MaybeNullable<N, T> = <N as MaybeNullableType<T>>::Out;
775
776 /// Represents the output type of [`OneIsNullable`]
777 /// for two given SQL types
778 pub type IsOneNullable<S1, S2> =
779 <IsSqlTypeNullable<S1> as OneIsNullable<IsSqlTypeNullable<S2>>>::Out;
780
781 /// Represents the output type of [`AllAreNullable`]
782 /// for two given SQL types
783 pub type AreAllNullable<S1, S2> =
784 <IsSqlTypeNullable<S1> as AllAreNullable<IsSqlTypeNullable<S2>>>::Out;
785
786 /// Represents if the SQL type is nullable or not
787 pub type IsSqlTypeNullable<T> = <T as SqlType>::IsNull;
788}
789
790/// A marker trait for accepting expressions of the type `Bool` and
791/// `Nullable<Bool>` in the same place
792#[diagnostic::on_unimplemented(
793 message = "`{Self}` is neither `diesel::sql_types::Bool` nor `diesel::sql_types::Nullable<Bool>`",
794 note = "try to provide an expression that produces one of the expected sql types"
795)]
796pub trait BoolOrNullableBool {}
797
798impl BoolOrNullableBool for Bool {}
799impl BoolOrNullableBool for Nullable<Bool> {}
800
801#[doc(inline)]
802pub use crate::expression::expression_types::Untyped;