/Users/andrewlamb/Software/datafusion/datafusion/expr/src/literal.rs
Line | Count | Source (jump to first uncovered line) |
1 | | // Licensed to the Apache Software Foundation (ASF) under one |
2 | | // or more contributor license agreements. See the NOTICE file |
3 | | // distributed with this work for additional information |
4 | | // regarding copyright ownership. The ASF licenses this file |
5 | | // to you under the Apache License, Version 2.0 (the |
6 | | // "License"); you may not use this file except in compliance |
7 | | // with the License. You may obtain a copy of the License at |
8 | | // |
9 | | // http://www.apache.org/licenses/LICENSE-2.0 |
10 | | // |
11 | | // Unless required by applicable law or agreed to in writing, |
12 | | // software distributed under the License is distributed on an |
13 | | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14 | | // KIND, either express or implied. See the License for the |
15 | | // specific language governing permissions and limitations |
16 | | // under the License. |
17 | | |
18 | | //! Literal module contains foundational types that are used to represent literals in DataFusion. |
19 | | |
20 | | use crate::Expr; |
21 | | use datafusion_common::ScalarValue; |
22 | | |
23 | | /// Create a literal expression |
24 | 0 | pub fn lit<T: Literal>(n: T) -> Expr { |
25 | 0 | n.lit() |
26 | 0 | } |
27 | | |
28 | | /// Create a literal timestamp expression |
29 | 0 | pub fn lit_timestamp_nano<T: TimestampLiteral>(n: T) -> Expr { |
30 | 0 | n.lit_timestamp_nano() |
31 | 0 | } |
32 | | |
33 | | /// Trait for converting a type to a [`Literal`] literal expression. |
34 | | pub trait Literal { |
35 | | /// convert the value to a Literal expression |
36 | | fn lit(&self) -> Expr; |
37 | | } |
38 | | |
39 | | /// Trait for converting a type to a literal timestamp |
40 | | pub trait TimestampLiteral { |
41 | | fn lit_timestamp_nano(&self) -> Expr; |
42 | | } |
43 | | |
44 | | impl Literal for &str { |
45 | 0 | fn lit(&self) -> Expr { |
46 | 0 | Expr::Literal(ScalarValue::from(*self)) |
47 | 0 | } |
48 | | } |
49 | | |
50 | | impl Literal for String { |
51 | 0 | fn lit(&self) -> Expr { |
52 | 0 | Expr::Literal(ScalarValue::from(self.as_ref())) |
53 | 0 | } |
54 | | } |
55 | | |
56 | | impl Literal for &String { |
57 | 0 | fn lit(&self) -> Expr { |
58 | 0 | Expr::Literal(ScalarValue::from(self.as_ref())) |
59 | 0 | } |
60 | | } |
61 | | |
62 | | impl Literal for Vec<u8> { |
63 | 0 | fn lit(&self) -> Expr { |
64 | 0 | Expr::Literal(ScalarValue::Binary(Some((*self).to_owned()))) |
65 | 0 | } |
66 | | } |
67 | | |
68 | | impl Literal for &[u8] { |
69 | 0 | fn lit(&self) -> Expr { |
70 | 0 | Expr::Literal(ScalarValue::Binary(Some((*self).to_owned()))) |
71 | 0 | } |
72 | | } |
73 | | |
74 | | impl Literal for ScalarValue { |
75 | 69 | fn lit(&self) -> Expr { |
76 | 69 | Expr::Literal(self.clone()) |
77 | 69 | } |
78 | | } |
79 | | |
80 | | macro_rules! make_literal { |
81 | | ($TYPE:ty, $SCALAR:ident, $DOC: expr) => { |
82 | | #[doc = $DOC] |
83 | | impl Literal for $TYPE { |
84 | 18 | fn lit(&self) -> Expr { |
85 | 18 | Expr::Literal(ScalarValue::$SCALAR(Some(self.clone()))) |
86 | 18 | } |
87 | | } |
88 | | }; |
89 | | } |
90 | | |
91 | | macro_rules! make_nonzero_literal { |
92 | | ($TYPE:ty, $SCALAR:ident, $DOC: expr) => { |
93 | | #[doc = $DOC] |
94 | | impl Literal for $TYPE { |
95 | 0 | fn lit(&self) -> Expr { |
96 | 0 | Expr::Literal(ScalarValue::$SCALAR(Some(self.get()))) |
97 | 0 | } |
98 | | } |
99 | | }; |
100 | | } |
101 | | |
102 | | macro_rules! make_timestamp_literal { |
103 | | ($TYPE:ty, $SCALAR:ident, $DOC: expr) => { |
104 | | #[doc = $DOC] |
105 | | impl TimestampLiteral for $TYPE { |
106 | 0 | fn lit_timestamp_nano(&self) -> Expr { |
107 | 0 | Expr::Literal(ScalarValue::TimestampNanosecond( |
108 | 0 | Some((self.clone()).into()), |
109 | 0 | None, |
110 | 0 | )) |
111 | 0 | } |
112 | | } |
113 | | }; |
114 | | } |
115 | | |
116 | | make_literal!(bool, Boolean, "literal expression containing a bool"); |
117 | | make_literal!(f32, Float32, "literal expression containing an f32"); |
118 | | make_literal!(f64, Float64, "literal expression containing an f64"); |
119 | | make_literal!(i8, Int8, "literal expression containing an i8"); |
120 | | make_literal!(i16, Int16, "literal expression containing an i16"); |
121 | | make_literal!(i32, Int32, "literal expression containing an i32"); |
122 | | make_literal!(i64, Int64, "literal expression containing an i64"); |
123 | | make_literal!(u8, UInt8, "literal expression containing a u8"); |
124 | | make_literal!(u16, UInt16, "literal expression containing a u16"); |
125 | | make_literal!(u32, UInt32, "literal expression containing a u32"); |
126 | | make_literal!(u64, UInt64, "literal expression containing a u64"); |
127 | | |
128 | | make_nonzero_literal!( |
129 | | std::num::NonZeroI8, |
130 | | Int8, |
131 | | "literal expression containing an i8" |
132 | | ); |
133 | | make_nonzero_literal!( |
134 | | std::num::NonZeroI16, |
135 | | Int16, |
136 | | "literal expression containing an i16" |
137 | | ); |
138 | | make_nonzero_literal!( |
139 | | std::num::NonZeroI32, |
140 | | Int32, |
141 | | "literal expression containing an i32" |
142 | | ); |
143 | | make_nonzero_literal!( |
144 | | std::num::NonZeroI64, |
145 | | Int64, |
146 | | "literal expression containing an i64" |
147 | | ); |
148 | | make_nonzero_literal!( |
149 | | std::num::NonZeroU8, |
150 | | UInt8, |
151 | | "literal expression containing a u8" |
152 | | ); |
153 | | make_nonzero_literal!( |
154 | | std::num::NonZeroU16, |
155 | | UInt16, |
156 | | "literal expression containing a u16" |
157 | | ); |
158 | | make_nonzero_literal!( |
159 | | std::num::NonZeroU32, |
160 | | UInt32, |
161 | | "literal expression containing a u32" |
162 | | ); |
163 | | make_nonzero_literal!( |
164 | | std::num::NonZeroU64, |
165 | | UInt64, |
166 | | "literal expression containing a u64" |
167 | | ); |
168 | | |
169 | | make_timestamp_literal!(i8, Int8, "literal expression containing an i8"); |
170 | | make_timestamp_literal!(i16, Int16, "literal expression containing an i16"); |
171 | | make_timestamp_literal!(i32, Int32, "literal expression containing an i32"); |
172 | | make_timestamp_literal!(i64, Int64, "literal expression containing an i64"); |
173 | | make_timestamp_literal!(u8, UInt8, "literal expression containing a u8"); |
174 | | make_timestamp_literal!(u16, UInt16, "literal expression containing a u16"); |
175 | | make_timestamp_literal!(u32, UInt32, "literal expression containing a u32"); |
176 | | |
177 | | #[cfg(test)] |
178 | | mod test { |
179 | | use std::num::NonZeroU32; |
180 | | |
181 | | use super::*; |
182 | | use crate::expr_fn::col; |
183 | | |
184 | | #[test] |
185 | | fn test_lit_nonzero() { |
186 | | let expr = col("id").eq(lit(NonZeroU32::new(1).unwrap())); |
187 | | let expected = col("id").eq(lit(ScalarValue::UInt32(Some(1)))); |
188 | | assert_eq!(expr, expected); |
189 | | } |
190 | | |
191 | | #[test] |
192 | | fn test_lit_timestamp_nano() { |
193 | | let expr = col("time").eq(lit_timestamp_nano(10)); // 10 is an implicit i32 |
194 | | let expected = |
195 | | col("time").eq(lit(ScalarValue::TimestampNanosecond(Some(10), None))); |
196 | | assert_eq!(expr, expected); |
197 | | |
198 | | let i: i64 = 10; |
199 | | let expr = col("time").eq(lit_timestamp_nano(i)); |
200 | | assert_eq!(expr, expected); |
201 | | |
202 | | let i: u32 = 10; |
203 | | let expr = col("time").eq(lit_timestamp_nano(i)); |
204 | | assert_eq!(expr, expected); |
205 | | } |
206 | | } |