datafusion_expr/
literal.rs1use crate::expr::FieldMetadata;
21use crate::Expr;
22use datafusion_common::ScalarValue;
23
24pub fn lit<T: Literal>(n: T) -> Expr {
26 n.lit()
27}
28
29pub fn lit_with_metadata<T: Literal>(n: T, metadata: Option<FieldMetadata>) -> Expr {
30 let Some(metadata) = metadata else {
31 return n.lit();
32 };
33
34 let Expr::Literal(sv, prior_metadata) = n.lit() else {
35 unreachable!();
36 };
37 let new_metadata = match prior_metadata {
38 Some(mut prior) => {
39 prior.extend(metadata);
40 prior
41 }
42 None => metadata,
43 };
44
45 Expr::Literal(sv, Some(new_metadata))
46}
47
48pub fn lit_timestamp_nano<T: TimestampLiteral>(n: T) -> Expr {
50 n.lit_timestamp_nano()
51}
52
53pub trait Literal {
55 fn lit(&self) -> Expr;
57}
58
59pub trait TimestampLiteral {
61 fn lit_timestamp_nano(&self) -> Expr;
62}
63
64impl Literal for &str {
65 fn lit(&self) -> Expr {
66 Expr::Literal(ScalarValue::from(*self), None)
67 }
68}
69
70impl Literal for String {
71 fn lit(&self) -> Expr {
72 Expr::Literal(ScalarValue::from(self.as_ref()), None)
73 }
74}
75
76impl Literal for &String {
77 fn lit(&self) -> Expr {
78 Expr::Literal(ScalarValue::from(self.as_ref()), None)
79 }
80}
81
82impl Literal for Vec<u8> {
83 fn lit(&self) -> Expr {
84 Expr::Literal(ScalarValue::Binary(Some((*self).to_owned())), None)
85 }
86}
87
88impl Literal for &[u8] {
89 fn lit(&self) -> Expr {
90 Expr::Literal(ScalarValue::Binary(Some((*self).to_owned())), None)
91 }
92}
93
94impl Literal for ScalarValue {
95 fn lit(&self) -> Expr {
96 Expr::Literal(self.clone(), None)
97 }
98}
99
100macro_rules! make_literal {
101 ($TYPE:ty, $SCALAR:ident, $DOC: expr) => {
102 #[doc = $DOC]
103 impl Literal for $TYPE {
104 fn lit(&self) -> Expr {
105 Expr::Literal(ScalarValue::$SCALAR(Some(self.clone())), None)
106 }
107 }
108 };
109}
110
111macro_rules! make_nonzero_literal {
112 ($TYPE:ty, $SCALAR:ident, $DOC: expr) => {
113 #[doc = $DOC]
114 impl Literal for $TYPE {
115 fn lit(&self) -> Expr {
116 Expr::Literal(ScalarValue::$SCALAR(Some(self.get())), None)
117 }
118 }
119 };
120}
121
122macro_rules! make_timestamp_literal {
123 ($TYPE:ty, $SCALAR:ident, $DOC: expr) => {
124 #[doc = $DOC]
125 impl TimestampLiteral for $TYPE {
126 fn lit_timestamp_nano(&self) -> Expr {
127 Expr::Literal(
128 ScalarValue::TimestampNanosecond(Some((self.clone()).into()), None),
129 None,
130 )
131 }
132 }
133 };
134}
135
136make_literal!(bool, Boolean, "literal expression containing a bool");
137make_literal!(f32, Float32, "literal expression containing an f32");
138make_literal!(f64, Float64, "literal expression containing an f64");
139make_literal!(i8, Int8, "literal expression containing an i8");
140make_literal!(i16, Int16, "literal expression containing an i16");
141make_literal!(i32, Int32, "literal expression containing an i32");
142make_literal!(i64, Int64, "literal expression containing an i64");
143make_literal!(u8, UInt8, "literal expression containing a u8");
144make_literal!(u16, UInt16, "literal expression containing a u16");
145make_literal!(u32, UInt32, "literal expression containing a u32");
146make_literal!(u64, UInt64, "literal expression containing a u64");
147
148make_nonzero_literal!(
149 std::num::NonZeroI8,
150 Int8,
151 "literal expression containing an i8"
152);
153make_nonzero_literal!(
154 std::num::NonZeroI16,
155 Int16,
156 "literal expression containing an i16"
157);
158make_nonzero_literal!(
159 std::num::NonZeroI32,
160 Int32,
161 "literal expression containing an i32"
162);
163make_nonzero_literal!(
164 std::num::NonZeroI64,
165 Int64,
166 "literal expression containing an i64"
167);
168make_nonzero_literal!(
169 std::num::NonZeroU8,
170 UInt8,
171 "literal expression containing a u8"
172);
173make_nonzero_literal!(
174 std::num::NonZeroU16,
175 UInt16,
176 "literal expression containing a u16"
177);
178make_nonzero_literal!(
179 std::num::NonZeroU32,
180 UInt32,
181 "literal expression containing a u32"
182);
183make_nonzero_literal!(
184 std::num::NonZeroU64,
185 UInt64,
186 "literal expression containing a u64"
187);
188
189make_timestamp_literal!(i8, Int8, "literal expression containing an i8");
190make_timestamp_literal!(i16, Int16, "literal expression containing an i16");
191make_timestamp_literal!(i32, Int32, "literal expression containing an i32");
192make_timestamp_literal!(i64, Int64, "literal expression containing an i64");
193make_timestamp_literal!(u8, UInt8, "literal expression containing a u8");
194make_timestamp_literal!(u16, UInt16, "literal expression containing a u16");
195make_timestamp_literal!(u32, UInt32, "literal expression containing a u32");
196
197#[cfg(test)]
198mod test {
199 use std::num::NonZeroU32;
200
201 use super::*;
202 use crate::expr_fn::col;
203
204 #[test]
205 fn test_lit_nonzero() {
206 let expr = col("id").eq(lit(NonZeroU32::new(1).unwrap()));
207 let expected = col("id").eq(lit(ScalarValue::UInt32(Some(1))));
208 assert_eq!(expr, expected);
209 }
210
211 #[test]
212 fn test_lit_timestamp_nano() {
213 let expr = col("time").eq(lit_timestamp_nano(10)); let expected =
215 col("time").eq(lit(ScalarValue::TimestampNanosecond(Some(10), None)));
216 assert_eq!(expr, expected);
217
218 let i: i64 = 10;
219 let expr = col("time").eq(lit_timestamp_nano(i));
220 assert_eq!(expr, expected);
221
222 let i: u32 = 10;
223 let expr = col("time").eq(lit_timestamp_nano(i));
224 assert_eq!(expr, expected);
225 }
226}