1 use expression::{Expression, NonAggregate};
2 use pg::Pg;
3 use query_builder::*;
4 use result::QueryResult;
5 use sql_types::{Date, Timestamp, Timestamptz, VarChar};
6 
7 /// Marker trait for types which are valid in `AT TIME ZONE` expressions
8 pub trait DateTimeLike {}
9 impl DateTimeLike for Date {}
10 impl DateTimeLike for Timestamp {}
11 impl DateTimeLike for Timestamptz {}
12 
13 #[derive(Debug, Copy, Clone, QueryId)]
14 pub struct AtTimeZone<Ts, Tz> {
15     timestamp: Ts,
16     timezone: Tz,
17 }
18 
19 impl<Ts, Tz> AtTimeZone<Ts, Tz> {
new(timestamp: Ts, timezone: Tz) -> Self20     pub fn new(timestamp: Ts, timezone: Tz) -> Self {
21         AtTimeZone {
22             timestamp: timestamp,
23             timezone: timezone,
24         }
25     }
26 }
27 
28 impl<Ts, Tz> Expression for AtTimeZone<Ts, Tz>
29 where
30     Ts: Expression,
31     Ts::SqlType: DateTimeLike,
32     Tz: Expression<SqlType = VarChar>,
33 {
34     type SqlType = Timestamp;
35 }
36 
37 impl<Ts, Tz> NonAggregate for AtTimeZone<Ts, Tz> where AtTimeZone<Ts, Tz>: Expression {}
38 
39 impl<Ts, Tz> QueryFragment<Pg> for AtTimeZone<Ts, Tz>
40 where
41     Ts: QueryFragment<Pg>,
42     Tz: QueryFragment<Pg>,
43 {
walk_ast(&self, mut out: AstPass<Pg>) -> QueryResult<()>44     fn walk_ast(&self, mut out: AstPass<Pg>) -> QueryResult<()> {
45         self.timestamp.walk_ast(out.reborrow())?;
46         out.push_sql(" AT TIME ZONE ");
47         self.timezone.walk_ast(out.reborrow())?;
48         Ok(())
49     }
50 }
51 
52 impl_selectable_expression!(AtTimeZone<Ts, Tz>);
53