Coverage Report

Created: 2024-10-13 08:39

/Users/andrewlamb/Software/datafusion/datafusion/expr/src/operation.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
//! This module contains implementations of operations (unary, binary etc.) for DataFusion expressions.
19
20
use crate::expr_fn::binary_expr;
21
use crate::{Expr, Like};
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
0
            _ => Expr::Not(Box::new(self)),
157
        }
158
0
    }
159
}
160
161
#[cfg(test)]
162
mod tests {
163
    use crate::lit;
164
165
    #[test]
166
    fn test_operators() {
167
        // Add
168
        assert_eq!(
169
            format!("{}", lit(1u32) + lit(2u32)),
170
            "UInt32(1) + UInt32(2)"
171
        );
172
        // Sub
173
        assert_eq!(
174
            format!("{}", lit(1u32) - lit(2u32)),
175
            "UInt32(1) - UInt32(2)"
176
        );
177
        // Mul
178
        assert_eq!(
179
            format!("{}", lit(1u32) * lit(2u32)),
180
            "UInt32(1) * UInt32(2)"
181
        );
182
        // Div
183
        assert_eq!(
184
            format!("{}", lit(1u32) / lit(2u32)),
185
            "UInt32(1) / UInt32(2)"
186
        );
187
        // Rem
188
        assert_eq!(
189
            format!("{}", lit(1u32) % lit(2u32)),
190
            "UInt32(1) % UInt32(2)"
191
        );
192
        // BitAnd
193
        assert_eq!(
194
            format!("{}", lit(1u32) & lit(2u32)),
195
            "UInt32(1) & UInt32(2)"
196
        );
197
        // BitOr
198
        assert_eq!(
199
            format!("{}", lit(1u32) | lit(2u32)),
200
            "UInt32(1) | UInt32(2)"
201
        );
202
        // BitXor
203
        assert_eq!(
204
            format!("{}", lit(1u32) ^ lit(2u32)),
205
            "UInt32(1) BIT_XOR UInt32(2)"
206
        );
207
        // Shl
208
        assert_eq!(
209
            format!("{}", lit(1u32) << lit(2u32)),
210
            "UInt32(1) << UInt32(2)"
211
        );
212
        // Shr
213
        assert_eq!(
214
            format!("{}", lit(1u32) >> lit(2u32)),
215
            "UInt32(1) >> UInt32(2)"
216
        );
217
        // Neg
218
        assert_eq!(format!("{}", -lit(1u32)), "(- UInt32(1))");
219
        // Not
220
        assert_eq!(format!("{}", !lit(1u32)), "NOT UInt32(1)");
221
    }
222
}