1use crate::dialect::{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)]
497pub fn is_distinct_from<'a, V, L, R>(
498 left: L,
499 right: R,
500) -> SQLExpr<
501 'a,
502 V,
503 <V::DialectMarker as DialectTypes>::Bool,
504 NonNull,
505 <L::Aggregate as AggOr<<R as ComparisonOperand<'a, V, L>>::Aggregate>>::Output,
506>
507where
508 V: SQLParam + 'a,
509 L: Expr<'a, V>,
510 R: ComparisonOperand<'a, V, L>,
511 L::SQLType: Compatible<<R as ComparisonOperand<'a, V, L>>::SQLType>,
512 L::Aggregate: AggOr<<R as ComparisonOperand<'a, V, L>>::Aggregate>,
513{
514 let left = operand_sql(left);
515 let right = ComparisonOperand::into_comparison_sql(right);
516 let sql = match V::DIALECT {
517 Dialect::MySQL => SQL::from(Token::NOT)
518 .push(Token::LPAREN)
519 .append(left)
520 .append(SQL::raw("<=>"))
521 .append(right)
522 .push(Token::RPAREN),
523 Dialect::SQLite | Dialect::PostgreSQL => left
524 .push(Token::IS)
525 .push(Token::DISTINCT)
526 .push(Token::FROM)
527 .append(right),
528 };
529 SQLExpr::new(sql)
530}
531
532#[allow(clippy::type_complexity)]
541pub fn is_not_distinct_from<'a, V, L, R>(
542 left: L,
543 right: R,
544) -> SQLExpr<
545 'a,
546 V,
547 <V::DialectMarker as DialectTypes>::Bool,
548 NonNull,
549 <L::Aggregate as AggOr<<R as ComparisonOperand<'a, V, L>>::Aggregate>>::Output,
550>
551where
552 V: SQLParam + 'a,
553 L: Expr<'a, V>,
554 R: ComparisonOperand<'a, V, L>,
555 L::SQLType: Compatible<<R as ComparisonOperand<'a, V, L>>::SQLType>,
556 L::Aggregate: AggOr<<R as ComparisonOperand<'a, V, L>>::Aggregate>,
557{
558 let left = operand_sql(left);
559 let right = ComparisonOperand::into_comparison_sql(right);
560 let sql = match V::DIALECT {
561 Dialect::MySQL => left.append(SQL::raw("<=>")).append(right),
562 Dialect::SQLite | Dialect::PostgreSQL => left
563 .push(Token::IS)
564 .push(Token::NOT)
565 .push(Token::DISTINCT)
566 .push(Token::FROM)
567 .append(right),
568 };
569 SQLExpr::new(sql)
570}
571
572pub fn is_true<'a, V, E>(
583 expr: E,
584) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, E::Aggregate>
585where
586 V: SQLParam + 'a,
587 E: Expr<'a, V>,
588{
589 SQLExpr::new(operand_sql(expr).push(Token::IS).append(SQL::raw("TRUE")))
590}
591
592pub fn is_false<'a, V, E>(
599 expr: E,
600) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, E::Aggregate>
601where
602 V: SQLParam + 'a,
603 E: Expr<'a, V>,
604{
605 SQLExpr::new(operand_sql(expr).push(Token::IS).append(SQL::raw("FALSE")))
606}
607
608pub trait ExprExt<'a, V: SQLParam>: Expr<'a, V> + Sized {
628 #[allow(clippy::type_complexity)]
636 fn eq<R>(
637 self,
638 other: R,
639 ) -> SQLExpr<
640 'a,
641 V,
642 <V::DialectMarker as DialectTypes>::Bool,
643 NonNull,
644 <Self::Aggregate as AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>>::Output,
645 >
646 where
647 R: ComparisonOperand<'a, V, Self>,
648 Self::SQLType: Compatible<<R as ComparisonOperand<'a, V, Self>>::SQLType>,
649 Self::Aggregate: AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>,
650 {
651 eq(self, other)
652 }
653
654 #[allow(clippy::type_complexity)]
662 fn ne<R>(
663 self,
664 other: R,
665 ) -> SQLExpr<
666 'a,
667 V,
668 <V::DialectMarker as DialectTypes>::Bool,
669 NonNull,
670 <Self::Aggregate as AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>>::Output,
671 >
672 where
673 R: ComparisonOperand<'a, V, Self>,
674 Self::SQLType: Compatible<<R as ComparisonOperand<'a, V, Self>>::SQLType>,
675 Self::Aggregate: AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>,
676 {
677 ne(self, other)
678 }
679
680 #[allow(clippy::type_complexity)]
688 fn gt<R>(
689 self,
690 other: R,
691 ) -> SQLExpr<
692 'a,
693 V,
694 <V::DialectMarker as DialectTypes>::Bool,
695 NonNull,
696 <Self::Aggregate as AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>>::Output,
697 >
698 where
699 R: ComparisonOperand<'a, V, Self>,
700 Self::SQLType: Compatible<<R as ComparisonOperand<'a, V, Self>>::SQLType>,
701 Self::Aggregate: AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>,
702 {
703 gt(self, other)
704 }
705
706 #[allow(clippy::type_complexity)]
714 fn ge<R>(
715 self,
716 other: R,
717 ) -> SQLExpr<
718 'a,
719 V,
720 <V::DialectMarker as DialectTypes>::Bool,
721 NonNull,
722 <Self::Aggregate as AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>>::Output,
723 >
724 where
725 R: ComparisonOperand<'a, V, Self>,
726 Self::SQLType: Compatible<<R as ComparisonOperand<'a, V, Self>>::SQLType>,
727 Self::Aggregate: AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>,
728 {
729 gte(self, other)
730 }
731
732 #[allow(clippy::type_complexity)]
740 fn lt<R>(
741 self,
742 other: R,
743 ) -> SQLExpr<
744 'a,
745 V,
746 <V::DialectMarker as DialectTypes>::Bool,
747 NonNull,
748 <Self::Aggregate as AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>>::Output,
749 >
750 where
751 R: ComparisonOperand<'a, V, Self>,
752 Self::SQLType: Compatible<<R as ComparisonOperand<'a, V, Self>>::SQLType>,
753 Self::Aggregate: AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>,
754 {
755 lt(self, other)
756 }
757
758 #[allow(clippy::type_complexity)]
766 fn le<R>(
767 self,
768 other: R,
769 ) -> SQLExpr<
770 'a,
771 V,
772 <V::DialectMarker as DialectTypes>::Bool,
773 NonNull,
774 <Self::Aggregate as AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>>::Output,
775 >
776 where
777 R: ComparisonOperand<'a, V, Self>,
778 Self::SQLType: Compatible<<R as ComparisonOperand<'a, V, Self>>::SQLType>,
779 Self::Aggregate: AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>,
780 {
781 lte(self, other)
782 }
783
784 #[allow(clippy::type_complexity)]
792 fn like<R>(
793 self,
794 pattern: R,
795 ) -> SQLExpr<
796 'a,
797 V,
798 <V::DialectMarker as DialectTypes>::Bool,
799 NonNull,
800 <Self::Aggregate as AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>>::Output,
801 >
802 where
803 R: ComparisonOperand<'a, V, Self>,
804 Self::SQLType: Compatible<<R as ComparisonOperand<'a, V, Self>>::SQLType>,
805 Self::SQLType: Textual,
806 <R as ComparisonOperand<'a, V, Self>>::SQLType: Textual,
807 Self::Aggregate: AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>,
808 {
809 like(self, pattern)
810 }
811
812 #[allow(clippy::type_complexity)]
820 fn not_like<R>(
821 self,
822 pattern: R,
823 ) -> SQLExpr<
824 'a,
825 V,
826 <V::DialectMarker as DialectTypes>::Bool,
827 NonNull,
828 <Self::Aggregate as AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>>::Output,
829 >
830 where
831 R: ComparisonOperand<'a, V, Self>,
832 Self::SQLType: Compatible<<R as ComparisonOperand<'a, V, Self>>::SQLType>,
833 Self::SQLType: Textual,
834 <R as ComparisonOperand<'a, V, Self>>::SQLType: Textual,
835 Self::Aggregate: AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>,
836 {
837 not_like(self, pattern)
838 }
839
840 #[allow(clippy::wrong_self_convention)]
848 fn is_null(
849 self,
850 ) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, Self::Aggregate> {
851 is_null(self)
852 }
853
854 #[allow(clippy::wrong_self_convention)]
862 fn is_not_null(
863 self,
864 ) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, Self::Aggregate> {
865 is_not_null(self)
866 }
867
868 #[allow(clippy::type_complexity)]
878 fn between<L, H>(
879 self,
880 low: L,
881 high: H,
882 ) -> SQLExpr<
883 'a,
884 V,
885 <V::DialectMarker as DialectTypes>::Bool,
886 NonNull,
887 <<Self::Aggregate as AggOr<
888 <L as ComparisonOperand<'a, V, Self>>::Aggregate,
889 >>::Output as AggOr<
890 <H as ComparisonOperand<'a, V, Self>>::Aggregate,
891 >>::Output,
892 >
893 where
894 L: ComparisonOperand<'a, V, Self>,
895 H: ComparisonOperand<'a, V, Self>,
896 Self::SQLType: Compatible<<L as ComparisonOperand<'a, V, Self>>::SQLType>,
897 Self::SQLType: Compatible<<H as ComparisonOperand<'a, V, Self>>::SQLType>,
898 Self::Aggregate:
899 AggOr<<L as ComparisonOperand<'a, V, Self>>::Aggregate>,
900 <Self::Aggregate as AggOr<
901 <L as ComparisonOperand<'a, V, Self>>::Aggregate,
902 >>::Output:
903 AggOr<<H as ComparisonOperand<'a, V, Self>>::Aggregate>,
904{
905 between(self, low, high)
906 }
907
908 #[allow(clippy::type_complexity)]
918 fn not_between<L, H>(
919 self,
920 low: L,
921 high: H,
922 ) -> SQLExpr<
923 'a,
924 V,
925 <V::DialectMarker as DialectTypes>::Bool,
926 NonNull,
927 <<Self::Aggregate as AggOr<
928 <L as ComparisonOperand<'a, V, Self>>::Aggregate,
929 >>::Output as AggOr<
930 <H as ComparisonOperand<'a, V, Self>>::Aggregate,
931 >>::Output,
932 >
933 where
934 L: ComparisonOperand<'a, V, Self>,
935 H: ComparisonOperand<'a, V, Self>,
936 Self::SQLType: Compatible<<L as ComparisonOperand<'a, V, Self>>::SQLType>,
937 Self::SQLType: Compatible<<H as ComparisonOperand<'a, V, Self>>::SQLType>,
938 Self::Aggregate:
939 AggOr<<L as ComparisonOperand<'a, V, Self>>::Aggregate>,
940 <Self::Aggregate as AggOr<
941 <L as ComparisonOperand<'a, V, Self>>::Aggregate,
942 >>::Output:
943 AggOr<<H as ComparisonOperand<'a, V, Self>>::Aggregate>,
944{
945 not_between(self, low, high)
946 }
947
948 fn in_array<I, R>(
959 self,
960 values: I,
961 ) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, Self::Aggregate>
962 where
963 I: IntoIterator<Item = R>,
964 R: Expr<'a, V>,
965 Self::SQLType: Compatible<R::SQLType>,
966 {
967 crate::expr::in_array(self, values)
968 }
969
970 fn not_in_array<I, R>(
981 self,
982 values: I,
983 ) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, Self::Aggregate>
984 where
985 I: IntoIterator<Item = R>,
986 R: Expr<'a, V>,
987 Self::SQLType: Compatible<R::SQLType>,
988 {
989 crate::expr::not_in_array(self, values)
990 }
991
992 fn in_subquery<S>(
994 self,
995 subquery: S,
996 ) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, Self::Aggregate>
997 where
998 S: Expr<'a, V>,
999 Self::SQLType: Compatible<S::SQLType> + Compatible<Self::SQLType>,
1000 {
1001 crate::expr::in_subquery(self, subquery)
1002 }
1003
1004 fn not_in_subquery<S>(
1006 self,
1007 subquery: S,
1008 ) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, Self::Aggregate>
1009 where
1010 S: Expr<'a, V>,
1011 Self::SQLType: Compatible<S::SQLType> + Compatible<Self::SQLType>,
1012 {
1013 crate::expr::not_in_subquery(self, subquery)
1014 }
1015
1016 #[allow(clippy::type_complexity, clippy::wrong_self_convention)]
1025 fn is_distinct_from<R>(
1026 self,
1027 other: R,
1028 ) -> SQLExpr<
1029 'a,
1030 V,
1031 <V::DialectMarker as DialectTypes>::Bool,
1032 NonNull,
1033 <Self::Aggregate as AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>>::Output,
1034 >
1035 where
1036 R: ComparisonOperand<'a, V, Self>,
1037 Self::SQLType: Compatible<<R as ComparisonOperand<'a, V, Self>>::SQLType>,
1038 Self::Aggregate: AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>,
1039 {
1040 is_distinct_from(self, other)
1041 }
1042
1043 #[allow(clippy::type_complexity, clippy::wrong_self_convention)]
1052 fn is_not_distinct_from<R>(
1053 self,
1054 other: R,
1055 ) -> SQLExpr<
1056 'a,
1057 V,
1058 <V::DialectMarker as DialectTypes>::Bool,
1059 NonNull,
1060 <Self::Aggregate as AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>>::Output,
1061 >
1062 where
1063 R: ComparisonOperand<'a, V, Self>,
1064 Self::SQLType: Compatible<<R as ComparisonOperand<'a, V, Self>>::SQLType>,
1065 Self::Aggregate: AggOr<<R as ComparisonOperand<'a, V, Self>>::Aggregate>,
1066 {
1067 is_not_distinct_from(self, other)
1068 }
1069
1070 #[allow(clippy::wrong_self_convention)]
1079 fn is_true(
1080 self,
1081 ) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, Self::Aggregate> {
1082 is_true(self)
1083 }
1084
1085 #[allow(clippy::wrong_self_convention)]
1094 fn is_false(
1095 self,
1096 ) -> SQLExpr<'a, V, <V::DialectMarker as DialectTypes>::Bool, NonNull, Self::Aggregate> {
1097 is_false(self)
1098 }
1099}
1100
1101impl<'a, V: SQLParam, E: Expr<'a, V>> ExprExt<'a, V> for E {}