diesel/pg/types/
mod.rs

1//! PostgreSQL specific types
2
3mod array;
4#[doc(hidden)]
5pub(in crate::pg) mod date_and_time;
6#[doc(hidden)]
7pub(in crate::pg) mod floats;
8mod integers;
9#[cfg(feature = "ipnet-address")]
10mod ipnet_address;
11#[cfg(feature = "serde_json")]
12mod json;
13mod mac_addr;
14#[doc(hidden)]
15pub(in crate::pg) mod money;
16#[cfg(feature = "network-address")]
17mod network_address;
18mod numeric;
19mod primitives;
20mod ranges;
21mod record;
22#[cfg(feature = "uuid")]
23mod uuid;
24
25/// PostgreSQL specific SQL types
26///
27/// Note: All types in this module can be accessed through `diesel::sql_types`
28pub mod sql_types {
29    use crate::query_builder::QueryId;
30    use crate::sql_types::SqlType;
31
32    /// The [`OID`] SQL type. This is a PostgreSQL specific type.
33    ///
34    /// ### [`ToSql`] impls
35    ///
36    /// - [`u32`]
37    ///
38    /// ### [`FromSql`] impls
39    ///
40    /// - [`u32`]
41    ///
42    /// [`ToSql`]: crate::serialize::ToSql
43    /// [`FromSql`]: crate::deserialize::FromSql
44    /// [`u32`]: https://doc.rust-lang.org/nightly/std/primitive.u32.html
45    /// [`OID`]: https://www.postgresql.org/docs/current/datatype-oid.html
46    #[cfg(feature = "postgres_backend")]
47    #[derive(Debug, Clone, Copy, Default, QueryId, SqlType)]
48    #[diesel(postgres_type(oid = 26, array_oid = 1018))]
49    pub struct Oid;
50
51    /// The ["timestamp with time zone" SQL type][tz], which PostgreSQL abbreviates
52    /// to `timestamptz`.
53    ///
54    /// ### [`ToSql`] impls
55    ///
56    /// - [`PgTimestamp`]
57    /// - [`chrono::NaiveDateTime`] with `feature = "chrono"`
58    /// - [`chrono::DateTime`] with `feature = "chrono"`
59    /// - [`time::PrimitiveDateTime`] with `feature = "time"`
60    /// - [`time::OffsetDateTime`] with `feature = "time"`
61    ///
62    /// ### [`FromSql`] impls
63    ///
64    /// - [`PgTimestamp`]
65    /// - [`chrono::NaiveDateTime`] with `feature = "chrono"`
66    /// - [`chrono::DateTime`] with `feature = "chrono"`
67    /// - [`time::PrimitiveDateTime`] with `feature = "time"`
68    /// - [`time::OffsetDateTime`] with `feature = "time"`
69    ///
70    /// [`ToSql`]: crate::serialize::ToSql
71    /// [`FromSql`]: crate::deserialize::FromSql
72    /// [`PgTimestamp`]: super::super::data_types::PgTimestamp
73    /// [tz]: https://www.postgresql.org/docs/current/datatype-datetime.html
74    #[cfg_attr(
75        feature = "chrono",
76        doc = " [`chrono::NaiveDateTime`]: chrono::naive::NaiveDateTime"
77    )]
78    #[cfg_attr(
79        not(feature = "chrono"),
80        doc = " [`chrono::NaiveDateTime`]: https://docs.rs/chrono/0.4.19/chrono/naive/struct.NaiveDateTime.html"
81    )]
82    #[cfg_attr(feature = "chrono", doc = " [`chrono::DateTime`]: chrono::DateTime")]
83    #[cfg_attr(
84        not(feature = "chrono"),
85        doc = " [`chrono::DateTime`]: https://docs.rs/chrono/0.4.19/chrono/struct.DateTime.html"
86    )]
87    #[cfg_attr(
88        feature = "time",
89        doc = " [`time::PrimitiveDateTime`]: time::PrimitiveDateTime"
90    )]
91    #[cfg_attr(
92        not(feature = "time"),
93        doc = " [`time::PrimitiveDateTime`]: https://docs.rs/time/0.3.9/time/struct.PrimitiveDateTime.html"
94    )]
95    #[cfg_attr(
96        feature = "time",
97        doc = " [`time::OffsetDateTime`]: time::OffsetDateTime"
98    )]
99    #[cfg_attr(
100        not(feature = "time"),
101        doc = " [`time::OffsetDateTime`]: https://docs.rs/time/0.3.9/time/struct.OffsetDateTime.html"
102    )]
103    #[cfg(feature = "postgres_backend")]
104    #[derive(Debug, Clone, Copy, Default, QueryId, SqlType)]
105    #[diesel(postgres_type(oid = 1184, array_oid = 1185))]
106    pub struct Timestamptz;
107
108    /// The [`Array`] SQL type.
109    ///
110    /// This wraps another type to represent a SQL array of that type.
111    /// Multidimensional arrays are not supported.
112    ///
113    /// ### [`ToSql`] impls
114    ///
115    /// - [`Vec<T>`][Vec] for any `T` which implements `ToSql<ST>`
116    /// - [`&[T]`][slice] for any `T` which implements `ToSql<ST>`
117    ///
118    /// ### [`FromSql`] impls
119    ///
120    /// - [`Vec<T>`][Vec] for any `T` which implements `ToSql<ST>`
121    ///
122    /// [`ToSql`]: crate::serialize::ToSql
123    /// [`FromSql`]: crate::deserialize::FromSql
124    /// [Vec]: std::vec::Vec
125    /// [slice]: https://doc.rust-lang.org/nightly/std/primitive.slice.html
126    /// [`Array`]: https://www.postgresql.org/docs/current/arrays.html
127    #[derive(Debug, Clone, Copy, Default, QueryId, SqlType)]
128    #[cfg(feature = "postgres_backend")]
129    pub struct Array<ST: 'static>(ST);
130
131    /// The [`Range`] SQL type.
132    ///
133    /// This wraps another type to represent a SQL range of that type.
134    ///
135    /// ### [`ToSql`] impls
136    ///
137    /// - [`(Bound<T>, Bound<T>)`][bound] for any `T` which implements `ToSql<ST>`.
138    ///
139    /// ### [`FromSql`] impls
140    ///
141    /// - [`(Bound<T>, Bound<T>)`][bound] for any `T` which implements `FromSql<ST>`.
142    ///
143    /// [`ToSql`]: crate::serialize::ToSql
144    /// [`FromSql`]: crate::deserialize::FromSql
145    /// [bound]: std::collections::Bound
146    /// [`Range`]: https://www.postgresql.org/docs/current/rangetypes.html
147    #[derive(Debug, Clone, Copy, Default, QueryId, SqlType)]
148    #[cfg(feature = "postgres_backend")]
149    pub struct Range<ST: 'static>(ST);
150
151    #[doc(hidden)]
152    pub type Int4range = Range<crate::sql_types::Int4>;
153    #[doc(hidden)]
154    pub type Int8range = Range<crate::sql_types::Int8>;
155    #[doc(hidden)]
156    pub type Daterange = Range<crate::sql_types::Date>;
157    #[doc(hidden)]
158    pub type Numrange = Range<crate::sql_types::Numeric>;
159    #[doc(hidden)]
160    pub type Tsrange = Range<crate::sql_types::Timestamp>;
161    #[doc(hidden)]
162    pub type Tstzrange = Range<crate::sql_types::Timestamptz>;
163
164    /// The [`Record`] (a.k.a. tuple) SQL type.
165    ///
166    /// ### [`ToSql`] impls
167    ///
168    /// - Any tuple which can be serialized to each of the elements
169    ///   (note: There are major caveats, see the section below)
170    ///
171    /// ### [`FromSql`] impls
172    ///
173    /// - Any tuple which can be deserialized from each of the elements.
174    ///
175    /// [`ToSql`]: crate::serialize::ToSql
176    /// [`FromSql`]: crate::deserialize::FromSql
177    ///
178    /// ### Caveats about serialization
179    ///
180    /// Typically in the documentation for SQL types, we use "`FromSql` impls"
181    /// as a shorthand for "Rust types that you can use to represent this type".
182    /// For every other type, that means there is specifically an implementation
183    /// of the `FromSql` trait.
184    ///
185    /// However, PostgreSQL does not support transmission of anonymous record
186    /// types as bind parameters. It only supports transmission for named
187    /// composite types. For this reason, if you tried to do
188    /// `int_tuple_col.eq((1, 2))`, we will generate the SQL `int_tuple_col =
189    /// ($1, $2)` rather than `int_tuple_col = $1` as we would for anything
190    /// else.
191    ///
192    /// This should not be visible during normal usage. The only time this would
193    /// affect you is if you were attempting to use `sql_query` with tuples.
194    /// Your code would not compile in that case, as the `ToSql` trait itself is
195    /// not implemented.
196    ///
197    /// You can implement `ToSql` for named composite types. See [`WriteTuple`]
198    /// for details.
199    ///
200    /// [`WriteTuple`]: super::super::super::serialize::WriteTuple
201    /// [`Record`]: https://www.postgresql.org/docs/current/rowtypes.html
202    #[cfg(feature = "postgres_backend")]
203    #[derive(Debug, Clone, Copy, Default, QueryId, SqlType)]
204    #[diesel(postgres_type(oid = 2249, array_oid = 2287))]
205    pub struct Record<ST: 'static>(ST);
206
207    /// Alias for [`SmallInt`](crate::sql_types::SmallInt)
208    #[cfg(feature = "postgres_backend")]
209    pub type SmallSerial = crate::sql_types::SmallInt;
210
211    /// Alias for [`Integer`](crate::sql_types::Integer)
212    #[cfg(feature = "postgres_backend")]
213    pub type Serial = crate::sql_types::Integer;
214
215    /// Alias for [`BigInt`](crate::sql_types::BigInt)
216    #[cfg(feature = "postgres_backend")]
217    pub type BigSerial = crate::sql_types::BigInt;
218
219    /// The [`UUID`] SQL type. This type can only be used with `feature = "uuid"`
220    ///
221    /// ### [`ToSql`] impls
222    ///
223    /// - [`uuid::Uuid`][Uuid]
224    ///
225    /// ### [`FromSql`] impls
226    ///
227    /// - [`uuid::Uuid`][Uuid]
228    ///
229    /// [`ToSql`]: crate::serialize::ToSql
230    /// [`FromSql`]: crate::deserialize::FromSql
231    /// [Uuid]: https://docs.rs/uuid/*/uuid/struct.Uuid.html
232    /// [`UUID`]: https://www.postgresql.org/docs/current/datatype-uuid.html
233    #[cfg(feature = "postgres_backend")]
234    #[derive(Debug, Clone, Copy, Default, QueryId, SqlType)]
235    #[diesel(postgres_type(oid = 2950, array_oid = 2951))]
236    pub struct Uuid;
237
238    /// Alias for `Binary`, to ensure `diesel print-schema` works
239    pub type Bytea = crate::sql_types::Binary;
240
241    #[doc(hidden)]
242    pub type Bpchar = crate::sql_types::VarChar;
243
244    /// The [`jsonb`] SQL type.  This type can only be used with `feature =
245    /// "serde_json"`
246    ///
247    /// `jsonb` offers [several advantages][adv] over regular JSON:
248    ///
249    /// > There are two JSON data types: `json` and `jsonb`. They accept almost
250    /// > identical sets of values as input. The major practical difference
251    /// > is one of efficiency. The `json` data type stores an exact copy of
252    /// > the input text, which processing functions must reparse on each
253    /// > execution; while `jsonb` data is stored in a decomposed binary format
254    /// > that makes it slightly slower to input due to added conversion
255    /// > overhead, but significantly faster to process, since no reparsing
256    /// > is needed. `jsonb` also supports indexing, which can be a significant
257    /// > advantage.
258    /// >
259    /// > ...In general, most applications should prefer to store JSON data as
260    /// > `jsonb`, unless there are quite specialized needs, such as legacy
261    /// > assumptions about ordering of object keys.
262    ///
263    /// [adv]: https://www.postgresql.org/docs/current/static/datatype-json.html
264    ///
265    /// ### [`ToSql`] impls
266    ///
267    /// - [`serde_json::Value`]
268    ///
269    /// ### [`FromSql`] impls
270    ///
271    /// - [`serde_json::Value`]
272    ///
273    /// [`ToSql`]: crate::serialize::ToSql
274    /// [`FromSql`]: crate::deserialize::FromSql
275    /// [`jsonb`]: https://www.postgresql.org/docs/current/datatype-json.html
276    #[cfg_attr(
277        feature = "serde_json",
278        doc = "[`serde_json::Value`]: serde_json::value::Value"
279    )]
280    #[cfg_attr(
281        not(feature = "serde_json"),
282        doc = "[`serde_json::Value`]: https://docs.rs/serde_json/1.0.64/serde_json/value/enum.Value.html"
283    )]
284    ///
285    /// # Examples
286    ///
287    /// ```rust
288    /// # #![allow(dead_code)]
289    /// # include!("../../doctest_setup.rs");
290    /// #
291    /// table! {
292    ///     contacts {
293    ///         id -> Integer,
294    ///         name -> VarChar,
295    ///         address -> Jsonb,
296    ///     }
297    /// }
298    ///
299    /// # #[cfg(feature = "serde_json")]
300    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
301    /// #     use diesel::insert_into;
302    /// #     use self::contacts::dsl::*;
303    /// #     let connection = &mut connection_no_data();
304    /// #     diesel::sql_query("CREATE TABLE contacts (
305    /// #         id SERIAL PRIMARY KEY,
306    /// #         name VARCHAR NOT NULL,
307    /// #         address JSONB NOT NULL
308    /// #     )").execute(connection)?;
309    /// let santas_address: serde_json::Value = serde_json::from_str(r#"{
310    ///     "street": "Article Circle Expressway 1",
311    ///     "city": "North Pole",
312    ///     "postcode": "99705",
313    ///     "state": "Alaska"
314    /// }"#)?;
315    /// let inserted_address = insert_into(contacts)
316    ///     .values((name.eq("Claus"), address.eq(&santas_address)))
317    ///     .returning(address)
318    ///     .get_result::<serde_json::Value>(connection)?;
319    /// assert_eq!(santas_address, inserted_address);
320    /// #     Ok(())
321    /// # }
322    /// # #[cfg(not(feature = "serde_json"))]
323    /// # fn main() {}
324    /// ```
325    #[cfg(feature = "postgres_backend")]
326    #[derive(Debug, Clone, Copy, Default, QueryId, SqlType)]
327    #[diesel(postgres_type(oid = 3802, array_oid = 3807))]
328    pub struct Jsonb;
329
330    /// The PostgreSQL [Money](https://www.postgresql.org/docs/current/static/datatype-money.html) type.
331    ///
332    /// ### [`ToSql`] impls
333    ///
334    /// - [`Cents` (also aliased as `PgMoney`)][PgMoney]
335    ///
336    /// ### [`FromSql`] impls
337    ///
338    /// - [`Cents` (also aliased as `PgMoney`)][PgMoney]
339    ///
340    /// [`ToSql`]: crate::serialize::ToSql
341    /// [`FromSql`]: crate::deserialize::FromSql
342    /// [PgMoney]: crate::data_types::PgMoney
343    ///
344    /// # Examples
345    ///
346    /// ```rust
347    /// # include!("../../doctest_setup.rs");
348    /// use diesel::data_types::Cents;
349    ///
350    /// table! {
351    ///     items {
352    ///         id -> Integer,
353    ///         name -> VarChar,
354    ///         price -> Money,
355    ///     }
356    /// }
357    ///
358    /// # fn main() {
359    /// #     use diesel::insert_into;
360    /// #     use self::items::dsl::*;
361    /// #     let connection = &mut connection_no_data();
362    /// #     diesel::sql_query("CREATE TABLE items (
363    /// #         id SERIAL PRIMARY KEY,
364    /// #         name VARCHAR NOT NULL,
365    /// #         price MONEY NOT NULL
366    /// #     )").execute(connection).unwrap();
367    /// let inserted_price = insert_into(items)
368    ///     .values((name.eq("Shiny Thing"), price.eq(Cents(123_456))))
369    ///     .returning(price)
370    ///     .get_result(connection);
371    /// assert_eq!(Ok(Cents(123_456)), inserted_price);
372    /// # }
373    /// ```
374    #[cfg(feature = "postgres_backend")]
375    #[derive(Debug, Clone, Copy, Default, QueryId, SqlType)]
376    #[diesel(postgres_type(oid = 790, array_oid = 791))]
377    pub struct Money;
378
379    /// The [`MACADDR`](https://www.postgresql.org/docs/current/static/datatype-net-types.html) SQL type.
380    ///
381    /// ### [`ToSql`] impls
382    ///
383    /// - `[u8; 6]`
384    ///
385    /// ### [`FromSql`] impls
386    ///
387    /// - `[u8; 6]`
388    ///
389    /// [`ToSql`]: crate::serialize::ToSql
390    /// [`FromSql`]: crate::deserialize::FromSql
391    ///
392    /// # Examples
393    ///
394    /// ```rust
395    /// # include!("../../doctest_setup.rs");
396    /// table! {
397    ///     devices {
398    ///         id -> Integer,
399    ///         macaddr -> MacAddr,
400    ///     }
401    /// }
402    ///
403    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
404    /// #     use diesel::insert_into;
405    /// #     use self::devices::dsl::*;
406    /// #     let connection = &mut connection_no_data();
407    /// #     diesel::sql_query("CREATE TABLE devices (
408    /// #         id SERIAL PRIMARY KEY,
409    /// #         macaddr MACADDR NOT NULL
410    /// #     )").execute(connection)?;
411    /// let inserted_macaddr = insert_into(devices)
412    ///     .values(macaddr.eq([0x08, 0x00, 0x2b, 0x01, 0x02, 0x03]))
413    ///     .returning(macaddr)
414    ///     .get_result::<[u8; 6]>(connection)?;
415    /// assert_eq!([0x08, 0x00, 0x2b, 0x01, 0x02, 0x03], inserted_macaddr);
416    /// #     Ok(())
417    /// # }
418    /// ```
419    #[cfg(feature = "postgres_backend")]
420    #[derive(Debug, Clone, Copy, Default, QueryId, SqlType)]
421    #[diesel(postgres_type(oid = 829, array_oid = 1040))]
422    pub struct MacAddr;
423
424    /// Alias for `MacAddr` to be able to use it with `diesel print-schema`.
425    pub type Macaddr = MacAddr;
426
427    /// The [`INET`](https://www.postgresql.org/docs/current/static/datatype-net-types.html) SQL type. This type can only be used with `feature = "network-address"` or `feature = "ipnet-address"`.
428    ///
429    /// ### [`ToSql`] impls
430    ///
431    #[cfg_attr(
432        feature = "network-address",
433        doc = " - [`ipnetwork::IpNetwork`][IpNetwork]"
434    )]
435    #[cfg_attr(feature = "ipnet-address", doc = " - [`ipnet::IpNet`][IpNet]")]
436    #[cfg_attr(
437        not(any(feature = "network-address", feature = "ipnet-address")),
438        doc = "N/A"
439    )]
440    ///
441    /// ### [`FromSql`] impls
442    ///
443    #[cfg_attr(
444        feature = "network-address",
445        doc = " - [`ipnetwork::IpNetwork`][IpNetwork]"
446    )]
447    #[cfg_attr(feature = "ipnet-address", doc = " - [`ipnet::IpNet`][IpNet]")]
448    #[cfg_attr(
449        not(any(feature = "network-address", feature = "ipnet-address")),
450        doc = "N/A"
451    )]
452    ///
453    /// [`ToSql`]: crate::serialize::ToSql
454    /// [`FromSql`]: crate::deserialize::FromSql
455    #[cfg_attr(
456        feature = "network-address",
457        doc = " [IpNetwork]: ipnetwork::IpNetwork"
458    )]
459    #[cfg_attr(feature = "ipnet-address", doc = " [IpNet]: ipnet::IpNet")]
460    ///
461    /// # Examples
462    ///
463    /// ```rust
464    /// # include!("../../doctest_setup.rs");
465    /// #
466    /// table! {
467    ///     clients {
468    ///         id -> Integer,
469    ///         ip_address -> Inet,
470    ///     }
471    /// }
472    ///
473    /// # #[cfg(any(feature = "network-address", feature = "ipnet-address"))]
474    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
475    ///
476    /// #     use diesel::insert_into;
477    /// #     use self::clients::dsl::*;
478    /// #     let connection = &mut connection_no_data();
479    /// #     diesel::sql_query("CREATE TABLE clients (
480    /// #         id SERIAL PRIMARY KEY,
481    /// #         ip_address INET NOT NULL
482    /// #     )").execute(connection)?;
483    /// // Parsing "ipnet::IpNet" would also work.
484    /// let addr = "10.1.9.32/32".parse::<ipnetwork::IpNetwork>()?;
485    /// let inserted_address = insert_into(clients)
486    ///     .values(ip_address.eq(&addr))
487    ///     .returning(ip_address)
488    ///     .get_result(connection)?;
489    /// assert_eq!(addr, inserted_address);
490    /// #     Ok(())
491    /// # }
492    /// #
493    /// # #[cfg(not(any(feature = "network-address", feature = "ipnet-address")))]
494    /// # fn main() {}
495    /// ```
496    #[cfg(feature = "postgres_backend")]
497    #[derive(Debug, Clone, Copy, Default, QueryId, SqlType)]
498    #[diesel(postgres_type(oid = 869, array_oid = 1041))]
499    pub struct Inet;
500
501    /// The [`CIDR`](https://www.postgresql.org/docs/postgresql/static/datatype-net-types.html) SQL type. This type can only be used with `feature = "network-address"` or `feature = "ipnet-address"`.
502    ///
503    /// ### [`ToSql`] impls
504    ///
505    #[cfg_attr(
506        feature = "network-address",
507        doc = " - [`ipnetwork::IpNetwork`][IpNetwork]"
508    )]
509    #[cfg_attr(feature = "ipnet-address", doc = " - [`ipnet::IpNet`][IpNet]")]
510    #[cfg_attr(
511        not(any(feature = "network-address", feature = "ipnet-address")),
512        doc = "N/A"
513    )]
514    ///
515    /// ### [`FromSql`] impls
516    ///
517    #[cfg_attr(
518        feature = "network-address",
519        doc = " - [`ipnetwork::IpNetwork`][IpNetwork]"
520    )]
521    #[cfg_attr(feature = "ipnet-address", doc = " - [`ipnet::IpNet`][IpNet]")]
522    #[cfg_attr(
523        not(any(feature = "network-address", feature = "ipnet-address")),
524        doc = "N/A"
525    )]
526    ///
527    /// [`ToSql`]: crate::serialize::ToSql
528    /// [`FromSql`]: crate::deserialize::FromSql
529    #[cfg_attr(
530        feature = "network-address",
531        doc = " [IpNetwork]: ipnetwork::IpNetwork"
532    )]
533    #[cfg_attr(feature = "ipnet-address", doc = " [IpNet]: ipnet::IpNet")]
534    ///
535    /// # Examples
536    ///
537    /// ```rust
538    /// # #![allow(dead_code)]
539    /// # include!("../../doctest_setup.rs");
540    /// table! {
541    ///     clients {
542    ///         id -> Integer,
543    ///         ip_address -> Cidr,
544    ///     }
545    /// }
546    ///
547    /// # #[cfg(any(feature = "network-address", feature = "ipnet-address"))]
548    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
549    ///
550    /// #     use diesel::insert_into;
551    /// #     use self::clients::dsl::*;
552    /// #     let connection = &mut connection_no_data();
553    /// #     diesel::sql_query("CREATE TABLE clients (
554    /// #         id SERIAL PRIMARY KEY,
555    /// #         ip_address CIDR NOT NULL
556    /// #     )").execute(connection)?;
557    /// // Parsing "ipnet::IpNet" would also work.
558    /// let addr = "10.1.9.32/32".parse::<ipnetwork::IpNetwork>()?;
559    /// let inserted_addr = insert_into(clients)
560    ///     .values(ip_address.eq(&addr))
561    ///     .returning(ip_address)
562    ///     .get_result(connection)?;
563    /// assert_eq!(addr, inserted_addr);
564    /// #     Ok(())
565    /// # }
566    /// # #[cfg(not(any(feature = "network-address", feature = "ipnet-address")))]
567    /// # fn main() {}
568    /// ```
569    #[cfg(feature = "postgres_backend")]
570    #[derive(Debug, Clone, Copy, Default, QueryId, SqlType)]
571    #[diesel(postgres_type(oid = 650, array_oid = 651))]
572    pub struct Cidr;
573
574    /// The [`"char"`] SQL type. This is a PostgreSQL specific type. Used for e.g. [setweight]. [Do not use in user tables].
575    ///
576    /// ### [`ToSql`] impls
577    ///
578    /// - [`u8`]
579    ///
580    /// ### [`FromSql`] impls
581    ///
582    /// - [`u8`]
583    ///
584    /// [`ToSql`]: crate::serialize::ToSql
585    /// [`FromSql`]: crate::deserialize::FromSql
586    /// [`u8`]: https://doc.rust-lang.org/nightly/std/primitive.u8.html
587    /// [`"char"`]: https://www.postgresql.org/docs/current/datatype-character.html#DATATYPE-CHARACTER-SPECIAL-TABLE
588    /// [setweight]: https://www.postgresql.org/docs/current/functions-textsearch.html
589    /// [Do not use in user tables]: https://www.postgresql.org/docs/current/datatype-character.html#DATATYPE-CHARACTER-SPECIAL-TABLE
590    #[cfg(feature = "postgres_backend")]
591    #[derive(Debug, Clone, Copy, Default, QueryId, SqlType)]
592    #[diesel(postgres_type(oid = 18, array_oid = 1002))]
593    pub struct CChar;
594
595    /// The [`Citext`] SQL type. This is a PostgreSQL specific type.
596    ///
597    /// Strings must be valid UTF-8.
598    ///
599    /// ### [`ToSql`] impls
600    ///
601    /// - [`String`]
602    /// - [`&str`][str]
603    ///
604    /// ### [`FromSql`] impls
605    ///
606    /// - [`String`]
607    ///
608    /// [`ToSql`]: crate::serialize::ToSql
609    /// [`FromSql`]: crate::deserialize::FromSql
610    /// [`Citext`]: https://www.postgresql.org/docs/current/citext.html
611    #[cfg(feature = "postgres_backend")]
612    #[derive(Debug, Clone, Copy, Default, QueryId, SqlType)]
613    #[diesel(postgres_type(name = "citext"))]
614    pub struct Citext;
615}
616
617mod ops {
618    use super::sql_types::*;
619    use crate::sql_types::ops::*;
620    use crate::sql_types::{Bigint, Interval};
621
622    impl Add for Timestamptz {
623        type Rhs = Interval;
624        type Output = Timestamptz;
625    }
626
627    impl Sub for Timestamptz {
628        type Rhs = Interval;
629        type Output = Timestamptz;
630    }
631
632    impl Add for Cidr {
633        type Rhs = Bigint;
634        type Output = Inet;
635    }
636
637    impl Add for Inet {
638        type Rhs = Bigint;
639        type Output = Inet;
640    }
641
642    impl Sub for Cidr {
643        type Rhs = Bigint;
644        type Output = Inet;
645    }
646
647    impl Sub for Inet {
648        type Rhs = Bigint;
649        type Output = Inet;
650    }
651}