## Coverage Report

#### Created: 2025-11-22 06:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)

    /Users/andrewlamb/Software/datafusion/datafusion/expr/src/operation.rs

    Line
    Count
    Source
    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
    //! This module contains implementations of operations (unary, binary etc.) for DataFusion expressions.
    19
    20
    use crate::expr::{Exists, Expr, InList, InSubquery, Like};
    21
    use crate::expr_fn::binary_expr;
    22
    use datafusion_expr_common::operator::Operator;
    23
    use std::ops::{self, Not};
    24
    25
    /// Support `<expr> + <expr>` fluent style
    26
    impl ops::Add for Expr {
    27
        type Output = Self;
    28
    29
    0
        fn add(self, rhs: Self) -> Self {
    30
    0
            binary_expr(self, Operator::Plus, rhs)
    31
    0
        }
    32
    }
    33
    34
    /// Support `<expr> - <expr>` fluent style
    35
    impl ops::Sub for Expr {
    36
        type Output = Self;
    37
    38
    0
        fn sub(self, rhs: Self) -> Self {
    39
    0
            binary_expr(self, Operator::Minus, rhs)
    40
    0
        }
    41
    }
    42
    43
    /// Support `<expr> * <expr>` fluent style
    44
    impl ops::Mul for Expr {
    45
        type Output = Self;
    46
    47
    0
        fn mul(self, rhs: Self) -> Self {
    48
    0
            binary_expr(self, Operator::Multiply, rhs)
    49
    0
        }
    50
    }
    51
    52
    /// Support `<expr> / <expr>` fluent style
    53
    impl ops::Div for Expr {
    54
        type Output = Self;
    55
    56
    0
        fn div(self, rhs: Self) -> Self {
    57
    0
            binary_expr(self, Operator::Divide, rhs)
    58
    0
        }
    59
    }
    60
    61
    /// Support `<expr> % <expr>` fluent style
    62
    impl ops::Rem for Expr {
    63
        type Output = Self;
    64
    65
    0
        fn rem(self, rhs: Self) -> Self {
    66
    0
            binary_expr(self, Operator::Modulo, rhs)
    67
    0
        }
    68
    }
    69
    70
    /// Support `<expr> & <expr>` fluent style
    71
    impl ops::BitAnd for Expr {
    72
        type Output = Self;
    73
    74
    0
        fn bitand(self, rhs: Self) -> Self {
    75
    0
            binary_expr(self, Operator::BitwiseAnd, rhs)
    76
    0
        }
    77
    }
    78
    79
    /// Support `<expr> | <expr>` fluent style
    80
    impl ops::BitOr for Expr {
    81
        type Output = Self;
    82
    83
    0
        fn bitor(self, rhs: Self) -> Self {
    84
    0
            binary_expr(self, Operator::BitwiseOr, rhs)
    85
    0
        }
    86
    }
    87
    88
    /// Support `<expr> ^ <expr>` fluent style
    89
    impl ops::BitXor for Expr {
    90
        type Output = Self;
    91
    92
    0
        fn bitxor(self, rhs: Self) -> Self {
    93
    0
            binary_expr(self, Operator::BitwiseXor, rhs)
    94
    0
        }
    95
    }
    96
    97
    /// Support `<expr> << <expr>` fluent style
    98
    impl ops::Shl for Expr {
    99
        type Output = Self;
    100
    101
    0
        fn shl(self, rhs: Self) -> Self::Output {
    102
    0
            binary_expr(self, Operator::BitwiseShiftLeft, rhs)
    103
    0
        }
    104
    }
    105
    106
    /// Support `<expr> >> <expr>` fluent style
    107
    impl ops::Shr for Expr {
    108
        type Output = Self;
    109
    110
    0
        fn shr(self, rhs: Self) -> Self::Output {
    111
    0
            binary_expr(self, Operator::BitwiseShiftRight, rhs)
    112
    0
        }
    113
    }
    114
    115
    /// Support `- <expr>` fluent style
    116
    impl ops::Neg for Expr {
    117
        type Output = Self;
    118
    119
    0
        fn neg(self) -> Self::Output {
    120
    0
            Expr::Negative(Box::new(self))
    121
    0
        }
    122
    }
    123
    124
    /// Support `NOT <expr>` fluent style
    125
    impl Not for Expr {
    126
        type Output = Self;
    127
    128
    0
        fn not(self) -> Self::Output {
    129
    0
            match self {
    130
                Expr::Like(Like {
    131
    0
                    negated,
    132
    0
                    expr,
    133
    0
                    pattern,
    134
    0
                    escape_char,
    135
    0
                    case_insensitive,
    136
    0
                }) => Expr::Like(Like::new(
    137
    0
                    !negated,
    138
    0
                    expr,
    139
    0
                    pattern,
    140
    0
                    escape_char,
    141
    0
                    case_insensitive,
    142
    0
                )),
    143
                Expr::SimilarTo(Like {
    144
    0
                    negated,
    145
    0
                    expr,
    146
    0
                    pattern,
    147
    0
                    escape_char,
    148
    0
                    case_insensitive,
    149
    0
                }) => Expr::SimilarTo(Like::new(
    150
    0
                    !negated,
    151
    0
                    expr,
    152
    0
                    pattern,
    153
    0
                    escape_char,
    154
    0
                    case_insensitive,
    155
    0
                )),
    156
                Expr::InList(InList {
    157
    0
                    expr,
    158
    0
                    list,
    159
    0
                    negated,
    160
    0
                }) => Expr::InList(InList::new(expr, list, !negated)),
    161
    0
                Expr::Exists(Exists { subquery, negated }) => {
    162
    0
                    Expr::Exists(Exists::new(subquery, !negated))
    163
                }
    164
                Expr::InSubquery(InSubquery {
    165
    0
                    expr,
    166
    0
                    subquery,
    167
    0
                    negated,
    168
    0
                }) => Expr::InSubquery(InSubquery::new(expr, subquery, !negated)),
    169
    0
                _ => Expr::Not(Box::new(self)),
    170
            }
    171
    0
        }
    172
    }
    173
    174
    #[cfg(test)]
    175
    mod tests {
    176
        use crate::lit;
    177
    178
        #[test]
    179
        fn test_operators() {
    180
            // Add
    181
            assert_eq!(
    182
                format!("{}", lit(1u32) + lit(2u32)),
    183
                "UInt32(1) + UInt32(2)"
    184
            );
    185
            // Sub
    186
            assert_eq!(
    187
                format!("{}", lit(1u32) - lit(2u32)),
    188
                "UInt32(1) - UInt32(2)"
    189
            );
    190
            // Mul
    191
            assert_eq!(
    192
                format!("{}", lit(1u32) * lit(2u32)),
    193
                "UInt32(1) * UInt32(2)"
    194
            );
    195
            // Div
    196
            assert_eq!(
    197
                format!("{}", lit(1u32) / lit(2u32)),
    198
                "UInt32(1) / UInt32(2)"
    199
            );
    200
            // Rem
    201
            assert_eq!(
    202
                format!("{}", lit(1u32) % lit(2u32)),
    203
                "UInt32(1) % UInt32(2)"
    204
            );
    205
            // BitAnd
    206
            assert_eq!(
    207
                format!("{}", lit(1u32) & lit(2u32)),
    208
                "UInt32(1) & UInt32(2)"
    209
            );
    210
            // BitOr
    211
            assert_eq!(
    212
                format!("{}", lit(1u32) | lit(2u32)),
    213
                "UInt32(1) | UInt32(2)"
    214
            );
    215
            // BitXor
    216
            assert_eq!(
    217
                format!("{}", lit(1u32) ^ lit(2u32)),
    218
                "UInt32(1) BIT_XOR UInt32(2)"
    219
            );
    220
            // Shl
    221
            assert_eq!(
    222
                format!("{}", lit(1u32) << lit(2u32)),
    223
                "UInt32(1) << UInt32(2)"
    224
            );
    225
            // Shr
    226
            assert_eq!(
    227
                format!("{}", lit(1u32) >> lit(2u32)),
    228
                "UInt32(1) >> UInt32(2)"
    229
            );
    230
            // Neg
    231
            assert_eq!(format!("{}", -lit(1u32)), "(- UInt32(1))");
    232
            // Not
    233
            assert_eq!(format!("{}", !lit(1u32)), "NOT UInt32(1)");
    234
        }
    235
    }