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