use core::marker::PhantomData;
use crate::{
BigInt, Date, Time, Timestamp,
expression::{Binary, Expression, op},
instr::TemporalKind,
lower::LowerCtx,
};
pub struct DateExtract<E> {
inner: E,
}
pub struct TimeExtract<E> {
inner: E,
}
pub struct YearExtract<E, S> {
inner: E,
marker: PhantomData<S>,
}
pub struct MonthExtract<E, S> {
inner: E,
marker: PhantomData<S>,
}
pub struct DayExtract<E, S> {
inner: E,
marker: PhantomData<S>,
}
pub struct TimestampSource;
pub struct DateSource;
pub trait TimestampExt: Sized + Expression<Type = Timestamp> {
fn date(self) -> DateExtract<Self> {
DateExtract { inner: self }
}
fn time(self) -> TimeExtract<Self> {
TimeExtract { inner: self }
}
fn year(self) -> YearExtract<Self, TimestampSource> {
YearExtract {
inner: self,
marker: PhantomData,
}
}
fn month(self) -> MonthExtract<Self, TimestampSource> {
MonthExtract {
inner: self,
marker: PhantomData,
}
}
fn day(self) -> DayExtract<Self, TimestampSource> {
DayExtract {
inner: self,
marker: PhantomData,
}
}
}
impl<E> TimestampExt for E where E: Expression<Type = Timestamp> {}
pub trait TimestampRelativeExt: Sized + Expression<Type = Timestamp> {
fn past(self) -> Binary<op::Lt, Self, crate::expression::Now> {
Binary {
left: self,
right: crate::expression::now(),
op: PhantomData,
}
}
fn future(self) -> Binary<op::Gt, Self, crate::expression::Now> {
Binary {
left: self,
right: crate::expression::now(),
op: PhantomData,
}
}
fn today(self) -> Binary<op::Eq, DateExtract<Self>, crate::expression::CurrentDate> {
Binary {
left: self.date(),
right: crate::expression::current_date(),
op: PhantomData,
}
}
fn before_today(self) -> Binary<op::Lt, DateExtract<Self>, crate::expression::CurrentDate> {
Binary {
left: self.date(),
right: crate::expression::current_date(),
op: PhantomData,
}
}
fn after_today(self) -> Binary<op::Gt, DateExtract<Self>, crate::expression::CurrentDate> {
Binary {
left: self.date(),
right: crate::expression::current_date(),
op: PhantomData,
}
}
}
impl<E> TimestampRelativeExt for E where E: Expression<Type = Timestamp> {}
pub trait DateExt: Sized + Expression<Type = Date> {
fn year(self) -> YearExtract<Self, DateSource> {
YearExtract {
inner: self,
marker: PhantomData,
}
}
fn month(self) -> MonthExtract<Self, DateSource> {
MonthExtract {
inner: self,
marker: PhantomData,
}
}
fn day(self) -> DayExtract<Self, DateSource> {
DayExtract {
inner: self,
marker: PhantomData,
}
}
}
impl<E> DateExt for E where E: Expression<Type = Date> {}
pub trait DateRelativeExt: Sized + Expression<Type = Date> {
fn past(self) -> Binary<op::Lt, Self, crate::expression::CurrentDate> {
Binary {
left: self,
right: crate::expression::current_date(),
op: PhantomData,
}
}
fn future(self) -> Binary<op::Gt, Self, crate::expression::CurrentDate> {
Binary {
left: self,
right: crate::expression::current_date(),
op: PhantomData,
}
}
fn today(self) -> Binary<op::Eq, Self, crate::expression::CurrentDate> {
Binary {
left: self,
right: crate::expression::current_date(),
op: PhantomData,
}
}
fn before_today(self) -> Binary<op::Lt, Self, crate::expression::CurrentDate> {
Binary {
left: self,
right: crate::expression::current_date(),
op: PhantomData,
}
}
fn after_today(self) -> Binary<op::Gt, Self, crate::expression::CurrentDate> {
Binary {
left: self,
right: crate::expression::current_date(),
op: PhantomData,
}
}
}
impl<E> DateRelativeExt for E where E: Expression<Type = Date> {}
#[qraft_expression_macro::as_expression]
impl<E> Expression for DateExtract<E>
where
E: Expression<Type = Timestamp>,
{
type Type = Date;
fn lower(&self, ctx: &mut LowerCtx) -> usize {
let inner = self.inner.lower(ctx);
ctx.lower_temporal(inner, TemporalKind::Date)
}
}
#[qraft_expression_macro::as_expression]
impl<E> Expression for TimeExtract<E>
where
E: Expression<Type = Timestamp>,
{
type Type = Time;
fn lower(&self, ctx: &mut LowerCtx) -> usize {
let inner = self.inner.lower(ctx);
ctx.lower_temporal(inner, TemporalKind::Time)
}
}
#[qraft_expression_macro::as_expression]
impl<E> Expression for YearExtract<E, TimestampSource>
where
E: Expression<Type = Timestamp>,
{
type Type = BigInt;
fn lower(&self, ctx: &mut LowerCtx) -> usize {
let inner = self.inner.lower(ctx);
ctx.lower_temporal(inner, TemporalKind::Year)
}
}
#[qraft_expression_macro::as_expression]
impl<E> Expression for MonthExtract<E, TimestampSource>
where
E: Expression<Type = Timestamp>,
{
type Type = BigInt;
fn lower(&self, ctx: &mut LowerCtx) -> usize {
let inner = self.inner.lower(ctx);
ctx.lower_temporal(inner, TemporalKind::Month)
}
}
#[qraft_expression_macro::as_expression]
impl<E> Expression for DayExtract<E, TimestampSource>
where
E: Expression<Type = Timestamp>,
{
type Type = BigInt;
fn lower(&self, ctx: &mut LowerCtx) -> usize {
let inner = self.inner.lower(ctx);
ctx.lower_temporal(inner, TemporalKind::Day)
}
}
#[qraft_expression_macro::as_expression]
impl<E> Expression for YearExtract<E, DateSource>
where
E: Expression<Type = Date>,
{
type Type = BigInt;
fn lower(&self, ctx: &mut LowerCtx) -> usize {
let inner = self.inner.lower(ctx);
ctx.lower_temporal(inner, TemporalKind::Year)
}
}
#[qraft_expression_macro::as_expression]
impl<E> Expression for MonthExtract<E, DateSource>
where
E: Expression<Type = Date>,
{
type Type = BigInt;
fn lower(&self, ctx: &mut LowerCtx) -> usize {
let inner = self.inner.lower(ctx);
ctx.lower_temporal(inner, TemporalKind::Month)
}
}
#[qraft_expression_macro::as_expression]
impl<E> Expression for DayExtract<E, DateSource>
where
E: Expression<Type = Date>,
{
type Type = BigInt;
fn lower(&self, ctx: &mut LowerCtx) -> usize {
let inner = self.inner.lower(ctx);
ctx.lower_temporal(inner, TemporalKind::Day)
}
}