1use crate::dialect::DialectTypes;
25use crate::sql::{SQL, Token};
26use crate::traits::{SQLParam, ToSQL};
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: ToSQL<'a, V>,
39 R: ToSQL<'a, V>,
40{
41 let left_sql = operand_sql(left);
42 let right_sql = operand_sql(right);
43
44 left_sql.push(operator).append(right_sql)
45}
46
47#[inline]
48fn operand_sql<'a, V, T>(value: T) -> SQL<'a, V>
49where
50 V: SQLParam + 'a,
51 T: ToSQL<'a, V>,
52{
53 value.into_sql().parens_if_subquery()
54}
55
56pub trait ComparisonOperand<'a, V, Expected>: ToSQL<'a, V>
67where
68 V: SQLParam + 'a,
69 Expected: DataType,
70{
71 type SQLType: DataType;
72 type Aggregate: AggregateKind;
73}
74
75impl<'a, V, Expected, R> ComparisonOperand<'a, V, Expected> for R
76where
77 V: SQLParam + 'a,
78 Expected: DataType + Compatible<R::SQLType>,
79 R: Expr<'a, V>,
80{
81 type SQLType = R::SQLType;
82 type Aggregate = R::Aggregate;
83}
84
85#[allow(clippy::type_complexity)]
108pub fn eq<'a, V, L, R>(
109 left: L,
110 right: R,
111) -> SQLExpr<
112 'a,
113 V,
114 <V::DialectMarker as DialectTypes>::Bool,
115 NonNull,
116 <L::Aggregate as AggOr<<R as ComparisonOperand<'a, V, L::SQLType>>::Aggregate>>::Output,
117>
118where
119 V: SQLParam + 'a,
120 L: Expr<'a, V>,
121 R: ComparisonOperand<'a, V, L::SQLType>,
122 L::Aggregate: AggOr<<R as ComparisonOperand<'a, V, L::SQLType>>::Aggregate>,
123{
124 SQLExpr::new(binary_op(left, Token::EQ, right))
125}
126
127#[allow(clippy::type_complexity)]
131pub fn neq<'a, V, L, R>(
132 left: L,
133 right: R,
134) -> SQLExpr<
135 'a,
136 V,
137 <V::DialectMarker as DialectTypes>::Bool,
138 NonNull,
139 <L::Aggregate as AggOr<<R as ComparisonOperand<'a, V, L::SQLType>>::Aggregate>>::Output,
140>
141where
142 V: SQLParam + 'a,
143 L: Expr<'a, V>,
144 R: ComparisonOperand<'a, V, L::SQLType>,
145 L::Aggregate: AggOr<<R as ComparisonOperand<'a, V, L::SQLType>>::Aggregate>,
146{
147 SQLExpr::new(binary_op(left, Token::NE, right))
148}
149
150#[allow(clippy::type_complexity)]
158pub fn gt<'a, V, L, R>(
159 left: L,
160 right: R,
161) -> SQLExpr<
162 'a,
163 V,
164 <V::DialectMarker as DialectTypes>::Bool,
165 NonNull,
166 <L::Aggregate as AggOr<<R as ComparisonOperand<'a, V, L::SQLType>>::Aggregate>>::Output,
167>
168where
169 V: SQLParam + 'a,
170 L: Expr<'a, V>,
171 R: ComparisonOperand<'a, V, L::SQLType>,
172 L::Aggregate: AggOr<<R as ComparisonOperand<'a, V, L::SQLType>>::Aggregate>,
173{
174 SQLExpr::new(binary_op(left, Token::GT, right))
175}
176
177#[allow(clippy::type_complexity)]
181pub fn gte<'a, V, L, R>(
182 left: L,
183 right: R,
184) -> SQLExpr<
185 'a,
186 V,
187 <V::DialectMarker as DialectTypes>::Bool,
188 NonNull,
189 <L::Aggregate as AggOr<<R as ComparisonOperand<'a, V, L::SQLType>>::Aggregate>>::Output,
190>
191where
192 V: SQLParam + 'a,
193 L: Expr<'a, V>,
194 R: ComparisonOperand<'a, V, L::SQLType>,
195 L::Aggregate: AggOr<<R as ComparisonOperand<'a, V, L::SQLType>>::Aggregate>,
196{
197 SQLExpr::new(binary_op(left, Token::GE, right))
198}
199
200#[allow(clippy::type_complexity)]
204pub fn lt<'a, V, L, R>(
205 left: L,
206 right: R,
207) -> SQLExpr<
208 'a,
209 V,
210 <V::DialectMarker as DialectTypes>::Bool,
211 NonNull,
212 <L::Aggregate as AggOr<<R as ComparisonOperand<'a, V, L::SQLType>>::Aggregate>>::Output,
213>
214where
215 V: SQLParam + 'a,
216 L: Expr<'a, V>,
217 R: ComparisonOperand<'a, V, L::SQLType>,
218 L::Aggregate: AggOr<<R as ComparisonOperand<'a, V, L::SQLType>>::Aggregate>,
219{
220 SQLExpr::new(binary_op(left, Token::LT, right))
221}
222
223#[allow(clippy::type_complexity)]
227pub fn lte<'a, V, L, R>(
228 left: L,
229 right: R,
230) -> SQLExpr<
231 'a,
232 V,
233 <V::DialectMarker as DialectTypes>::Bool,
234 NonNull,
235 <L::Aggregate as AggOr<<R as ComparisonOperand<'a, V, L::SQLType>>::Aggregate>>::Output,
236>
237where
238 V: SQLParam + 'a,
239 L: Expr<'a, V>,
240 R: ComparisonOperand<'a, V, L::SQLType>,
241 L::Aggregate: AggOr<<R as ComparisonOperand<'a, V, L::SQLType>>::Aggregate>,
242{
243 SQLExpr::new(binary_op(left, Token::LE, right))
244}
245
246#[allow(clippy::type_complexity)]
266pub fn like<'a, V, L, R>(
267 left: L,
268 pattern: R,
269) -> SQLExpr<
270 'a,
271 V,
272 <V::DialectMarker as DialectTypes>::Bool,
273 NonNull,
274 <L::Aggregate as AggOr<<R as ComparisonOperand<'a, V, L::SQLType>>::Aggregate>>::Output,
275>
276where
277 V: SQLParam + 'a,
278 L: Expr<'a, V>,
279 R: ComparisonOperand<'a, V, L::SQLType>,
280 L::SQLType: Textual,
281 <R as ComparisonOperand<'a, V, L::SQLType>>::SQLType: Textual,
282 L::Aggregate: AggOr<<R as ComparisonOperand<'a, V, L::SQLType>>::Aggregate>,
283{
284 SQLExpr::new(
285 operand_sql(left)
286 .push(Token::LIKE)
287 .append(operand_sql(pattern)),
288 )
289}
290
291#[allow(clippy::type_complexity)]
295pub fn not_like<'a, V, L, R>(
296 left: L,
297 pattern: R,
298) -> SQLExpr<
299 'a,
300 V,
301 <V::DialectMarker as DialectTypes>::Bool,
302 NonNull,
303 <L::Aggregate as AggOr<<R as ComparisonOperand<'a, V, L::SQLType>>::Aggregate>>::Output,
304>
305where
306 V: SQLParam + 'a,
307 L: Expr<'a, V>,
308 R: ComparisonOperand<'a, V, L::SQLType>,
309 L::SQLType: Textual,
310 <R as ComparisonOperand<'a, V, L::SQLType>>::SQLType: Textual,
311 L::Aggregate: AggOr<<R as ComparisonOperand<'a, V, L::SQLType>>::Aggregate>,
312{
313 SQLExpr::new(
314 operand_sql(left)
315 .push(Token::NOT)
316 .push(Token::LIKE)
317 .append(operand_sql(pattern)),
318 )
319}
320
321#[allow(clippy::type_complexity)]
330pub fn between<'a, V, E, L, H>(
331 expr: E,
332 low: L,
333 high: H,
334) -> SQLExpr<
335 'a,
336 V,
337 <V::DialectMarker as DialectTypes>::Bool,
338 NonNull,
339 <<E::Aggregate as AggOr<<L as ComparisonOperand<'a, V, E::SQLType>>::Aggregate>>::Output as AggOr<<H as ComparisonOperand<'a, V, E::SQLType>>::Aggregate>>::Output,
340>
341where
342 V: SQLParam + 'a,
343 E: Expr<'a, V>,
344 L: ComparisonOperand<'a, V, E::SQLType>,
345 H: ComparisonOperand<'a, V, E::SQLType>,
346 E::Aggregate: AggOr<<L as ComparisonOperand<'a, V, E::SQLType>>::Aggregate>,
347 <E::Aggregate as AggOr<<L as ComparisonOperand<'a, V, E::SQLType>>::Aggregate>>::Output:
348 AggOr<<H as ComparisonOperand<'a, V, E::SQLType>>::Aggregate>,
349{
350 SQLExpr::new(
351 SQL::from(Token::LPAREN)
352 .append(operand_sql(expr))
353 .push(Token::BETWEEN)
354 .append(operand_sql(low))
355 .push(Token::AND)
356 .append(operand_sql(high))
357 .push(Token::RPAREN),
358 )
359}
360
361#[allow(clippy::type_complexity)]
365pub fn not_between<'a, V, E, L, H>(
366 expr: E,
367 low: L,
368 high: H,
369) -> SQLExpr<
370 'a,
371 V,
372 <V::DialectMarker as DialectTypes>::Bool,
373 NonNull,
374 <<E::Aggregate as AggOr<<L as ComparisonOperand<'a, V, E::SQLType>>::Aggregate>>::Output as AggOr<<H as ComparisonOperand<'a, V, E::SQLType>>::Aggregate>>::Output,
375>
376where
377 V: SQLParam + 'a,
378 E: Expr<'a, V>,
379 L: ComparisonOperand<'a, V, E::SQLType>,
380 H: ComparisonOperand<'a, V, E::SQLType>,
381 E::Aggregate: AggOr<<L as ComparisonOperand<'a, V, E::SQLType>>::Aggregate>,
382 <E::Aggregate as AggOr<<L as ComparisonOperand<'a, V, E::SQLType>>::Aggregate>>::Output:
383 AggOr<<H as ComparisonOperand<'a, V, E::SQLType>>::Aggregate>,
384{
385 SQLExpr::new(
386 SQL::from(Token::LPAREN)
387 .append(operand_sql(expr))
388 .push(Token::NOT)
389 .push(Token::BETWEEN)
390 .append(operand_sql(low))
391 .push(Token::AND)
392 .append(operand_sql(high))
393 .push(Token::RPAREN),
394 )
395}
396
397pub fn is_null<'a, V, E>(
406 expr: E,
407) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, E::Aggregate>
408where
409 V: SQLParam + 'a,
410 E: Expr<'a, V>,
411{
412 SQLExpr::new(operand_sql(expr).push(Token::IS).push(Token::NULL))
413}
414
415pub fn is_not_null<'a, V, E>(
420 expr: E,
421) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, E::Aggregate>
422where
423 V: SQLParam + 'a,
424 E: Expr<'a, V>,
425{
426 SQLExpr::new(
427 operand_sql(expr)
428 .push(Token::IS)
429 .push(Token::NOT)
430 .push(Token::NULL),
431 )
432}
433
434#[allow(clippy::type_complexity)]
447pub fn is_distinct_from<'a, V, L, R>(
448 left: L,
449 right: R,
450) -> SQLExpr<
451 'a,
452 V,
453 <V::DialectMarker as DialectTypes>::Bool,
454 NonNull,
455 <L::Aggregate as AggOr<<R as ComparisonOperand<'a, V, L::SQLType>>::Aggregate>>::Output,
456>
457where
458 V: SQLParam + 'a,
459 L: Expr<'a, V>,
460 R: ComparisonOperand<'a, V, L::SQLType>,
461 L::Aggregate: AggOr<<R as ComparisonOperand<'a, V, L::SQLType>>::Aggregate>,
462{
463 SQLExpr::new(
464 operand_sql(left)
465 .push(Token::IS)
466 .push(Token::DISTINCT)
467 .push(Token::FROM)
468 .append(operand_sql(right)),
469 )
470}
471
472#[allow(clippy::type_complexity)]
480pub fn is_not_distinct_from<'a, V, L, R>(
481 left: L,
482 right: R,
483) -> SQLExpr<
484 'a,
485 V,
486 <V::DialectMarker as DialectTypes>::Bool,
487 NonNull,
488 <L::Aggregate as AggOr<<R as ComparisonOperand<'a, V, L::SQLType>>::Aggregate>>::Output,
489>
490where
491 V: SQLParam + 'a,
492 L: Expr<'a, V>,
493 R: ComparisonOperand<'a, V, L::SQLType>,
494 L::Aggregate: AggOr<<R as ComparisonOperand<'a, V, L::SQLType>>::Aggregate>,
495{
496 SQLExpr::new(
497 operand_sql(left)
498 .push(Token::IS)
499 .push(Token::NOT)
500 .push(Token::DISTINCT)
501 .push(Token::FROM)
502 .append(operand_sql(right)),
503 )
504}
505
506pub fn is_true<'a, V, E>(
517 expr: E,
518) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, E::Aggregate>
519where
520 V: SQLParam + 'a,
521 E: Expr<'a, V>,
522{
523 SQLExpr::new(operand_sql(expr).push(Token::IS).append(SQL::raw("TRUE")))
524}
525
526pub fn is_false<'a, V, E>(
533 expr: E,
534) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, E::Aggregate>
535where
536 V: SQLParam + 'a,
537 E: Expr<'a, V>,
538{
539 SQLExpr::new(operand_sql(expr).push(Token::IS).append(SQL::raw("FALSE")))
540}
541
542pub trait ExprExt<'a, V: SQLParam>: Expr<'a, V> + Sized {
562 #[allow(clippy::type_complexity)]
570 fn eq<R>(
571 self,
572 other: R,
573 ) -> SQLExpr<
574 'a,
575 V,
576 <V::DialectMarker as DialectTypes>::Bool,
577 NonNull,
578 <Self::Aggregate as AggOr<
579 <R as ComparisonOperand<'a, V, Self::SQLType>>::Aggregate,
580 >>::Output,
581 >
582 where
583 R: ComparisonOperand<'a, V, Self::SQLType>,
584 Self::Aggregate:
585 AggOr<<R as ComparisonOperand<'a, V, Self::SQLType>>::Aggregate>,
586 {
587 eq(self, other)
588 }
589
590 #[allow(clippy::type_complexity)]
598 fn ne<R>(
599 self,
600 other: R,
601 ) -> SQLExpr<
602 'a,
603 V,
604 <V::DialectMarker as DialectTypes>::Bool,
605 NonNull,
606 <Self::Aggregate as AggOr<
607 <R as ComparisonOperand<'a, V, Self::SQLType>>::Aggregate,
608 >>::Output,
609 >
610 where
611 R: ComparisonOperand<'a, V, Self::SQLType>,
612 Self::Aggregate:
613 AggOr<<R as ComparisonOperand<'a, V, Self::SQLType>>::Aggregate>,
614 {
615 neq(self, other)
616 }
617
618 #[allow(clippy::type_complexity)]
626 fn gt<R>(
627 self,
628 other: R,
629 ) -> SQLExpr<
630 'a,
631 V,
632 <V::DialectMarker as DialectTypes>::Bool,
633 NonNull,
634 <Self::Aggregate as AggOr<
635 <R as ComparisonOperand<'a, V, Self::SQLType>>::Aggregate,
636 >>::Output,
637 >
638 where
639 R: ComparisonOperand<'a, V, Self::SQLType>,
640 Self::Aggregate:
641 AggOr<<R as ComparisonOperand<'a, V, Self::SQLType>>::Aggregate>,
642 {
643 gt(self, other)
644 }
645
646 #[allow(clippy::type_complexity)]
654 fn ge<R>(
655 self,
656 other: R,
657 ) -> SQLExpr<
658 'a,
659 V,
660 <V::DialectMarker as DialectTypes>::Bool,
661 NonNull,
662 <Self::Aggregate as AggOr<
663 <R as ComparisonOperand<'a, V, Self::SQLType>>::Aggregate,
664 >>::Output,
665 >
666 where
667 R: ComparisonOperand<'a, V, Self::SQLType>,
668 Self::Aggregate:
669 AggOr<<R as ComparisonOperand<'a, V, Self::SQLType>>::Aggregate>,
670 {
671 gte(self, other)
672 }
673
674 #[allow(clippy::type_complexity)]
682 fn lt<R>(
683 self,
684 other: R,
685 ) -> SQLExpr<
686 'a,
687 V,
688 <V::DialectMarker as DialectTypes>::Bool,
689 NonNull,
690 <Self::Aggregate as AggOr<
691 <R as ComparisonOperand<'a, V, Self::SQLType>>::Aggregate,
692 >>::Output,
693 >
694 where
695 R: ComparisonOperand<'a, V, Self::SQLType>,
696 Self::Aggregate:
697 AggOr<<R as ComparisonOperand<'a, V, Self::SQLType>>::Aggregate>,
698 {
699 lt(self, other)
700 }
701
702 #[allow(clippy::type_complexity)]
710 fn le<R>(
711 self,
712 other: R,
713 ) -> SQLExpr<
714 'a,
715 V,
716 <V::DialectMarker as DialectTypes>::Bool,
717 NonNull,
718 <Self::Aggregate as AggOr<
719 <R as ComparisonOperand<'a, V, Self::SQLType>>::Aggregate,
720 >>::Output,
721 >
722 where
723 R: ComparisonOperand<'a, V, Self::SQLType>,
724 Self::Aggregate:
725 AggOr<<R as ComparisonOperand<'a, V, Self::SQLType>>::Aggregate>,
726 {
727 lte(self, other)
728 }
729
730 #[allow(clippy::type_complexity)]
738 fn like<R>(
739 self,
740 pattern: R,
741 ) -> SQLExpr<
742 'a,
743 V,
744 <V::DialectMarker as DialectTypes>::Bool,
745 NonNull,
746 <Self::Aggregate as AggOr<
747 <R as ComparisonOperand<'a, V, Self::SQLType>>::Aggregate,
748 >>::Output,
749 >
750 where
751 R: ComparisonOperand<'a, V, Self::SQLType>,
752 Self::SQLType: Textual,
753 <R as ComparisonOperand<'a, V, Self::SQLType>>::SQLType: Textual,
754 Self::Aggregate:
755 AggOr<<R as ComparisonOperand<'a, V, Self::SQLType>>::Aggregate>,
756 {
757 like(self, pattern)
758 }
759
760 #[allow(clippy::type_complexity)]
768 fn not_like<R>(
769 self,
770 pattern: R,
771 ) -> SQLExpr<
772 'a,
773 V,
774 <V::DialectMarker as DialectTypes>::Bool,
775 NonNull,
776 <Self::Aggregate as AggOr<
777 <R as ComparisonOperand<'a, V, Self::SQLType>>::Aggregate,
778 >>::Output,
779 >
780 where
781 R: ComparisonOperand<'a, V, Self::SQLType>,
782 Self::SQLType: Textual,
783 <R as ComparisonOperand<'a, V, Self::SQLType>>::SQLType: Textual,
784 Self::Aggregate:
785 AggOr<<R as ComparisonOperand<'a, V, Self::SQLType>>::Aggregate>,
786 {
787 not_like(self, pattern)
788 }
789
790 #[allow(clippy::wrong_self_convention)]
798 fn is_null(
799 self,
800 ) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, Self::Aggregate> {
801 is_null(self)
802 }
803
804 #[allow(clippy::wrong_self_convention)]
812 fn is_not_null(
813 self,
814 ) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, Self::Aggregate> {
815 is_not_null(self)
816 }
817
818 #[allow(clippy::type_complexity)]
828 fn between<L, H>(
829 self,
830 low: L,
831 high: H,
832 ) -> SQLExpr<
833 'a,
834 V,
835 <V::DialectMarker as DialectTypes>::Bool,
836 NonNull,
837 <<Self::Aggregate as AggOr<
838 <L as ComparisonOperand<'a, V, Self::SQLType>>::Aggregate,
839 >>::Output as AggOr<
840 <H as ComparisonOperand<'a, V, Self::SQLType>>::Aggregate,
841 >>::Output,
842 >
843 where
844 L: ComparisonOperand<'a, V, Self::SQLType>,
845 H: ComparisonOperand<'a, V, Self::SQLType>,
846 Self::Aggregate:
847 AggOr<<L as ComparisonOperand<'a, V, Self::SQLType>>::Aggregate>,
848 <Self::Aggregate as AggOr<
849 <L as ComparisonOperand<'a, V, Self::SQLType>>::Aggregate,
850 >>::Output:
851 AggOr<<H as ComparisonOperand<'a, V, Self::SQLType>>::Aggregate>,
852 {
853 between(self, low, high)
854 }
855
856 #[allow(clippy::type_complexity)]
866 fn not_between<L, H>(
867 self,
868 low: L,
869 high: H,
870 ) -> SQLExpr<
871 'a,
872 V,
873 <V::DialectMarker as DialectTypes>::Bool,
874 NonNull,
875 <<Self::Aggregate as AggOr<
876 <L as ComparisonOperand<'a, V, Self::SQLType>>::Aggregate,
877 >>::Output as AggOr<
878 <H as ComparisonOperand<'a, V, Self::SQLType>>::Aggregate,
879 >>::Output,
880 >
881 where
882 L: ComparisonOperand<'a, V, Self::SQLType>,
883 H: ComparisonOperand<'a, V, Self::SQLType>,
884 Self::Aggregate:
885 AggOr<<L as ComparisonOperand<'a, V, Self::SQLType>>::Aggregate>,
886 <Self::Aggregate as AggOr<
887 <L as ComparisonOperand<'a, V, Self::SQLType>>::Aggregate,
888 >>::Output:
889 AggOr<<H as ComparisonOperand<'a, V, Self::SQLType>>::Aggregate>,
890 {
891 not_between(self, low, high)
892 }
893
894 fn in_array<I, R>(
905 self,
906 values: I,
907 ) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, Self::Aggregate>
908 where
909 I: IntoIterator<Item = R>,
910 R: Expr<'a, V>,
911 Self::SQLType: Compatible<R::SQLType>,
912 {
913 crate::expr::in_array(self, values)
914 }
915
916 fn not_in_array<I, R>(
927 self,
928 values: I,
929 ) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, Self::Aggregate>
930 where
931 I: IntoIterator<Item = R>,
932 R: Expr<'a, V>,
933 Self::SQLType: Compatible<R::SQLType>,
934 {
935 crate::expr::not_in_array(self, values)
936 }
937
938 fn in_subquery<S>(
940 self,
941 subquery: S,
942 ) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, Self::Aggregate>
943 where
944 S: Expr<'a, V>,
945 Self::SQLType: Compatible<S::SQLType>,
946 {
947 crate::expr::in_subquery(self, subquery)
948 }
949
950 fn not_in_subquery<S>(
952 self,
953 subquery: S,
954 ) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, Self::Aggregate>
955 where
956 S: Expr<'a, V>,
957 Self::SQLType: Compatible<S::SQLType>,
958 {
959 crate::expr::not_in_subquery(self, subquery)
960 }
961
962 #[allow(clippy::type_complexity, clippy::wrong_self_convention)]
971 fn is_distinct_from<R>(
972 self,
973 other: R,
974 ) -> SQLExpr<
975 'a,
976 V,
977 <V::DialectMarker as DialectTypes>::Bool,
978 NonNull,
979 <Self::Aggregate as AggOr<
980 <R as ComparisonOperand<'a, V, Self::SQLType>>::Aggregate,
981 >>::Output,
982 >
983 where
984 R: ComparisonOperand<'a, V, Self::SQLType>,
985 Self::Aggregate:
986 AggOr<<R as ComparisonOperand<'a, V, Self::SQLType>>::Aggregate>,
987 {
988 is_distinct_from(self, other)
989 }
990
991 #[allow(clippy::type_complexity, clippy::wrong_self_convention)]
1000 fn is_not_distinct_from<R>(
1001 self,
1002 other: R,
1003 ) -> SQLExpr<
1004 'a,
1005 V,
1006 <V::DialectMarker as DialectTypes>::Bool,
1007 NonNull,
1008 <Self::Aggregate as AggOr<
1009 <R as ComparisonOperand<'a, V, Self::SQLType>>::Aggregate,
1010 >>::Output,
1011 >
1012 where
1013 R: ComparisonOperand<'a, V, Self::SQLType>,
1014 Self::Aggregate:
1015 AggOr<<R as ComparisonOperand<'a, V, Self::SQLType>>::Aggregate>,
1016 {
1017 is_not_distinct_from(self, other)
1018 }
1019
1020 #[allow(clippy::wrong_self_convention)]
1029 fn is_true(
1030 self,
1031 ) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, Self::Aggregate> {
1032 is_true(self)
1033 }
1034
1035 #[allow(clippy::wrong_self_convention)]
1044 fn is_false(
1045 self,
1046 ) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, Self::Aggregate> {
1047 is_false(self)
1048 }
1049}
1050
1051impl<'a, V: SQLParam, E: Expr<'a, V>> ExprExt<'a, V> for E {}