1#[macro_export]
2#[doc(hidden)]
3macro_rules! __diesel_operator_body {
4 (
5 notation = $notation:ident,
6 struct_name = $name:ident,
7 operator = $operator:expr,
8 return_ty = (ReturnBasedOnArgs),
9 ty_params = ($($ty_param:ident,)+),
10 field_names = $field_names:tt,
11 backend_ty_params = $backend_ty_params:tt,
12 backend_ty = $backend_ty:ty,
13 ) => {
14 $crate::__diesel_operator_body! {
15 notation = $notation,
16 struct_name = $name,
17 operator = $operator,
18 return_ty = (ST),
19 ty_params = ($($ty_param,)+),
20 field_names = $field_names,
21 backend_ty_params = $backend_ty_params,
22 backend_ty = $backend_ty,
23 expression_ty_params = (ST,),
24 expression_bounds = ($($ty_param: $crate::expression::Expression<SqlType = ST>,)+),
25 }
26 };
27
28 (
29 notation = $notation:ident,
30 struct_name = $name:ident,
31 operator = $operator:expr,
32 return_ty = ($($return_ty:tt)+),
33 ty_params = ($($ty_param:ident,)+),
34 field_names = $field_names:tt,
35 backend_ty_params = $backend_ty_params:tt,
36 backend_ty = $backend_ty:ty,
37 ) => {
38 $crate::__diesel_operator_body! {
39 notation = $notation,
40 struct_name = $name,
41 operator = $operator,
42 return_ty = ($($return_ty)*),
43 ty_params = ($($ty_param,)+),
44 field_names = $field_names,
45 backend_ty_params = $backend_ty_params,
46 backend_ty = $backend_ty,
47 expression_ty_params = (),
48 expression_bounds = ($($ty_param: $crate::expression::Expression,)+),
49 }
50 };
51
52 (
53 notation = $notation:ident,
54 struct_name = $name:ident,
55 operator = $operator:expr,
56 return_ty = ($($return_ty:tt)+),
57 ty_params = ($($ty_param:ident,)+),
58 field_names = ($($field_name:ident,)+),
59 backend_ty_params = ($($backend_ty_param:ident,)*),
60 backend_ty = $backend_ty:ty,
61 expression_ty_params = ($($expression_ty_params:ident,)*),
62 expression_bounds = ($($expression_bounds:tt)*),
63 ) => {
64 #[derive(
65 Debug,
66 Clone,
67 Copy,
68 $crate::query_builder::QueryId,
69 $crate::sql_types::DieselNumericOps,
70 $crate::expression::ValidGrouping
71 )]
72 #[doc(hidden)]
73 pub struct $name<$($ty_param,)+> {
74 $(pub(crate) $field_name: $ty_param,)+
75 }
76
77 impl<$($ty_param,)+> $name<$($ty_param,)+> {
78 pub(crate) fn new($($field_name: $ty_param,)+) -> Self {
79 $name { $($field_name,)+ }
80 }
81 }
82
83 $crate::impl_selectable_expression!($name<$($ty_param),+>);
84
85 impl<$($ty_param,)+ $($expression_ty_params,)*> $crate::expression::Expression for $name<$($ty_param,)+> where
86 $($expression_bounds)*
87 {
88 type SqlType = $($return_ty)*;
89 }
90
91 impl<$($ty_param,)+ $($backend_ty_param,)*> $crate::query_builder::QueryFragment<$backend_ty>
92 for $name<$($ty_param,)+> where
93 $($ty_param: $crate::query_builder::QueryFragment<$backend_ty>,)+
94 $($backend_ty_param: $crate::backend::Backend,)*
95 {
96 fn walk_ast<'b>(
97 &'b self,
98 mut out: $crate::query_builder::AstPass<'_, 'b, $backend_ty>
99 ) -> $crate::result::QueryResult<()>
100 {
101 $crate::__diesel_operator_to_sql!(
102 notation = $notation,
103 operator_expr = out.push_sql($operator),
104 field_exprs = ($(self.$field_name.walk_ast(out.reborrow())?),+),
105 );
106 Ok(())
107 }
108 }
109
110 impl<S, $($ty_param,)+> $crate::internal::operators_macro::FieldAliasMapper<S> for $name<$($ty_param,)+>
111 where
112 S: $crate::query_source::AliasSource,
113 $($ty_param: $crate::internal::operators_macro::FieldAliasMapper<S>,)+
114 {
115 type Out = $name<
116 $(<$ty_param as $crate::internal::operators_macro::FieldAliasMapper<S>>::Out,)+
117 >;
118 fn map(self, alias: &$crate::query_source::Alias<S>) -> Self::Out {
119 $name {
120 $($field_name: self.$field_name.map(alias),)+
121 }
122 }
123 }
124 }
125}
126
127#[macro_export]
128#[doc(hidden)]
129macro_rules! __diesel_operator_to_sql {
130 (
131 notation = infix,
132 operator_expr = $op:expr,
133 field_exprs = ($left:expr, $right:expr),
134 ) => {
135 $left;
136 $op;
137 $right;
138 };
139
140 (
141 notation = postfix,
142 operator_expr = $op:expr,
143 field_exprs = ($expr:expr),
144 ) => {
145 $expr;
146 $op;
147 };
148
149 (
150 notation = prefix,
151 operator_expr = $op:expr,
152 field_exprs = ($expr:expr),
153 ) => {
154 $op;
155 $expr;
156 };
157}
158
159#[macro_export]
234macro_rules! infix_operator {
235 ($name:ident, $operator:expr) => {
236 $crate::infix_operator!($name, $operator, $crate::sql_types::Bool);
237 };
238
239 ($name:ident, $operator:expr, backend: $backend:ty) => {
240 $crate::infix_operator!($name, $operator, $crate::sql_types::Bool, backend: $backend);
241 };
242
243 ($name:ident, $operator:expr, $($return_ty:tt)::*) => {
244 $crate::__diesel_infix_operator!(
245 name = $name,
246 operator = $operator,
247 return_ty = NullableBasedOnArgs ($($return_ty)::*),
248 backend_ty_params = (DB,),
249 backend_ty = DB,
250 );
251 };
252
253 ($name:ident, $operator:expr, $($return_ty:tt)::*, backend: $backend:ty) => {
254 $crate::__diesel_infix_operator!(
255 name = $name,
256 operator = $operator,
257 return_ty = NullableBasedOnArgs ($($return_ty)::*),
258 backend_ty_params = (),
259 backend_ty = $backend,
260 );
261 };
262
263}
264#[macro_export]
265#[doc(hidden)]
266macro_rules! __diesel_infix_operator {
267 ($name:ident, $operator:expr, ConstantNullability $($return_ty:tt)::*) => {
268 $crate::__diesel_infix_operator!(
269 name = $name,
270 operator = $operator,
271 return_ty = ($($return_ty)::*),
272 backend_ty_params = (DB,),
273 backend_ty = DB,
274 );
275 };
276 ($name:ident, $operator:expr, __diesel_internal_SameResultAsInput, backend: $backend:ty) => {
277 $crate::__diesel_infix_operator!(
278 name = $name,
279 operator = $operator,
280 return_ty = (<T as $crate::expression::Expression>::SqlType),
281 backend_ty_params = (),
282 backend_ty = $backend,
283 );
284 };
285 ($name:ident, $operator:expr, ConstantNullability $($return_ty:tt)::*, backend: $backend:ty) => {
286 $crate::__diesel_infix_operator!(
287 name = $name,
288 operator = $operator,
289 return_ty = ($($return_ty)::*),
290 backend_ty_params = (),
291 backend_ty = $backend,
292 );
293 };
294
295 (
296 name = $name:ident,
297 operator = $operator:expr,
298 return_ty = NullableBasedOnArgs ($($return_ty:tt)+),
299 backend_ty_params = $backend_ty_params:tt,
300 backend_ty = $backend_ty:ty,
301 ) => {
302 $crate::__diesel_infix_operator!(
303 name = $name,
304 operator = $operator,
305 return_ty = (
306 $crate::sql_types::is_nullable::MaybeNullable<
307 $crate::sql_types::is_nullable::IsOneNullable<
308 <T as $crate::expression::Expression>::SqlType,
309 <U as $crate::expression::Expression>::SqlType
310 >,
311 $($return_ty)+
312 >
313 ),
314 expression_bounds = (
315 $crate::sql_types::is_nullable::IsSqlTypeNullable<
316 <T as $crate::expression::Expression>::SqlType
317 >: $crate::sql_types::OneIsNullable<
318 $crate::sql_types::is_nullable::IsSqlTypeNullable<
319 <U as $crate::expression::Expression>::SqlType
320 >
321 >,
322 $crate::sql_types::is_nullable::IsOneNullable<
323 <T as $crate::expression::Expression>::SqlType,
324 <U as $crate::expression::Expression>::SqlType
325 >: $crate::sql_types::MaybeNullableType<$($return_ty)+>,
326 ),
327 backend_ty_params = $backend_ty_params,
328 backend_ty = $backend_ty,
329 );
330 };
331
332 (
333 name = $name:ident,
334 operator = $operator:expr,
335 return_ty = ($($return_ty:tt)+),
336 backend_ty_params = $backend_ty_params:tt,
337 backend_ty = $backend_ty:ty,
338 ) => {
339 $crate::__diesel_infix_operator!(
340 name = $name,
341 operator = $operator,
342 return_ty = ($($return_ty)+),
343 expression_bounds = (),
344 backend_ty_params = $backend_ty_params,
345 backend_ty = $backend_ty,
346 );
347 };
348
349 (
350 name = $name:ident,
351 operator = $operator:expr,
352 return_ty = ($($return_ty:tt)+),
353 expression_bounds = ($($expression_bounds:tt)*),
354 backend_ty_params = $backend_ty_params:tt,
355 backend_ty = $backend_ty:ty,
356 ) => {
357 $crate::__diesel_operator_body!(
358 notation = infix,
359 struct_name = $name,
360 operator = $operator,
361 return_ty = ($($return_ty)+),
362 ty_params = (T, U,),
363 field_names = (left, right,),
364 backend_ty_params = $backend_ty_params,
365 backend_ty = $backend_ty,
366 expression_ty_params = (),
367 expression_bounds = (
368 T: $crate::expression::Expression,
369 U: $crate::expression::Expression,
370 <T as $crate::expression::Expression>::SqlType: $crate::sql_types::SqlType,
371 <U as $crate::expression::Expression>::SqlType: $crate::sql_types::SqlType,
372 $($expression_bounds)*
373 ),
374 );
375 };
376}
377
378#[macro_export]
379#[deprecated(since = "2.0.0", note = "use `diesel::infix_operator!` instead")]
380#[cfg(all(feature = "with-deprecated", not(feature = "without-deprecated")))]
381#[doc(hidden)]
382macro_rules! diesel_infix_operator {
383 ($($args:tt)*) => {
384 $crate::infix_operator!($($args)*);
385 }
386}
387
388#[macro_export]
396macro_rules! postfix_operator {
397 ($name:ident, $operator:expr) => {
398 $crate::postfix_operator!($name, $operator, $crate::sql_types::Bool);
399 };
400
401 ($name:ident, $operator:expr, backend: $backend:ty) => {
402 $crate::postfix_operator!($name, $operator, $crate::sql_types::Bool, backend: $backend);
403 };
404
405 ($name:ident, $operator:expr, $return_ty:ty) => {
406 $crate::__diesel_operator_body!(
407 notation = postfix,
408 struct_name = $name,
409 operator = $operator,
410 return_ty = ($return_ty),
411 ty_params = (Expr,),
412 field_names = (expr,),
413 backend_ty_params = (DB,),
414 backend_ty = DB,
415 );
416 };
417
418 ($name:ident, $operator:expr, $return_ty:ty, backend: $backend:ty) => {
419 $crate::__diesel_operator_body!(
420 notation = postfix,
421 struct_name = $name,
422 operator = $operator,
423 return_ty = ($return_ty),
424 ty_params = (Expr,),
425 field_names = (expr,),
426 backend_ty_params = (),
427 backend_ty = $backend,
428 );
429 };
430}
431
432#[macro_export]
433#[deprecated(since = "2.0.0", note = "use `diesel::postfix_operator!` instead")]
434#[cfg(all(feature = "with-deprecated", not(feature = "without-deprecated")))]
435#[doc(hidden)]
436macro_rules! diesel_postfix_operator {
437 ($($args:tt)*) => {
438 $crate::postfix_operator!($($args)*);
439 }
440}
441
442#[macro_export]
450macro_rules! prefix_operator {
451 ($name:ident, $operator:expr) => {
452 $crate::prefix_operator!($name, $operator, $crate::sql_types::Bool);
453 };
454
455 ($name:ident, $operator:expr, backend: $backend:ty) => {
456 $crate::prefix_operator!($name, $operator, $crate::sql_types::Bool, backend: $backend);
457 };
458
459 ($name:ident, $operator:expr, $return_ty:ty) => {
460 $crate::__diesel_operator_body!(
461 notation = prefix,
462 struct_name = $name,
463 operator = $operator,
464 return_ty = (
465 $crate::sql_types::is_nullable::MaybeNullable<
466 $crate::sql_types::is_nullable::IsSqlTypeNullable<
467 <Expr as $crate::expression::Expression>::SqlType
468 >,
469 $return_ty,
470 >
471 ),
472 ty_params = (Expr,),
473 field_names = (expr,),
474 backend_ty_params = (DB,),
475 backend_ty = DB,
476 expression_ty_params = (),
477 expression_bounds = (
478 Expr: $crate::expression::Expression,
479 <Expr as $crate::expression::Expression>::SqlType: $crate::sql_types::SqlType,
480 $crate::sql_types::is_nullable::IsSqlTypeNullable<
481 <Expr as $crate::expression::Expression>::SqlType
482 >: $crate::sql_types::MaybeNullableType<$return_ty>,
483 ),
484 );
485 };
486
487 ($name:ident, $operator:expr, $return_ty:ty, backend: $backend:ty) => {
488 $crate::__diesel_operator_body!(
489 notation = prefix,
490 struct_name = $name,
491 operator = $operator,
492 return_ty = (
493 $crate::sql_types::is_nullable::MaybeNullable<
494 $crate::sql_types::is_nullable::IsSqlTypeNullable<
495 <Expr as $crate::expression::Expression>::SqlType
496 >,
497 $return_ty,
498 >
499 ),
500 ty_params = (Expr,),
501 field_names = (expr,),
502 backend_ty_params = (),
503 backend_ty = $backend,
504 expression_ty_params = (),
505 expression_bounds = (
506 Expr: $crate::expression::Expression,
507 <Expr as $crate::expression::Expression>::SqlType: $crate::sql_types::SqlType,
508 $crate::sql_types::is_nullable::IsSqlTypeNullable<
509 <Expr as $crate::expression::Expression>::SqlType
510 >: $crate::sql_types::MaybeNullableType<$return_ty>,
511 ),
512 );
513 };
514}
515
516#[macro_export]
517#[deprecated(since = "2.0.0", note = "use `diesel::prefix_operator!` instead")]
518#[cfg(all(feature = "with-deprecated", not(feature = "without-deprecated")))]
519#[doc(hidden)]
520macro_rules! diesel_prefix_operator {
521 ($($args:tt)*) => {
522 $crate::prefix_operator!($($args)*);
523 }
524}
525
526infix_operator!(And, " AND ");
527infix_operator!(Or, " OR ");
528infix_operator!(Escape, " ESCAPE ");
529infix_operator!(Eq, " = ");
530infix_operator!(Gt, " > ");
531infix_operator!(GtEq, " >= ");
532infix_operator!(Lt, " < ");
533infix_operator!(LtEq, " <= ");
534infix_operator!(NotEq, " != ");
535infix_operator!(NotLike, " NOT LIKE ");
536infix_operator!(Between, " BETWEEN ");
537infix_operator!(NotBetween, " NOT BETWEEN ");
538
539postfix_operator!(IsNull, " IS NULL");
540postfix_operator!(IsNotNull, " IS NOT NULL");
541postfix_operator!(
542 Asc,
543 " ASC",
544 crate::expression::expression_types::NotSelectable
545);
546postfix_operator!(
547 Desc,
548 " DESC",
549 crate::expression::expression_types::NotSelectable
550);
551
552prefix_operator!(Not, " NOT ");
553
554use crate::backend::{sql_dialect, Backend, SqlDialect};
555use crate::expression::{TypedExpressionType, ValidGrouping};
556use crate::insertable::{ColumnInsertValue, Insertable};
557use crate::query_builder::{QueryFragment, QueryId, ValuesClause};
558use crate::query_source::Column;
559use crate::sql_types::{DieselNumericOps, SqlType};
560
561impl<T, U> Insertable<T::Table> for Eq<T, U>
562where
563 T: Column,
564{
565 type Values = ValuesClause<ColumnInsertValue<T, U>, T::Table>;
566
567 fn values(self) -> Self::Values {
568 ValuesClause::new(ColumnInsertValue::new(self.right))
569 }
570}
571
572impl<'a, T, Tab, U> Insertable<Tab> for &'a Eq<T, U>
573where
574 T: Copy,
575 Eq<T, &'a U>: Insertable<Tab>,
576{
577 type Values = <Eq<T, &'a U> as Insertable<Tab>>::Values;
578
579 fn values(self) -> Self::Values {
580 Eq::new(self.left, &self.right).values()
581 }
582}
583
584#[diesel_derives::__diesel_public_if(
586 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
587 public_fields(left, right)
588)]
589#[derive(Debug, Clone, Copy, QueryId, DieselNumericOps, ValidGrouping)]
590pub struct Concat<L, R> {
591 pub(crate) left: L,
593 pub(crate) right: R,
595}
596
597impl<L, R> Concat<L, R> {
598 pub(crate) fn new(left: L, right: R) -> Self {
599 Self { left, right }
600 }
601}
602
603impl<L, R, ST> crate::expression::Expression for Concat<L, R>
604where
605 L: crate::expression::Expression<SqlType = ST>,
606 R: crate::expression::Expression<SqlType = ST>,
607 ST: SqlType + TypedExpressionType,
608{
609 type SqlType = ST;
610}
611
612impl_selectable_expression!(Concat<L, R>);
613
614impl<L, R, DB> QueryFragment<DB> for Concat<L, R>
615where
616 DB: Backend,
617 Self: QueryFragment<DB, DB::ConcatClause>,
618{
619 fn walk_ast<'b>(
620 &'b self,
621 pass: crate::query_builder::AstPass<'_, 'b, DB>,
622 ) -> crate::result::QueryResult<()> {
623 <Self as QueryFragment<DB, DB::ConcatClause>>::walk_ast(self, pass)
624 }
625}
626
627impl<L, R, DB> QueryFragment<DB, sql_dialect::concat_clause::ConcatWithPipesClause> for Concat<L, R>
628where
629 L: QueryFragment<DB>,
630 R: QueryFragment<DB>,
631 DB: Backend + SqlDialect<ConcatClause = sql_dialect::concat_clause::ConcatWithPipesClause>,
632{
633 fn walk_ast<'b>(
634 &'b self,
635 mut out: crate::query_builder::AstPass<'_, 'b, DB>,
636 ) -> crate::result::QueryResult<()> {
637 out.push_sql("(");
640 self.left.walk_ast(out.reborrow())?;
641 out.push_sql(" || ");
642 self.right.walk_ast(out.reborrow())?;
643 out.push_sql(")");
644 Ok(())
645 }
646}
647
648#[derive(
650 Debug,
651 Clone,
652 Copy,
653 crate::query_builder::QueryId,
654 crate::sql_types::DieselNumericOps,
655 crate::expression::ValidGrouping,
656)]
657#[doc(hidden)]
658pub struct Like<T, U> {
659 pub(crate) left: T,
660 pub(crate) right: U,
661}
662
663impl<T, U> Like<T, U> {
664 pub(crate) fn new(left: T, right: U) -> Self {
665 Like { left, right }
666 }
667}
668
669impl<T, U, QS> crate::expression::SelectableExpression<QS> for Like<T, U>
670where
671 Like<T, U>: crate::expression::AppearsOnTable<QS>,
672 T: crate::expression::SelectableExpression<QS>,
673 U: crate::expression::SelectableExpression<QS>,
674{
675}
676
677impl<T, U, QS> crate::expression::AppearsOnTable<QS> for Like<T, U>
678where
679 Like<T, U>: crate::expression::Expression,
680 T: crate::expression::AppearsOnTable<QS>,
681 U: crate::expression::AppearsOnTable<QS>,
682{
683}
684
685impl<T, U> crate::expression::Expression for Like<T, U>
686where
687 T: crate::expression::Expression,
688 U: crate::expression::Expression,
689 <T as crate::expression::Expression>::SqlType: crate::sql_types::SqlType,
690 <U as crate::expression::Expression>::SqlType: crate::sql_types::SqlType,
691 crate::sql_types::is_nullable::IsSqlTypeNullable<<T as crate::expression::Expression>::SqlType>:
692 crate::sql_types::OneIsNullable<
693 crate::sql_types::is_nullable::IsSqlTypeNullable<
694 <U as crate::expression::Expression>::SqlType,
695 >,
696 >,
697 crate::sql_types::is_nullable::IsOneNullable<
698 <T as crate::expression::Expression>::SqlType,
699 <U as crate::expression::Expression>::SqlType,
700 >: crate::sql_types::MaybeNullableType<crate::sql_types::Bool>,
701{
702 type SqlType = crate::sql_types::is_nullable::MaybeNullable<
703 crate::sql_types::is_nullable::IsOneNullable<
704 <T as crate::expression::Expression>::SqlType,
705 <U as crate::expression::Expression>::SqlType,
706 >,
707 crate::sql_types::Bool,
708 >;
709}
710
711impl<T, U, DB> crate::query_builder::QueryFragment<DB> for Like<T, U>
712where
713 T: crate::query_builder::QueryFragment<DB> + crate::Expression,
714 U: crate::query_builder::QueryFragment<DB>,
715 DB: crate::backend::Backend,
716 DB: LikeIsAllowedForType<T::SqlType>,
717{
718 fn walk_ast<'b>(
719 &'b self,
720 mut out: crate::query_builder::AstPass<'_, 'b, DB>,
721 ) -> crate::result::QueryResult<()> {
722 (self.left.walk_ast(out.reborrow())?);
723 (out.push_sql(" LIKE "));
724 (self.right.walk_ast(out.reborrow())?);
725 Ok(())
726 }
727}
728
729impl<S, T, U> crate::internal::operators_macro::FieldAliasMapper<S> for Like<T, U>
730where
731 S: crate::query_source::AliasSource,
732 T: crate::internal::operators_macro::FieldAliasMapper<S>,
733 U: crate::internal::operators_macro::FieldAliasMapper<S>,
734{
735 type Out = Like<
736 <T as crate::internal::operators_macro::FieldAliasMapper<S>>::Out,
737 <U as crate::internal::operators_macro::FieldAliasMapper<S>>::Out,
738 >;
739 fn map(self, alias: &crate::query_source::Alias<S>) -> Self::Out {
740 Like {
741 left: self.left.map(alias),
742 right: self.right.map(alias),
743 }
744 }
745}
746
747#[diagnostic::on_unimplemented(
748 message = "Cannot use the `LIKE` operator with expressions of the type `{ST}` for the backend `{Self}`",
749 note = "Expressions of the type `diesel::sql_types::Text` and `diesel::sql_types::Nullable<Text>` are \n\
750 allowed for all backends"
751)]
752#[cfg_attr(
753 feature = "postgres_backend",
754 diagnostic::on_unimplemented(
755 note = "Expressions of the type `diesel::sql_types::Binary` and `diesel::sql_types::Nullable<Binary>` are \n\
756 allowed for the PostgreSQL backend"
757 )
758)]
759pub trait LikeIsAllowedForType<ST>: Backend {}
760
761impl<DB> LikeIsAllowedForType<crate::sql_types::Text> for DB where DB: Backend {}
762
763impl<T, DB> LikeIsAllowedForType<crate::sql_types::Nullable<T>> for DB where
764 DB: Backend + LikeIsAllowedForType<T>
765{
766}