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