1use core::ops::{Add, Div, Mul, Neg, Rem, Sub};
7
8use crate::sql::{SQL, Token};
9use crate::traits::{SQLParam, ToSQL};
10use crate::types::{ArithmeticOutput, Numeric};
11
12use super::{AggregateKind, Expr, NullOr, Nullability, SQLExpr, Scalar};
13
14impl<'a, V, T, N, A, Rhs> Add<Rhs> for SQLExpr<'a, V, T, N, A>
19where
20 V: SQLParam + 'a,
21 T: ArithmeticOutput<Rhs::SQLType>,
22 N: Nullability + NullOr<Rhs::Nullable>,
23 A: AggregateKind,
24 Rhs: Expr<'a, V>,
25 Rhs::SQLType: Numeric,
26 Rhs::Nullable: Nullability,
27{
28 type Output = SQLExpr<'a, V, T::Output, <N as NullOr<Rhs::Nullable>>::Output, Scalar>;
29
30 fn add(self, rhs: Rhs) -> Self::Output {
31 SQLExpr::new(self.to_sql().push(Token::PLUS).append(rhs.to_sql()))
32 }
33}
34
35impl<'a, V, T, N, A, Rhs> Sub<Rhs> for SQLExpr<'a, V, T, N, A>
40where
41 V: SQLParam + 'a,
42 T: ArithmeticOutput<Rhs::SQLType>,
43 N: Nullability + NullOr<Rhs::Nullable>,
44 A: AggregateKind,
45 Rhs: Expr<'a, V>,
46 Rhs::SQLType: Numeric,
47 Rhs::Nullable: Nullability,
48{
49 type Output = SQLExpr<'a, V, T::Output, <N as NullOr<Rhs::Nullable>>::Output, Scalar>;
50
51 fn sub(self, rhs: Rhs) -> Self::Output {
52 SQLExpr::new(self.to_sql().push(Token::MINUS).append(rhs.to_sql()))
53 }
54}
55
56impl<'a, V, T, N, A, Rhs> Mul<Rhs> for SQLExpr<'a, V, T, N, A>
61where
62 V: SQLParam + 'a,
63 T: ArithmeticOutput<Rhs::SQLType>,
64 N: Nullability + NullOr<Rhs::Nullable>,
65 A: AggregateKind,
66 Rhs: Expr<'a, V>,
67 Rhs::SQLType: Numeric,
68 Rhs::Nullable: Nullability,
69{
70 type Output = SQLExpr<'a, V, T::Output, <N as NullOr<Rhs::Nullable>>::Output, Scalar>;
71
72 fn mul(self, rhs: Rhs) -> Self::Output {
73 SQLExpr::new(self.to_sql().push(Token::STAR).append(rhs.to_sql()))
74 }
75}
76
77impl<'a, V, T, N, A, Rhs> Div<Rhs> for SQLExpr<'a, V, T, N, A>
82where
83 V: SQLParam + 'a,
84 T: ArithmeticOutput<Rhs::SQLType>,
85 N: Nullability + NullOr<Rhs::Nullable>,
86 A: AggregateKind,
87 Rhs: Expr<'a, V>,
88 Rhs::SQLType: Numeric,
89 Rhs::Nullable: Nullability,
90{
91 type Output = SQLExpr<'a, V, T::Output, <N as NullOr<Rhs::Nullable>>::Output, Scalar>;
92
93 fn div(self, rhs: Rhs) -> Self::Output {
94 SQLExpr::new(self.to_sql().push(Token::SLASH).append(rhs.to_sql()))
95 }
96}
97
98impl<'a, V, T, N, A, Rhs> Rem<Rhs> for SQLExpr<'a, V, T, N, A>
103where
104 V: SQLParam + 'a,
105 T: ArithmeticOutput<Rhs::SQLType>,
106 N: Nullability + NullOr<Rhs::Nullable>,
107 A: AggregateKind,
108 Rhs: Expr<'a, V>,
109 Rhs::SQLType: Numeric,
110 Rhs::Nullable: Nullability,
111{
112 type Output = SQLExpr<'a, V, T::Output, <N as NullOr<Rhs::Nullable>>::Output, Scalar>;
113
114 fn rem(self, rhs: Rhs) -> Self::Output {
115 SQLExpr::new(self.to_sql().push(Token::REM).append(rhs.to_sql()))
116 }
117}
118
119impl<'a, V, T, N, A> Neg for SQLExpr<'a, V, T, N, A>
124where
125 V: SQLParam + 'a,
126 T: Numeric,
127 N: Nullability,
128 A: AggregateKind,
129{
130 type Output = SQLExpr<'a, V, T, N, Scalar>;
131
132 fn neg(self) -> Self::Output {
133 SQLExpr::new(SQL::from(Token::MINUS).append(self.to_sql().parens()))
134 }
135}