## Coverage Report

#### Created: 2024-10-13 08:39

    /Users/andrewlamb/Software/datafusion/datafusion/expr-common/src/operator.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
    use std::fmt;
    19
    20
    /// Operators applied to expressions
    21
    #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Hash)]
    22
    pub enum Operator {
    23
        /// Expressions are equal
    24
        Eq,
    25
        /// Expressions are not equal
    26
        NotEq,
    27
        /// Left side is smaller than right side
    28
        Lt,
    29
        /// Left side is smaller or equal to right side
    30
        LtEq,
    31
        /// Left side is greater than right side
    32
        Gt,
    33
        /// Left side is greater or equal to right side
    34
        GtEq,
    35
        /// Addition
    36
        Plus,
    37
        /// Subtraction
    38
        Minus,
    39
        /// Multiplication operator, like `*`
    40
        Multiply,
    41
        /// Division operator, like `/`
    42
        Divide,
    43
        /// Remainder operator, like `%`
    44
        Modulo,
    45
        /// Logical AND, like `&&`
    46
        And,
    47
        /// Logical OR, like `||`
    48
        Or,
    49
        /// `IS DISTINCT FROM` (see [`distinct`])
    50
        ///
    51
        /// [`distinct`]: arrow::compute::kernels::cmp::distinct
    52
        IsDistinctFrom,
    53
        /// `IS NOT DISTINCT FROM` (see [`not_distinct`])
    54
        ///
    55
        /// [`not_distinct`]: arrow::compute::kernels::cmp::not_distinct
    56
        IsNotDistinctFrom,
    57
        /// Case sensitive regex match
    58
        RegexMatch,
    59
        /// Case insensitive regex match
    60
        RegexIMatch,
    61
        /// Case sensitive regex not match
    62
        RegexNotMatch,
    63
        /// Case insensitive regex not match
    64
        RegexNotIMatch,
    65
        /// Case sensitive pattern match
    66
        LikeMatch,
    67
        /// Case insensitive pattern match
    68
        ILikeMatch,
    69
        /// Case sensitive pattern not match
    70
        NotLikeMatch,
    71
        /// Case insensitive pattern not match
    72
        NotILikeMatch,
    73
        /// Bitwise and, like `&`
    74
        BitwiseAnd,
    75
        /// Bitwise or, like `|`
    76
        BitwiseOr,
    77
        /// Bitwise xor, such as `^` in MySQL or `#` in PostgreSQL
    78
        BitwiseXor,
    79
        /// Bitwise right, like `>>`
    80
        BitwiseShiftRight,
    81
        /// Bitwise left, like `<<`
    82
        BitwiseShiftLeft,
    83
        /// String concat
    84
        StringConcat,
    85
        /// At arrow, like `@>`
    86
        AtArrow,
    87
        /// Arrow at, like `<@`
    88
        ArrowAt,
    89
    }
    90
    91
    impl Operator {
    92
        /// If the operator can be negated, return the negated operator
    93
        /// otherwise return None
    94
    0
        pub fn negate(&self) -> Option<Operator> {
    95
    0
            match self {
    96
    0
                Operator::Eq => Some(Operator::NotEq),
    97
    0
                Operator::NotEq => Some(Operator::Eq),
    98
    0
                Operator::Lt => Some(Operator::GtEq),
    99
    0
                Operator::LtEq => Some(Operator::Gt),
    100
    0
                Operator::Gt => Some(Operator::LtEq),
    101
    0
                Operator::GtEq => Some(Operator::Lt),
    102
    0
                Operator::IsDistinctFrom => Some(Operator::IsNotDistinctFrom),
    103
    0
                Operator::IsNotDistinctFrom => Some(Operator::IsDistinctFrom),
    104
    0
                Operator::LikeMatch => Some(Operator::NotLikeMatch),
    105
    0
                Operator::ILikeMatch => Some(Operator::NotILikeMatch),
    106
    0
                Operator::NotLikeMatch => Some(Operator::LikeMatch),
    107
    0
                Operator::NotILikeMatch => Some(Operator::ILikeMatch),
    108
                Operator::Plus
    109
                | Operator::Minus
    110
                | Operator::Multiply
    111
                | Operator::Divide
    112
                | Operator::Modulo
    113
                | Operator::And
    114
                | Operator::Or
    115
                | Operator::RegexMatch
    116
                | Operator::RegexIMatch
    117
                | Operator::RegexNotMatch
    118
                | Operator::RegexNotIMatch
    119
                | Operator::BitwiseAnd
    120
                | Operator::BitwiseOr
    121
                | Operator::BitwiseXor
    122
                | Operator::BitwiseShiftRight
    123
                | Operator::BitwiseShiftLeft
    124
                | Operator::StringConcat
    125
                | Operator::AtArrow
    126
    0
                | Operator::ArrowAt => None,
    127
            }
    128
    0
        }
    129
    130
        /// Return true if the operator is a numerical operator.
    131
        ///
    132
        /// For example, 'Binary(a, +, b)' would be a numerical expression.
    133
        /// PostgresSQL concept: <https://www.postgresql.org/docs/7.0/operators2198.htm>
    134
    0
        pub fn is_numerical_operators(&self) -> bool {
    135
    0
            matches!(
    136
    0
                self,
    137
                Operator::Plus
    138
                    | Operator::Minus
    139
                    | Operator::Multiply
    140
                    | Operator::Divide
    141
                    | Operator::Modulo
    142
            )
    143
    0
        }
    144
    145
        /// Return true if the operator is a comparison operator.
    146
        ///
    147
        /// For example, 'Binary(a, >, b)' would be a comparison expression.
    148
    33.6k
        pub fn is_comparison_operator(&self) -> bool {
    149
    22.1k
            matches!(
    150
    33.6k
                self,
    151
                Operator::Eq
    152
                    | Operator::NotEq
    153
                    | Operator::Lt
    154
                    | Operator::LtEq
    155
                    | Operator::Gt
    156
                    | Operator::GtEq
    157
                    | Operator::IsDistinctFrom
    158
                    | Operator::IsNotDistinctFrom
    159
                    | Operator::RegexMatch
    160
                    | Operator::RegexIMatch
    161
                    | Operator::RegexNotMatch
    162
                    | Operator::RegexNotIMatch
    163
            )
    164
    33.6k
        }
    165
    166
        /// Return true if the operator is a logic operator.
    167
        ///
    168
        /// For example, 'Binary(Binary(a, >, b), AND, Binary(a, <, b + 3))' would
    169
        /// be a logical expression.
    170
    0
        pub fn is_logic_operator(&self) -> bool {
    171
    0
            matches!(self, Operator::And | Operator::Or)
    172
    0
        }
    173
    174
        /// Return the operator where swapping lhs and rhs wouldn't change the result.
    175
        ///
    176
        /// For example `Binary(50, >=, a)` could also be represented as `Binary(a, <=, 50)`.
    177
    0
        pub fn swap(&self) -> Option<Operator> {
    178
    0
            match self {
    179
    0
                Operator::Eq => Some(Operator::Eq),
    180
    0
                Operator::NotEq => Some(Operator::NotEq),
    181
    0
                Operator::Lt => Some(Operator::Gt),
    182
    0
                Operator::LtEq => Some(Operator::GtEq),
    183
    0
                Operator::Gt => Some(Operator::Lt),
    184
    0
                Operator::GtEq => Some(Operator::LtEq),
    185
    0
                Operator::AtArrow => Some(Operator::ArrowAt),
    186
    0
                Operator::ArrowAt => Some(Operator::AtArrow),
    187
                Operator::IsDistinctFrom
    188
                | Operator::IsNotDistinctFrom
    189
                | Operator::Plus
    190
                | Operator::Minus
    191
                | Operator::Multiply
    192
                | Operator::Divide
    193
                | Operator::Modulo
    194
                | Operator::And
    195
                | Operator::Or
    196
                | Operator::RegexMatch
    197
                | Operator::RegexIMatch
    198
                | Operator::RegexNotMatch
    199
                | Operator::RegexNotIMatch
    200
                | Operator::LikeMatch
    201
                | Operator::ILikeMatch
    202
                | Operator::NotLikeMatch
    203
                | Operator::NotILikeMatch
    204
                | Operator::BitwiseAnd
    205
                | Operator::BitwiseOr
    206
                | Operator::BitwiseXor
    207
                | Operator::BitwiseShiftRight
    208
                | Operator::BitwiseShiftLeft
    209
    0
                | Operator::StringConcat => None,
    210
            }
    211
    0
        }
    212
    213
        /// Get the operator precedence
    214
        /// use <https://www.postgresql.org/docs/7.2/sql-precedence.html> as a reference
    215
    0
        pub fn precedence(&self) -> u8 {
    216
    0
            match self {
    217
    0
                Operator::Or => 5,
    218
    0
                Operator::And => 10,
    219
    0
                Operator::Eq | Operator::NotEq | Operator::LtEq | Operator::GtEq => 15,
    220
    0
                Operator::Lt | Operator::Gt => 20,
    221
                Operator::LikeMatch
    222
                | Operator::NotLikeMatch
    223
                | Operator::ILikeMatch
    224
    0
                | Operator::NotILikeMatch => 25,
    225
                Operator::IsDistinctFrom
    226
                | Operator::IsNotDistinctFrom
    227
                | Operator::RegexMatch
    228
                | Operator::RegexNotMatch
    229
                | Operator::RegexIMatch
    230
                | Operator::RegexNotIMatch
    231
                | Operator::BitwiseAnd
    232
                | Operator::BitwiseOr
    233
                | Operator::BitwiseShiftLeft
    234
                | Operator::BitwiseShiftRight
    235
                | Operator::BitwiseXor
    236
                | Operator::StringConcat
    237
                | Operator::AtArrow
    238
    0
                | Operator::ArrowAt => 30,
    239
    0
                Operator::Plus | Operator::Minus => 40,
    240
    0
                Operator::Multiply | Operator::Divide | Operator::Modulo => 45,
    241
            }
    242
    0
        }
    243
    }
    244
    245
    impl fmt::Display for Operator {
    246
    0
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    247
    0
            let display = match &self {
    248
    0
                Operator::Eq => "=",
    249
    0
                Operator::NotEq => "!=",
    250
    0
                Operator::Lt => "<",
    251
    0
                Operator::LtEq => "<=",
    252
    0
                Operator::Gt => ">",
    253
    0
                Operator::GtEq => ">=",
    254
    0
                Operator::Plus => "+",
    255
    0
                Operator::Minus => "-",
    256
    0
                Operator::Multiply => "*",
    257
    0
                Operator::Divide => "/",
    258
    0
                Operator::Modulo => "%",
    259
    0
                Operator::And => "AND",
    260
    0
                Operator::Or => "OR",
    261
    0
                Operator::RegexMatch => "~",
    262
    0
                Operator::RegexIMatch => "~*",
    263
    0
                Operator::RegexNotMatch => "!~",
    264
    0
                Operator::RegexNotIMatch => "!~*",
    265
    0
                Operator::LikeMatch => "~~",
    266
    0
                Operator::ILikeMatch => "~~*",
    267
    0
                Operator::NotLikeMatch => "!~~",
    268
    0
                Operator::NotILikeMatch => "!~~*",
    269
    0
                Operator::IsDistinctFrom => "IS DISTINCT FROM",
    270
    0
                Operator::IsNotDistinctFrom => "IS NOT DISTINCT FROM",
    271
    0
                Operator::BitwiseAnd => "&",
    272
    0
                Operator::BitwiseOr => "|",
    273
    0
                Operator::BitwiseXor => "BIT_XOR",
    274
    0
                Operator::BitwiseShiftRight => ">>",
    275
    0
                Operator::BitwiseShiftLeft => "<<",
    276
    0
                Operator::StringConcat => "||",
    277
    0
                Operator::AtArrow => "@>",
    278
    0
                Operator::ArrowAt => "<@",
    279
            };
    280
    0
            write!(f, "{display}")
    281
    0
        }
    282
    }