diesel/pg/expression/functions.rs
1//! PostgreSQL specific functions
2
3use super::expression_methods::InetOrCidr;
4use crate::expression::functions::declare_sql_function;
5use crate::pg::expression::expression_methods::ArrayOrNullableArray;
6use crate::pg::expression::expression_methods::CombinedAllNullableValue;
7use crate::pg::expression::expression_methods::JsonOrNullableJson;
8use crate::pg::expression::expression_methods::JsonbOrNullableJsonb;
9use crate::pg::expression::expression_methods::MaybeNullableValue;
10use crate::pg::expression::expression_methods::MultirangeOrNullableMultirange;
11use crate::pg::expression::expression_methods::MultirangeOrRangeMaybeNullable;
12use crate::pg::expression::expression_methods::RangeOrNullableRange;
13use crate::pg::expression::expression_methods::RecordOrNullableRecord;
14use crate::pg::expression::expression_methods::TextArrayOrNullableTextArray;
15use crate::pg::expression::expression_methods::TextOrNullableText;
16use crate::sql_types::helper::CombinedNullableValue;
17use crate::sql_types::*;
18
19#[declare_sql_function(generate_return_type_helpers = true)]
20#[backends(crate::pg::Pg)]
21extern "SQL" {
22 /// Creates an abbreviated display format as text.
23 #[cfg(feature = "postgres_backend")]
24 fn abbrev<T: InetOrCidr + SingleValue>(addr: T) -> Text;
25
26 /// Computes the broadcast address for the address's network.
27 #[cfg(feature = "postgres_backend")]
28 fn broadcast<T: InetOrCidr + SingleValue>(addr: T) -> Inet;
29
30 /// Returns the address's family: 4 for IPv4, 6 for IPv6.
31 #[cfg(feature = "postgres_backend")]
32 fn family<T: InetOrCidr + SingleValue>(addr: T) -> Integer;
33
34 /// Returns the IP address as text, ignoring the netmask.
35 #[cfg(feature = "postgres_backend")]
36 fn host<T: InetOrCidr + SingleValue>(addr: T) -> Text;
37
38 /// Computes the host mask for the address's network.
39 #[cfg(feature = "postgres_backend")]
40 fn hostmask<T: InetOrCidr + SingleValue>(addr: T) -> Inet;
41
42 /// Computes the smallest network that includes both of the given networks.
43 #[cfg(feature = "postgres_backend")]
44 fn inet_merge<T: InetOrCidr + SingleValue, U: InetOrCidr + SingleValue>(a: T, b: U) -> Cidr;
45
46 /// Tests whether the addresses belong to the same IP family.
47 #[cfg(feature = "postgres_backend")]
48 fn inet_same_family<T: InetOrCidr + SingleValue, U: InetOrCidr + SingleValue>(
49 a: T,
50 b: U,
51 ) -> Bool;
52
53 /// Returns the netmask length in bits.
54 #[cfg(feature = "postgres_backend")]
55 fn masklen<T: InetOrCidr + SingleValue>(addr: T) -> Integer;
56
57 /// Computes the network mask for the address's network.
58 #[cfg(feature = "postgres_backend")]
59 fn netmask<T: InetOrCidr + SingleValue>(addr: T) -> Inet;
60
61 /// Returns the network part of the address, zeroing out whatever is to the right of the
62 /// netmask. (This is equivalent to casting the value to cidr.)
63 #[cfg(feature = "postgres_backend")]
64 fn network<T: InetOrCidr + SingleValue>(addr: T) -> Cidr;
65
66 /// Sets the netmask length for an inet or cidr value.
67 /// For inet, the address part does not changes. For cidr, address bits to the right of the new
68 /// netmask are set to zero.
69 #[cfg(feature = "postgres_backend")]
70 fn set_masklen<T: InetOrCidr + SingleValue>(addr: T, len: Integer) -> T;
71
72 /// Returns the lower bound of the range
73 ///
74 /// If the range is empty or has no lower bound, it returns NULL.
75 ///
76 /// # Example
77 ///
78 /// ```rust
79 /// # include!("../../doctest_setup.rs");
80 /// #
81 /// # fn main() {
82 /// # run_test().unwrap();
83 /// # }
84 /// #
85 /// # fn run_test() -> QueryResult<()> {
86 /// # use diesel::pg::sql_types::{Range, Multirange};
87 /// # use diesel::dsl::lower;
88 /// # use std::collections::Bound;
89 /// # use diesel::sql_types::{Nullable, Integer, Array};
90 /// # let connection = &mut establish_connection();
91 /// let int = diesel::select(lower::<Range<_>, _>(1..2)).get_result::<Option<i32>>(connection)?;
92 /// assert_eq!(Some(1), int);
93 ///
94 /// let int = diesel::select(lower::<Range<_>, _>(..2)).get_result::<Option<i32>>(connection)?;
95 /// assert_eq!(None, int);
96 ///
97 /// let int = diesel::select(lower::<Nullable<Range<_>>, _>(None::<std::ops::Range<i32>>))
98 /// .get_result::<Option<i32>>(connection)?;
99 /// assert_eq!(None, int);
100 ///
101 /// let int = diesel::select(lower::<Multirange<_>, _>(vec![5..7]))
102 /// .get_result::<Option<i32>>(connection)?;
103 /// assert_eq!(Some(5), int);
104 /// # Ok(())
105 /// # }
106 /// ```
107 #[cfg(feature = "postgres_backend")]
108 fn lower<R: MultirangeOrRangeMaybeNullable + SingleValue>(range: R) -> Nullable<R::Inner>;
109
110 /// Returns the upper bound of the range
111 ///
112 /// If the range is empty or has no upper bound, it returns NULL.
113 ///
114 /// # Example
115 ///
116 /// ```rust
117 /// # include!("../../doctest_setup.rs");
118 /// #
119 /// # fn main() {
120 /// # run_test().unwrap();
121 /// # }
122 /// #
123 /// # fn run_test() -> QueryResult<()> {
124 /// # use diesel::pg::sql_types::{Range, Multirange};
125 /// # use diesel::dsl::upper;
126 /// # use std::collections::Bound;
127 /// # use diesel::sql_types::{Nullable, Integer, Array};
128 /// # let connection = &mut establish_connection();
129 /// let int = diesel::select(upper::<Range<_>, _>(1..2)).get_result::<Option<i32>>(connection)?;
130 /// assert_eq!(Some(2), int);
131 ///
132 /// let int = diesel::select(upper::<Range<_>, _>(1..)).get_result::<Option<i32>>(connection)?;
133 /// assert_eq!(None, int);
134 ///
135 /// let int = diesel::select(upper::<Nullable<Range<_>>, _>(None::<std::ops::Range<i32>>))
136 /// .get_result::<Option<i32>>(connection)?;
137 /// assert_eq!(None, int);
138 ///
139 /// let int = diesel::select(upper::<Multirange<_>, _>(vec![5..7]))
140 /// .get_result::<Option<i32>>(connection)?;
141 /// assert_eq!(Some(7), int);
142 /// # Ok(())
143 /// # }
144 /// ```
145 #[cfg(feature = "postgres_backend")]
146 fn upper<R: MultirangeOrRangeMaybeNullable + SingleValue>(range: R) -> Nullable<R::Inner>;
147
148 /// Returns true if the range is empty
149 ///
150 /// # Example
151 ///
152 /// ```rust
153 /// # include!("../../doctest_setup.rs");
154 /// #
155 /// # fn main() {
156 /// # run_test().unwrap();
157 /// # }
158 /// #
159 /// # fn run_test() -> QueryResult<()> {
160 /// # use diesel::pg::sql_types::{Range, Multirange};
161 /// # use diesel::dsl::isempty;
162 /// # use std::collections::Bound;
163 /// # use diesel::sql_types::{Nullable, Integer, Array};
164 /// # let connection = &mut establish_connection();
165 /// let int = diesel::select(isempty::<Range<Integer>, _>(1..5)).get_result::<bool>(connection)?;
166 /// assert_eq!(false, int);
167 ///
168 /// let int = diesel::select(isempty::<Range<Integer>, _>(1..1)).get_result::<bool>(connection)?;
169 /// assert_eq!(true, int);
170 ///
171 /// let int = diesel::select(isempty::<Nullable<Range<Integer>>, _>(
172 /// None::<std::ops::Range<i32>>,
173 /// ))
174 /// .get_result::<Option<bool>>(connection)?;
175 /// assert_eq!(None, int);
176 ///
177 /// let int = diesel::select(isempty::<Multirange<Integer>, _>(vec![5..7]))
178 /// .get_result::<bool>(connection)?;
179 /// assert_eq!(false, int);
180 /// # Ok(())
181 /// # }
182 /// ```
183 #[cfg(feature = "postgres_backend")]
184 fn isempty<R: MultirangeOrRangeMaybeNullable + SingleValue + MaybeNullableValue<Bool>>(
185 range: R,
186 ) -> R::Out;
187
188 /// Returns true if the range's lower bound is inclusive
189 ///
190 /// # Example
191 ///
192 /// ```rust
193 /// # include!("../../doctest_setup.rs");
194 /// #
195 /// # fn main() {
196 /// # run_test().unwrap();
197 /// # }
198 /// #
199 /// # fn run_test() -> QueryResult<()> {
200 /// # use diesel::pg::sql_types::{Range, Multirange};
201 /// # use diesel::dsl::lower_inc;
202 /// # use std::collections::Bound;
203 /// # use diesel::sql_types::{Nullable, Integer, Array};
204 /// # let connection = &mut establish_connection();
205 /// let int =
206 /// diesel::select(lower_inc::<Range<Integer>, _>(1..5)).get_result::<bool>(connection)?;
207 /// assert_eq!(true, int);
208 ///
209 /// let int = diesel::select(lower_inc::<Range<Integer>, _>(..5)).get_result::<bool>(connection)?;
210 /// assert_eq!(false, int);
211 ///
212 /// let int = diesel::select(lower_inc::<Nullable<Range<Integer>>, _>(
213 /// None::<std::ops::Range<i32>>,
214 /// ))
215 /// .get_result::<Option<bool>>(connection)?;
216 /// assert_eq!(None, int);
217 ///
218 /// let int = diesel::select(lower_inc::<Multirange<Integer>, _>(vec![5..7]))
219 /// .get_result::<bool>(connection)?;
220 /// assert_eq!(true, int);
221 /// # Ok(())
222 /// # }
223 /// ```
224 #[cfg(feature = "postgres_backend")]
225 fn lower_inc<R: MultirangeOrRangeMaybeNullable + SingleValue + MaybeNullableValue<Bool>>(
226 range: R,
227 ) -> R::Out;
228
229 /// Returns true if the range's upper bound is inclusive
230 ///
231 /// # Example
232 ///
233 /// ```rust
234 /// # include!("../../doctest_setup.rs");
235 /// #
236 /// # fn main() {
237 /// # run_test().unwrap();
238 /// # }
239 /// #
240 /// # fn run_test() -> QueryResult<()> {
241 /// # use diesel::pg::sql_types::{Range, Multirange};
242 /// # use diesel::dsl::upper_inc;
243 /// # use std::collections::Bound;
244 /// # use diesel::sql_types::{Nullable, Integer, Array};
245 /// # let connection = &mut establish_connection();
246 /// let int =
247 /// diesel::select(upper_inc::<Range<Integer>, _>(1..5)).get_result::<bool>(connection)?;
248 /// assert_eq!(false, int);
249 ///
250 /// let int = diesel::select(upper_inc::<Nullable<Range<Integer>>, _>(
251 /// None::<std::ops::Range<i32>>,
252 /// ))
253 /// .get_result::<Option<bool>>(connection)?;
254 /// assert_eq!(None, int);
255 ///
256 /// let int = diesel::select(upper_inc::<Multirange<Integer>, _>(vec![5..7]))
257 /// .get_result::<bool>(connection)?;
258 /// assert_eq!(false, int);
259 /// # Ok(())
260 /// # }
261 /// ```
262 #[cfg(feature = "postgres_backend")]
263 fn upper_inc<R: MultirangeOrRangeMaybeNullable + SingleValue + MaybeNullableValue<Bool>>(
264 range: R,
265 ) -> R::Out;
266
267 /// Returns true if the range's lower bound is unbounded
268 ///
269 /// # Example
270 ///
271 /// ```rust
272 /// # include!("../../doctest_setup.rs");
273 /// #
274 /// # fn main() {
275 /// # run_test().unwrap();
276 /// # }
277 /// #
278 /// # fn run_test() -> QueryResult<()> {
279 /// # use diesel::pg::sql_types::{Range, Multirange};
280 /// # use diesel::dsl::lower_inf;
281 /// # use std::collections::Bound;
282 /// # use diesel::sql_types::{Nullable, Integer, Array};
283 /// # let connection = &mut establish_connection();
284 /// let int =
285 /// diesel::select(lower_inf::<Range<Integer>, _>(1..5)).get_result::<bool>(connection)?;
286 /// assert_eq!(false, int);
287 ///
288 /// let int = diesel::select(lower_inf::<Range<Integer>, _>(..5)).get_result::<bool>(connection)?;
289 /// assert_eq!(true, int);
290 ///
291 /// let int = diesel::select(lower_inf::<Nullable<Range<Integer>>, _>(
292 /// None::<std::ops::Range<i32>>,
293 /// ))
294 /// .get_result::<Option<bool>>(connection)?;
295 /// assert_eq!(None, int);
296 ///
297 /// let int = diesel::select(lower_inf::<Multirange<Integer>, _>(vec![5..7]))
298 /// .get_result::<bool>(connection)?;
299 /// assert_eq!(false, int);
300 /// # Ok(())
301 /// # }
302 /// ```
303 #[cfg(feature = "postgres_backend")]
304 fn lower_inf<R: MultirangeOrRangeMaybeNullable + SingleValue + MaybeNullableValue<Bool>>(
305 range: R,
306 ) -> R::Out;
307
308 /// Returns true if the range's upper bound is unbounded
309 ///
310 /// # Example
311 ///
312 /// ```rust
313 /// # include!("../../doctest_setup.rs");
314 /// #
315 /// # fn main() {
316 /// # run_test().unwrap();
317 /// # }
318 /// #
319 /// # fn run_test() -> QueryResult<()> {
320 /// # use diesel::pg::sql_types::{Range, Multirange};
321 /// # use diesel::dsl::upper_inf;
322 /// # use std::collections::Bound;
323 /// # use diesel::sql_types::{Nullable, Integer, Array};
324 /// # let connection = &mut establish_connection();
325 /// let int =
326 /// diesel::select(upper_inf::<Range<Integer>, _>(1..5)).get_result::<bool>(connection)?;
327 /// assert_eq!(false, int);
328 ///
329 /// let int = diesel::select(upper_inf::<Range<Integer>, _>(1..)).get_result::<bool>(connection)?;
330 /// assert_eq!(true, int);
331 ///
332 /// let int = diesel::select(upper_inf::<Nullable<Range<Integer>>, _>(
333 /// None::<std::ops::Range<i32>>,
334 /// ))
335 /// .get_result::<Option<bool>>(connection)?;
336 /// assert_eq!(None, int);
337 ///
338 /// let int = diesel::select(upper_inf::<Multirange<Integer>, _>(vec![5..7]))
339 /// .get_result::<bool>(connection)?;
340 /// assert_eq!(false, int);
341 /// # Ok(())
342 /// # }
343 /// ```
344 #[cfg(feature = "postgres_backend")]
345 fn upper_inf<R: MultirangeOrRangeMaybeNullable + SingleValue + MaybeNullableValue<Bool>>(
346 range: R,
347 ) -> R::Out;
348
349 /// Returns the smallest range which includes both of the given ranges
350 ///
351 /// # Example
352 ///
353 /// ```rust
354 /// # include!("../../doctest_setup.rs");
355 /// #
356 /// # fn main() {
357 /// # run_test().unwrap();
358 /// # }
359 /// #
360 /// # fn run_test() -> QueryResult<()> {
361 /// # use diesel::pg::sql_types::{Range, Multirange};
362 /// # use diesel::dsl::range_merge;
363 /// # use std::collections::Bound;
364 /// # use diesel::sql_types::{Nullable, Integer, Array};
365 /// # let connection = &mut establish_connection();
366 /// let int = diesel::select(range_merge::<Range<Integer>, Range<_>, _, _>(5..11, 10..))
367 /// .get_result::<(Bound<i32>, Bound<i32>)>(connection)?;
368 /// assert_eq!((Bound::Included(5), Bound::Unbounded), int);
369 ///
370 /// let int = diesel::select(range_merge::<Range<Integer>, Range<_>, _, _>(1..3, 7..10))
371 /// .get_result::<(Bound<i32>, Bound<i32>)>(connection)?;
372 /// assert_eq!((Bound::Included(1), Bound::Excluded(10)), int);
373 ///
374 /// let int = diesel::select(range_merge::<
375 /// Nullable<Range<Integer>>,
376 /// Nullable<Range<_>>,
377 /// _,
378 /// _,
379 /// >(None::<std::ops::Range<i32>>, 7..10))
380 /// .get_result::<Option<(Bound<i32>, Bound<i32>)>>(connection)?;
381 /// assert_eq!(None, int);
382 ///
383 /// let int = diesel::select(range_merge::<
384 /// Nullable<Range<Integer>>,
385 /// Nullable<Range<_>>,
386 /// _,
387 /// _,
388 /// >(1..3, None::<std::ops::Range<i32>>))
389 /// .get_result::<Option<(Bound<i32>, Bound<i32>)>>(connection)?;
390 /// assert_eq!(None, int);
391 /// # Ok(())
392 /// # }
393 /// ```
394 #[cfg(feature = "postgres_backend")]
395 fn range_merge<
396 R1: RangeOrNullableRange + SingleValue,
397 R2: RangeOrNullableRange<Inner = R1::Inner>
398 + SingleValue
399 + CombinedNullableValue<R1, Range<R1::Inner>>,
400 >(
401 lhs: R1,
402 rhs: R2,
403 ) -> R2::Out;
404
405 /// Returns the smallest range which includes all ranges in the multirange
406 ///
407 /// # Example
408 ///
409 /// ```rust
410 /// # include!("../../doctest_setup.rs");
411 /// #
412 /// # fn main() {
413 /// # run_test().unwrap();
414 /// # }
415 /// #
416 /// # fn run_test() -> QueryResult<()> {
417 /// # use diesel::pg::sql_types::{Range, Multirange};
418 /// # use diesel::dsl::multirange_merge;
419 /// # use std::collections::Bound;
420 /// # use diesel::sql_types::{Nullable, Integer, Array};
421 /// # let connection = &mut establish_connection();
422 /// let int = diesel::select(multirange_merge::<Multirange<Integer>, _>(vec![
423 /// 1..3,
424 /// 7..10,
425 /// ]))
426 /// .get_result::<(Bound<i32>, Bound<i32>)>(connection)?;
427 /// assert_eq!((Bound::Included(1), Bound::Excluded(10)), int);
428 ///
429 /// let int = diesel::select(multirange_merge::<Nullable<Multirange<Integer>>, _>(
430 /// None::<Vec<std::ops::Range<i32>>>,
431 /// ))
432 /// .get_result::<Option<(Bound<i32>, Bound<i32>)>>(connection)?;
433 /// assert_eq!(None, int);
434 /// # Ok(())
435 /// # }
436 /// ```
437 #[cfg(feature = "postgres_backend")]
438 #[sql_name = "range_merge"]
439 fn multirange_merge<R: MultirangeOrNullableMultirange + SingleValue>(multirange: R)
440 -> R::Range;
441
442 /// Returns range of integer
443 ///
444 /// # Example
445 ///
446 /// ```rust
447 /// # include!("../../doctest_setup.rs");
448 /// #
449 /// # table! {
450 /// # posts {
451 /// # id -> Integer,
452 /// # versions -> Int4range,
453 /// # }
454 /// # }
455 /// #
456 /// # fn main() {
457 /// # run_test().unwrap();
458 /// # }
459 /// #
460 /// # fn run_test() -> QueryResult<()> {
461 /// # use self::posts::dsl::*;
462 /// # use std::collections::Bound;
463 /// # let conn = &mut establish_connection();
464 /// # diesel::sql_query("DROP TABLE IF EXISTS posts").execute(conn).unwrap();
465 /// # diesel::sql_query("CREATE TABLE posts (id SERIAL PRIMARY KEY, versions INT4RANGE NOT NULL)").execute(conn).unwrap();
466 /// #
467 /// use diesel::dsl::int4range;
468 /// use diesel::pg::sql_types::RangeBound;
469 ///
470 /// diesel::insert_into(posts)
471 /// .values(&[
472 /// versions.eq(int4range(Some(3), Some(5), RangeBound::LowerBoundInclusiveUpperBoundInclusive)),
473 /// versions.eq(int4range(None, Some(2), RangeBound::LowerBoundInclusiveUpperBoundExclusive)),
474 /// ]).execute(conn)?;
475 ///
476 /// let cool_posts = posts.select(versions)
477 /// .load::<(Bound<i32>, Bound<i32>)>(conn)?;
478 /// assert_eq!(vec![
479 /// (Bound::Included(3), Bound::Excluded(6)), // Postgres cast this internally
480 /// (Bound::Unbounded, Bound::Excluded(2)),
481 /// ], cool_posts);
482 /// # Ok(())
483 /// # }
484 /// ```
485 #[cfg(feature = "postgres_backend")]
486 fn int4range(
487 lower: Nullable<Integer>,
488 upper: Nullable<Integer>,
489 bound: RangeBoundEnum,
490 ) -> Int4range;
491
492 /// Returns range of big ints
493 ///
494 /// # Example
495 ///
496 /// ```rust
497 /// # include!("../../doctest_setup.rs");
498 /// #
499 /// # table! {
500 /// # posts {
501 /// # id -> Integer,
502 /// # versions -> Int8range,
503 /// # }
504 /// # }
505 /// #
506 /// # fn main() {
507 /// # run_test().unwrap();
508 /// # }
509 /// #
510 /// # fn run_test() -> QueryResult<()> {
511 /// # use self::posts::dsl::*;
512 /// # use std::collections::Bound;
513 /// # let conn = &mut establish_connection();
514 /// # diesel::sql_query("DROP TABLE IF EXISTS posts").execute(conn).unwrap();
515 /// # diesel::sql_query("CREATE TABLE posts (id SERIAL PRIMARY KEY, versions INT8RANGE NOT NULL)").execute(conn).unwrap();
516 /// #
517 /// use diesel::dsl::int8range;
518 /// use diesel::pg::sql_types::RangeBound;
519 ///
520 /// diesel::insert_into(posts)
521 /// .values(&[
522 /// versions.eq(int8range(Some(3), Some(5), RangeBound::LowerBoundInclusiveUpperBoundInclusive)),
523 /// versions.eq(int8range(None, Some(2), RangeBound::LowerBoundInclusiveUpperBoundExclusive)),
524 /// ]).execute(conn)?;
525 ///
526 /// let cool_posts = posts.select(versions)
527 /// .load::<(Bound<i64>, Bound<i64>)>(conn)?;
528 /// assert_eq!(vec![
529 /// (Bound::Included(3), Bound::Excluded(6)), // Postgres cast this internally
530 /// (Bound::Unbounded, Bound::Excluded(2)),
531 /// ], cool_posts);
532 /// # Ok(())
533 /// # }
534 /// ```
535 #[cfg(feature = "postgres_backend")]
536 fn int8range(
537 lower: Nullable<BigInt>,
538 upper: Nullable<BigInt>,
539 bound: RangeBoundEnum,
540 ) -> Int8range;
541
542 /// Returns range of numeric values
543 ///
544 /// # Example
545 ///
546 /// ```rust
547 /// # include!("../../doctest_setup.rs");
548 /// #
549 /// # table! {
550 /// # posts {
551 /// # id -> Integer,
552 /// # versions -> Numrange,
553 /// # }
554 /// # }
555 /// #
556 /// # fn main() {
557 /// # #[cfg(feature = "numeric")]
558 /// # run_test().unwrap();
559 /// # }
560 /// #
561 /// # #[cfg(feature = "numeric")]
562 /// # fn run_test() -> QueryResult<()> {
563 /// # use self::posts::dsl::*;
564 /// # use std::collections::Bound;
565 /// # let conn = &mut establish_connection();
566 /// # diesel::sql_query("DROP TABLE IF EXISTS posts").execute(conn).unwrap();
567 /// # diesel::sql_query("CREATE TABLE posts (id SERIAL PRIMARY KEY, versions NUMRANGE NOT NULL)").execute(conn).unwrap();
568 /// #
569 /// # use bigdecimal::BigDecimal;
570 /// use diesel::dsl::numrange;
571 /// use diesel::pg::sql_types::RangeBound;
572 ///
573 /// diesel::insert_into(posts)
574 /// .values(&[
575 /// versions.eq(numrange(Some(BigDecimal::from(3)), Some(BigDecimal::from(5)), RangeBound::LowerBoundInclusiveUpperBoundInclusive)),
576 /// versions.eq(numrange(None, Some(BigDecimal::from(2)), RangeBound::LowerBoundInclusiveUpperBoundExclusive)),
577 /// ]).execute(conn)?;
578 ///
579 /// let cool_posts = posts.select(versions)
580 /// .load::<(Bound<BigDecimal>, Bound<BigDecimal>)>(conn)?;
581 /// assert_eq!(vec![
582 /// (Bound::Included(BigDecimal::from(3)), Bound::Included(BigDecimal::from(5))),
583 /// (Bound::Unbounded, Bound::Excluded(BigDecimal::from(2))),
584 /// ], cool_posts);
585 /// # Ok(())
586 /// # }
587 /// ```
588 #[cfg(feature = "postgres_backend")]
589 fn numrange(
590 lower: Nullable<Numeric>,
591 upper: Nullable<Numeric>,
592 bound: RangeBoundEnum,
593 ) -> Numrange;
594
595 /// Returns range of timestamps without timezone
596 ///
597 /// # Example
598 ///
599 /// ```rust
600 /// # include!("../../doctest_setup.rs");
601 /// #
602 /// # table! {
603 /// # posts {
604 /// # id -> Integer,
605 /// # versions -> Tsrange,
606 /// # }
607 /// # }
608 /// #
609 /// # fn main() {
610 /// # #[cfg(feature = "time")]
611 /// # run_test().unwrap();
612 /// # }
613 /// #
614 /// # #[cfg(feature = "time")]
615 /// # fn run_test() -> QueryResult<()> {
616 /// # use self::posts::dsl::*;
617 /// # use std::collections::Bound;
618 /// # let conn = &mut establish_connection();
619 /// # diesel::sql_query("DROP TABLE IF EXISTS posts").execute(conn).unwrap();
620 /// # diesel::sql_query("CREATE TABLE posts (id SERIAL PRIMARY KEY, versions TSRANGE NOT NULL)").execute(conn).unwrap();
621 /// #
622 /// use diesel::dsl::tsrange;
623 /// use diesel::pg::sql_types::RangeBound;
624 /// use time::{PrimitiveDateTime, macros::datetime};
625 ///
626 /// diesel::insert_into(posts)
627 /// .values(&[
628 /// versions.eq(tsrange(Some(datetime!(2020-01-01 0:00)), Some(datetime!(2021-01-01 0:00)), RangeBound::LowerBoundInclusiveUpperBoundInclusive)),
629 /// versions.eq(tsrange(None, Some(datetime!(2020-01-01 0:00)), RangeBound::LowerBoundInclusiveUpperBoundExclusive)),
630 /// ]).execute(conn)?;
631 ///
632 /// let cool_posts = posts.select(versions)
633 /// .load::<(Bound<PrimitiveDateTime>, Bound<PrimitiveDateTime>)>(conn)?;
634 /// assert_eq!(vec![
635 /// (Bound::Included(datetime!(2020-01-01 0:00)), Bound::Included(datetime!(2021-01-01 0:00))),
636 /// (Bound::Unbounded, Bound::Excluded(datetime!(2020-01-01 0:00))),
637 /// ], cool_posts);
638 /// # Ok(())
639 /// # }
640 /// ```
641 #[cfg(feature = "postgres_backend")]
642 fn tsrange(
643 lower: Nullable<Timestamp>,
644 upper: Nullable<Timestamp>,
645 bound: RangeBoundEnum,
646 ) -> Tsrange;
647
648 /// Returns range of timestamps with timezone
649 ///
650 /// # Example
651 ///
652 /// ```rust
653 /// # include!("../../doctest_setup.rs");
654 /// #
655 /// # table! {
656 /// # posts {
657 /// # id -> Integer,
658 /// # versions -> Tstzrange,
659 /// # }
660 /// # }
661 /// #
662 /// # fn main() {
663 /// # #[cfg(feature = "time")]
664 /// # run_test().unwrap();
665 /// # }
666 /// #
667 /// # #[cfg(feature = "time")]
668 /// # fn run_test() -> QueryResult<()> {
669 /// # use self::posts::dsl::*;
670 /// # use std::collections::Bound;
671 /// # let conn = &mut establish_connection();
672 /// # diesel::sql_query("DROP TABLE IF EXISTS posts").execute(conn).unwrap();
673 /// # diesel::sql_query("CREATE TABLE posts (id SERIAL PRIMARY KEY, versions TSTZRANGE NOT NULL)").execute(conn).unwrap();
674 /// #
675 /// use diesel::dsl::tstzrange;
676 /// use diesel::pg::sql_types::RangeBound;
677 /// use time::{OffsetDateTime, macros::datetime};
678 ///
679 /// diesel::insert_into(posts)
680 /// .values(&[
681 /// versions.eq(tstzrange(Some(datetime!(2020-01-01 0:00 UTC)), Some(datetime!(2021-01-01 0:00 -3)), RangeBound::LowerBoundInclusiveUpperBoundInclusive)),
682 /// versions.eq(tstzrange(None, Some(datetime!(2020-01-01 0:00 +2)), RangeBound::LowerBoundInclusiveUpperBoundExclusive)),
683 /// ]).execute(conn)?;
684 ///
685 /// let cool_posts = posts.select(versions)
686 /// .load::<(Bound<OffsetDateTime>, Bound<OffsetDateTime>)>(conn)?;
687 /// assert_eq!(vec![
688 /// (Bound::Included(datetime!(2020-01-01 0:00 UTC)), Bound::Included(datetime!(2021-01-01 0:00 -3))),
689 /// (Bound::Unbounded, Bound::Excluded(datetime!(2020-01-01 0:00 +2))),
690 /// ], cool_posts);
691 /// # Ok(())
692 /// # }
693 /// ```
694 #[cfg(feature = "postgres_backend")]
695 fn tstzrange(
696 lower: Nullable<Timestamptz>,
697 upper: Nullable<Timestamptz>,
698 bound: RangeBoundEnum,
699 ) -> Tstzrange;
700
701 /// Returns range of dates
702 ///
703 /// # Example
704 ///
705 /// ```rust
706 /// # include!("../../doctest_setup.rs");
707 /// #
708 /// # table! {
709 /// # posts {
710 /// # id -> Integer,
711 /// # versions -> Daterange,
712 /// # }
713 /// # }
714 /// #
715 /// # fn main() {
716 /// # #[cfg(feature = "time")]
717 /// # run_test().unwrap();
718 /// # }
719 /// #
720 /// # #[cfg(feature = "time")]
721 /// # fn run_test() -> QueryResult<()> {
722 /// # use self::posts::dsl::*;
723 /// # use std::collections::Bound;
724 /// # let conn = &mut establish_connection();
725 /// # diesel::sql_query("DROP TABLE IF EXISTS posts").execute(conn).unwrap();
726 /// # diesel::sql_query("CREATE TABLE posts (id SERIAL PRIMARY KEY, versions DATERANGE NOT NULL)").execute(conn).unwrap();
727 /// #
728 /// use diesel::dsl::daterange;
729 /// use diesel::pg::sql_types::RangeBound;
730 /// use time::{Date, macros::date};
731 ///
732 /// diesel::insert_into(posts)
733 /// .values(&[
734 /// versions.eq(daterange(Some(date!(2020-01-01)), Some(date!(2021-01-01)), RangeBound::LowerBoundInclusiveUpperBoundInclusive)),
735 /// versions.eq(daterange(None, Some(date!(2020-01-01)), RangeBound::LowerBoundInclusiveUpperBoundExclusive)),
736 /// ]).execute(conn)?;
737 ///
738 /// let cool_posts = posts.select(versions)
739 /// .load::<(Bound<Date>, Bound<Date>)>(conn)?;
740 /// assert_eq!(vec![
741 /// (Bound::Included(date!(2020-01-01)), Bound::Excluded(date!(2021-01-02))),
742 /// (Bound::Unbounded, Bound::Excluded(date!(2020-01-01))),
743 /// ], cool_posts);
744 /// # Ok(())
745 /// # }
746 /// ```
747 #[cfg(feature = "postgres_backend")]
748 fn daterange(lower: Nullable<Date>, upper: Nullable<Date>, bound: RangeBoundEnum) -> Daterange;
749
750 /// Append an element to the end of an array
751 ///
752 /// # Example
753 ///
754 /// ```rust
755 /// # include!("../../doctest_setup.rs");
756 /// #
757 /// # fn main() {
758 /// # run_test().unwrap();
759 /// # }
760 /// #
761 /// # fn run_test() -> QueryResult<()> {
762 /// # use diesel::dsl::array_append;
763 /// # use diesel::sql_types::{Nullable, Integer, Array};
764 /// # let connection = &mut establish_connection();
765 /// let ints = diesel::select(array_append::<Array<_>, Integer, _, _>(vec![1, 2], 3))
766 /// .get_result::<Vec<i32>>(connection)?;
767 /// assert_eq!(vec![1, 2, 3], ints);
768 ///
769 /// let ints = diesel::select(array_append::<Array<_>, Nullable<Integer>, _, _>(
770 /// vec![Some(1), Some(2)],
771 /// None::<i32>,
772 /// ))
773 /// .get_result::<Vec<Option<i32>>>(connection)?;
774 /// assert_eq!(vec![Some(1), Some(2), None], ints);
775 ///
776 /// let ints = diesel::select(array_append::<Nullable<Array<_>>, Integer, _, _>(
777 /// None::<Vec<i32>>,
778 /// 3,
779 /// ))
780 /// .get_result::<Vec<i32>>(connection)?;
781 /// assert_eq!(vec![3], ints);
782 ///
783 /// let ints = diesel::select(array_append::<Nullable<Array<_>>, Nullable<Integer>, _, _>(
784 /// None::<Vec<i32>>,
785 /// None::<i32>,
786 /// ))
787 /// .get_result::<Vec<Option<i32>>>(connection)?;
788 /// assert_eq!(vec![None], ints);
789 /// # Ok(())
790 /// # }
791 /// ```
792 #[cfg(feature = "postgres_backend")]
793 fn array_append<Arr: ArrayOrNullableArray<Inner = T> + SingleValue, T: SingleValue>(
794 a: Arr,
795 e: T,
796 ) -> Array<T>;
797
798 /// Replace all occurrences of an element in an array with a given element
799 ///
800 /// # Example
801 ///
802 /// ```rust
803 /// # include!("../../doctest_setup.rs");
804 /// #
805 /// # fn main() {
806 /// # run_test().unwrap();
807 /// # }
808 /// #
809 /// # fn run_test() -> QueryResult<()> {
810 /// # use diesel::dsl::array_replace;
811 /// # use diesel::sql_types::{Nullable, Integer, Array};
812 /// # let connection = &mut establish_connection();
813 /// let ints = diesel::select(array_replace::<Array<_>, Integer, _, _, _>(
814 /// vec![1, 2, 5, 4],
815 /// 5,
816 /// 3,
817 /// ))
818 /// .get_result::<Vec<i32>>(connection)?;
819 /// assert_eq!(vec![1, 2, 3, 4], ints);
820 ///
821 /// let ints = diesel::select(array_replace::<Array<_>, Nullable<Integer>, _, _, _>(
822 /// vec![Some(1), Some(2), Some(3)],
823 /// Some(3),
824 /// None::<i32>,
825 /// ))
826 /// .get_result::<Vec<Option<i32>>>(connection)?;
827 /// assert_eq!(vec![Some(1), Some(2), None], ints);
828 ///
829 /// let ints = diesel::select(array_replace::<Nullable<Array<_>>, Integer, _, _, _>(
830 /// None::<Vec<i32>>,
831 /// 1,
832 /// 2,
833 /// ))
834 /// .get_result::<Option<Vec<i32>>>(connection)?;
835 ///
836 /// let ints = diesel::select(array_replace::<
837 /// Nullable<Array<_>>,
838 /// Nullable<Integer>,
839 /// _,
840 /// _,
841 /// _,
842 /// >(None::<Vec<i32>>, None::<i32>, Some(1)))
843 /// .get_result::<Option<Vec<Option<i32>>>>(connection)?;
844 /// assert_eq!(None, ints);
845 /// # Ok(())
846 /// # }
847 /// ```
848 #[cfg(feature = "postgres_backend")]
849 fn array_replace<Arr: ArrayOrNullableArray<Inner = T> + SingleValue, T: SingleValue>(
850 a: Arr,
851 e: T,
852 r: T,
853 ) -> Arr;
854
855 /// Returns a text representation of the array's dimensions
856 ///
857 /// # Example
858 ///
859 /// ```rust
860 /// # include!("../../doctest_setup.rs");
861 /// #
862 /// # fn main(){
863 /// # run_test().unwrap();
864 /// # }
865 /// # fn run_test()->QueryResult<()>{
866 /// # use diesel::dsl::array_dims;
867 /// # use diesel::sql_types::{Nullable,Array,Integer};
868 /// # let connection = &mut establish_connection();
869 ///
870 /// let dims = diesel::select(array_dims::<Array<Integer>,_>(vec![1,2]))
871 /// .get_result::<String>(connection)?;
872 /// assert!(String::from("[1:2]").eq(&dims));
873 ///
874 /// let dims = diesel::select(array_dims::<Array<Nullable<Integer>>,_>(vec![None::<i32>,Some(2)]))
875 /// .get_result::<String>(connection)?;
876 /// assert!(String::from("[1:2]").eq(&dims));
877 ///
878 /// let dims = diesel::select(array_dims::<Array<Nullable<Integer>>,_>(vec![None::<i32>]))
879 /// .get_result::<String>(connection)?;
880 /// assert!(String::from("[1:1]").eq(&dims));
881 /// # Ok(())
882 /// # }
883 #[cfg(feature = "postgres_backend")]
884 fn array_dims<Arr: ArrayOrNullableArray + SingleValue>(arr: Arr) -> Text;
885
886 /// Prepends an element to the beginning of an array
887 ///
888 /// # Example
889 ///
890 /// ```rust
891 /// # include!("../../doctest_setup.rs");
892 /// #
893 /// # fn main() {
894 /// # run_test().unwrap();
895 /// # }
896 /// #
897 /// # fn run_test() -> QueryResult<()> {
898 /// # use diesel::dsl::array_prepend;
899 /// # use diesel::sql_types::{Nullable, Integer, Array};
900 /// # let connection = &mut establish_connection();
901 /// let ints = diesel::select(array_prepend::<Integer, Array<_>, _, _>(3, vec![1, 2]))
902 /// .get_result::<Vec<i32>>(connection)?;
903 /// assert_eq!(vec![3, 1, 2], ints);
904 ///
905 /// let ints = diesel::select(array_prepend::<Nullable<Integer>, Array<_>, _, _>(
906 /// None::<i32>,
907 /// vec![Some(1), Some(2)],
908 /// ))
909 /// .get_result::<Vec<Option<i32>>>(connection)?;
910 /// assert_eq!(vec![None, Some(1), Some(2)], ints);
911 ///
912 /// let ints = diesel::select(array_prepend::<Integer, Nullable<Array<_>>, _, _>(
913 /// 3,
914 /// None::<Vec<i32>>,
915 /// ))
916 /// .get_result::<Vec<i32>>(connection)?;
917 /// assert_eq!(vec![3], ints);
918 ///
919 /// let ints = diesel::select(
920 /// array_prepend::<Nullable<Integer>, Nullable<Array<_>>, _, _>(None::<i32>, None::<Vec<i32>>),
921 /// )
922 /// .get_result::<Vec<Option<i32>>>(connection)?;
923 /// assert_eq!(vec![None], ints);
924 /// # Ok(())
925 /// # }
926 /// ```
927 #[cfg(feature = "postgres_backend")]
928 fn array_prepend<T: SingleValue, Arr: ArrayOrNullableArray<Inner = T> + SingleValue>(
929 e: T,
930 a: Arr,
931 ) -> Array<T>;
932
933 /// Removes all elements equal to the given value from the array
934 ///
935 /// # Example
936 ///
937 /// ```rust
938 /// # include!("../../doctest_setup.rs");
939 /// #
940 /// # fn main() {
941 /// # run_test().unwrap();
942 /// # }
943 /// #
944 /// # fn run_test() -> QueryResult<()> {
945 /// # use diesel::dsl::array_remove;
946 /// # use diesel::sql_types::{Nullable, Integer, Array};
947 /// # let connection = &mut establish_connection();
948 /// let ints = diesel::select(array_remove::<Array<_>, Integer, _, _>(vec![1, 2, 3, 2], 2))
949 /// .get_result::<Vec<i32>>(connection)?;
950 /// assert_eq!(vec![1, 3], ints);
951 ///
952 /// let ints = diesel::select(array_remove::<Array<_>, Nullable<Integer>, _, _>(
953 /// vec![None, Some(1), Some(2), None, Some(4)],
954 /// None::<i32>,
955 /// ))
956 /// .get_result::<Vec<Option<i32>>>(connection)?;
957 /// assert_eq!(vec![Some(1), Some(2), Some(4)], ints);
958 ///
959 /// let ints = diesel::select(array_remove::<Nullable<Array<_>>, Nullable<Integer>, _, _>(
960 /// None::<Vec<i32>>,
961 /// None::<i32>,
962 /// ))
963 /// .get_result::<Option<Vec<Option<i32>>>>(connection)?;
964 /// assert_eq!(None, ints);
965 /// # Ok(())
966 /// # }
967 /// ```
968 #[cfg(feature = "postgres_backend")]
969 fn array_remove<Arr: ArrayOrNullableArray<Inner = T> + SingleValue, T: SingleValue>(
970 a: Arr,
971 e: T,
972 ) -> Arr;
973
974 /// Converts each array element to its text representation and concatenates those elements
975 /// separated by the delimiter string. If `null_string` is provided and is not `NULL`, then `NULL`
976 /// array entries are represented by that string; otherwise, they are omitted.
977 ///
978 /// # Example
979 ///
980 /// ```rust
981 /// # include!("../../doctest_setup.rs");
982 /// #
983 /// # fn main() {
984 /// # run_test().unwrap();
985 /// # }
986 /// #
987 /// # fn run_test() -> QueryResult<()> {
988 /// # use diesel::dsl::array_to_string_with_null_string;
989 /// # use diesel::sql_types::{Nullable, Text, Array};
990 /// # let connection = &mut establish_connection();
991 ///
992 /// // Example with `NULL` representation as a string
993 /// let result: String = diesel::select(array_to_string_with_null_string::<
994 /// Array<Nullable<Text>>,
995 /// _,
996 /// _,
997 /// _,
998 /// >(
999 /// vec![Some("first"), None::<&str>, Some("third")],
1000 /// ",",
1001 /// "NULL",
1002 /// ))
1003 /// .get_result(connection)?;
1004 /// assert_eq!(result, "first,NULL,third");
1005 ///
1006 /// // Example without any `NULL` values
1007 /// let result: String = diesel::select(array_to_string_with_null_string::<
1008 /// Array<Nullable<Text>>,
1009 /// _,
1010 /// _,
1011 /// _,
1012 /// >(vec![Some("first"), Some("second")], ",", "NULL"))
1013 /// .get_result(connection)?;
1014 /// assert_eq!(result, "first,second");
1015 ///
1016 /// // Example with all `NULL` values
1017 /// let result: String = diesel::select(array_to_string_with_null_string::<
1018 /// Array<Nullable<Text>>,
1019 /// _,
1020 /// _,
1021 /// _,
1022 /// >(vec![None::<&str>, None::<&str>], ",", "NULL"))
1023 /// .get_result(connection)?;
1024 /// assert_eq!(result, "NULL,NULL");
1025 ///
1026 /// # Ok(())
1027 /// # }
1028 /// ```
1029 #[cfg(feature = "postgres_backend")]
1030 #[sql_name = "array_to_string"]
1031 fn array_to_string_with_null_string<Arr: ArrayOrNullableArray + SingleValue>(
1032 array: Arr,
1033 del: Text,
1034 null: Text,
1035 ) -> Text;
1036
1037 /// Converts each array element to its text representation and concatenates those elements
1038 /// separated by the delimiter string. `NULL` entries are omitted in this variant.
1039 /// See [array_to_string_with_null_string](array_to_string_with_null_string()) for a variant with that argument.
1040 ///
1041 /// # Example
1042 ///
1043 /// ```rust
1044 /// # include!("../../doctest_setup.rs");
1045 /// #
1046 /// # fn main() {
1047 /// # run_test().unwrap();
1048 /// # }
1049 /// #
1050 /// # fn run_test() -> QueryResult<()> {
1051 /// # use diesel::dsl::array_to_string;
1052 /// # use diesel::sql_types::{Text, Array, Nullable};
1053 /// # let connection = &mut establish_connection();
1054 ///
1055 /// // Example with non-null values
1056 /// let result: String = diesel::select(array_to_string::<Array<Nullable<Text>>, _, _>(
1057 /// vec![Some("first"), Some("second")],
1058 /// ",",
1059 /// ))
1060 /// .get_result(connection)?;
1061 /// assert_eq!(result, "first,second");
1062 ///
1063 /// // Example with `NULL` values (omitted in the result)
1064 /// let result: String = diesel::select(array_to_string::<Array<Nullable<Text>>, _, _>(
1065 /// vec![Some("first"), None::<&str>, Some("third")],
1066 /// ",",
1067 /// ))
1068 /// .get_result(connection)?;
1069 /// assert_eq!(result, "first,third");
1070 ///
1071 /// // Example with only `NULL` values (empty result)
1072 /// let result: String = diesel::select(array_to_string::<Array<Nullable<Text>>, _, _>(
1073 /// vec![None::<&str>, None::<&str>],
1074 /// ",",
1075 /// ))
1076 /// .get_result(connection)?;
1077 /// assert_eq!(result, "");
1078 ///
1079 /// # Ok(())
1080 /// # }
1081 /// ```
1082 #[cfg(feature = "postgres_backend")]
1083 fn array_to_string<Arr: ArrayOrNullableArray + SingleValue>(array: Arr, del: Text) -> Text;
1084
1085 /// Returns the total number of elements in the array, or 0 if the array is empty.
1086 ///
1087 /// # Example
1088 ///
1089 /// ```rust
1090 /// # include!("../../doctest_setup.rs");
1091 /// #
1092 /// # fn main(){
1093 /// # run_test().unwrap();
1094 /// # }
1095 /// # fn run_test()->QueryResult<()>{
1096 /// # use diesel::dsl::cardinality;
1097 /// # use diesel::sql_types::{Nullable,Array,Integer};
1098 /// # let connection = &mut establish_connection();
1099 ///
1100 /// let array_cardinality = diesel::select(cardinality::<Array<Integer>, _>(vec![1, 2, 3, 4]))
1101 /// .get_result::<i32>(connection)?;
1102 /// assert_eq!(4, array_cardinality);
1103 ///
1104 /// let array_cardinality = diesel::select(cardinality::<Array<Nullable<Integer>>, _>(vec![Some(1), Some(2), Some(3)]))
1105 /// .get_result::<i32>(connection)?;
1106 /// assert_eq!(3, array_cardinality);
1107 ///
1108 /// let array_cardinality = diesel::select(cardinality::<Array<Integer>, _>(Vec::<i32>::new()))
1109 /// .get_result::<i32>(connection)?;
1110 /// assert_eq!(0, array_cardinality);
1111 ///
1112 /// let array_cardinality = diesel::select(cardinality::<Nullable<Array<Integer>>, _>(None::<Vec<i32>>))
1113 /// .get_result::<Option<i32>>(connection)?;
1114 /// assert_eq!(None, array_cardinality);
1115 /// # Ok(())
1116 /// # }
1117 #[cfg(feature = "postgres_backend")]
1118 fn cardinality<Arr: ArrayOrNullableArray + SingleValue + MaybeNullableValue<Integer>>(
1119 a: Arr,
1120 ) -> Arr::Out;
1121
1122 /// Trims an array by removing the last n elements. If the array is multidimensional, only the first dimension is trimmed.
1123 ///
1124 /// # Example
1125 ///
1126 /// ```rust
1127 /// # include!("../../doctest_setup.rs");
1128 /// #
1129 /// # fn main(){
1130 /// # run_test().unwrap();
1131 /// # }
1132 /// # fn run_test()->QueryResult<()>{
1133 /// # use diesel::dsl::trim_array;
1134 /// # use diesel::sql_types::{Nullable,Array,Integer};
1135 /// # let connection = &mut establish_connection();
1136 ///
1137 /// let trimmed_array = diesel::select(trim_array::<Array<Integer>, _, _>(vec![1, 2, 3, 4], 3))
1138 /// .get_result::<Vec<i32>>(connection)?;
1139 /// assert_eq!(vec![1], trimmed_array);
1140 ///
1141 /// let trimmed_array = diesel::select(trim_array::<Array<Nullable<Integer>>, _, _>(vec![Some(1), Some(2), Some(3)], 1))
1142 /// .get_result::<Vec<Option<i32>>>(connection)?;
1143 /// assert_eq!(vec![Some(1), Some(2)], trimmed_array);
1144 ///
1145 /// let trimmed_array = diesel::select(trim_array::<Array<Integer>, _, _>(Vec::<i32>::new(), 0))
1146 /// .get_result::<Vec<i32>>(connection)?;
1147 /// assert_eq!(Vec::<i32>::new(), trimmed_array);
1148 ///
1149 /// let trimmed_array = diesel::select(trim_array::<Nullable<Array<Integer>>, _, _>(None::<Vec<i32>>, 0))
1150 /// .get_result::<Option<Vec<i32>>>(connection)?;
1151 /// assert_eq!(None, trimmed_array);
1152 ///
1153 /// let trimmed_array = diesel::select(trim_array::<Nullable<Array<Integer>>, _, _>(None::<Vec<i32>>, 1))
1154 /// .get_result::<Option<Vec<i32>>>(connection)?;
1155 /// assert_eq!(None, trimmed_array);
1156 /// # Ok(())
1157 /// # }
1158 #[cfg(feature = "postgres_backend")]
1159 fn trim_array<Arr: ArrayOrNullableArray + SingleValue>(a: Arr, n: Integer) -> Arr;
1160
1161 /// Concatenates two arrays
1162 ///
1163 /// # Example
1164 ///
1165 /// ```rust
1166 /// # include!("../../doctest_setup.rs");
1167 /// #
1168 /// # fn main() {
1169 /// # run_test().unwrap();
1170 /// # }
1171 /// #
1172 /// # fn run_test() -> QueryResult<()> {
1173 /// # use diesel::dsl::array_cat;
1174 /// # use diesel::sql_types::{Integer, Array, Nullable};
1175 /// # let connection = &mut establish_connection();
1176 /// let result = diesel::select(array_cat::<Array<Integer>, _, _>(vec![1, 2], vec![3, 4]))
1177 /// .get_result::<Vec<i32>>(connection)?;
1178 /// assert_eq!(vec![1, 2, 3, 4], result);
1179 ///
1180 /// let nullable_result = diesel::select(array_cat::<Nullable<Array<Integer>>, _, _>(
1181 /// None::<Vec<i32>>,
1182 /// None::<Vec<i32>>,
1183 /// ))
1184 /// .get_result::<Option<Vec<i32>>>(connection)?;
1185 /// assert_eq!(None, nullable_result);
1186 /// # Ok(())
1187 /// # }
1188 /// ```
1189 #[cfg(feature = "postgres_backend")]
1190 fn array_cat<Arr: ArrayOrNullableArray + SingleValue>(a: Arr, b: Arr) -> Arr;
1191
1192 /// Returns the length of the requested array
1193 ///
1194 /// # Example
1195 ///
1196 /// ```rust
1197 /// # include!("../../doctest_setup.rs");
1198 /// #
1199 /// # fn main() {
1200 /// # run_test().unwrap();
1201 /// # }
1202 /// #
1203 /// # fn run_test() -> QueryResult<()> {
1204 /// # use diesel::dsl::array_length;
1205 /// # use diesel::sql_types::{Integer, Array, Nullable};
1206 /// # let connection = &mut establish_connection();
1207 /// let result = diesel::select(array_length::<Array<Integer>, _, _>(vec![1, 2, 3], 1))
1208 /// .get_result::<Option<i32>>(connection)?;
1209 /// assert_eq!(Some(3), result);
1210 ///
1211 /// let result = diesel::select(array_length::<Array<Integer>, _, _>(vec![1, 2, 3], 2))
1212 /// .get_result::<Option<i32>>(connection)?;
1213 /// assert_eq!(None, result);
1214 ///
1215 /// let result = diesel::select(array_length::<Nullable<Array<Integer>>, _, _>(
1216 /// None::<Vec<i32>>,
1217 /// 1,
1218 /// ))
1219 /// .get_result::<Option<i32>>(connection)?;
1220 /// assert_eq!(None, result);
1221 /// # Ok(())
1222 /// # }
1223 /// ```
1224 #[cfg(feature = "postgres_backend")]
1225 fn array_length<Arr: ArrayOrNullableArray + SingleValue>(
1226 array: Arr,
1227 dimension: Integer,
1228 ) -> Nullable<Integer>;
1229
1230 /// Returns an array initialized with supplied value and dimensions,
1231 /// optionally with lower bounds other than 1. This function omits the optional
1232 /// lower bound argument. See [array_fill_with_lower_bound](array_fill_with_lower_bound()) for that.
1233 ///
1234 /// # Example
1235 ///
1236 /// ```rust
1237 /// # include!("../../doctest_setup.rs");
1238 /// #
1239 /// # fn main(){
1240 /// # run_test().unwrap();
1241 /// # }
1242 /// # fn run_test()->QueryResult<()>{
1243 /// # use diesel::dsl::array_fill;
1244 /// # use diesel::sql_types::{Nullable,Array,Integer,Text};
1245 /// # let connection = &mut establish_connection();
1246 ///
1247 /// let array = diesel::select(array_fill::<Integer,_,_>(2,vec![2]))
1248 /// .get_result::<Vec<i32>>(connection)?;
1249 /// assert_eq!(vec![2,2],array);
1250 ///
1251 /// let array = diesel::select(array_fill::<Text,_,_>(String::from("abc"),vec![3]))
1252 /// .get_result::<Vec<String>>(connection)?;
1253 /// assert_eq!(vec!["abc","abc","abc"],array);
1254 ///
1255 /// let array = diesel::select(array_fill::<Nullable<Integer>,_,_>(Some(4),vec![3]))
1256 /// .get_result::<Vec<Option<i32>>>(connection)?;
1257 /// assert_eq!(vec![Some(4),Some(4),Some(4)],array);
1258 ///
1259 /// let array = diesel::select(array_fill::<Nullable<Integer>,_,_>(None::<i32>,vec![3]))
1260 /// .get_result::<Vec<Option<i32>>>(connection)?;
1261 /// assert_eq!(vec![None::<i32>,None::<i32>,None::<i32>],array);
1262 /// # Ok(())
1263 /// # }
1264 #[cfg(feature = "postgres_backend")]
1265 fn array_fill<E: SingleValue>(value: E, dim: Array<Integer>) -> Array<E>;
1266
1267 /// Returns an array initialized with supplied value and dimensions,
1268 /// with lower bounds other than 1
1269 ///
1270 /// # Example
1271 ///
1272 /// ```rust
1273 /// # include!("../../doctest_setup.rs");
1274 /// #
1275 /// # fn main(){
1276 /// # run_test().unwrap();
1277 /// # }
1278 /// # fn run_test()->QueryResult<()>{
1279 /// # use diesel::dsl::array_fill_with_lower_bound;
1280 /// # use diesel::sql_types::{Nullable,Array,Integer,Text};
1281 /// # let connection = &mut establish_connection();
1282 ///
1283 /// let array = diesel::select(array_fill_with_lower_bound::<Integer,_,_,_>(2,vec![2],vec![2]))
1284 /// .get_result::<Vec<i32>>(connection)?;
1285 /// assert_eq!(vec![2,2],array);
1286 ///
1287 /// let array = diesel::select(array_fill_with_lower_bound::<Text,_,_,_>(String::from("abc"),vec![3],vec![3]))
1288 /// .get_result::<Vec<String>>(connection)?;
1289 /// assert_eq!(vec!["abc","abc","abc"],array);
1290 ///
1291 /// let array = diesel::select(array_fill_with_lower_bound::<Nullable<Integer>,_,_,_>(Some(4),vec![3],vec![3]))
1292 /// .get_result::<Vec<Option<i32>>>(connection)?;
1293 /// assert_eq!(vec![Some(4),Some(4),Some(4)],array);
1294 ///
1295 /// let array = diesel::select(array_fill_with_lower_bound::<Nullable<Integer>,_,_,_>(None::<i32>,vec![3],vec![3]))
1296 /// .get_result::<Vec<Option<i32>>>(connection)?;
1297 /// assert_eq!(vec![None::<i32>,None::<i32>,None::<i32>],array);
1298 /// # Ok(())
1299 /// # }
1300 #[sql_name = "array_fill"]
1301 #[cfg(feature = "postgres_backend")]
1302 fn array_fill_with_lower_bound<E: SingleValue>(
1303 value: E,
1304 dim: Array<Integer>,
1305 lower_bound: Array<Integer>,
1306 ) -> Array<E>;
1307
1308 /// Returns the lower bound of the requested array
1309 ///
1310 /// This function returns null for dimensions that do not exist
1311 ///
1312 /// # Example
1313 ///
1314 /// ```rust
1315 /// # include!("../../doctest_setup.rs");
1316 /// #
1317 /// # fn main() {
1318 /// # run_test().unwrap();
1319 /// # }
1320 /// #
1321 /// # fn run_test() -> QueryResult<()> {
1322 /// # use diesel::dsl::array_lower;
1323 /// # use diesel::sql_types::{Integer, Array};
1324 /// # let connection = &mut establish_connection();
1325 /// let result = diesel::select(array_lower::<Array<Integer>, _, _>(vec![1, 2, 3], 1))
1326 /// .get_result::<Option<i32>>(connection)?;
1327 /// assert_eq!(Some(1), result);
1328 ///
1329 /// // the array has only one dimension
1330 /// let result = diesel::select(array_lower::<Array<Integer>, _, _>(vec![1, 2, 3], 2))
1331 /// .get_result::<Option<i32>>(connection)?;
1332 /// assert_eq!(None, result);
1333 /// # Ok(())
1334 /// # }
1335 /// ```
1336 #[cfg(feature = "postgres_backend")]
1337 fn array_lower<Arr: ArrayOrNullableArray + SingleValue>(
1338 array: Arr,
1339 dimension: Integer,
1340 ) -> Nullable<Integer>;
1341
1342 /// Returns the subscript of the first occurrence of the second argument in the array, or NULL if it's not present.
1343 /// If the third argument is given, the search begins at that subscript. This function omits the third argument.
1344 /// See [array_position_with_subscript](array_position_with_subscript()).
1345 ///
1346 /// The array must be one-dimensional. Comparisons are done using IS NOT DISTINCT FROM semantics,
1347 /// so it is possible to search for NULL.
1348 ///
1349 /// # Example
1350 ///
1351 /// ```rust
1352 /// # include!("../../doctest_setup.rs");
1353 /// #
1354 /// # fn main(){
1355 /// # run_test().unwrap();
1356 /// # }
1357 /// # fn run_test()->QueryResult<()>{
1358 /// # use diesel::dsl::array_position;
1359 /// # use diesel::sql_types::{Nullable,Array,Integer};
1360 /// # let connection = &mut establish_connection();
1361 ///
1362 /// let pos = diesel::select(array_position::<Array<_>, Integer, _, _>(vec![1, 2, 3, 4], 3))
1363 /// .get_result::<Option<i32>>(connection)?;
1364 /// assert_eq!(Some(3), pos);
1365 ///
1366 /// let pos = diesel::select(array_position::<Array<_>, Integer, _, _>(vec![1, 2, 3, 4], 5))
1367 /// .get_result::<Option<i32>>(connection)?;
1368 /// assert_eq!(None::<i32>, pos);
1369 ///
1370 /// let pos = diesel::select(array_position::<Array<_>, Nullable<Integer>, _, _>(
1371 /// vec![1, 2, 3, 4], None::<i32>))
1372 /// .get_result::<Option<i32>>(connection)?;
1373 /// assert_eq!(None::<i32>, pos);
1374 ///
1375 /// let pos = diesel::select(array_position::<Array<_>, Nullable<Integer>, _, _>(
1376 /// vec![None::<i32>, Some(1), Some(2), Some(3)], None::<i32>))
1377 /// .get_result::<Option<i32>>(connection)?;
1378 /// assert_eq!(Some(1), pos);
1379 ///
1380 /// let dims = diesel::select(array_position::<Nullable<Array<Integer>>, Integer, _, _>(None::<Vec<i32>>, 1))
1381 /// .get_result::<Option<i32>>(connection)?;
1382 /// assert_eq!(None, dims);
1383 ///
1384 /// # Ok(())
1385 /// # }
1386 #[cfg(feature = "postgres_backend")]
1387 fn array_position<Arr: ArrayOrNullableArray<Inner = E> + SingleValue, E: SingleValue>(
1388 a: Arr,
1389 elem: E,
1390 ) -> Nullable<Integer>;
1391
1392 /// Returns the subscript of the first occurrence of the second argument in the array,
1393 /// or NULL if it's not present, beginning at the subscript given as the third argument.
1394 ///
1395 /// The array must be one-dimensional.
1396 /// Comparisons are done using IS NOT DISTINCT FROM semantics,
1397 /// so it is possible to search for NULL.
1398 /// # Example
1399 ///
1400 /// ```rust
1401 /// # include!("../../doctest_setup.rs");
1402 /// #
1403 /// # fn main(){
1404 /// # run_test().unwrap();
1405 /// # }
1406 /// # fn run_test()->QueryResult<()>{
1407 /// # use diesel::dsl::array_position_with_subscript;
1408 /// # use diesel::sql_types::{Nullable,Array,Integer};
1409 /// # let connection = &mut establish_connection();
1410 ///
1411 /// let pos = diesel::select(array_position_with_subscript::<Array<_>, Integer, _, _, _>(
1412 /// vec![1, 2, 3, 4], 3, 2))
1413 /// .get_result::<Option<i32>>(connection)?;
1414 /// assert_eq!(Some(3), pos);
1415 ///
1416 /// let pos = diesel::select(array_position_with_subscript::<Array<_>, Integer, _, _, _>(
1417 /// vec![1, 2, 3, 4], 1, 2))
1418 /// .get_result::<Option<i32>>(connection)?;
1419 /// assert_eq!(None::<i32>, pos);
1420 ///
1421 /// let pos = diesel::select(array_position_with_subscript::<Array<_>, Nullable<Integer>, _, _, _>(
1422 /// vec![None::<i32>, Some(1), Some(2), Some(3)], None::<i32>, 1))
1423 /// .get_result::<Option<i32>>(connection)?;
1424 /// assert_eq!(Some(1), pos);
1425 ///
1426 /// let pos = diesel::select(array_position_with_subscript::<Array<_>, Nullable<Integer>, _, _, _>(
1427 /// vec![None::<i32>, Some(1), Some(2), Some(3)], None::<i32>, 2))
1428 /// .get_result::<Option<i32>>(connection)?;
1429 /// assert_eq!(None::<i32>, pos);
1430 /// # Ok(())
1431 /// # }
1432 #[sql_name = "array_position"]
1433 #[cfg(feature = "postgres_backend")]
1434 fn array_position_with_subscript<
1435 Arr: ArrayOrNullableArray<Inner = E> + SingleValue,
1436 E: SingleValue,
1437 >(
1438 a: Arr,
1439 elem: E,
1440 subscript: Integer,
1441 ) -> Nullable<Integer>;
1442
1443 /// Returns an array of the subscripts of all occurrences of the second argument in the
1444 /// array given as first argument.
1445 ///
1446 /// The array must be one-dimensional. Comparisons are done using IS NOT DISTINCT FROM semantics,
1447 /// so it is possible to search for NULL.
1448 /// NULL is returned only if the array is NULL; if the value is not found in the array, an empty array is returned.
1449 ///
1450 /// # Example
1451 ///
1452 /// ```rust
1453 /// # include!("../../doctest_setup.rs");
1454 /// #
1455 /// # fn main(){
1456 /// # run_test().unwrap();
1457 /// # }
1458 /// # fn run_test()->QueryResult<()>{
1459 /// # use diesel::dsl::array_positions;
1460 /// # use diesel::sql_types::{Nullable,Array,Integer};
1461 /// # let connection = &mut establish_connection();
1462 ///
1463 /// let pos = diesel::select(array_positions::<Array<_>, Integer, _, _>(vec![1, 1, 2, 1], 1))
1464 /// .get_result::<Vec<i32>>(connection)?;
1465 /// assert_eq!(vec![1,2,4], pos);
1466 ///
1467 /// let pos = diesel::select(array_positions::<Array<_>, Integer, _, _>(vec![1, 2, 3, 4], 5))
1468 /// .get_result::<Vec<i32>>(connection)?;
1469 /// assert_eq!(Vec::<i32>::new(), pos);
1470 ///
1471 /// let pos = diesel::select(array_positions::<Array<_>, Nullable<Integer>, _, _>(
1472 /// vec![None::<i32>, Some(2), Some(3), None::<i32>], None::<i32>))
1473 /// .get_result::<Vec<i32>>(connection)?;
1474 /// assert_eq!(vec![1,4], pos);
1475 ///
1476 /// let pos = diesel::select(array_positions::<Nullable<Array<_>>, Integer, _, _>(
1477 /// None::<Vec<i32>>, 1))
1478 /// .get_result::<Option<Vec<i32>>>(connection)?;
1479 /// assert_eq!(None::<Vec<i32>>, pos);
1480 /// # Ok(())
1481 /// # }
1482 #[cfg(feature = "postgres_backend")]
1483 fn array_positions<
1484 Arr: ArrayOrNullableArray<Inner = E> + SingleValue + MaybeNullableValue<Array<Integer>>,
1485 E: SingleValue,
1486 >(
1487 a: Arr,
1488 elem: E,
1489 ) -> Arr::Out;
1490
1491 /// Returns the number of dimensions of the array
1492 ///
1493 /// # Example
1494 ///
1495 /// ```rust
1496 /// # include!("../../doctest_setup.rs");
1497 /// #
1498 /// # fn main() {
1499 /// # run_test().unwrap();
1500 /// # }
1501 /// #
1502 /// # fn run_test() -> QueryResult<()> {
1503 /// # use diesel::dsl::array_ndims;
1504 /// # use diesel::sql_types::{Nullable, Array, Integer};
1505 /// # let connection = &mut establish_connection();
1506 ///
1507 /// // diesel currently only supports 1D arrays
1508 /// let dims = diesel::select(array_ndims::<Array<Integer>, _>(vec![1, 2]))
1509 /// .get_result::<i32>(connection)?;
1510 /// assert_eq!(1, dims);
1511 ///
1512 /// let dims = diesel::select(array_ndims::<Nullable<Array<Integer>>, _>(None::<Vec<i32>>))
1513 /// .get_result::<Option<i32>>(connection)?;
1514 /// assert_eq!(None, dims);
1515 ///
1516 /// # Ok(())
1517 /// # }
1518 /// ```
1519 #[cfg(feature = "postgres_backend")]
1520 fn array_ndims<Arr: ArrayOrNullableArray + SingleValue + MaybeNullableValue<Integer>>(
1521 arr: Arr,
1522 ) -> Arr::Out;
1523
1524 /// Returns the upper bound of the requested array
1525 ///
1526 /// This function returns null for dimensions that do not exist
1527 ///
1528 /// # Example
1529 ///
1530 /// ```rust
1531 /// # include!("../../doctest_setup.rs");
1532 /// #
1533 /// # fn main() {
1534 /// # run_test().unwrap();
1535 /// # }
1536 /// #
1537 /// # fn run_test() -> QueryResult<()> {
1538 /// # use diesel::dsl::array_upper;
1539 /// # use diesel::sql_types::{Integer, Array};
1540 /// # let connection = &mut establish_connection();
1541 /// let result = diesel::select(array_upper::<Array<Integer>, _, _>(vec![1, 2, 3], 1))
1542 /// .get_result::<Option<i32>>(connection)?;
1543 /// assert_eq!(Some(3), result);
1544 ///
1545 /// // the array has only one dimension
1546 /// let result = diesel::select(array_upper::<Array<Integer>, _, _>(vec![1, 2, 3], 2))
1547 /// .get_result::<Option<i32>>(connection)?;
1548 /// assert_eq!(None, result);
1549 /// # Ok(())
1550 /// # }
1551 /// ```
1552 #[cfg(feature = "postgres_backend")]
1553 fn array_upper<Arr: ArrayOrNullableArray + SingleValue>(
1554 array: Arr,
1555 dimension: Integer,
1556 ) -> Nullable<Integer>;
1557
1558 /// Randomly shuffles the first dimension of the array.
1559 ///
1560 /// # Example
1561 // This function requires postgres >= 16.0
1562 // which we cannot expect to be widely used at the
1563 // point of writing this comment, so we skip running this test
1564 /// ```rust,no_run
1565 /// # include!("../../doctest_setup.rs");
1566 /// #
1567 /// # fn main() {
1568 /// # run_test().unwrap();
1569 /// # }
1570 /// #
1571 /// # fn run_test() -> QueryResult<()> {
1572 /// # use diesel::dsl::array_shuffle;
1573 /// # use diesel::sql_types::{Array, Integer};
1574 /// # let connection = &mut establish_connection();
1575 /// let shuffled = diesel::select(array_shuffle::<Array<Integer>, _>(vec![1, 2, 3, 4, 5]))
1576 /// .get_result::<Vec<i32>>(connection)?;
1577 /// assert_eq!(5, shuffled.len());
1578 /// assert_eq!(shuffled.iter().sum::<i32>(), 15);
1579 /// # Ok(())
1580 /// # }
1581 /// ```
1582 #[cfg(feature = "postgres_backend")]
1583 fn array_shuffle<Arr: ArrayOrNullableArray + SingleValue>(array: Arr) -> Arr;
1584
1585 /// Returns an array of n items randomly selected from array.
1586 /// n may not exceed the length of the array.
1587 ///
1588 /// # Example
1589 // This function requires postgres >= 16.0
1590 // which we cannot expect to be widely used at the
1591 // point of writing this comment, so we skip running this test
1592 /// ```rust,no_run
1593 /// # include!("../../doctest_setup.rs");
1594 /// #
1595 /// # fn main() {
1596 /// # run_test().unwrap();
1597 /// # }
1598 /// #
1599 /// # fn run_test() -> QueryResult<()> {
1600 /// # use diesel::dsl::array_sample;
1601 /// # use diesel::sql_types::{Array, Integer, Nullable};
1602 /// # let connection = &mut establish_connection();
1603 ///
1604 /// let vec = vec![1, 2, 3, 4, 5];
1605 /// let sampled = diesel::select(array_sample::<Array<Integer>, _, _>(vec.clone(), 3))
1606 /// .get_result::<Vec<i32>>(connection)?;
1607 /// assert_eq!(3, sampled.len());
1608 /// assert!(sampled.iter().all(|x| vec.contains(x)));
1609 ///
1610 /// let vec: Vec<i32> = Vec::new();
1611 /// let sampled = diesel::select(array_sample::<Array<Integer>, _, _>(vec, 0))
1612 /// .get_result::<Vec<i32>>(connection)?;
1613 /// assert_eq!(0, sampled.len());
1614 ///
1615 /// let sampled = diesel::select(array_sample::<Nullable<Array<Integer>>, _, _>(
1616 /// None::<Vec<i32>>,
1617 /// 1,
1618 /// ))
1619 /// .get_result::<Option<Vec<i32>>>(connection)?;
1620 /// assert!(sampled.is_none());
1621 /// # Ok(())
1622 /// # }
1623 /// ```
1624 #[cfg(feature = "postgres_backend")]
1625 fn array_sample<Arr: ArrayOrNullableArray + SingleValue>(array: Arr, n: Integer) -> Arr;
1626
1627 /// Converts any Array to json.
1628 ///
1629 /// # Example
1630 ///
1631 /// ```rust
1632 /// # include!("../../doctest_setup.rs");
1633 /// #
1634 /// # fn main() {
1635 /// # #[cfg(feature = "serde_json")]
1636 /// # run_test().unwrap();
1637 /// # }
1638 /// #
1639 /// # #[cfg(feature = "serde_json")]
1640 /// # fn run_test() -> QueryResult<()> {
1641 /// # use diesel::dsl::array_to_json;
1642 /// # use diesel::sql_types::{Array, Integer, Text, Nullable};
1643 /// # use serde_json::Value;
1644 /// # let connection = &mut establish_connection();
1645 /// let json = diesel::select(array_to_json::<Array<Integer>, _>(vec![1, 2, 3, 4, 5]))
1646 /// .get_result::<Value>(connection)?;
1647 /// let expected: Value = serde_json::json!([1, 2, 3, 4, 5]);
1648 /// assert_eq!(expected, json);
1649 /// let json = diesel::select(array_to_json::<Array<Text>, _>(vec![
1650 /// "hello", "world", "John", "Doe",
1651 /// ]))
1652 /// .get_result::<Value>(connection)?;
1653 /// let expected: Value = serde_json::json!(["hello", "world", "John", "Doe"]);
1654 /// assert_eq!(expected, json);
1655 /// let empty: Vec<String> = Vec::new();
1656 /// let json = diesel::select(array_to_json::<Array<Nullable<Text>>, _>(empty))
1657 /// .get_result::<Value>(connection)?;
1658 /// assert_eq!(serde_json::json!([]), json);
1659 /// let json = diesel::select(array_to_json::<Nullable<Array<Integer>>, _>(
1660 /// None::<Vec<i32>>,
1661 /// ))
1662 /// .get_result::<Option<Value>>(connection)?;
1663 /// assert_eq!(None, json);
1664 /// # Ok(())
1665 /// # }
1666 /// ```
1667 #[cfg(feature = "postgres_backend")]
1668 fn array_to_json<Arr: ArrayOrNullableArray + MaybeNullableValue<Json>>(array: Arr) -> Arr::Out;
1669
1670 /// Converts any SQL value to json
1671 ///
1672 /// # Example
1673 ///
1674 /// ```rust
1675 /// # include!("../../doctest_setup.rs");
1676 /// #
1677 /// # fn main() {
1678 /// # #[cfg(feature = "serde_json")]
1679 /// # run_test().unwrap();
1680 /// # }
1681 /// #
1682 /// # #[cfg(feature = "serde_json")]
1683 /// # fn run_test() -> QueryResult<()> {
1684 /// # use diesel::dsl::to_json;
1685 /// # use serde_json::{json, Value};
1686 /// # use diesel::sql_types::{Integer, Array, Json, Text, Nullable};
1687 /// # let connection = &mut establish_connection();
1688 /// let result = diesel::select(to_json::<Integer, _>(1)).get_result::<Value>(connection)?;
1689 ///
1690 /// assert_eq!(json!(1), result);
1691 ///
1692 /// let result = diesel::select(to_json::<Array<Text>, _>(vec!["abc", "xyz"]))
1693 /// .get_result::<Value>(connection)?;
1694 ///
1695 /// assert_eq!(json!(["abc", "xyz"]), result);
1696 ///
1697 /// let result = diesel::select(to_json::<Array<Nullable<Text>>, _>(Vec::<String>::new()))
1698 /// .get_result::<Value>(connection)?;
1699 ///
1700 /// assert_eq!(json!([]), result);
1701 ///
1702 /// let result = diesel::select(to_json::<Nullable<Text>, _>(None::<String>))
1703 /// .get_result::<Option<Value>>(connection)?;
1704 ///
1705 /// assert!(result.is_none());
1706 ///
1707 /// # Ok(())
1708 /// # }
1709 /// ```
1710 #[cfg(feature = "postgres_backend")]
1711 fn to_json<E: MaybeNullableValue<Json>>(e: E) -> E::Out;
1712
1713 /// Converts any SQL value to jsonb
1714 ///
1715 /// # Example
1716 ///
1717 /// ```rust
1718 /// # include!("../../doctest_setup.rs");
1719 /// #
1720 /// # fn main() {
1721 /// # #[cfg(feature = "serde_json")]
1722 /// # run_test().unwrap();
1723 /// # }
1724 /// #
1725 /// # #[cfg(feature = "serde_json")]
1726 /// # fn run_test() -> QueryResult<()> {
1727 /// # use diesel::dsl::to_jsonb;
1728 /// # use serde_json::{json, Value};
1729 /// # use diesel::sql_types::{Integer, Array, Jsonb, Text, Nullable};
1730 /// # let connection = &mut establish_connection();
1731 /// let result = diesel::select(to_jsonb::<Integer, _>(1)).get_result::<Value>(connection)?;
1732 ///
1733 /// assert_eq!(json!(1), result);
1734 ///
1735 /// let result = diesel::select(to_jsonb::<Array<Text>, _>(vec!["abc", "def"]))
1736 /// .get_result::<Value>(connection)?;
1737 ///
1738 /// assert_eq!(json!(["abc", "def"]), result);
1739 ///
1740 /// let result = diesel::select(to_jsonb::<Array<Nullable<Text>>, _>(Vec::<String>::new()))
1741 /// .get_result::<Value>(connection)?;
1742 ///
1743 /// assert_eq!(json!([]), result);
1744 ///
1745 /// let result = diesel::select(to_jsonb::<Nullable<Text>, _>(None::<String>))
1746 /// .get_result::<Option<Value>>(connection)?;
1747 ///
1748 /// assert!(result.is_none());
1749 ///
1750 /// # Ok(())
1751 /// # }
1752 /// ```
1753 #[cfg(feature = "postgres_backend")]
1754 fn to_jsonb<E: MaybeNullableValue<Jsonb>>(e: E) -> E::Out;
1755
1756 /// Builds a JSON object out of a text array. The array must have an even number of members,
1757 /// in which case they are taken as alternating key/value pairs
1758 ///
1759 /// # Example
1760 ///
1761 /// ```rust
1762 /// # include!("../../doctest_setup.rs");
1763 /// #
1764 /// # fn main() {
1765 /// # #[cfg(feature = "serde_json")]
1766 /// # run_test().unwrap();
1767 /// # }
1768 /// #
1769 /// # #[cfg(feature = "serde_json")]
1770 /// # fn run_test() -> QueryResult<()> {
1771 /// # use diesel::dsl::json_object;
1772 /// # use diesel::sql_types::{Array, Json, Nullable, Text};
1773 /// # use serde_json::Value;
1774 /// # let connection = &mut establish_connection();
1775 /// let json = diesel::select(json_object::<Array<Text>,_>(vec!["hello","world"]))
1776 /// .get_result::<Value>(connection)?;
1777 /// let expected:Value = serde_json::json!({"hello":"world"});
1778 /// assert_eq!(expected,json);
1779 ///
1780 /// let json = diesel::select(json_object::<Array<Text>,_>(vec!["hello","world","John","Doe"]))
1781 /// .get_result::<Value>(connection)?;
1782 /// let expected:Value = serde_json::json!({"hello":"world","John":"Doe"});
1783 /// assert_eq!(expected,json);
1784 ///
1785 /// let json = diesel::select(json_object::<Array<Text>,_>(vec!["hello","world","John"]))
1786 /// .get_result::<Value>(connection);
1787 /// assert!(json.is_err());
1788 ///
1789 /// let empty:Vec<String> = Vec::new();
1790 /// let json = diesel::select(json_object::<Array<Nullable<Text>>,_>(empty))
1791 /// .get_result::<Value>(connection);
1792 /// assert!(json.is_err());
1793 ///
1794 /// # Ok(())
1795 /// # }
1796 /// ```
1797 #[cfg(feature = "postgres_backend")]
1798 fn json_object<Arr: TextArrayOrNullableTextArray + MaybeNullableValue<Json>>(
1799 text_array: Arr,
1800 ) -> Arr::Out;
1801
1802 /// This form of json_object takes keys and values pairwise from two separate arrays.
1803 /// In all other respects it is identical to the one-argument form.
1804 ///
1805 /// # Example
1806 ///
1807 /// ```rust
1808 /// # include!("../../doctest_setup.rs");
1809 /// #
1810 /// # fn main() {
1811 /// # #[cfg(feature = "serde_json")]
1812 /// # run_test().unwrap();
1813 /// # }
1814 /// #
1815 /// # #[cfg(feature = "serde_json")]
1816 /// # fn run_test() -> QueryResult<()> {
1817 /// # use diesel::dsl::json_object_with_keys_and_values;
1818 /// # use diesel::sql_types::{Array, Json, Nullable, Text};
1819 /// # use serde_json::Value;
1820 /// # let connection = &mut establish_connection();
1821 /// let json = diesel::select(json_object_with_keys_and_values::<Array<Text>, Array<Text>, _, _>(
1822 /// vec!["hello","John"],vec!["world","Doe"]))
1823 /// .get_result::<Value>(connection)?;
1824 /// let expected:Value = serde_json::json!({"hello":"world","John":"Doe"});
1825 /// assert_eq!(expected,json);
1826 ///
1827 /// let json = diesel::select(json_object_with_keys_and_values::<Nullable<Array<Text>>, Nullable<Array<Text>>, _, _>(
1828 /// Some(vec!["hello","John"]), None::<Vec<String>>))
1829 /// .get_result::<Option<Value>>(connection)?;
1830 /// assert_eq!(None::<Value>,json);
1831 ///
1832 /// let empty: Vec<String> = Vec::new();
1833 /// let json = diesel::select(json_object_with_keys_and_values::<Array<Text>, Array<Text>, _, _>(
1834 /// vec!["hello","John"], empty))
1835 /// .get_result::<Value>(connection);
1836 /// assert!(json.is_err());
1837 ///
1838 /// # Ok(())
1839 /// # }
1840 /// ```
1841 #[sql_name = "json_object"]
1842 #[cfg(feature = "postgres_backend")]
1843 fn json_object_with_keys_and_values<
1844 Arr1: TextArrayOrNullableTextArray + SingleValue,
1845 Arr2: TextArrayOrNullableTextArray + CombinedNullableValue<Arr1, Json>,
1846 >(
1847 keys: Arr1,
1848 values: Arr2,
1849 ) -> Arr2::Out;
1850
1851 /// Returns the type of the top-level json value as a text-string
1852 ///
1853 /// # Example
1854 ///
1855 /// ```rust
1856 /// # include!("../../doctest_setup.rs");
1857 /// #
1858 /// # fn main() {
1859 /// # #[cfg(feature = "serde_json")]
1860 /// # run_test().unwrap();
1861 /// # }
1862 /// #
1863 /// # #[cfg(feature = "serde_json")]
1864 /// # fn run_test() -> QueryResult<()> {
1865 /// # use diesel::dsl::json_typeof;
1866 /// # use serde_json::{json, Value};
1867 /// # use diesel::sql_types::{Json, Nullable};
1868 /// # let connection = &mut establish_connection();
1869 /// let result = diesel::select(json_typeof::<Json, _>(json!({"a": "b", "c": 1})))
1870 /// .get_result::<String>(connection)?;
1871 ///
1872 /// assert_eq!("object".to_string(), result);
1873 ///
1874 /// let result = diesel::select(json_typeof::<Json, _>(json!([1,2,3])))
1875 /// .get_result::<String>(connection)?;
1876 ///
1877 /// assert_eq!("array".to_string(), result);
1878 ///
1879 /// let result = diesel::select(json_typeof::<Json, _>(json!("abc")))
1880 /// .get_result::<String>(connection)?;
1881 ///
1882 /// assert_eq!("string".to_string(), result);
1883 ///
1884 /// let result = diesel::select(json_typeof::<Json, _>(json!(-123.4)))
1885 /// .get_result::<String>(connection)?;
1886 ///
1887 /// assert_eq!("number".to_string(), result);
1888 ///
1889 /// let result = diesel::select(json_typeof::<Json, _>(json!(true)))
1890 /// .get_result::<String>(connection)?;
1891 ///
1892 /// assert_eq!("boolean".to_string(), result);
1893 ///
1894 /// let result = diesel::select(json_typeof::<Json, _>(json!(null)))
1895 /// .get_result::<String>(connection)?;
1896 ///
1897 /// assert_eq!("null".to_string(), result);
1898 ///
1899 /// let result = diesel::select(json_typeof::<Nullable<Json>, _>(None::<Value>))
1900 /// .get_result::<Option<String>>(connection)?;
1901 ///
1902 /// assert!(result.is_none());
1903 /// # Ok(())
1904 /// # }
1905 /// ```
1906 #[cfg(feature = "postgres_backend")]
1907 fn json_typeof<E: JsonOrNullableJson + SingleValue + MaybeNullableValue<Text>>(e: E) -> E::Out;
1908
1909 /// Returns the type of the top-level jsonb value as a text-string
1910 ///
1911 /// # Example
1912 ///
1913 /// ```rust
1914 /// # include!("../../doctest_setup.rs");
1915 /// #
1916 /// # fn main() {
1917 /// # #[cfg(feature = "serde_json")]
1918 /// # run_test().unwrap();
1919 /// # }
1920 /// #
1921 /// # #[cfg(feature = "serde_json")]
1922 /// # fn run_test() -> QueryResult<()> {
1923 /// # use diesel::dsl::jsonb_typeof;
1924 /// # use serde_json::{json, Value};
1925 /// # use diesel::sql_types::{Jsonb, Nullable};
1926 /// # let connection = &mut establish_connection();
1927 /// let result = diesel::select(jsonb_typeof::<Jsonb, _>(json!({"a": "b", "c": 1})))
1928 /// .get_result::<String>(connection)?;
1929 ///
1930 /// assert_eq!("object".to_string(), result);
1931 ///
1932 /// let result = diesel::select(jsonb_typeof::<Jsonb, _>(json!([1,2,3])))
1933 /// .get_result::<String>(connection)?;
1934 ///
1935 /// assert_eq!("array".to_string(), result);
1936 ///
1937 /// let result = diesel::select(jsonb_typeof::<Jsonb, _>(json!("abc")))
1938 /// .get_result::<String>(connection)?;
1939 ///
1940 /// assert_eq!("string".to_string(), result);
1941 ///
1942 /// let result = diesel::select(jsonb_typeof::<Jsonb, _>(json!(-123.4)))
1943 /// .get_result::<String>(connection)?;
1944 ///
1945 /// assert_eq!("number".to_string(), result);
1946 ///
1947 /// let result = diesel::select(jsonb_typeof::<Jsonb, _>(json!(true)))
1948 /// .get_result::<String>(connection)?;
1949 ///
1950 /// assert_eq!("boolean".to_string(), result);
1951 ///
1952 /// let result = diesel::select(jsonb_typeof::<Jsonb, _>(json!(null)))
1953 /// .get_result::<String>(connection)?;
1954 ///
1955 /// assert_eq!("null".to_string(), result);
1956 ///
1957 /// let result = diesel::select(jsonb_typeof::<Nullable<Jsonb>, _>(None::<Value>))
1958 /// .get_result::<Option<String>>(connection)?;
1959 ///
1960 /// assert!(result.is_none());
1961 /// # Ok(())
1962 /// # }
1963 /// ```
1964 #[cfg(feature = "postgres_backend")]
1965 fn jsonb_typeof<E: JsonbOrNullableJsonb + SingleValue + MaybeNullableValue<Text>>(
1966 e: E,
1967 ) -> E::Out;
1968
1969 /// Converts the given json value to pretty-printed, indented text
1970 ///
1971 /// # Example
1972 ///
1973 /// ```rust
1974 /// # include!("../../doctest_setup.rs");
1975 /// #
1976 /// # fn main() {
1977 /// # #[cfg(feature = "serde_json")]
1978 /// # run_test().unwrap();
1979 /// # }
1980 /// #
1981 /// # #[cfg(feature = "serde_json")]
1982 /// # fn run_test() -> QueryResult<()> {
1983 /// # use diesel::dsl::jsonb_pretty;
1984 /// # use serde_json::{json, Value};
1985 /// # use diesel::sql_types::{Jsonb, Nullable};
1986 /// # let connection = &mut establish_connection();
1987 /// let result = diesel::select(jsonb_pretty::<Jsonb, _>(json!([{"f1":1,"f2":null},2,null,3])))
1988 /// .get_result::<String>(connection)?;
1989 ///
1990 /// assert_eq!(r#"[
1991 /// {
1992 /// "f1": 1,
1993 /// "f2": null
1994 /// },
1995 /// 2,
1996 /// null,
1997 /// 3
1998 /// ]"#, result);
1999 ///
2000 /// let result = diesel::select(jsonb_pretty::<Jsonb, _>(json!({"a": 1, "b": "cd"})))
2001 /// .get_result::<String>(connection)?;
2002 ///
2003 /// assert_eq!(r#"{
2004 /// "a": 1,
2005 /// "b": "cd"
2006 /// }"#, result);
2007 ///
2008 /// let result = diesel::select(jsonb_pretty::<Jsonb, _>(json!("abc")))
2009 /// .get_result::<String>(connection)?;
2010 ///
2011 /// assert_eq!(r#""abc""#, result);
2012 ///
2013 /// let result = diesel::select(jsonb_pretty::<Jsonb, _>(json!(22)))
2014 /// .get_result::<String>(connection)?;
2015 ///
2016 /// assert_eq!(r#"22"#, result);
2017 ///
2018 /// let result = diesel::select(jsonb_pretty::<Jsonb, _>(json!(false)))
2019 /// .get_result::<String>(connection)?;
2020 ///
2021 /// assert_eq!(r#"false"#, result);
2022 ///
2023 /// let result = diesel::select(jsonb_pretty::<Jsonb, _>(json!(null)))
2024 /// .get_result::<String>(connection)?;
2025 ///
2026 /// assert_eq!(r#"null"#, result);
2027 ///
2028 /// let result = diesel::select(jsonb_pretty::<Jsonb, _>(json!({})))
2029 /// .get_result::<String>(connection)?;
2030 ///
2031 /// assert_eq!(r#"{
2032 /// }"#, result);
2033 ///
2034 /// let result = diesel::select(jsonb_pretty::<Nullable<Jsonb>, _>(None::<Value>))
2035 /// .get_result::<Option<String>>(connection)?;
2036 ///
2037 /// assert!(result.is_none());
2038 /// # Ok(())
2039 /// # }
2040 /// ```
2041 #[cfg(feature = "postgres_backend")]
2042 fn jsonb_pretty<E: JsonbOrNullableJsonb + SingleValue + MaybeNullableValue<Text>>(
2043 e: E,
2044 ) -> E::Out;
2045
2046 /// Deletes all object fields that have null values from the given JSON value, recursively.
2047 ///
2048 /// # Example
2049 ///
2050 /// ```rust
2051 /// # include!("../../doctest_setup.rs");
2052 /// #
2053 /// # fn main() {
2054 /// # #[cfg(feature = "serde_json")]
2055 /// # run_test().unwrap();
2056 /// # }
2057 /// #
2058 /// # #[cfg(feature = "serde_json")]
2059 /// # fn run_test() -> QueryResult<()> {
2060 /// # use diesel::dsl::json_strip_nulls;
2061 /// # use diesel::sql_types::{Json, Nullable};
2062 /// # use serde_json::{json, Value};
2063 /// # let connection = &mut establish_connection();
2064 ///
2065 /// let result = diesel::select(json_strip_nulls::<Json, _>(json!({"hello": null})))
2066 /// .get_result::<Value>(connection)?;
2067 /// let expected: Value = json!({});
2068 /// assert_eq!(result, expected);
2069 ///
2070 /// let result = diesel::select(json_strip_nulls::<Json, _>(json!([{"f1":1, "f2":null}, 2, null, 3])))
2071 /// .get_result::<Value>(connection)?;
2072 /// let expected: Value = json!([{"f1":1}, 2, null, 3]);
2073 /// assert_eq!(result, expected);
2074 ///
2075 /// let result = diesel::select(json_strip_nulls::<Nullable<Json>, _>(None::<Value>))
2076 /// .get_result::<Option<Value>>(connection)?;
2077 /// assert!(result.is_none());
2078 ///
2079 /// let result = diesel::select(json_strip_nulls::<Json, _>(json!(null)))
2080 /// .get_result::<Value>(connection)?;
2081 /// let expected = json!(null);
2082 /// assert_eq!(result, expected);
2083 ///
2084 ///
2085 /// # Ok(())
2086 /// # }
2087 /// ```
2088 #[cfg(feature = "postgres_backend")]
2089 fn json_strip_nulls<E: JsonOrNullableJson + SingleValue>(json: E) -> E;
2090
2091 /// Deletes all object fields that have null values from the given JSON value, recursively.
2092 ///
2093 /// # Example
2094 ///
2095 /// ```rust
2096 /// # include!("../../doctest_setup.rs");
2097 /// #
2098 /// # fn main() {
2099 /// # #[cfg(feature = "serde_json")]
2100 /// # run_test().unwrap();
2101 /// # }
2102 /// #
2103 /// # #[cfg(feature = "serde_json")]
2104 /// # fn run_test() -> QueryResult<()> {
2105 /// # use diesel::dsl::jsonb_strip_nulls;
2106 /// # use diesel::sql_types::{Jsonb, Nullable};
2107 /// # use serde_json::{json, Value};
2108 /// # let connection = &mut establish_connection();
2109 ///
2110 /// let result = diesel::select(jsonb_strip_nulls::<Jsonb, _>(json!({"hello": null})))
2111 /// .get_result::<Value>(connection)?;
2112 /// let expected: Value = json!({});
2113 /// assert_eq!(result, expected);
2114 ///
2115 /// let result = diesel::select(jsonb_strip_nulls::<Jsonb, _>(json!([{"f1":1, "f2":null}, 2, null, 3])))
2116 /// .get_result::<Value>(connection)?;
2117 /// let expected: Value = json!([{"f1":1}, 2, null, 3]);
2118 /// assert_eq!(result, expected);
2119 ///
2120 /// let result = diesel::select(jsonb_strip_nulls::<Nullable<Jsonb>, _>(None::<Value>))
2121 /// .get_result::<Option<Value>>(connection)?;
2122 /// assert!(result.is_none());
2123 ///
2124 /// let result = diesel::select(jsonb_strip_nulls::<Jsonb, _>(json!(null)))
2125 /// .get_result::<Value>(connection)?;
2126 /// let expected = json!(null);
2127 /// assert_eq!(result, expected);
2128 ///
2129 ///
2130 ///
2131 /// # Ok(())
2132 /// # }
2133 /// ```
2134 #[cfg(feature = "postgres_backend")]
2135 fn jsonb_strip_nulls<E: JsonbOrNullableJsonb + SingleValue>(jsonb: E) -> E;
2136
2137 /// Returns the number of elements in the top-level JSON array
2138 ///
2139 ///
2140 /// # Example
2141 ///
2142 /// ```rust
2143 /// # include!("../../doctest_setup.rs");
2144 /// #
2145 /// # fn main() {
2146 /// # #[cfg(feature = "serde_json")]
2147 /// # run_test().unwrap();
2148 /// # }
2149 /// #
2150 /// # #[cfg(feature = "serde_json")]
2151 /// # fn run_test() -> QueryResult<()> {
2152 /// # use diesel::dsl::json_array_length;
2153 /// # use serde_json::{json, Value};
2154 /// # use diesel::sql_types::{Integer, Json, Nullable};
2155 /// # let connection = &mut establish_connection();
2156 ///
2157 /// let result = diesel::select(json_array_length::<Json, _>(json!([1, 2, 3])))
2158 /// .get_result::<i32>(connection)?;
2159 /// assert_eq!(result, 3);
2160 ///
2161 /// let result =
2162 /// diesel::select(json_array_length::<Json, _>(json!([]))).get_result::<i32>(connection)?;
2163 /// assert_eq!(result, 0);
2164 ///
2165 /// let result = diesel::select(json_array_length::<Nullable<Json>, _>(None::<Value>))
2166 /// .get_result::<Option<i32>>(connection)?;
2167 /// assert!(result.is_none());
2168 ///
2169 /// # Ok(())
2170 /// # }
2171 /// ```
2172 #[cfg(feature = "postgres_backend")]
2173 fn json_array_length<E: JsonOrNullableJson + MaybeNullableValue<Integer>>(json: E) -> E::Out;
2174
2175 /// Returns the number of elements in the top-level JSON array
2176 ///
2177 ///
2178 /// # Example
2179 ///
2180 /// ```rust
2181 /// # include!("../../doctest_setup.rs");
2182 /// #
2183 /// # fn main() {
2184 /// # #[cfg(feature = "serde_json")]
2185 /// # run_test().unwrap();
2186 /// # }
2187 /// #
2188 /// # #[cfg(feature = "serde_json")]
2189 /// # fn run_test() -> QueryResult<()> {
2190 /// # use diesel::dsl::jsonb_array_length;
2191 /// # use serde_json::{json, Value};
2192 /// # use diesel::sql_types::{Integer, Jsonb, Nullable};
2193 /// # let connection = &mut establish_connection();
2194 ///
2195 /// let result = diesel::select(jsonb_array_length::<Jsonb, _>(json!([1, 2, 3])))
2196 /// .get_result::<i32>(connection)?;
2197 /// assert_eq!(result, 3);
2198 ///
2199 /// let result =
2200 /// diesel::select(jsonb_array_length::<Jsonb, _>(json!([]))).get_result::<i32>(connection)?;
2201 /// assert_eq!(result, 0);
2202 ///
2203 /// let result = diesel::select(jsonb_array_length::<Nullable<Jsonb>, _>(None::<Value>))
2204 /// .get_result::<Option<i32>>(connection)?;
2205 /// assert!(result.is_none());
2206 ///
2207 /// # Ok(())
2208 /// # }
2209 /// ```
2210 #[cfg(feature = "postgres_backend")]
2211 fn jsonb_array_length<E: JsonbOrNullableJsonb + MaybeNullableValue<Integer>>(
2212 jsonb: E,
2213 ) -> E::Out;
2214 /// Builds a JSON object out of a text array. The array must have an even number of members,
2215 /// in which case they are taken as alternating key/value pairs. This function also has a form that
2216 /// that takes keys and values as separate text array arguments.
2217 /// See [jsonb_object_with_keys_and_values](jsonb_object_with_keys_and_values())
2218 ///
2219 /// # Example
2220 ///
2221 /// ```rust
2222 /// # include!("../../doctest_setup.rs");
2223 /// #
2224 /// # fn main() {
2225 /// # #[cfg(feature = "serde_json")]
2226 /// # run_test().unwrap();
2227 /// # }
2228 /// #
2229 /// # #[cfg(feature = "serde_json")]
2230 /// # fn run_test() -> QueryResult<()> {
2231 /// # use diesel::dsl::jsonb_object;
2232 /// # use diesel::sql_types::{Array, Json, Nullable, Text};
2233 /// # use serde_json::Value;
2234 /// # let connection = &mut establish_connection();
2235 /// let jsonb = diesel::select(jsonb_object::<Array<Text>,_>(vec!["hello","world"]))
2236 /// .get_result::<Value>(connection)?;
2237 /// let expected:Value = serde_json::json!({"hello":"world"});
2238 /// assert_eq!(expected, jsonb);
2239 ///
2240 /// let jsonb = diesel::select(jsonb_object::<Array<Text>, _>(vec!["hello","world","John","Doe"]))
2241 /// .get_result::<Value>(connection)?;
2242 /// let expected:Value = serde_json::json!({"hello": "world","John": "Doe"});
2243 /// assert_eq!(expected, jsonb);
2244 ///
2245 /// let jsonb = diesel::select(jsonb_object::<Nullable<Array<Text>>, _>(None::<Vec<String>>))
2246 /// .get_result::<Option<Value>>(connection)?;
2247 /// assert!(jsonb.is_none());
2248 ///
2249 /// let empty:Vec<String> = Vec::new();
2250 /// let jsonb = diesel::select(jsonb_object::<Array<Nullable<Text>>,_>(empty))
2251 /// .get_result::<Value>(connection)?;
2252 /// let expected = serde_json::json!({});
2253 /// assert_eq!(expected, jsonb);
2254 ///
2255 /// let jsonb = diesel::select(jsonb_object::<Array<Text>, _>(vec!["hello","world","John"]))
2256 /// .get_result::<Value>(connection);
2257 /// assert!(jsonb.is_err());
2258 ///
2259 ///
2260 /// # Ok(())
2261 /// # }
2262 /// ```
2263 #[cfg(feature = "postgres_backend")]
2264 fn jsonb_object<Arr: TextArrayOrNullableTextArray + MaybeNullableValue<Jsonb>>(
2265 text_array: Arr,
2266 ) -> Arr::Out;
2267
2268 /// This form of jsonb_object takes keys and values pairwise from two separate arrays.
2269 /// In all other respects it is identical to the one-argument form.
2270 ///
2271 /// # Example
2272 ///
2273 /// ```rust
2274 /// # include!("../../doctest_setup.rs");
2275 /// #
2276 /// # fn main() {
2277 /// # #[cfg(feature = "serde_json")]
2278 /// # run_test().unwrap();
2279 /// # }
2280 /// #
2281 /// # #[cfg(feature = "serde_json")]
2282 /// # fn run_test() -> QueryResult<()> {
2283 /// # use diesel::dsl::jsonb_object_with_keys_and_values;
2284 /// # use diesel::sql_types::{Array, Nullable, Text};
2285 /// # use serde_json::Value;
2286 /// # let connection = &mut establish_connection();
2287 /// let jsonb = diesel::select(jsonb_object_with_keys_and_values::<Array<Text>, Array<Text>, _, _>(
2288 /// vec!["hello","John"],vec!["world","Doe"]))
2289 /// .get_result::<Value>(connection)?;
2290 /// let expected:Value = serde_json::json!({"hello":"world","John":"Doe"});
2291 /// assert_eq!(expected, jsonb);
2292 ///
2293 /// let jsonb = diesel::select(jsonb_object_with_keys_and_values::<Nullable<Array<Text>>, Nullable<Array<Text>>, _, _>(
2294 /// Some(vec!["hello","John"]),None::<Vec<String>>))
2295 /// .get_result::<Option<Value>>(connection)?;
2296 /// assert_eq!(None::<Value>,jsonb);
2297 ///
2298 /// let empty: Vec<String> = Vec::new();
2299 /// let jsonb = diesel::select(jsonb_object_with_keys_and_values::<Array<Text>, Array<Text>, _, _>(
2300 /// vec!["hello","John"],empty))
2301 /// .get_result::<Value>(connection);
2302 /// assert!(jsonb.is_err());
2303 ///
2304 /// # Ok(())
2305 /// # }
2306 /// ```
2307 #[sql_name = "jsonb_object"]
2308 #[cfg(feature = "postgres_backend")]
2309 fn jsonb_object_with_keys_and_values<
2310 Arr1: TextArrayOrNullableTextArray + SingleValue,
2311 Arr2: TextArrayOrNullableTextArray + CombinedNullableValue<Arr1, Jsonb>,
2312 >(
2313 keys: Arr1,
2314 values: Arr2,
2315 ) -> Arr2::Out;
2316
2317 /// This function `row_to_json` takes a Record type as an input and converts it to JSON.
2318 ///
2319 /// # Example
2320 ///
2321 /// ```rust
2322 /// # include!("../../doctest_setup.rs");
2323 /// #
2324 /// # fn main() {
2325 /// # #[cfg(feature = "serde_json")]
2326 /// # run_test().unwrap();
2327 /// # }
2328 /// #
2329 /// # #[cfg(feature = "serde_json")]
2330 /// # fn run_test() -> QueryResult<()> {
2331 /// # use diesel::dsl::row_to_json;
2332 /// # use diesel::dsl::sql;
2333 /// # use diesel::sql_types::{Record, Text, Integer};
2334 /// # use serde_json::Value;
2335 /// # let connection = &mut establish_connection();
2336 ///
2337 /// let json_value = diesel::select(row_to_json(sql::<Record<(Text, Integer)>>(
2338 /// "ROW('John', 30)"
2339 /// )))
2340 /// .get_result::<Value>(connection)?;
2341 /// let expected: Value = serde_json::json!({
2342 /// "f1": "John",
2343 /// "f2": 30
2344 /// });
2345 /// assert_eq!(expected, json_value);
2346 ///
2347 /// let json_value = diesel::select(row_to_json(sql::<Record<()>>("ROW()")))
2348 /// .get_result::<Value>(connection)?;
2349 /// let expected: Value = serde_json::json!({});
2350 /// assert_eq!(expected, json_value);
2351 ///
2352 /// # Ok(())
2353 /// # }
2354 /// ```
2355 #[sql_name = "row_to_json"]
2356 #[cfg(feature = "postgres_backend")]
2357 fn row_to_json<R: RecordOrNullableRecord + MaybeNullableValue<Json>>(record: R) -> R::Out;
2358
2359 /// This function `json_populate_record` takes a Record base and Json as an input and converts it to top-level
2360 /// JSON object to a row having the composite type of the base argument.
2361 ///
2362 /// # Example
2363 ///
2364 /// ```rust
2365 /// # include!("../../doctest_setup.rs");
2366 /// #
2367 /// # fn main() {
2368 /// # #[cfg(feature = "serde_json")]
2369 /// # run_test().unwrap();
2370 /// # }
2371 /// #
2372 /// # #[cfg(feature = "serde_json")]
2373 /// # fn run_test() -> QueryResult<()> {
2374 /// # use diesel::dsl::json_populate_record;
2375 /// # use diesel::dsl::sql;
2376 /// # use diesel::sql_types::{Record, Text, Integer, Json};
2377 /// # use serde_json::Value;
2378 /// # let connection = &mut establish_connection();
2379 ///
2380 /// let expected: Value = serde_json::json!({
2381 /// "f1": "Alice",
2382 /// "f2": 16
2383 /// });
2384 /// let record: (String, i32) = diesel::select(json_populate_record::<Record<(Text, Integer)>, Json, _, _>(
2385 /// sql::<Record<(Text, Integer)>>("ROW('John', 30)"),
2386 /// expected
2387 /// )).get_result(connection)?;
2388 /// assert_eq!(record, ("Alice".to_string(), 16));
2389 ///
2390 /// let expected: Value = serde_json::json!({});
2391 /// let record: (String, i32) = diesel::select(json_populate_record::<Record<(Text, Integer)>, Json, _, _>(
2392 /// sql::<Record<(Text, Integer)>>("ROW('John', 30)"),
2393 /// expected
2394 /// )).get_result(connection)?;
2395 /// assert_eq!(record, ("John".to_string(), 30));
2396 ///
2397 /// let expected: Value = serde_json::json!({
2398 /// "f1": "Alice"
2399 /// });
2400 /// let record: (String, i32) = diesel::select(json_populate_record::<Record<(Text, Integer)>, Json, _, _>(
2401 /// sql::<Record<(Text, Integer)>>("ROW('John', 30)"),
2402 /// expected
2403 /// )).get_result(connection)?;
2404 /// assert_eq!(record, ("Alice".to_string(), 30));
2405 ///
2406 /// # Ok(())
2407 /// # }
2408 /// ```
2409 #[sql_name = "json_populate_record"]
2410 #[cfg(feature = "postgres_backend")]
2411 fn json_populate_record<
2412 B: RecordOrNullableRecord + SingleValue,
2413 J: JsonOrNullableJson + CombinedAllNullableValue<Json, B>,
2414 >(
2415 base: B,
2416 from_json: J,
2417 ) -> J::Out;
2418
2419 /// This function `jsonb_populate_record` takes a Record base and Jsonb as an input and converts it to top-level
2420 /// JSON object to a row having the composite type of the base argument.
2421 ///
2422 /// # Example
2423 ///
2424 /// ```rust
2425 /// # include!("../../doctest_setup.rs");
2426 /// #
2427 /// # fn main() {
2428 /// # #[cfg(feature = "serde_json")]
2429 /// # run_test().unwrap();
2430 /// # }
2431 /// #
2432 /// # #[cfg(feature = "serde_json")]
2433 /// # fn run_test() -> QueryResult<()> {
2434 /// # use diesel::dsl::jsonb_populate_record;
2435 /// # use diesel::dsl::sql;
2436 /// # use diesel::sql_types::{Record, Text, Integer, Jsonb};
2437 /// # use serde_json::Value;
2438 /// # let connection = &mut establish_connection();
2439 ///
2440 /// let expected: Value = serde_json::json!({
2441 /// "f1": "Alice",
2442 /// "f2": 16
2443 /// });
2444 /// let record: (String, i32) = diesel::select(jsonb_populate_record::<Record<(Text, Integer)>, Jsonb, _, _>(
2445 /// sql::<Record<(Text, Integer)>>("ROW('John', 30)"),
2446 /// expected
2447 /// )).get_result(connection)?;
2448 /// assert_eq!(record, ("Alice".to_string(), 16));
2449 ///
2450 /// let expected: Value = serde_json::json!({});
2451 /// let record: (String, i32) = diesel::select(jsonb_populate_record::<Record<(Text, Integer)>, Jsonb, _, _>(
2452 /// sql::<Record<(Text, Integer)>>("ROW('John', 30)"),
2453 /// expected
2454 /// )).get_result(connection)?;
2455 /// assert_eq!(record, ("John".to_string(), 30));
2456 ///
2457 /// let expected: Value = serde_json::json!({
2458 /// "f2": 42,
2459 /// });
2460 /// let record: (String, i32) = diesel::select(jsonb_populate_record::<Record<(Text, Integer)>, Jsonb, _, _>(
2461 /// sql::<Record<(Text, Integer)>>("ROW('John', 30)"),
2462 /// expected
2463 /// )).get_result(connection)?;
2464 /// assert_eq!(record, ("John".to_string(), 42));
2465 ///
2466 /// # Ok(())
2467 /// # }
2468 /// ```
2469 #[sql_name = "jsonb_populate_record"]
2470 #[cfg(feature = "postgres_backend")]
2471 fn jsonb_populate_record<
2472 B: RecordOrNullableRecord + SingleValue,
2473 J: JsonbOrNullableJsonb + CombinedAllNullableValue<Jsonb, B>,
2474 >(
2475 base: B,
2476 from_json: J,
2477 ) -> J::Out;
2478
2479 /// Returns target with the item designated by path replaced by new_value,
2480 /// or with new_value added and the item designated by path does not exist.
2481 ///
2482 /// It can't set path in scalar
2483 ///
2484 /// All earlier steps in the path must exist, or the target is returned unchanged.
2485 /// As with the path oriented operators, negative integers that appear in the path count from the end of JSON arrays.
2486 /// If the last path step is an array index that is out of range,
2487 /// the new value is added at the beginning of the array if the index is negative,
2488 /// or at the end of the array if it is positive.
2489 ///
2490 /// # Example
2491 ///
2492 /// ```rust
2493 /// # include!("../../doctest_setup.rs");
2494 /// #
2495 /// # fn main() {
2496 /// # #[cfg(feature = "serde_json")]
2497 /// # run_test().unwrap();
2498 /// # }
2499 /// #
2500 /// # #[cfg(feature = "serde_json")]
2501 /// # fn run_test() -> QueryResult<()> {
2502 /// # use diesel::dsl::jsonb_set;
2503 /// # use diesel::sql_types::{Jsonb,Array, Json, Nullable, Text};
2504 /// # use serde_json::{json,Value};
2505 /// # let connection = &mut establish_connection();
2506 ///
2507 /// let result = diesel::select(jsonb_set::<Jsonb, Array<Text>, _, _, _>(
2508 /// json!([{"f1":1,"f2":null},2,null,3]),
2509 /// vec!["0","f1"],
2510 /// json!([2,3,4])
2511 /// )).get_result::<Value>(connection)?;
2512 /// let expected: Value = json!([{"f1": [2, 3, 4], "f2": null}, 2, null, 3]);
2513 /// assert_eq!(result, expected);
2514 ///
2515 /// let result = diesel::select(jsonb_set::<Jsonb, Array<Text>, _, _, _>(
2516 /// json!([{"odd":[2,4,6,8]}]),
2517 /// // not vec!["odd"], cannot set path in scalar
2518 /// vec!["0","odd"],
2519 /// json!([1,3,5,7])
2520 /// )).get_result::<Value>(connection)?;
2521 /// let expected: Value = json!([{"odd":[1,3,5,7]}]);
2522 /// assert_eq!(result, expected);
2523 ///
2524 /// let empty:Vec<String> = Vec::new();
2525 /// let result = diesel::select(jsonb_set::<Nullable<Jsonb>, Array<Nullable<Text>>, _, _, _>(
2526 /// None::<Value>,
2527 /// empty,
2528 /// None::<Value>
2529 /// )).get_result::<Option<Value>>(connection)?;
2530 /// assert!(result.is_none());
2531 ///
2532 /// let empty:Vec<String> = Vec::new();
2533 /// let result = diesel::select(jsonb_set::<Jsonb, Array<Nullable<Text>>, _, _, _>(
2534 /// // cannot be json!(null)
2535 /// json!([]),
2536 /// empty,
2537 /// json!(null)
2538 /// )).get_result::<Value>(connection)?;
2539 /// let expected = json!([]);
2540 /// assert_eq!(result, expected);
2541 ///
2542 /// let result = diesel::select(jsonb_set::<Jsonb, Nullable<Array<Nullable<Text>>>, _, _, _,>(
2543 /// json!(null),
2544 /// None::<Vec<String>>,
2545 /// json!({"foo": 42})
2546 /// )).get_result::<Option<Value>>(connection)?;
2547 /// assert!(result.is_none());
2548 ///
2549 ///
2550 /// # Ok(())
2551 /// # }
2552 /// ```
2553 #[cfg(feature = "postgres_backend")]
2554 fn jsonb_set<
2555 E: JsonbOrNullableJsonb + SingleValue,
2556 Arr: TextArrayOrNullableTextArray + CombinedNullableValue<E, Jsonb>,
2557 >(
2558 base: E,
2559 path: Arr,
2560 new_value: E,
2561 ) -> Arr::Out;
2562
2563 /// Returns target with the item designated by path replaced by new_value,
2564 /// or with new_value added if create_if_missing is true (which is the default)
2565 /// and the item designated by path does not exist.
2566 ///
2567 /// It can't set path in scalar
2568 ///
2569 /// All earlier steps in the path must exist, or the target is returned unchanged.
2570 /// As with the path oriented operators, negative integers that appear in the path count from the end of JSON arrays.
2571 /// If the last path step is an array index that is out of range,
2572 /// and create_if_missing is true, the new value is added at the beginning of the array if the index is negative,
2573 /// or at the end of the array if it is positive.
2574 ///
2575 /// # Example
2576 ///
2577 /// ```rust
2578 /// # include!("../../doctest_setup.rs");
2579 /// #
2580 /// # fn main() {
2581 /// # #[cfg(feature = "serde_json")]
2582 /// # run_test().unwrap();
2583 /// # }
2584 /// #
2585 /// # #[cfg(feature = "serde_json")]
2586 /// # fn run_test() -> QueryResult<()> {
2587 /// # use diesel::dsl::jsonb_set_create_if_missing;
2588 /// # use diesel::sql_types::{Jsonb, Array, Json, Nullable, Text};
2589 /// # use serde_json::{json, Value};
2590 /// # let connection = &mut establish_connection();
2591 ///
2592 /// let result = diesel::select(jsonb_set_create_if_missing::<Jsonb, Array<Text>, _, _, _, _>(
2593 /// json!([{"f1":1,"f2":null},2,null,3]),
2594 /// vec!["0","f1"],
2595 /// json!([2,3,4]),
2596 /// true
2597 /// )).get_result::<Value>(connection)?;
2598 /// let expected: Value = json!([{"f1": [2, 3, 4], "f2": null}, 2, null, 3]);
2599 /// assert_eq!(result, expected);
2600 ///
2601 /// let result = diesel::select(jsonb_set_create_if_missing::<Jsonb, Array<Text>, _, _, _, _>(
2602 /// json!([{"f1":1,"f2":null},2,null,3]),
2603 /// vec!["0","f3"],
2604 /// json!([2,3,4]),
2605 /// false
2606 /// )).get_result::<Value>(connection)?;
2607 /// let expected: Value = json!([{"f1":1, "f2": null},2, null, 3]);
2608 /// assert_eq!(result, expected);
2609 ///
2610 /// let result = diesel::select(jsonb_set_create_if_missing::<Jsonb, Array<Text>, _, _, _, _>(
2611 /// json!([{"odd":[2,4,6,8]}]),
2612 /// // not vec!["odd"], cannot set path in scalar
2613 /// vec!["0","odd"],
2614 /// json!([1,3,5,7]),
2615 /// true
2616 /// )).get_result::<Value>(connection)?;
2617 /// let expected: Value = json!([{"odd":[1,3,5,7]}]);
2618 /// assert_eq!(result, expected);
2619 ///
2620 /// let empty:Vec<String> = Vec::new();
2621 /// let result = diesel::select(jsonb_set_create_if_missing::<Nullable<Jsonb>, Array<Nullable<Text>>, _, _, _, _>(
2622 /// None::<Value>,
2623 /// empty,
2624 /// None::<Value>,
2625 /// true
2626 /// )).get_result::<Option<Value>>(connection)?;
2627 /// assert!(result.is_none());
2628 ///
2629 /// let empty:Vec<String> = Vec::new();
2630 /// let result = diesel::select(jsonb_set_create_if_missing::<Jsonb, Array<Nullable<Text>>, _, _, _, _>(
2631 /// // cannot be json!(null)
2632 /// json!([]),
2633 /// empty,
2634 /// json!(null),
2635 /// true
2636 /// )).get_result::<Value>(connection)?;
2637 /// let expected = json!([]);
2638 /// assert_eq!(result, expected);
2639 ///
2640 /// let result = diesel::select(jsonb_set_create_if_missing::<Jsonb, Nullable<Array<Nullable<Text>>>, _, _, _, _>(
2641 /// json!(null),
2642 /// None::<Vec<String>>,
2643 /// json!({"foo": 42}),
2644 /// true
2645 /// )).get_result::<Option<Value>>(connection)?;
2646 /// assert!(result.is_none());
2647 ///
2648 ///
2649 /// # Ok(())
2650 /// # }
2651 /// ```
2652 #[sql_name = "jsonb_set"]
2653 fn jsonb_set_create_if_missing<
2654 E: JsonbOrNullableJsonb + SingleValue,
2655 Arr: TextArrayOrNullableTextArray + CombinedNullableValue<E, Jsonb>,
2656 >(
2657 base: E,
2658 path: Arr,
2659 new_value: E,
2660 create_if_missing: Bool,
2661 ) -> Arr::Out;
2662
2663 /// Returns target with the item designated by path replaced by new_value,
2664 /// or with new_value added and the item designated by path does not exist.
2665 ///
2666 /// It can't set path in scalar
2667 ///
2668 /// All earlier steps in the path must exist, or the target is returned unchanged.
2669 /// As with the path oriented operators, negative integers that appear in the path count from the end of JSON arrays.
2670 /// If the last path step is an array index that is out of range,
2671 /// the new value is added at the beginning of the array if the index is negative,
2672 /// or at the end of the array if it is positive.
2673 ///
2674 /// If new_value is not NULL, behaves identically to jsonb_set.
2675 /// Otherwise behaves according to the value of null_value_treatment
2676 /// which must be one of 'raise_exception', 'use_json_null', 'delete_key', or 'return_target'.
2677 /// The default is 'use_json_null'.
2678 ///
2679 /// # Example
2680 ///
2681 /// ```rust
2682 /// # include!("../../doctest_setup.rs");
2683 /// #
2684 /// # fn main() {
2685 /// # #[cfg(feature = "serde_json")]
2686 /// # run_test().unwrap();
2687 /// # }
2688 /// #
2689 /// # #[cfg(feature = "serde_json")]
2690 /// # fn run_test() -> QueryResult<()> {
2691 /// # use diesel::dsl::jsonb_set_lax;
2692 /// # use diesel::sql_types::{Jsonb,Array,NullValueTreatment, Json, Nullable, Text};
2693 /// # use serde_json::{json,Value};
2694 /// # let connection = &mut establish_connection();
2695 ///
2696 /// let null_value_treatment = NullValueTreatment::UseJsonNull;
2697 /// let result = diesel::select(jsonb_set_lax::<Jsonb, Array<Text>, _, _, _, _, _>(
2698 /// json!([{"f1":1,"f2":null},2,null,3]),
2699 /// vec!["0","f1"],
2700 /// json!([2,3,4]),
2701 /// true,
2702 /// null_value_treatment
2703 /// )).get_result::<Value>(connection)?;
2704 /// let expected: Value = json!([{"f1": [2, 3, 4], "f2": null}, 2, null, 3]);
2705 /// assert_eq!(result, expected);
2706 ///
2707 /// let null_value_treatment = NullValueTreatment::ReturnTarget;
2708 /// let result = diesel::select(jsonb_set_lax::<Nullable<Jsonb>, Array<Nullable<Text>>, _, _, _, _, _>(
2709 /// json!([{"f1":99,"f2":null},2]),
2710 /// vec!["0","f3"],
2711 /// None::<Value>,
2712 /// true,
2713 /// null_value_treatment
2714 /// )).get_result::<Option<Value>>(connection)?;
2715 /// assert_eq!(result, Some(json!([{"f1":99,"f2":null},2])));
2716 ///
2717 /// let null_value_treatment = NullValueTreatment::UseJsonNull;
2718 /// let empty:Vec<String> = Vec::new();
2719 /// let result = diesel::select(jsonb_set_lax::<Jsonb, Array<Nullable<Text>>, _, _, _, _, _>(
2720 /// // cannot be json!(null)
2721 /// json!([]),
2722 /// empty,
2723 /// json!(null),
2724 /// true,
2725 /// null_value_treatment
2726 /// )).get_result::<Value>(connection)?;
2727 /// let expected = json!([]);
2728 /// assert_eq!(result, expected);
2729 ///
2730 /// let null_value_treatment = NullValueTreatment::UseJsonNull;
2731 /// let result = diesel::select(jsonb_set_lax::<Jsonb, Nullable<Array<Nullable<Text>>>, _, _, _, _, _,>(
2732 /// json!(null),
2733 /// None::<Vec<String>>,
2734 /// json!({"foo": 42}),
2735 /// true,
2736 /// null_value_treatment
2737 /// )).get_result::<Option<Value>>(connection)?;
2738 /// assert!(result.is_none());
2739 ///
2740 /// # Ok(())
2741 /// # }
2742 /// ```
2743 fn jsonb_set_lax<
2744 E: JsonbOrNullableJsonb + SingleValue,
2745 Arr: TextArrayOrNullableTextArray + CombinedNullableValue<E, Jsonb>,
2746 >(
2747 base: E,
2748 path: Arr,
2749 new_value: E,
2750 create_if_missing: Bool,
2751 null_value_treatment: NullValueTreatmentEnum,
2752 ) -> Arr::Out;
2753
2754 /// Returns target with `new_value` inserted into `base`.
2755 ///
2756 /// If the item designated by the `path` is an array element, `new_value` will be inserted before that item
2757 ///
2758 /// If the item designated by the `path` is an object field, `new_value` will be
2759 /// inserted only if the object does not already contain that key.
2760 ///
2761 /// * All earlier steps in the path must exist, or the target is returned unchanged.
2762 /// * As with the path oriented operators, negative integers that appear in the `path` count
2763 /// from the end of JSON arrays.
2764 /// * If the last `path` step is an array index that is out of range,
2765 /// the new value is added at the beginning of the array if the index is negative,
2766 /// or at the end of the array if it is positive.
2767 ///
2768 /// # Example
2769 ///
2770 /// ```rust
2771 /// # include!("../../doctest_setup.rs");
2772 /// #
2773 /// # fn main() {
2774 /// # #[cfg(feature = "serde_json")]
2775 /// # run_test().unwrap();
2776 /// # }
2777 /// #
2778 /// # #[cfg(feature = "serde_json")]
2779 /// # fn run_test() -> QueryResult<()> {
2780 /// # use diesel::dsl::jsonb_insert;
2781 /// # use diesel::sql_types::{Jsonb, Array, Json, Nullable, Text};
2782 /// # use serde_json::{json,Value};
2783 /// # let connection = &mut establish_connection();
2784 ///
2785 /// let result = diesel::select(jsonb_insert::<Jsonb, Array<Text>, _, _, _>(
2786 /// json!({"a":[0,1,2]}),
2787 /// vec!["a","1"],
2788 /// json!("new_value"),
2789 /// )).get_result::<Value>(connection)?;
2790 /// let expected: Value = json!({"a":[0,"new_value",1,2]});
2791 /// assert_eq!(result, expected);
2792 ///
2793 /// let result = diesel::select(jsonb_insert::<Nullable<Jsonb>, Array<Text>, _, _, _>(
2794 /// None::<serde_json::Value>,
2795 /// vec!["a","1"],
2796 /// Some(json!("new_value")),
2797 /// )).get_result::<Option<Value>>(connection)?;
2798 /// assert_eq!(result, None);
2799 ///
2800 /// # Ok(())
2801 /// # }
2802 /// ```
2803 fn jsonb_insert<
2804 E: JsonbOrNullableJsonb + SingleValue,
2805 Arr: TextArrayOrNullableTextArray + CombinedNullableValue<E, Jsonb>,
2806 >(
2807 base: E,
2808 path: Arr,
2809 new_value: E,
2810 ) -> Arr::Out;
2811
2812 /// Returns target with `new_value` inserted into `base`.
2813 ///
2814 /// If the item designated by the `path` is an array element, `new_value` will be inserted before that
2815 /// item if `insert_after` is false (which is the default),
2816 /// or after it if `insert_after` is true.
2817 ///
2818 /// If the item designated by the `path` is an object field, `new_value` will be inserted only
2819 /// if the object does not already contain that key.
2820 ///
2821 /// * All earlier steps in the `path` must exist, or the target is returned unchanged.
2822 /// * As with the path oriented operators, negative integers that appear in the `path` count
2823 /// from the end of JSON arrays.
2824 /// * If the last `path` step is an array index that is out of range,
2825 /// the new value is added at the beginning of the array if the index is negative,
2826 /// or at the end of the array if it is positive.
2827 ///
2828 /// # Example
2829 ///
2830 /// ```rust
2831 /// # include!("../../doctest_setup.rs");
2832 /// #
2833 /// # fn main() {
2834 /// # #[cfg(feature = "serde_json")]
2835 /// # run_test().unwrap();
2836 /// # }
2837 /// #
2838 /// # #[cfg(feature = "serde_json")]
2839 /// # fn run_test() -> QueryResult<()> {
2840 /// # use diesel::dsl::jsonb_insert_with_insert_after;
2841 /// # use diesel::sql_types::{Jsonb, Array, Json, Nullable, Text};
2842 /// # use serde_json::{json,Value};
2843 /// # let connection = &mut establish_connection();
2844 ///
2845 /// let result = diesel::select(jsonb_insert_with_insert_after::<Jsonb, Array<Text>, _, _, _, _>(
2846 /// json!({"a":[0,1,2]}),
2847 /// vec!["a","1"],
2848 /// json!("new_value"),
2849 /// false
2850 /// )).get_result::<Value>(connection)?;
2851 /// let expected: Value = json!({"a":[0,"new_value",1,2]});
2852 /// assert_eq!(result, expected);
2853 ///
2854 /// let result = diesel::select(jsonb_insert_with_insert_after::<Jsonb, Array<Text>, _, _, _, _>(
2855 /// json!({"a":[0,1,2]}),
2856 /// vec!["a","1"],
2857 /// json!("new_value"),
2858 /// true
2859 /// )).get_result::<Value>(connection)?;
2860 /// let expected: Value = json!({"a":[0,1,"new_value",2,]});
2861 /// assert_eq!(result, expected);
2862 ///
2863 /// # Ok(())
2864 /// # }
2865 /// ```
2866 #[sql_name = "jsonb_insert"]
2867 fn jsonb_insert_with_insert_after<
2868 E: JsonbOrNullableJsonb + SingleValue,
2869 Arr: TextArrayOrNullableTextArray + CombinedNullableValue<E, Jsonb>,
2870 >(
2871 base: E,
2872 path: Arr,
2873 new_value: E,
2874 insert_after: Bool,
2875 ) -> Arr::Out;
2876
2877 /// Builds a possibly-heterogeneously-typed JSON array out of a variadic argument list. Each argument is converted as per to_json.
2878 ///
2879 ///
2880 /// # Example
2881 ///
2882 /// ```rust
2883 /// # include!("../../doctest_setup.rs");
2884 /// #
2885 /// # fn main() {
2886 /// # #[cfg(feature = "serde_json")]
2887 /// # run_test().unwrap();
2888 /// # }
2889 /// #
2890 /// # #[cfg(feature = "serde_json")]
2891 /// # fn run_test() -> QueryResult<()> {
2892 /// # use diesel::dsl::{json_build_array_1, json_build_array_2, json_build_array_0};
2893 /// # use diesel::sql_types::{Jsonb, Array, Json, Nullable, Text, Integer, Record, Double};
2894 /// # use serde_json::{json,Value};
2895 /// # use diesel::dsl::sql;
2896 /// # let connection = &mut establish_connection();
2897 ///
2898 /// let result = diesel::select(json_build_array_0()).get_result::<serde_json::Value>(connection)?;
2899 /// assert_eq!(json!([]), result);
2900 ///
2901 /// let result = diesel::select(json_build_array_1::<Text, _>("abc"))
2902 /// .get_result::<serde_json::Value>(connection)?;
2903 /// assert_eq!(json!(["abc"]), result);
2904 ///
2905 /// let result = diesel::select(json_build_array_2::<Text, Double, _, _>("abc", 3.1415))
2906 /// .get_result::<serde_json::Value>(connection)?;
2907 /// assert_eq!(json!(["abc", 3.1415]), result);
2908 ///
2909 /// let result = diesel::select(json_build_array_1::<Record<(Text, Double)>, _>(sql::<Record<(Text, Double)>>("ROW('abc',3.1415)")))
2910 /// .get_result::<serde_json::Value>(connection)?;
2911 /// assert_eq!(json!([
2912 /// {
2913 /// "f1":"abc",
2914 /// "f2":3.1415
2915 /// }
2916 /// ]), result);
2917 ///
2918 /// let result = diesel::select(json_build_array_1::<Array<Integer>, _>(vec![1, 2, 3]))
2919 /// .get_result::<serde_json::Value>(connection)?;
2920 /// assert_eq!(json!([ [1, 2, 3] ]), result);
2921 ///
2922 /// let result = diesel::select(json_build_array_2::<Nullable<Text>, Double, _, _>(None::<String>, 3.1415))
2923 /// .get_result::<serde_json::Value>(connection)?;
2924 /// assert_eq!(json!([None::<String>, 3.1415]), result);
2925 ///
2926 /// let result = diesel::select(json_build_array_1::<Record<(Nullable<Text>, Double)>, _>(sql::<Record<(Nullable<Text>, Double)>>("ROW(null,3.1415)")))
2927 /// .get_result::<serde_json::Value>(connection)?;
2928 ///
2929 /// assert_eq!(json!([
2930 /// {
2931 /// "f1":None::<String>,
2932 /// "f2":3.1415
2933 /// }
2934 /// ]), result);
2935 ///
2936 /// # Ok(())
2937 /// # }
2938 /// ```
2939 #[cfg(feature = "postgres_backend")]
2940 #[sql_name = "json_build_array"]
2941 #[variadic(1)]
2942 fn json_build_array<V: SingleValue>(value: V) -> Json;
2943
2944 /// Builds a possibly-heterogeneously-typed JSON array out of a variadic argument list. Each argument is converted as per to_jsonb.
2945 ///
2946 ///
2947 /// # Example
2948 ///
2949 /// ```rust
2950 /// # include!("../../doctest_setup.rs");
2951 /// #
2952 /// # fn main() {
2953 /// # #[cfg(feature = "serde_json")]
2954 /// # run_test().unwrap();
2955 /// # }
2956 /// #
2957 /// # #[cfg(feature = "serde_json")]
2958 /// # fn run_test() -> QueryResult<()> {
2959 /// # use diesel::dsl::{jsonb_build_array_1, jsonb_build_array_2, jsonb_build_array_0};
2960 /// # use diesel::sql_types::{Jsonb, Array, Json, Nullable, Text, Integer, Record, Double};
2961 /// # use serde_json::{json,Value};
2962 /// # use diesel::dsl::sql;
2963 /// # let connection = &mut establish_connection();
2964 ///
2965 /// let result = diesel::select(jsonb_build_array_0()).get_result::<serde_json::Value>(connection)?;
2966 /// assert_eq!(json!([]), result);
2967 ///
2968 /// let result = diesel::select(jsonb_build_array_1::<Text, _>("abc"))
2969 /// .get_result::<serde_json::Value>(connection)?;
2970 /// assert_eq!(json!(["abc"]), result);
2971 ///
2972 /// let result = diesel::select(jsonb_build_array_2::<Text, Double, _, _>("abc", 3.1415))
2973 /// .get_result::<serde_json::Value>(connection)?;
2974 /// assert_eq!(json!(["abc", 3.1415]), result);
2975 ///
2976 /// let result = diesel::select(jsonb_build_array_1::<Record<(Text, Double)>, _>(sql::<Record<(Text, Double)>>("ROW('abc',3.1415)")))
2977 /// .get_result::<serde_json::Value>(connection)?;
2978 /// assert_eq!(json!([
2979 /// {
2980 /// "f1":"abc",
2981 /// "f2":3.1415
2982 /// }
2983 /// ]), result);
2984 ///
2985 /// let result = diesel::select(jsonb_build_array_1::<Array<Integer>, _>(vec![1, 2, 3]))
2986 /// .get_result::<serde_json::Value>(connection)?;
2987 /// assert_eq!(json!([ [1, 2, 3] ]), result);
2988 ///
2989 /// let result = diesel::select(jsonb_build_array_2::<Nullable<Text>, Double, _, _>(None::<String>, 3.1415))
2990 /// .get_result::<serde_json::Value>(connection)?;
2991 /// assert_eq!(json!([None::<String>, 3.1415]), result);
2992 ///
2993 /// let result = diesel::select(jsonb_build_array_1::<Record<(Nullable<Text>, Double)>, _>(sql::<Record<(Nullable<Text>, Double)>>("ROW(null,3.1415)")))
2994 /// .get_result::<serde_json::Value>(connection)?;
2995 ///
2996 /// assert_eq!(json!([
2997 /// {
2998 /// "f1":None::<String>,
2999 /// "f2":3.1415
3000 /// }
3001 /// ]), result);
3002 ///
3003 /// # Ok(())
3004 /// # }
3005 /// ```
3006 #[cfg(feature = "postgres_backend")]
3007 #[sql_name = "jsonb_build_array"]
3008 #[variadic(1)]
3009 fn jsonb_build_array<V: SingleValue>(value: V) -> Jsonb;
3010 /// Extracts JSON sub-object at the specified path. (This is functionally equivalent to the #> operator, but writing the path out as a variadic list can be more convenient in some cases.)
3011 ///
3012 /// # Example
3013 ///
3014 /// ```rust
3015 /// # include!("../../doctest_setup.rs");
3016 /// #
3017 /// # fn main() {
3018 /// # #[cfg(feature = "serde_json")]
3019 /// # run_test().unwrap();
3020 /// # }
3021 /// #
3022 /// # #[cfg(feature = "serde_json")]
3023 /// # fn run_test() -> QueryResult<()> {
3024 /// # use diesel::dsl::{json_extract_path_1, json_extract_path_2};
3025 /// # use diesel::sql_types::{Json, Nullable, Text};
3026 /// # use serde_json::{json,Value};
3027 /// # use diesel::dsl::sql;
3028 /// # let connection = &mut establish_connection();
3029 ///
3030 /// let expected = Some(json!({"f5":99, "f6":"foo"}));
3031 /// let result = diesel::select(json_extract_path_1::<Json, Text, _, _>(
3032 /// json!({"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}),
3033 /// "f4",
3034 /// ))
3035 /// .get_result::<Option<serde_json::Value>>(connection)?;
3036 ///
3037 /// assert_eq!(expected, result);
3038 ///
3039 /// let expected = Some(json!("foo"));
3040 /// let result = diesel::select(json_extract_path_2::<Json, Text, Text, _, _, _>(
3041 /// json!({"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}),
3042 /// "f4",
3043 /// "f6"
3044 /// ))
3045 /// .get_result::<Option<serde_json::Value>>(connection)?;
3046 ///
3047 /// assert_eq!(expected, result);
3048 ///
3049 /// let result = diesel::select(json_extract_path_1::<Nullable<Json>, Text, _, _>(None::<serde_json::Value>, "f4"))
3050 /// .get_result::<Option<serde_json::Value>>(connection)?;
3051 ///
3052 /// assert_eq!(None::<serde_json::Value>, result);
3053 ///
3054 /// let result = diesel::select(json_extract_path_2::<Json, Nullable<Text>, Text, _, _, _>(json!({"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}), None::<String>, "f6"))
3055 /// .get_result::<Option<serde_json::Value>>(connection)?;
3056 ///
3057 ///
3058 /// assert_eq!(None::<serde_json::Value>, result);
3059 ///
3060 /// # Ok(())
3061 /// # }
3062 /// ```
3063 #[cfg(feature = "postgres_backend")]
3064 #[sql_name = "json_extract_path"]
3065 #[variadic(last_arguments = 1, skip_zero_argument_variant = true)]
3066 fn json_extract_path<J: JsonOrNullableJson + SingleValue, T: SingleValue>(
3067 json: J,
3068 text: T,
3069 ) -> Nullable<Json>;
3070
3071 /// Extracts JSON sub-object at the specified path. (This is functionally equivalent to the #> operator, but writing the path out as a variadic list can be more convenient in some cases.)
3072 ///
3073 /// # Example
3074 ///
3075 /// ```rust
3076 /// # include!("../../doctest_setup.rs");
3077 /// #
3078 /// # fn main() {
3079 /// # #[cfg(feature = "serde_json")]
3080 /// # run_test().unwrap();
3081 /// # }
3082 /// #
3083 /// # #[cfg(feature = "serde_json")]
3084 /// # fn run_test() -> QueryResult<()> {
3085 /// # use diesel::dsl::{jsonb_extract_path_1, jsonb_extract_path_2};
3086 /// # use diesel::sql_types::{Jsonb, Nullable, Text};
3087 /// # use serde_json::{json,Value};
3088 /// # use diesel::dsl::sql;
3089 /// # let connection = &mut establish_connection();
3090 ///
3091 /// let expected = Some(json!({"f5":99, "f6":"foo"}));
3092 /// let result = diesel::select(jsonb_extract_path_1::<Jsonb, Text, _, _>(
3093 /// json!({"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}),
3094 /// "f4",
3095 /// ))
3096 /// .get_result::<Option<serde_json::Value>>(connection)?;
3097 ///
3098 /// assert_eq!(expected, result);
3099 ///
3100 /// let expected = Some(json!("foo"));
3101 /// let result = diesel::select(jsonb_extract_path_2::<Jsonb, Text, Text, _, _, _>(
3102 /// json!({"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}),
3103 /// "f4",
3104 /// "f6"
3105 /// ))
3106 /// .get_result::<Option<serde_json::Value>>(connection)?;
3107 ///
3108 /// assert_eq!(expected, result);
3109 ///
3110 /// let result = diesel::select(jsonb_extract_path_1::<Nullable<Jsonb>, Text, _, _>(None::<serde_json::Value>, "f4"))
3111 /// .get_result::<Option<serde_json::Value>>(connection)?;
3112 ///
3113 /// assert_eq!(None::<serde_json::Value>, result);
3114 ///
3115 /// let result = diesel::select(jsonb_extract_path_2::<Jsonb, Nullable<Text>, Text, _, _, _>(json!({"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}), None::<String>, "f6"))
3116 /// .get_result::<Option<serde_json::Value>>(connection)?;
3117 ///
3118 ///
3119 /// assert_eq!(None::<serde_json::Value>, result);
3120 ///
3121 /// # Ok(())
3122 /// # }
3123 /// ```
3124 #[cfg(feature = "postgres_backend")]
3125 #[sql_name = "jsonb_extract_path"]
3126 #[variadic(last_arguments = 1, skip_zero_argument_variant = true)]
3127 fn jsonb_extract_path<J: JsonbOrNullableJsonb + SingleValue, T: SingleValue>(
3128 json: J,
3129 text: T,
3130 ) -> Nullable<Jsonb>;
3131
3132 /// Extracts JSON sub-object at the specified path as text. (This is functionally equivalent to the #>> operator.)
3133 ///
3134 /// # Example
3135 ///
3136 /// ```rust
3137 /// # include!("../../doctest_setup.rs");
3138 /// #
3139 /// # fn main() {
3140 /// # #[cfg(feature = "serde_json")]
3141 /// # run_test().unwrap();
3142 /// # }
3143 /// #
3144 /// # #[cfg(feature = "serde_json")]
3145 /// # fn run_test() -> QueryResult<()> {
3146 /// # use diesel::dsl::{json_extract_path_text_1, json_extract_path_text_2};
3147 /// # use diesel::sql_types::{Json, Nullable, Text};
3148 /// # use serde_json::{json,Value};
3149 /// # use diesel::dsl::sql;
3150 /// # let connection = &mut establish_connection();
3151 ///
3152 /// let expected = Some(String::from("{\"f5\":99,\"f6\":\"foo\"}"));
3153 /// let result = diesel::select(json_extract_path_text_1::<Json, Text, _, _>(
3154 /// json!({"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}),
3155 /// "f4",
3156 /// ))
3157 /// .get_result::<Option<String>>(connection)?;
3158 ///
3159 /// assert_eq!(expected, result);
3160 ///
3161 /// let expected = Some(String::from("foo"));
3162 /// let result = diesel::select(json_extract_path_text_2::<Json, Text, Text, _, _, _>(
3163 /// json!({"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}),
3164 /// "f4",
3165 /// "f6"
3166 /// ))
3167 /// .get_result::<Option<String>>(connection)?;
3168 ///
3169 /// assert_eq!(expected, result);
3170 ///
3171 /// let result = diesel::select(json_extract_path_text_1::<Nullable<Json>, Text, _, _>(None::<serde_json::Value>, "f4"))
3172 /// .get_result::<Option<String>>(connection)?;
3173 ///
3174 /// assert_eq!(None::<String>, result);
3175 ///
3176 /// let result = diesel::select(json_extract_path_text_2::<Json, Nullable<Text>, Text, _, _, _>(json!({"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}), None::<String>, "f6"))
3177 /// .get_result::<Option<String>>(connection)?;
3178 ///
3179 /// assert_eq!(None::<String>, result);
3180 ///
3181 /// # Ok(())
3182 /// # }
3183 /// ```
3184 #[cfg(feature = "postgres_backend")]
3185 #[sql_name = "json_extract_path_text"]
3186 #[variadic(last_arguments = 1, skip_zero_argument_variant = true)]
3187 fn json_extract_path_text<
3188 J: JsonOrNullableJson + SingleValue,
3189 T: SingleValue + TextOrNullableText,
3190 >(
3191 json: J,
3192 text: T,
3193 ) -> Nullable<Text>;
3194
3195 /// Extracts JSON sub-object at the specified path as text. (This is functionally equivalent to the #>> operator.)
3196 ///
3197 /// # Example
3198 ///
3199 /// ```rust
3200 /// # include!("../../doctest_setup.rs");
3201 /// #
3202 /// # fn main() {
3203 /// # #[cfg(feature = "serde_json")]
3204 /// # run_test().unwrap();
3205 /// # }
3206 /// #
3207 /// # #[cfg(feature = "serde_json")]
3208 /// # fn run_test() -> QueryResult<()> {
3209 /// # use diesel::dsl::{jsonb_extract_path_text_1, jsonb_extract_path_text_2};
3210 /// # use diesel::sql_types::{Jsonb, Nullable, Text};
3211 /// # use serde_json::{json,Value};
3212 /// # use diesel::dsl::sql;
3213 /// # let connection = &mut establish_connection();
3214 ///
3215 /// let expected = Some(String::from("{\"f5\": 99, \"f6\": \"foo\"}"));
3216 /// let result = diesel::select(jsonb_extract_path_text_1::<Jsonb, Text, _, _>(
3217 /// json!({"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}),
3218 /// "f4",
3219 /// ))
3220 /// .get_result::<Option<String>>(connection)?;
3221 ///
3222 /// assert_eq!(expected, result);
3223 ///
3224 /// let expected = Some(String::from("foo"));
3225 /// let result = diesel::select(jsonb_extract_path_text_2::<Jsonb, Text, Text, _, _, _>(
3226 /// json!({"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}),
3227 /// "f4",
3228 /// "f6"
3229 /// ))
3230 /// .get_result::<Option<String>>(connection)?;
3231 ///
3232 /// assert_eq!(expected, result);
3233 ///
3234 /// let result = diesel::select(jsonb_extract_path_text_1::<Nullable<Jsonb>, Text, _, _>(None::<serde_json::Value>, "f4"))
3235 /// .get_result::<Option<String>>(connection)?;
3236 ///
3237 /// assert_eq!(None::<String>, result);
3238 ///
3239 /// let result = diesel::select(jsonb_extract_path_text_2::<Jsonb, Nullable<Text>, Text, _, _, _>(json!({"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}), None::<String>, "f6"))
3240 /// .get_result::<Option<String>>(connection)?;
3241 ///
3242 /// assert_eq!(None::<String>, result);
3243 ///
3244 /// # Ok(())
3245 /// # }
3246 /// ```
3247 #[cfg(feature = "postgres_backend")]
3248 #[sql_name = "jsonb_extract_path_text"]
3249 #[variadic(last_arguments = 1, skip_zero_argument_variant = true)]
3250 fn jsonb_extract_path_text<
3251 J: JsonbOrNullableJsonb + SingleValue,
3252 T: SingleValue + TextOrNullableText,
3253 >(
3254 json: J,
3255 text: T,
3256 ) -> Nullable<Text>;
3257}
3258
3259pub(super) mod return_type_helpers_reexported {
3260 #[allow(unused_imports)]
3261 #[doc(inline)]
3262 pub use super::return_type_helpers::*;
3263}