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 neq<'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)]
169pub fn gt<'a, V, L, R>(
170 left: L,
171 right: R,
172) -> SQLExpr<
173 'a,
174 V,
175 <V::DialectMarker as DialectTypes>::Bool,
176 NonNull,
177 <L::Aggregate as AggOr<<R as ComparisonOperand<'a, V, L>>::Aggregate>>::Output,
178>
179where
180 V: SQLParam + 'a,
181 L: Expr<'a, V>,
182 R: ComparisonOperand<'a, V, L>,
183 L::SQLType: Compatible<<R as ComparisonOperand<'a, V, L>>::SQLType>,
184 L::Aggregate: AggOr<<R as ComparisonOperand<'a, V, L>>::Aggregate>,
185{
186 SQLExpr::new(binary_op(left, Token::GT, right))
187}
188
189#[allow(clippy::type_complexity)]
193pub fn gte<'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::GE, right))
211}
212
213#[allow(clippy::type_complexity)]
217pub fn lt<'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::LT, right))
235}
236
237#[allow(clippy::type_complexity)]
241pub fn lte<'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::LE, right))
259}
260
261#[allow(clippy::type_complexity)]
281pub fn like<'a, V, L, R>(
282 left: L,
283 pattern: R,
284) -> SQLExpr<
285 'a,
286 V,
287 <V::DialectMarker as DialectTypes>::Bool,
288 NonNull,
289 <L::Aggregate as AggOr<<R as ComparisonOperand<'a, V, L>>::Aggregate>>::Output,
290>
291where
292 V: SQLParam + 'a,
293 L: Expr<'a, V>,
294 R: ComparisonOperand<'a, V, L>,
295 L::SQLType: Compatible<<R as ComparisonOperand<'a, V, L>>::SQLType>,
296 L::SQLType: Textual,
297 <R as ComparisonOperand<'a, V, L>>::SQLType: Textual,
298 L::Aggregate: AggOr<<R as ComparisonOperand<'a, V, L>>::Aggregate>,
299{
300 SQLExpr::new(
301 operand_sql(left)
302 .push(Token::LIKE)
303 .append(ComparisonOperand::into_comparison_sql(pattern)),
304 )
305}
306
307#[allow(clippy::type_complexity)]
311pub fn not_like<'a, V, L, R>(
312 left: L,
313 pattern: R,
314) -> SQLExpr<
315 'a,
316 V,
317 <V::DialectMarker as DialectTypes>::Bool,
318 NonNull,
319 <L::Aggregate as AggOr<<R as ComparisonOperand<'a, V, L>>::Aggregate>>::Output,
320>
321where
322 V: SQLParam + 'a,
323 L: Expr<'a, V>,
324 R: ComparisonOperand<'a, V, L>,
325 L::SQLType: Compatible<<R as ComparisonOperand<'a, V, L>>::SQLType>,
326 L::SQLType: Textual,
327 <R as ComparisonOperand<'a, V, L>>::SQLType: Textual,
328 L::Aggregate: AggOr<<R as ComparisonOperand<'a, V, L>>::Aggregate>,
329{
330 SQLExpr::new(
331 operand_sql(left)
332 .push(Token::NOT)
333 .push(Token::LIKE)
334 .append(ComparisonOperand::into_comparison_sql(pattern)),
335 )
336}
337
338#[allow(clippy::type_complexity)]
347pub fn between<'a, V, E, L, H>(
348 expr: E,
349 low: L,
350 high: H,
351) -> SQLExpr<
352 'a,
353 V,
354 <V::DialectMarker as DialectTypes>::Bool,
355 NonNull,
356 <<E::Aggregate as AggOr<<L as ComparisonOperand<'a, V, E>>::Aggregate>>::Output as AggOr<
357 <H as ComparisonOperand<'a, V, E>>::Aggregate,
358 >>::Output,
359>
360where
361 V: SQLParam + 'a,
362 E: Expr<'a, V>,
363 L: ComparisonOperand<'a, V, E>,
364 H: ComparisonOperand<'a, V, E>,
365 E::SQLType: Compatible<<L as ComparisonOperand<'a, V, E>>::SQLType>,
366 E::SQLType: Compatible<<H as ComparisonOperand<'a, V, E>>::SQLType>,
367 E::Aggregate: AggOr<<L as ComparisonOperand<'a, V, E>>::Aggregate>,
368 <E::Aggregate as AggOr<<L as ComparisonOperand<'a, V, E>>::Aggregate>>::Output:
369 AggOr<<H as ComparisonOperand<'a, V, E>>::Aggregate>,
370{
371 SQLExpr::new(
372 SQL::from(Token::LPAREN)
373 .append(operand_sql(expr))
374 .push(Token::BETWEEN)
375 .append(ComparisonOperand::into_comparison_sql(low))
376 .push(Token::AND)
377 .append(ComparisonOperand::into_comparison_sql(high))
378 .push(Token::RPAREN),
379 )
380}
381
382#[allow(clippy::type_complexity)]
386pub fn not_between<'a, V, E, L, H>(
387 expr: E,
388 low: L,
389 high: H,
390) -> SQLExpr<
391 'a,
392 V,
393 <V::DialectMarker as DialectTypes>::Bool,
394 NonNull,
395 <<E::Aggregate as AggOr<<L as ComparisonOperand<'a, V, E>>::Aggregate>>::Output as AggOr<
396 <H as ComparisonOperand<'a, V, E>>::Aggregate,
397 >>::Output,
398>
399where
400 V: SQLParam + 'a,
401 E: Expr<'a, V>,
402 L: ComparisonOperand<'a, V, E>,
403 H: ComparisonOperand<'a, V, E>,
404 E::SQLType: Compatible<<L as ComparisonOperand<'a, V, E>>::SQLType>,
405 E::SQLType: Compatible<<H as ComparisonOperand<'a, V, E>>::SQLType>,
406 E::Aggregate: AggOr<<L as ComparisonOperand<'a, V, E>>::Aggregate>,
407 <E::Aggregate as AggOr<<L as ComparisonOperand<'a, V, E>>::Aggregate>>::Output:
408 AggOr<<H as ComparisonOperand<'a, V, E>>::Aggregate>,
409{
410 SQLExpr::new(
411 SQL::from(Token::LPAREN)
412 .append(operand_sql(expr))
413 .push(Token::NOT)
414 .push(Token::BETWEEN)
415 .append(ComparisonOperand::into_comparison_sql(low))
416 .push(Token::AND)
417 .append(ComparisonOperand::into_comparison_sql(high))
418 .push(Token::RPAREN),
419 )
420}
421
422pub fn is_null<'a, V, E>(
431 expr: E,
432) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, E::Aggregate>
433where
434 V: SQLParam + 'a,
435 E: Expr<'a, V>,
436{
437 SQLExpr::new(operand_sql(expr).push(Token::IS).push(Token::NULL))
438}
439
440pub fn is_not_null<'a, V, E>(
445 expr: E,
446) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, E::Aggregate>
447where
448 V: SQLParam + 'a,
449 E: Expr<'a, V>,
450{
451 SQLExpr::new(
452 operand_sql(expr)
453 .push(Token::IS)
454 .push(Token::NOT)
455 .push(Token::NULL),
456 )
457}
458
459#[allow(clippy::type_complexity)]
472pub fn is_distinct_from<'a, V, L, R>(
473 left: L,
474 right: R,
475) -> SQLExpr<
476 'a,
477 V,
478 <V::DialectMarker as DialectTypes>::Bool,
479 NonNull,
480 <L::Aggregate as AggOr<<R as ComparisonOperand<'a, V, L>>::Aggregate>>::Output,
481>
482where
483 V: SQLParam + 'a,
484 L: Expr<'a, V>,
485 R: ComparisonOperand<'a, V, L>,
486 L::SQLType: Compatible<<R as ComparisonOperand<'a, V, L>>::SQLType>,
487 L::Aggregate: AggOr<<R as ComparisonOperand<'a, V, L>>::Aggregate>,
488{
489 SQLExpr::new(
490 operand_sql(left)
491 .push(Token::IS)
492 .push(Token::DISTINCT)
493 .push(Token::FROM)
494 .append(ComparisonOperand::into_comparison_sql(right)),
495 )
496}
497
498#[allow(clippy::type_complexity)]
506pub fn is_not_distinct_from<'a, V, L, R>(
507 left: L,
508 right: R,
509) -> SQLExpr<
510 'a,
511 V,
512 <V::DialectMarker as DialectTypes>::Bool,
513 NonNull,
514 <L::Aggregate as AggOr<<R as ComparisonOperand<'a, V, L>>::Aggregate>>::Output,
515>
516where
517 V: SQLParam + 'a,
518 L: Expr<'a, V>,
519 R: ComparisonOperand<'a, V, L>,
520 L::SQLType: Compatible<<R as ComparisonOperand<'a, V, L>>::SQLType>,
521 L::Aggregate: AggOr<<R as ComparisonOperand<'a, V, L>>::Aggregate>,
522{
523 SQLExpr::new(
524 operand_sql(left)
525 .push(Token::IS)
526 .push(Token::NOT)
527 .push(Token::DISTINCT)
528 .push(Token::FROM)
529 .append(ComparisonOperand::into_comparison_sql(right)),
530 )
531}
532
533pub fn is_true<'a, V, E>(
544 expr: E,
545) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, E::Aggregate>
546where
547 V: SQLParam + 'a,
548 E: Expr<'a, V>,
549{
550 SQLExpr::new(operand_sql(expr).push(Token::IS).append(SQL::raw("TRUE")))
551}
552
553pub fn is_false<'a, V, E>(
560 expr: E,
561) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, E::Aggregate>
562where
563 V: SQLParam + 'a,
564 E: Expr<'a, V>,
565{
566 SQLExpr::new(operand_sql(expr).push(Token::IS).append(SQL::raw("FALSE")))
567}
568
569pub trait ExprExt<'a, V: SQLParam>: Expr<'a, V> + Sized {
589 #[allow(clippy::type_complexity)]
597 fn eq<R>(
598 self,
599 other: R,
600 ) -> SQLExpr<
601 'a,
602 V,
603 <V::DialectMarker as DialectTypes>::Bool,
604 NonNull,
605 <Self::Aggregate as AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>>::Output,
606 >
607 where
608 R: ComparisonOperand<'a, V, Self>,
609 Self::SQLType: Compatible<<R as ComparisonOperand<'a, V, Self>>::SQLType>,
610 Self::Aggregate: AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>,
611 {
612 eq(self, other)
613 }
614
615 #[allow(clippy::type_complexity)]
623 fn ne<R>(
624 self,
625 other: R,
626 ) -> SQLExpr<
627 'a,
628 V,
629 <V::DialectMarker as DialectTypes>::Bool,
630 NonNull,
631 <Self::Aggregate as AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>>::Output,
632 >
633 where
634 R: ComparisonOperand<'a, V, Self>,
635 Self::SQLType: Compatible<<R as ComparisonOperand<'a, V, Self>>::SQLType>,
636 Self::Aggregate: AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>,
637 {
638 neq(self, other)
639 }
640
641 #[allow(clippy::type_complexity)]
649 fn gt<R>(
650 self,
651 other: R,
652 ) -> SQLExpr<
653 'a,
654 V,
655 <V::DialectMarker as DialectTypes>::Bool,
656 NonNull,
657 <Self::Aggregate as AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>>::Output,
658 >
659 where
660 R: ComparisonOperand<'a, V, Self>,
661 Self::SQLType: Compatible<<R as ComparisonOperand<'a, V, Self>>::SQLType>,
662 Self::Aggregate: AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>,
663 {
664 gt(self, other)
665 }
666
667 #[allow(clippy::type_complexity)]
675 fn ge<R>(
676 self,
677 other: R,
678 ) -> SQLExpr<
679 'a,
680 V,
681 <V::DialectMarker as DialectTypes>::Bool,
682 NonNull,
683 <Self::Aggregate as AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>>::Output,
684 >
685 where
686 R: ComparisonOperand<'a, V, Self>,
687 Self::SQLType: Compatible<<R as ComparisonOperand<'a, V, Self>>::SQLType>,
688 Self::Aggregate: AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>,
689 {
690 gte(self, other)
691 }
692
693 #[allow(clippy::type_complexity)]
701 fn lt<R>(
702 self,
703 other: R,
704 ) -> SQLExpr<
705 'a,
706 V,
707 <V::DialectMarker as DialectTypes>::Bool,
708 NonNull,
709 <Self::Aggregate as AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>>::Output,
710 >
711 where
712 R: ComparisonOperand<'a, V, Self>,
713 Self::SQLType: Compatible<<R as ComparisonOperand<'a, V, Self>>::SQLType>,
714 Self::Aggregate: AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>,
715 {
716 lt(self, other)
717 }
718
719 #[allow(clippy::type_complexity)]
727 fn le<R>(
728 self,
729 other: R,
730 ) -> SQLExpr<
731 'a,
732 V,
733 <V::DialectMarker as DialectTypes>::Bool,
734 NonNull,
735 <Self::Aggregate as AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>>::Output,
736 >
737 where
738 R: ComparisonOperand<'a, V, Self>,
739 Self::SQLType: Compatible<<R as ComparisonOperand<'a, V, Self>>::SQLType>,
740 Self::Aggregate: AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>,
741 {
742 lte(self, other)
743 }
744
745 #[allow(clippy::type_complexity)]
753 fn like<R>(
754 self,
755 pattern: R,
756 ) -> SQLExpr<
757 'a,
758 V,
759 <V::DialectMarker as DialectTypes>::Bool,
760 NonNull,
761 <Self::Aggregate as AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>>::Output,
762 >
763 where
764 R: ComparisonOperand<'a, V, Self>,
765 Self::SQLType: Compatible<<R as ComparisonOperand<'a, V, Self>>::SQLType>,
766 Self::SQLType: Textual,
767 <R as ComparisonOperand<'a, V, Self>>::SQLType: Textual,
768 Self::Aggregate: AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>,
769 {
770 like(self, pattern)
771 }
772
773 #[allow(clippy::type_complexity)]
781 fn not_like<R>(
782 self,
783 pattern: R,
784 ) -> SQLExpr<
785 'a,
786 V,
787 <V::DialectMarker as DialectTypes>::Bool,
788 NonNull,
789 <Self::Aggregate as AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>>::Output,
790 >
791 where
792 R: ComparisonOperand<'a, V, Self>,
793 Self::SQLType: Compatible<<R as ComparisonOperand<'a, V, Self>>::SQLType>,
794 Self::SQLType: Textual,
795 <R as ComparisonOperand<'a, V, Self>>::SQLType: Textual,
796 Self::Aggregate: AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>,
797 {
798 not_like(self, pattern)
799 }
800
801 #[allow(clippy::wrong_self_convention)]
809 fn is_null(
810 self,
811 ) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, Self::Aggregate> {
812 is_null(self)
813 }
814
815 #[allow(clippy::wrong_self_convention)]
823 fn is_not_null(
824 self,
825 ) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, Self::Aggregate> {
826 is_not_null(self)
827 }
828
829 #[allow(clippy::type_complexity)]
839 fn between<L, H>(
840 self,
841 low: L,
842 high: H,
843 ) -> SQLExpr<
844 'a,
845 V,
846 <V::DialectMarker as DialectTypes>::Bool,
847 NonNull,
848 <<Self::Aggregate as AggOr<
849 <L as ComparisonOperand<'a, V, Self>>::Aggregate,
850 >>::Output as AggOr<
851 <H as ComparisonOperand<'a, V, Self>>::Aggregate,
852 >>::Output,
853 >
854 where
855 L: ComparisonOperand<'a, V, Self>,
856 H: ComparisonOperand<'a, V, Self>,
857 Self::SQLType: Compatible<<L as ComparisonOperand<'a, V, Self>>::SQLType>,
858 Self::SQLType: Compatible<<H as ComparisonOperand<'a, V, Self>>::SQLType>,
859 Self::Aggregate:
860 AggOr<<L as ComparisonOperand<'a, V, Self>>::Aggregate>,
861 <Self::Aggregate as AggOr<
862 <L as ComparisonOperand<'a, V, Self>>::Aggregate,
863 >>::Output:
864 AggOr<<H as ComparisonOperand<'a, V, Self>>::Aggregate>,
865 {
866 between(self, low, high)
867 }
868
869 #[allow(clippy::type_complexity)]
879 fn not_between<L, H>(
880 self,
881 low: L,
882 high: H,
883 ) -> SQLExpr<
884 'a,
885 V,
886 <V::DialectMarker as DialectTypes>::Bool,
887 NonNull,
888 <<Self::Aggregate as AggOr<
889 <L as ComparisonOperand<'a, V, Self>>::Aggregate,
890 >>::Output as AggOr<
891 <H as ComparisonOperand<'a, V, Self>>::Aggregate,
892 >>::Output,
893 >
894 where
895 L: ComparisonOperand<'a, V, Self>,
896 H: ComparisonOperand<'a, V, Self>,
897 Self::SQLType: Compatible<<L as ComparisonOperand<'a, V, Self>>::SQLType>,
898 Self::SQLType: Compatible<<H as ComparisonOperand<'a, V, Self>>::SQLType>,
899 Self::Aggregate:
900 AggOr<<L as ComparisonOperand<'a, V, Self>>::Aggregate>,
901 <Self::Aggregate as AggOr<
902 <L as ComparisonOperand<'a, V, Self>>::Aggregate,
903 >>::Output:
904 AggOr<<H as ComparisonOperand<'a, V, Self>>::Aggregate>,
905 {
906 not_between(self, low, high)
907 }
908
909 fn in_array<I, R>(
920 self,
921 values: I,
922 ) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, Self::Aggregate>
923 where
924 I: IntoIterator<Item = R>,
925 R: Expr<'a, V>,
926 Self::SQLType: Compatible<R::SQLType>,
927 {
928 crate::expr::in_array(self, values)
929 }
930
931 fn not_in_array<I, R>(
942 self,
943 values: I,
944 ) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, Self::Aggregate>
945 where
946 I: IntoIterator<Item = R>,
947 R: Expr<'a, V>,
948 Self::SQLType: Compatible<R::SQLType>,
949 {
950 crate::expr::not_in_array(self, values)
951 }
952
953 fn in_subquery<S>(
955 self,
956 subquery: S,
957 ) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, Self::Aggregate>
958 where
959 S: Expr<'a, V>,
960 Self::SQLType: Compatible<S::SQLType>,
961 {
962 crate::expr::in_subquery(self, subquery)
963 }
964
965 fn not_in_subquery<S>(
967 self,
968 subquery: S,
969 ) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, Self::Aggregate>
970 where
971 S: Expr<'a, V>,
972 Self::SQLType: Compatible<S::SQLType>,
973 {
974 crate::expr::not_in_subquery(self, subquery)
975 }
976
977 #[allow(clippy::type_complexity, clippy::wrong_self_convention)]
986 fn is_distinct_from<R>(
987 self,
988 other: R,
989 ) -> SQLExpr<
990 'a,
991 V,
992 <V::DialectMarker as DialectTypes>::Bool,
993 NonNull,
994 <Self::Aggregate as AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>>::Output,
995 >
996 where
997 R: ComparisonOperand<'a, V, Self>,
998 Self::SQLType: Compatible<<R as ComparisonOperand<'a, V, Self>>::SQLType>,
999 Self::Aggregate: AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>,
1000 {
1001 is_distinct_from(self, other)
1002 }
1003
1004 #[allow(clippy::type_complexity, clippy::wrong_self_convention)]
1013 fn is_not_distinct_from<R>(
1014 self,
1015 other: R,
1016 ) -> SQLExpr<
1017 'a,
1018 V,
1019 <V::DialectMarker as DialectTypes>::Bool,
1020 NonNull,
1021 <Self::Aggregate as AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>>::Output,
1022 >
1023 where
1024 R: ComparisonOperand<'a, V, Self>,
1025 Self::SQLType: Compatible<<R as ComparisonOperand<'a, V, Self>>::SQLType>,
1026 Self::Aggregate: AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>,
1027 {
1028 is_not_distinct_from(self, other)
1029 }
1030
1031 #[allow(clippy::wrong_self_convention)]
1040 fn is_true(
1041 self,
1042 ) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, Self::Aggregate> {
1043 is_true(self)
1044 }
1045
1046 #[allow(clippy::wrong_self_convention)]
1055 fn is_false(
1056 self,
1057 ) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, Self::Aggregate> {
1058 is_false(self)
1059 }
1060}
1061
1062impl<'a, V: SQLParam, E: Expr<'a, V>> ExprExt<'a, V> for E {}