Skip to main content

qraft_core/expression/
temporal.rs

1//! Temporal extraction expressions for date and time filtering.
2
3use core::marker::PhantomData;
4
5use crate::{
6    BigInt, Date, Time, Timestamp,
7    expression::{Binary, Expression, op},
8    instr::TemporalKind,
9    lower::LowerCtx,
10};
11
12pub struct DateExtract<E> {
13    inner: E,
14}
15
16pub struct TimeExtract<E> {
17    inner: E,
18}
19
20pub struct YearExtract<E, S> {
21    inner: E,
22    marker: PhantomData<S>,
23}
24
25pub struct MonthExtract<E, S> {
26    inner: E,
27    marker: PhantomData<S>,
28}
29
30pub struct DayExtract<E, S> {
31    inner: E,
32    marker: PhantomData<S>,
33}
34
35pub struct TimestampSource;
36pub struct DateSource;
37
38pub trait TimestampExt: Sized + Expression<Type = Timestamp> {
39    fn date(self) -> DateExtract<Self> {
40        DateExtract { inner: self }
41    }
42
43    fn time(self) -> TimeExtract<Self> {
44        TimeExtract { inner: self }
45    }
46
47    fn year(self) -> YearExtract<Self, TimestampSource> {
48        YearExtract {
49            inner: self,
50            marker: PhantomData,
51        }
52    }
53
54    fn month(self) -> MonthExtract<Self, TimestampSource> {
55        MonthExtract {
56            inner: self,
57            marker: PhantomData,
58        }
59    }
60
61    fn day(self) -> DayExtract<Self, TimestampSource> {
62        DayExtract {
63            inner: self,
64            marker: PhantomData,
65        }
66    }
67}
68
69impl<E> TimestampExt for E where E: Expression<Type = Timestamp> {}
70
71pub trait TimestampRelativeExt: Sized + Expression<Type = Timestamp> {
72    fn past(self) -> Binary<op::Lt, Self, crate::expression::Now> {
73        Binary {
74            left: self,
75            right: crate::expression::now(),
76            op: PhantomData,
77        }
78    }
79
80    fn future(self) -> Binary<op::Gt, Self, crate::expression::Now> {
81        Binary {
82            left: self,
83            right: crate::expression::now(),
84            op: PhantomData,
85        }
86    }
87
88    fn today(self) -> Binary<op::Eq, DateExtract<Self>, crate::expression::CurrentDate> {
89        Binary {
90            left: self.date(),
91            right: crate::expression::current_date(),
92            op: PhantomData,
93        }
94    }
95
96    fn before_today(self) -> Binary<op::Lt, DateExtract<Self>, crate::expression::CurrentDate> {
97        Binary {
98            left: self.date(),
99            right: crate::expression::current_date(),
100            op: PhantomData,
101        }
102    }
103
104    fn after_today(self) -> Binary<op::Gt, DateExtract<Self>, crate::expression::CurrentDate> {
105        Binary {
106            left: self.date(),
107            right: crate::expression::current_date(),
108            op: PhantomData,
109        }
110    }
111}
112
113impl<E> TimestampRelativeExt for E where E: Expression<Type = Timestamp> {}
114
115pub trait DateExt: Sized + Expression<Type = Date> {
116    fn year(self) -> YearExtract<Self, DateSource> {
117        YearExtract {
118            inner: self,
119            marker: PhantomData,
120        }
121    }
122
123    fn month(self) -> MonthExtract<Self, DateSource> {
124        MonthExtract {
125            inner: self,
126            marker: PhantomData,
127        }
128    }
129
130    fn day(self) -> DayExtract<Self, DateSource> {
131        DayExtract {
132            inner: self,
133            marker: PhantomData,
134        }
135    }
136}
137
138impl<E> DateExt for E where E: Expression<Type = Date> {}
139
140pub trait DateRelativeExt: Sized + Expression<Type = Date> {
141    fn past(self) -> Binary<op::Lt, Self, crate::expression::CurrentDate> {
142        Binary {
143            left: self,
144            right: crate::expression::current_date(),
145            op: PhantomData,
146        }
147    }
148
149    fn future(self) -> Binary<op::Gt, Self, crate::expression::CurrentDate> {
150        Binary {
151            left: self,
152            right: crate::expression::current_date(),
153            op: PhantomData,
154        }
155    }
156
157    fn today(self) -> Binary<op::Eq, Self, crate::expression::CurrentDate> {
158        Binary {
159            left: self,
160            right: crate::expression::current_date(),
161            op: PhantomData,
162        }
163    }
164
165    fn before_today(self) -> Binary<op::Lt, Self, crate::expression::CurrentDate> {
166        Binary {
167            left: self,
168            right: crate::expression::current_date(),
169            op: PhantomData,
170        }
171    }
172
173    fn after_today(self) -> Binary<op::Gt, Self, crate::expression::CurrentDate> {
174        Binary {
175            left: self,
176            right: crate::expression::current_date(),
177            op: PhantomData,
178        }
179    }
180}
181
182impl<E> DateRelativeExt for E where E: Expression<Type = Date> {}
183
184#[qraft_expression_macro::as_expression]
185impl<E> Expression for DateExtract<E>
186where
187    E: Expression<Type = Timestamp>,
188{
189    type Type = Date;
190
191    fn lower(&self, ctx: &mut LowerCtx) -> usize {
192        let inner = self.inner.lower(ctx);
193        ctx.lower_temporal(inner, TemporalKind::Date)
194    }
195}
196
197#[qraft_expression_macro::as_expression]
198impl<E> Expression for TimeExtract<E>
199where
200    E: Expression<Type = Timestamp>,
201{
202    type Type = Time;
203
204    fn lower(&self, ctx: &mut LowerCtx) -> usize {
205        let inner = self.inner.lower(ctx);
206        ctx.lower_temporal(inner, TemporalKind::Time)
207    }
208}
209
210#[qraft_expression_macro::as_expression]
211impl<E> Expression for YearExtract<E, TimestampSource>
212where
213    E: Expression<Type = Timestamp>,
214{
215    type Type = BigInt;
216
217    fn lower(&self, ctx: &mut LowerCtx) -> usize {
218        let inner = self.inner.lower(ctx);
219        ctx.lower_temporal(inner, TemporalKind::Year)
220    }
221}
222
223#[qraft_expression_macro::as_expression]
224impl<E> Expression for MonthExtract<E, TimestampSource>
225where
226    E: Expression<Type = Timestamp>,
227{
228    type Type = BigInt;
229
230    fn lower(&self, ctx: &mut LowerCtx) -> usize {
231        let inner = self.inner.lower(ctx);
232        ctx.lower_temporal(inner, TemporalKind::Month)
233    }
234}
235
236#[qraft_expression_macro::as_expression]
237impl<E> Expression for DayExtract<E, TimestampSource>
238where
239    E: Expression<Type = Timestamp>,
240{
241    type Type = BigInt;
242
243    fn lower(&self, ctx: &mut LowerCtx) -> usize {
244        let inner = self.inner.lower(ctx);
245        ctx.lower_temporal(inner, TemporalKind::Day)
246    }
247}
248
249#[qraft_expression_macro::as_expression]
250impl<E> Expression for YearExtract<E, DateSource>
251where
252    E: Expression<Type = Date>,
253{
254    type Type = BigInt;
255
256    fn lower(&self, ctx: &mut LowerCtx) -> usize {
257        let inner = self.inner.lower(ctx);
258        ctx.lower_temporal(inner, TemporalKind::Year)
259    }
260}
261
262#[qraft_expression_macro::as_expression]
263impl<E> Expression for MonthExtract<E, DateSource>
264where
265    E: Expression<Type = Date>,
266{
267    type Type = BigInt;
268
269    fn lower(&self, ctx: &mut LowerCtx) -> usize {
270        let inner = self.inner.lower(ctx);
271        ctx.lower_temporal(inner, TemporalKind::Month)
272    }
273}
274
275#[qraft_expression_macro::as_expression]
276impl<E> Expression for DayExtract<E, DateSource>
277where
278    E: Expression<Type = Date>,
279{
280    type Type = BigInt;
281
282    fn lower(&self, ctx: &mut LowerCtx) -> usize {
283        let inner = self.inner.lower(ctx);
284        ctx.lower_temporal(inner, TemporalKind::Day)
285    }
286}