Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
literal.rs - source
[go: Go Back, main page]

datafusion_expr/
literal.rs

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