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::FieldMetadata;
21use crate::Expr;
22use datafusion_common::ScalarValue;
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>(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
48/// Create a literal timestamp expression
49pub fn lit_timestamp_nano<T: TimestampLiteral>(n: T) -> Expr {
50    n.lit_timestamp_nano()
51}
52
53/// Trait for converting a type to a [`Literal`] literal expression.
54pub trait Literal {
55    /// convert the value to a Literal expression
56    fn lit(&self) -> Expr;
57}
58
59/// Trait for converting a type to a literal timestamp
60pub 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)); // 10 is an implicit i32
214        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}