use core::ops::{Add, Div, Mul, Neg, Rem, Sub};
use crate::sql::{SQL, Token};
use crate::traits::SQLParam;
use crate::types::{ArithmeticOutput, Numeric};
use super::{AggregateKind, Expr, NullOr, Nullability, SQLExpr, Scalar};
impl<'a, V, T, N, A, Rhs> Add<Rhs> for SQLExpr<'a, V, T, N, A>
where
V: SQLParam + 'a,
T: ArithmeticOutput<Rhs::SQLType>,
N: Nullability + NullOr<Rhs::Nullable>,
A: AggregateKind,
Rhs: Expr<'a, V>,
Rhs::SQLType: Numeric,
Rhs::Nullable: Nullability,
{
type Output = SQLExpr<'a, V, T::Output, <N as NullOr<Rhs::Nullable>>::Output, Scalar>;
fn add(self, rhs: Rhs) -> Self::Output {
SQLExpr::new(self.into_sql().push(Token::PLUS).append(rhs.into_sql()))
}
}
impl<'a, V, T, N, A, Rhs> Sub<Rhs> for SQLExpr<'a, V, T, N, A>
where
V: SQLParam + 'a,
T: ArithmeticOutput<Rhs::SQLType>,
N: Nullability + NullOr<Rhs::Nullable>,
A: AggregateKind,
Rhs: Expr<'a, V>,
Rhs::SQLType: Numeric,
Rhs::Nullable: Nullability,
{
type Output = SQLExpr<'a, V, T::Output, <N as NullOr<Rhs::Nullable>>::Output, Scalar>;
fn sub(self, rhs: Rhs) -> Self::Output {
SQLExpr::new(self.into_sql().push(Token::MINUS).append(rhs.into_sql()))
}
}
impl<'a, V, T, N, A, Rhs> Mul<Rhs> for SQLExpr<'a, V, T, N, A>
where
V: SQLParam + 'a,
T: ArithmeticOutput<Rhs::SQLType>,
N: Nullability + NullOr<Rhs::Nullable>,
A: AggregateKind,
Rhs: Expr<'a, V>,
Rhs::SQLType: Numeric,
Rhs::Nullable: Nullability,
{
type Output = SQLExpr<'a, V, T::Output, <N as NullOr<Rhs::Nullable>>::Output, Scalar>;
fn mul(self, rhs: Rhs) -> Self::Output {
SQLExpr::new(self.into_sql().push(Token::STAR).append(rhs.into_sql()))
}
}
impl<'a, V, T, N, A, Rhs> Div<Rhs> for SQLExpr<'a, V, T, N, A>
where
V: SQLParam + 'a,
T: ArithmeticOutput<Rhs::SQLType>,
N: Nullability + NullOr<Rhs::Nullable>,
A: AggregateKind,
Rhs: Expr<'a, V>,
Rhs::SQLType: Numeric,
Rhs::Nullable: Nullability,
{
type Output = SQLExpr<'a, V, T::Output, <N as NullOr<Rhs::Nullable>>::Output, Scalar>;
fn div(self, rhs: Rhs) -> Self::Output {
SQLExpr::new(self.into_sql().push(Token::SLASH).append(rhs.into_sql()))
}
}
impl<'a, V, T, N, A, Rhs> Rem<Rhs> for SQLExpr<'a, V, T, N, A>
where
V: SQLParam + 'a,
T: ArithmeticOutput<Rhs::SQLType>,
N: Nullability + NullOr<Rhs::Nullable>,
A: AggregateKind,
Rhs: Expr<'a, V>,
Rhs::SQLType: Numeric,
Rhs::Nullable: Nullability,
{
type Output = SQLExpr<'a, V, T::Output, <N as NullOr<Rhs::Nullable>>::Output, Scalar>;
fn rem(self, rhs: Rhs) -> Self::Output {
SQLExpr::new(self.into_sql().push(Token::REM).append(rhs.into_sql()))
}
}
impl<'a, V, T, N, A> Neg for SQLExpr<'a, V, T, N, A>
where
V: SQLParam + 'a,
T: Numeric,
N: Nullability,
A: AggregateKind,
{
type Output = SQLExpr<'a, V, T, N, Scalar>;
fn neg(self) -> Self::Output {
SQLExpr::new(SQL::from(Token::MINUS).append(self.into_sql().parens()))
}
}