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}