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