Coverage Report

Created: 2024-10-13 08:39

/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
}