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