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