1use 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}