1use crate::dialect::DialectTypes;
25use crate::sql::{SQL, Token};
26use crate::traits::SQLParam;
27use crate::types::{Compatible, DataType, Textual};
28
29use super::{AggOr, AggregateKind, Expr, NonNull, SQLExpr};
30
31fn binary_op<'a, V, L, R>(left: L, operator: Token, right: R) -> SQL<'a, V>
36where
37 V: SQLParam + 'a,
38 L: Expr<'a, V>,
39 R: ComparisonOperand<'a, V, L>,
40 L::SQLType: Compatible<<R as ComparisonOperand<'a, V, L>>::SQLType>,
41{
42 let left_sql = operand_sql(left);
43 let right_sql = ComparisonOperand::into_comparison_sql(right);
44
45 left_sql.push(operator).append(right_sql)
46}
47
48#[inline]
49fn operand_sql<'a, V, T>(value: T) -> SQL<'a, V>
50where
51 V: SQLParam + 'a,
52 T: Expr<'a, V>,
53{
54 value.into_expr_sql()
55}
56
57pub trait ComparisonOperand<'a, V, L>: Sized
69where
70 V: SQLParam + 'a,
71 L: Expr<'a, V>,
72{
73 type SQLType: DataType;
74 type Aggregate: AggregateKind;
75
76 fn into_comparison_sql(self) -> SQL<'a, V>;
77}
78
79impl<'a, V, L, R> ComparisonOperand<'a, V, L> for R
80where
81 V: SQLParam + 'a,
82 L: Expr<'a, V>,
83 R: Expr<'a, V>,
84 L::SQLType: Compatible<R::SQLType>,
85{
86 type SQLType = R::SQLType;
87 type Aggregate = R::Aggregate;
88
89 fn into_comparison_sql(self) -> SQL<'a, V> {
90 self.into_expr_sql()
91 }
92}
93
94#[allow(clippy::type_complexity)]
117pub fn eq<'a, V, L, R>(
118 left: L,
119 right: R,
120) -> SQLExpr<
121 'a,
122 V,
123 <V::DialectMarker as DialectTypes>::Bool,
124 NonNull,
125 <L::Aggregate as AggOr<<R as ComparisonOperand<'a, V, L>>::Aggregate>>::Output,
126>
127where
128 V: SQLParam + 'a,
129 L: Expr<'a, V>,
130 R: ComparisonOperand<'a, V, L>,
131 L::SQLType: Compatible<<R as ComparisonOperand<'a, V, L>>::SQLType>,
132 L::Aggregate: AggOr<<R as ComparisonOperand<'a, V, L>>::Aggregate>,
133{
134 SQLExpr::new(binary_op(left, Token::EQ, right))
135}
136
137#[allow(clippy::type_complexity)]
141pub fn ne<'a, V, L, R>(
142 left: L,
143 right: R,
144) -> SQLExpr<
145 'a,
146 V,
147 <V::DialectMarker as DialectTypes>::Bool,
148 NonNull,
149 <L::Aggregate as AggOr<<R as ComparisonOperand<'a, V, L>>::Aggregate>>::Output,
150>
151where
152 V: SQLParam + 'a,
153 L: Expr<'a, V>,
154 R: ComparisonOperand<'a, V, L>,
155 L::SQLType: Compatible<<R as ComparisonOperand<'a, V, L>>::SQLType>,
156 L::Aggregate: AggOr<<R as ComparisonOperand<'a, V, L>>::Aggregate>,
157{
158 SQLExpr::new(binary_op(left, Token::NE, right))
159}
160
161#[allow(clippy::type_complexity)]
165pub fn neq<'a, V, L, R>(
166 left: L,
167 right: R,
168) -> SQLExpr<
169 'a,
170 V,
171 <V::DialectMarker as DialectTypes>::Bool,
172 NonNull,
173 <L::Aggregate as AggOr<<R as ComparisonOperand<'a, V, L>>::Aggregate>>::Output,
174>
175where
176 V: SQLParam + 'a,
177 L: Expr<'a, V>,
178 R: ComparisonOperand<'a, V, L>,
179 L::SQLType: Compatible<<R as ComparisonOperand<'a, V, L>>::SQLType>,
180 L::Aggregate: AggOr<<R as ComparisonOperand<'a, V, L>>::Aggregate>,
181{
182 ne(left, right)
183}
184
185#[allow(clippy::type_complexity)]
193pub fn gt<'a, V, L, R>(
194 left: L,
195 right: R,
196) -> SQLExpr<
197 'a,
198 V,
199 <V::DialectMarker as DialectTypes>::Bool,
200 NonNull,
201 <L::Aggregate as AggOr<<R as ComparisonOperand<'a, V, L>>::Aggregate>>::Output,
202>
203where
204 V: SQLParam + 'a,
205 L: Expr<'a, V>,
206 R: ComparisonOperand<'a, V, L>,
207 L::SQLType: Compatible<<R as ComparisonOperand<'a, V, L>>::SQLType>,
208 L::Aggregate: AggOr<<R as ComparisonOperand<'a, V, L>>::Aggregate>,
209{
210 SQLExpr::new(binary_op(left, Token::GT, right))
211}
212
213#[allow(clippy::type_complexity)]
217pub fn gte<'a, V, L, R>(
218 left: L,
219 right: R,
220) -> SQLExpr<
221 'a,
222 V,
223 <V::DialectMarker as DialectTypes>::Bool,
224 NonNull,
225 <L::Aggregate as AggOr<<R as ComparisonOperand<'a, V, L>>::Aggregate>>::Output,
226>
227where
228 V: SQLParam + 'a,
229 L: Expr<'a, V>,
230 R: ComparisonOperand<'a, V, L>,
231 L::SQLType: Compatible<<R as ComparisonOperand<'a, V, L>>::SQLType>,
232 L::Aggregate: AggOr<<R as ComparisonOperand<'a, V, L>>::Aggregate>,
233{
234 SQLExpr::new(binary_op(left, Token::GE, right))
235}
236
237#[allow(clippy::type_complexity)]
241pub fn lt<'a, V, L, R>(
242 left: L,
243 right: R,
244) -> SQLExpr<
245 'a,
246 V,
247 <V::DialectMarker as DialectTypes>::Bool,
248 NonNull,
249 <L::Aggregate as AggOr<<R as ComparisonOperand<'a, V, L>>::Aggregate>>::Output,
250>
251where
252 V: SQLParam + 'a,
253 L: Expr<'a, V>,
254 R: ComparisonOperand<'a, V, L>,
255 L::SQLType: Compatible<<R as ComparisonOperand<'a, V, L>>::SQLType>,
256 L::Aggregate: AggOr<<R as ComparisonOperand<'a, V, L>>::Aggregate>,
257{
258 SQLExpr::new(binary_op(left, Token::LT, right))
259}
260
261#[allow(clippy::type_complexity)]
265pub fn lte<'a, V, L, R>(
266 left: L,
267 right: R,
268) -> SQLExpr<
269 'a,
270 V,
271 <V::DialectMarker as DialectTypes>::Bool,
272 NonNull,
273 <L::Aggregate as AggOr<<R as ComparisonOperand<'a, V, L>>::Aggregate>>::Output,
274>
275where
276 V: SQLParam + 'a,
277 L: Expr<'a, V>,
278 R: ComparisonOperand<'a, V, L>,
279 L::SQLType: Compatible<<R as ComparisonOperand<'a, V, L>>::SQLType>,
280 L::Aggregate: AggOr<<R as ComparisonOperand<'a, V, L>>::Aggregate>,
281{
282 SQLExpr::new(binary_op(left, Token::LE, right))
283}
284
285#[allow(clippy::type_complexity)]
305pub fn like<'a, V, L, R>(
306 left: L,
307 pattern: R,
308) -> SQLExpr<
309 'a,
310 V,
311 <V::DialectMarker as DialectTypes>::Bool,
312 NonNull,
313 <L::Aggregate as AggOr<<R as ComparisonOperand<'a, V, L>>::Aggregate>>::Output,
314>
315where
316 V: SQLParam + 'a,
317 L: Expr<'a, V>,
318 R: ComparisonOperand<'a, V, L>,
319 L::SQLType: Compatible<<R as ComparisonOperand<'a, V, L>>::SQLType>,
320 L::SQLType: Textual,
321 <R as ComparisonOperand<'a, V, L>>::SQLType: Textual,
322 L::Aggregate: AggOr<<R as ComparisonOperand<'a, V, L>>::Aggregate>,
323{
324 SQLExpr::new(
325 operand_sql(left)
326 .push(Token::LIKE)
327 .append(ComparisonOperand::into_comparison_sql(pattern)),
328 )
329}
330
331#[allow(clippy::type_complexity)]
335pub fn not_like<'a, V, L, R>(
336 left: L,
337 pattern: R,
338) -> SQLExpr<
339 'a,
340 V,
341 <V::DialectMarker as DialectTypes>::Bool,
342 NonNull,
343 <L::Aggregate as AggOr<<R as ComparisonOperand<'a, V, L>>::Aggregate>>::Output,
344>
345where
346 V: SQLParam + 'a,
347 L: Expr<'a, V>,
348 R: ComparisonOperand<'a, V, L>,
349 L::SQLType: Compatible<<R as ComparisonOperand<'a, V, L>>::SQLType>,
350 L::SQLType: Textual,
351 <R as ComparisonOperand<'a, V, L>>::SQLType: Textual,
352 L::Aggregate: AggOr<<R as ComparisonOperand<'a, V, L>>::Aggregate>,
353{
354 SQLExpr::new(
355 operand_sql(left)
356 .push(Token::NOT)
357 .push(Token::LIKE)
358 .append(ComparisonOperand::into_comparison_sql(pattern)),
359 )
360}
361
362#[allow(clippy::type_complexity)]
371pub fn between<'a, V, E, L, H>(
372 expr: E,
373 low: L,
374 high: H,
375) -> SQLExpr<
376 'a,
377 V,
378 <V::DialectMarker as DialectTypes>::Bool,
379 NonNull,
380 <<E::Aggregate as AggOr<<L as ComparisonOperand<'a, V, E>>::Aggregate>>::Output as AggOr<
381 <H as ComparisonOperand<'a, V, E>>::Aggregate,
382 >>::Output,
383>
384where
385 V: SQLParam + 'a,
386 E: Expr<'a, V>,
387 L: ComparisonOperand<'a, V, E>,
388 H: ComparisonOperand<'a, V, E>,
389 E::SQLType: Compatible<<L as ComparisonOperand<'a, V, E>>::SQLType>,
390 E::SQLType: Compatible<<H as ComparisonOperand<'a, V, E>>::SQLType>,
391 E::Aggregate: AggOr<<L as ComparisonOperand<'a, V, E>>::Aggregate>,
392 <E::Aggregate as AggOr<<L as ComparisonOperand<'a, V, E>>::Aggregate>>::Output:
393 AggOr<<H as ComparisonOperand<'a, V, E>>::Aggregate>,
394{
395 SQLExpr::new(
396 SQL::from(Token::LPAREN)
397 .append(operand_sql(expr))
398 .push(Token::BETWEEN)
399 .append(ComparisonOperand::into_comparison_sql(low))
400 .push(Token::AND)
401 .append(ComparisonOperand::into_comparison_sql(high))
402 .push(Token::RPAREN),
403 )
404}
405
406#[allow(clippy::type_complexity)]
410pub fn not_between<'a, V, E, L, H>(
411 expr: E,
412 low: L,
413 high: H,
414) -> SQLExpr<
415 'a,
416 V,
417 <V::DialectMarker as DialectTypes>::Bool,
418 NonNull,
419 <<E::Aggregate as AggOr<<L as ComparisonOperand<'a, V, E>>::Aggregate>>::Output as AggOr<
420 <H as ComparisonOperand<'a, V, E>>::Aggregate,
421 >>::Output,
422>
423where
424 V: SQLParam + 'a,
425 E: Expr<'a, V>,
426 L: ComparisonOperand<'a, V, E>,
427 H: ComparisonOperand<'a, V, E>,
428 E::SQLType: Compatible<<L as ComparisonOperand<'a, V, E>>::SQLType>,
429 E::SQLType: Compatible<<H as ComparisonOperand<'a, V, E>>::SQLType>,
430 E::Aggregate: AggOr<<L as ComparisonOperand<'a, V, E>>::Aggregate>,
431 <E::Aggregate as AggOr<<L as ComparisonOperand<'a, V, E>>::Aggregate>>::Output:
432 AggOr<<H as ComparisonOperand<'a, V, E>>::Aggregate>,
433{
434 SQLExpr::new(
435 SQL::from(Token::LPAREN)
436 .append(operand_sql(expr))
437 .push(Token::NOT)
438 .push(Token::BETWEEN)
439 .append(ComparisonOperand::into_comparison_sql(low))
440 .push(Token::AND)
441 .append(ComparisonOperand::into_comparison_sql(high))
442 .push(Token::RPAREN),
443 )
444}
445
446pub fn is_null<'a, V, E>(
455 expr: E,
456) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, E::Aggregate>
457where
458 V: SQLParam + 'a,
459 E: Expr<'a, V>,
460{
461 SQLExpr::new(operand_sql(expr).push(Token::IS).push(Token::NULL))
462}
463
464pub fn is_not_null<'a, V, E>(
469 expr: E,
470) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, E::Aggregate>
471where
472 V: SQLParam + 'a,
473 E: Expr<'a, V>,
474{
475 SQLExpr::new(
476 operand_sql(expr)
477 .push(Token::IS)
478 .push(Token::NOT)
479 .push(Token::NULL),
480 )
481}
482
483#[allow(clippy::type_complexity)]
496pub fn is_distinct_from<'a, V, L, R>(
497 left: L,
498 right: R,
499) -> SQLExpr<
500 'a,
501 V,
502 <V::DialectMarker as DialectTypes>::Bool,
503 NonNull,
504 <L::Aggregate as AggOr<<R as ComparisonOperand<'a, V, L>>::Aggregate>>::Output,
505>
506where
507 V: SQLParam + 'a,
508 L: Expr<'a, V>,
509 R: ComparisonOperand<'a, V, L>,
510 L::SQLType: Compatible<<R as ComparisonOperand<'a, V, L>>::SQLType>,
511 L::Aggregate: AggOr<<R as ComparisonOperand<'a, V, L>>::Aggregate>,
512{
513 SQLExpr::new(
514 operand_sql(left)
515 .push(Token::IS)
516 .push(Token::DISTINCT)
517 .push(Token::FROM)
518 .append(ComparisonOperand::into_comparison_sql(right)),
519 )
520}
521
522#[allow(clippy::type_complexity)]
530pub fn is_not_distinct_from<'a, V, L, R>(
531 left: L,
532 right: R,
533) -> SQLExpr<
534 'a,
535 V,
536 <V::DialectMarker as DialectTypes>::Bool,
537 NonNull,
538 <L::Aggregate as AggOr<<R as ComparisonOperand<'a, V, L>>::Aggregate>>::Output,
539>
540where
541 V: SQLParam + 'a,
542 L: Expr<'a, V>,
543 R: ComparisonOperand<'a, V, L>,
544 L::SQLType: Compatible<<R as ComparisonOperand<'a, V, L>>::SQLType>,
545 L::Aggregate: AggOr<<R as ComparisonOperand<'a, V, L>>::Aggregate>,
546{
547 SQLExpr::new(
548 operand_sql(left)
549 .push(Token::IS)
550 .push(Token::NOT)
551 .push(Token::DISTINCT)
552 .push(Token::FROM)
553 .append(ComparisonOperand::into_comparison_sql(right)),
554 )
555}
556
557pub fn is_true<'a, V, E>(
568 expr: E,
569) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, E::Aggregate>
570where
571 V: SQLParam + 'a,
572 E: Expr<'a, V>,
573{
574 SQLExpr::new(operand_sql(expr).push(Token::IS).append(SQL::raw("TRUE")))
575}
576
577pub fn is_false<'a, V, E>(
584 expr: E,
585) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, E::Aggregate>
586where
587 V: SQLParam + 'a,
588 E: Expr<'a, V>,
589{
590 SQLExpr::new(operand_sql(expr).push(Token::IS).append(SQL::raw("FALSE")))
591}
592
593pub trait ExprExt<'a, V: SQLParam>: Expr<'a, V> + Sized {
613 #[allow(clippy::type_complexity)]
621 fn eq<R>(
622 self,
623 other: R,
624 ) -> SQLExpr<
625 'a,
626 V,
627 <V::DialectMarker as DialectTypes>::Bool,
628 NonNull,
629 <Self::Aggregate as AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>>::Output,
630 >
631 where
632 R: ComparisonOperand<'a, V, Self>,
633 Self::SQLType: Compatible<<R as ComparisonOperand<'a, V, Self>>::SQLType>,
634 Self::Aggregate: AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>,
635 {
636 eq(self, other)
637 }
638
639 #[allow(clippy::type_complexity)]
647 fn ne<R>(
648 self,
649 other: R,
650 ) -> SQLExpr<
651 'a,
652 V,
653 <V::DialectMarker as DialectTypes>::Bool,
654 NonNull,
655 <Self::Aggregate as AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>>::Output,
656 >
657 where
658 R: ComparisonOperand<'a, V, Self>,
659 Self::SQLType: Compatible<<R as ComparisonOperand<'a, V, Self>>::SQLType>,
660 Self::Aggregate: AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>,
661 {
662 ne(self, other)
663 }
664
665 #[allow(clippy::type_complexity)]
673 fn gt<R>(
674 self,
675 other: R,
676 ) -> SQLExpr<
677 'a,
678 V,
679 <V::DialectMarker as DialectTypes>::Bool,
680 NonNull,
681 <Self::Aggregate as AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>>::Output,
682 >
683 where
684 R: ComparisonOperand<'a, V, Self>,
685 Self::SQLType: Compatible<<R as ComparisonOperand<'a, V, Self>>::SQLType>,
686 Self::Aggregate: AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>,
687 {
688 gt(self, other)
689 }
690
691 #[allow(clippy::type_complexity)]
699 fn ge<R>(
700 self,
701 other: R,
702 ) -> SQLExpr<
703 'a,
704 V,
705 <V::DialectMarker as DialectTypes>::Bool,
706 NonNull,
707 <Self::Aggregate as AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>>::Output,
708 >
709 where
710 R: ComparisonOperand<'a, V, Self>,
711 Self::SQLType: Compatible<<R as ComparisonOperand<'a, V, Self>>::SQLType>,
712 Self::Aggregate: AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>,
713 {
714 gte(self, other)
715 }
716
717 #[allow(clippy::type_complexity)]
725 fn lt<R>(
726 self,
727 other: R,
728 ) -> SQLExpr<
729 'a,
730 V,
731 <V::DialectMarker as DialectTypes>::Bool,
732 NonNull,
733 <Self::Aggregate as AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>>::Output,
734 >
735 where
736 R: ComparisonOperand<'a, V, Self>,
737 Self::SQLType: Compatible<<R as ComparisonOperand<'a, V, Self>>::SQLType>,
738 Self::Aggregate: AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>,
739 {
740 lt(self, other)
741 }
742
743 #[allow(clippy::type_complexity)]
751 fn le<R>(
752 self,
753 other: R,
754 ) -> SQLExpr<
755 'a,
756 V,
757 <V::DialectMarker as DialectTypes>::Bool,
758 NonNull,
759 <Self::Aggregate as AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>>::Output,
760 >
761 where
762 R: ComparisonOperand<'a, V, Self>,
763 Self::SQLType: Compatible<<R as ComparisonOperand<'a, V, Self>>::SQLType>,
764 Self::Aggregate: AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>,
765 {
766 lte(self, other)
767 }
768
769 #[allow(clippy::type_complexity)]
777 fn like<R>(
778 self,
779 pattern: R,
780 ) -> SQLExpr<
781 'a,
782 V,
783 <V::DialectMarker as DialectTypes>::Bool,
784 NonNull,
785 <Self::Aggregate as AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>>::Output,
786 >
787 where
788 R: ComparisonOperand<'a, V, Self>,
789 Self::SQLType: Compatible<<R as ComparisonOperand<'a, V, Self>>::SQLType>,
790 Self::SQLType: Textual,
791 <R as ComparisonOperand<'a, V, Self>>::SQLType: Textual,
792 Self::Aggregate: AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>,
793 {
794 like(self, pattern)
795 }
796
797 #[allow(clippy::type_complexity)]
805 fn not_like<R>(
806 self,
807 pattern: R,
808 ) -> SQLExpr<
809 'a,
810 V,
811 <V::DialectMarker as DialectTypes>::Bool,
812 NonNull,
813 <Self::Aggregate as AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>>::Output,
814 >
815 where
816 R: ComparisonOperand<'a, V, Self>,
817 Self::SQLType: Compatible<<R as ComparisonOperand<'a, V, Self>>::SQLType>,
818 Self::SQLType: Textual,
819 <R as ComparisonOperand<'a, V, Self>>::SQLType: Textual,
820 Self::Aggregate: AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>,
821 {
822 not_like(self, pattern)
823 }
824
825 #[allow(clippy::wrong_self_convention)]
833 fn is_null(
834 self,
835 ) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, Self::Aggregate> {
836 is_null(self)
837 }
838
839 #[allow(clippy::wrong_self_convention)]
847 fn is_not_null(
848 self,
849 ) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, Self::Aggregate> {
850 is_not_null(self)
851 }
852
853 #[allow(clippy::type_complexity)]
863 fn between<L, H>(
864 self,
865 low: L,
866 high: H,
867 ) -> SQLExpr<
868 'a,
869 V,
870 <V::DialectMarker as DialectTypes>::Bool,
871 NonNull,
872 <<Self::Aggregate as AggOr<
873 <L as ComparisonOperand<'a, V, Self>>::Aggregate,
874 >>::Output as AggOr<
875 <H as ComparisonOperand<'a, V, Self>>::Aggregate,
876 >>::Output,
877 >
878 where
879 L: ComparisonOperand<'a, V, Self>,
880 H: ComparisonOperand<'a, V, Self>,
881 Self::SQLType: Compatible<<L as ComparisonOperand<'a, V, Self>>::SQLType>,
882 Self::SQLType: Compatible<<H as ComparisonOperand<'a, V, Self>>::SQLType>,
883 Self::Aggregate:
884 AggOr<<L as ComparisonOperand<'a, V, Self>>::Aggregate>,
885 <Self::Aggregate as AggOr<
886 <L as ComparisonOperand<'a, V, Self>>::Aggregate,
887 >>::Output:
888 AggOr<<H as ComparisonOperand<'a, V, Self>>::Aggregate>,
889 {
890 between(self, low, high)
891 }
892
893 #[allow(clippy::type_complexity)]
903 fn not_between<L, H>(
904 self,
905 low: L,
906 high: H,
907 ) -> SQLExpr<
908 'a,
909 V,
910 <V::DialectMarker as DialectTypes>::Bool,
911 NonNull,
912 <<Self::Aggregate as AggOr<
913 <L as ComparisonOperand<'a, V, Self>>::Aggregate,
914 >>::Output as AggOr<
915 <H as ComparisonOperand<'a, V, Self>>::Aggregate,
916 >>::Output,
917 >
918 where
919 L: ComparisonOperand<'a, V, Self>,
920 H: ComparisonOperand<'a, V, Self>,
921 Self::SQLType: Compatible<<L as ComparisonOperand<'a, V, Self>>::SQLType>,
922 Self::SQLType: Compatible<<H as ComparisonOperand<'a, V, Self>>::SQLType>,
923 Self::Aggregate:
924 AggOr<<L as ComparisonOperand<'a, V, Self>>::Aggregate>,
925 <Self::Aggregate as AggOr<
926 <L as ComparisonOperand<'a, V, Self>>::Aggregate,
927 >>::Output:
928 AggOr<<H as ComparisonOperand<'a, V, Self>>::Aggregate>,
929 {
930 not_between(self, low, high)
931 }
932
933 fn in_array<I, R>(
944 self,
945 values: I,
946 ) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, Self::Aggregate>
947 where
948 I: IntoIterator<Item = R>,
949 R: Expr<'a, V>,
950 Self::SQLType: Compatible<R::SQLType>,
951 {
952 crate::expr::in_array(self, values)
953 }
954
955 fn not_in_array<I, R>(
966 self,
967 values: I,
968 ) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, Self::Aggregate>
969 where
970 I: IntoIterator<Item = R>,
971 R: Expr<'a, V>,
972 Self::SQLType: Compatible<R::SQLType>,
973 {
974 crate::expr::not_in_array(self, values)
975 }
976
977 fn in_subquery<S>(
979 self,
980 subquery: S,
981 ) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, Self::Aggregate>
982 where
983 S: Expr<'a, V>,
984 Self::SQLType: Compatible<S::SQLType>,
985 {
986 crate::expr::in_subquery(self, subquery)
987 }
988
989 fn not_in_subquery<S>(
991 self,
992 subquery: S,
993 ) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, Self::Aggregate>
994 where
995 S: Expr<'a, V>,
996 Self::SQLType: Compatible<S::SQLType>,
997 {
998 crate::expr::not_in_subquery(self, subquery)
999 }
1000
1001 #[allow(clippy::type_complexity, clippy::wrong_self_convention)]
1010 fn is_distinct_from<R>(
1011 self,
1012 other: R,
1013 ) -> SQLExpr<
1014 'a,
1015 V,
1016 <V::DialectMarker as DialectTypes>::Bool,
1017 NonNull,
1018 <Self::Aggregate as AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>>::Output,
1019 >
1020 where
1021 R: ComparisonOperand<'a, V, Self>,
1022 Self::SQLType: Compatible<<R as ComparisonOperand<'a, V, Self>>::SQLType>,
1023 Self::Aggregate: AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>,
1024 {
1025 is_distinct_from(self, other)
1026 }
1027
1028 #[allow(clippy::type_complexity, clippy::wrong_self_convention)]
1037 fn is_not_distinct_from<R>(
1038 self,
1039 other: R,
1040 ) -> SQLExpr<
1041 'a,
1042 V,
1043 <V::DialectMarker as DialectTypes>::Bool,
1044 NonNull,
1045 <Self::Aggregate as AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>>::Output,
1046 >
1047 where
1048 R: ComparisonOperand<'a, V, Self>,
1049 Self::SQLType: Compatible<<R as ComparisonOperand<'a, V, Self>>::SQLType>,
1050 Self::Aggregate: AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>,
1051 {
1052 is_not_distinct_from(self, other)
1053 }
1054
1055 #[allow(clippy::wrong_self_convention)]
1064 fn is_true(
1065 self,
1066 ) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, Self::Aggregate> {
1067 is_true(self)
1068 }
1069
1070 #[allow(clippy::wrong_self_convention)]
1079 fn is_false(
1080 self,
1081 ) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, Self::Aggregate> {
1082 is_false(self)
1083 }
1084}
1085
1086impl<'a, V: SQLParam, E: Expr<'a, V>> ExprExt<'a, V> for E {}