• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

getdozer / dozer / 4361707165

pending completion
4361707165

push

github

GitHub
refactor: comparison errors (#1163)

286 of 286 new or added lines in 3 files covered. (100.0%)

27143 of 35806 relevant lines covered (75.81%)

33477.66 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

21.79
/dozer-sql/src/pipeline/expression/mathematical.rs
1
use crate::pipeline::errors::PipelineError;
2
use crate::pipeline::expression::execution::{Expression, ExpressionExecutor};
3
use dozer_types::rust_decimal::Decimal;
4
use dozer_types::types::Schema;
5
use dozer_types::{
6
    ordered_float::OrderedFloat,
7
    types::{Field, Record},
8
};
9
use num_traits::cast::*;
10
use std::ops::Neg;
11

12
macro_rules! define_math_operator {
13
    ($id:ident, $op:expr, $fct:expr, $t: expr) => {
14
        pub fn $id(
20✔
15
            schema: &Schema,
20✔
16
            left: &Expression,
20✔
17
            right: &Expression,
20✔
18
            record: &Record,
20✔
19
        ) -> Result<Field, PipelineError> {
20✔
20
            let left_p = left.evaluate(&record, schema)?;
20✔
21
            let right_p = right.evaluate(&record, schema)?;
20✔
22

23
            match left_p {
20✔
24
                Field::Timestamp(left_v) => match right_p {
3✔
25
                    Field::Timestamp(right_v) => match $op {
3✔
26
                        "-" => {
3✔
27
                            let duration = left_v - right_v;
3✔
28
                            Ok(Field::Int(duration.num_milliseconds()))
3✔
29
                        }
30
                        _ => Err(PipelineError::InvalidTypeComparison(
×
31
                            left_p,
×
32
                            right_p,
×
33
                            $op.to_string(),
×
34
                        )),
×
35
                    },
36
                    _ => Err(PipelineError::InvalidTypeComparison(
×
37
                        left_p,
×
38
                        right_p,
×
39
                        $op.to_string(),
×
40
                    )),
×
41
                },
42
                Field::Float(left_v) => match right_p {
5✔
43
                    // left: Float, right: Int
44
                    Field::Int(right_v) => Ok(Field::Float($fct(
×
45
                        left_v,
×
46
                        OrderedFloat::<f64>::from_i64(right_v).ok_or(
×
47
                            PipelineError::UnableToCast(format!("{}", right_v), "f64".to_string()),
×
48
                        )?,
×
49
                    ))),
50
                    // left: Float, right: UInt
51
                    Field::UInt(right_v) => Ok(Field::Float($fct(
×
52
                        left_v,
×
53
                        OrderedFloat::<f64>::from_u64(right_v).ok_or(
×
54
                            PipelineError::UnableToCast(format!("{}", right_v), "f64".to_string()),
×
55
                        )?,
×
56
                    ))),
57
                    // left: Float, right: Float
58
                    Field::Float(right_v) => Ok(Field::Float($fct(left_v, right_v))),
×
59
                    // left: Float, right: Decimal
60
                    Field::Decimal(right_v) => Ok(Field::Decimal($fct(
5✔
61
                        Decimal::from_f64(left_v.to_f64().ok_or(PipelineError::UnableToCast(
5✔
62
                            format!("{}", left_v),
5✔
63
                            "f64".to_string(),
5✔
64
                        ))?)
5✔
65
                        .ok_or(PipelineError::UnableToCast(
5✔
66
                            format!("{}", left_v),
5✔
67
                            "Decimal".to_string(),
5✔
68
                        ))?,
5✔
69
                        right_v,
5✔
70
                    ))),
71
                    _ => Err(PipelineError::InvalidTypeComparison(
×
72
                        left_p,
×
73
                        right_p,
×
74
                        $op.to_string(),
×
75
                    )),
×
76
                },
77
                Field::Int(left_v) => match right_p {
7✔
78
                    // left: Int, right: Int
79
                    Field::Int(right_v) => {
2✔
80
                        return match ($t) {
81
                            // When Int / Int division happens
82
                            1 => Ok(Field::Float($fct(
83
                                OrderedFloat::<f64>::from_i64(left_v).ok_or(
×
84
                                    PipelineError::UnableToCast(
×
85
                                        format!("{}", left_v),
×
86
                                        "f64".to_string(),
×
87
                                    ),
×
88
                                )?,
×
89
                                OrderedFloat::<f64>::from_i64(right_v).ok_or(
×
90
                                    PipelineError::UnableToCast(
×
91
                                        format!("{}", right_v),
×
92
                                        "f64".to_string(),
×
93
                                    ),
×
94
                                )?,
×
95
                            ))),
96
                            // When it's not division operation
97
                            _ => Ok(Field::Int($fct(left_v, right_v))),
2✔
98
                        };
99
                    }
100
                    // left: Int, right: UInt
101
                    Field::UInt(right_v) => {
×
102
                        return match ($t) {
103
                            // When Int / UInt division happens
104
                            1 => Ok(Field::Float($fct(
105
                                OrderedFloat::<f64>::from_i64(left_v).ok_or(
×
106
                                    PipelineError::UnableToCast(
×
107
                                        format!("{}", left_v),
×
108
                                        "f64".to_string(),
×
109
                                    ),
×
110
                                )?,
×
111
                                OrderedFloat::<f64>::from_u64(right_v).ok_or(
×
112
                                    PipelineError::UnableToCast(
×
113
                                        format!("{}", right_v),
×
114
                                        "f64".to_string(),
×
115
                                    ),
×
116
                                )?,
×
117
                            ))),
118
                            // When it's not division operation
119
                            _ => Ok(Field::Int($fct(
120
                                left_v,
×
121
                                right_v.to_i64().ok_or(PipelineError::UnableToCast(
×
122
                                    format!("{}", right_v),
×
123
                                    "i64".to_string(),
×
124
                                ))?,
×
125
                            ))),
126
                        };
127
                    }
128
                    // left: Int, right: Float
129
                    Field::Float(right_v) => Ok(Field::Float($fct(
×
130
                        OrderedFloat::<f64>::from_i64(left_v).ok_or(
×
131
                            PipelineError::UnableToCast(format!("{}", left_v), "f64".to_string()),
×
132
                        )?,
×
133
                        right_v,
×
134
                    ))),
135
                    // left: Int, right: Decimal
136
                    Field::Decimal(right_v) => Ok(Field::Decimal($fct(
5✔
137
                        Decimal::from_i64(left_v).ok_or(PipelineError::UnableToCast(
5✔
138
                            format!("{}", left_v),
5✔
139
                            "Decimal".to_string(),
5✔
140
                        ))?,
5✔
141
                        right_v,
5✔
142
                    ))),
143
                    _ => Err(PipelineError::InvalidTypeComparison(
×
144
                        left_p,
×
145
                        right_p,
×
146
                        $op.to_string(),
×
147
                    )),
×
148
                },
149
                Field::UInt(left_v) => match right_p {
5✔
150
                    // left: UInt, right: Int
151
                    Field::Int(right_v) => {
×
152
                        return match ($t) {
153
                            // When UInt / Int division happens
154
                            1 => Ok(Field::Float($fct(
155
                                OrderedFloat::<f64>::from_u64(left_v).ok_or(
×
156
                                    PipelineError::UnableToCast(
×
157
                                        format!("{}", left_v),
×
158
                                        "f64".to_string(),
×
159
                                    ),
×
160
                                )?,
×
161
                                OrderedFloat::<f64>::from_i64(right_v).ok_or(
×
162
                                    PipelineError::UnableToCast(
×
163
                                        format!("{}", right_v),
×
164
                                        "f64".to_string(),
×
165
                                    ),
×
166
                                )?,
×
167
                            ))),
168
                            // When it's not division operation
169
                            _ => Ok(Field::Int($fct(
170
                                left_v.to_i64().ok_or(PipelineError::UnableToCast(
×
171
                                    format!("{}", left_v),
×
172
                                    "i64".to_string(),
×
173
                                ))?,
×
174
                                right_v,
×
175
                            ))),
176
                        };
177
                    }
178
                    // left: UInt, right: UInt
179
                    Field::UInt(right_v) => {
×
180
                        return match ($t) {
181
                            // When UInt / UInt division happens
182
                            1 => Ok(Field::Float($fct(
183
                                OrderedFloat::<f64>::from_u64(left_v).ok_or(
×
184
                                    PipelineError::UnableToCast(
×
185
                                        format!("{}", left_v),
×
186
                                        "f64".to_string(),
×
187
                                    ),
×
188
                                )?,
×
189
                                OrderedFloat::<f64>::from_u64(right_v).ok_or(
×
190
                                    PipelineError::UnableToCast(
×
191
                                        format!("{}", right_v),
×
192
                                        "f64".to_string(),
×
193
                                    ),
×
194
                                )?,
×
195
                            ))),
196
                            // When it's not division operation
197
                            _ => Ok(Field::UInt($fct(left_v, right_v))),
×
198
                        };
199
                    }
200
                    // left: UInt, right: Float
201
                    Field::Float(right_v) => Ok(Field::Float($fct(
×
202
                        OrderedFloat::<f64>::from_u64(left_v).ok_or(
×
203
                            PipelineError::UnableToCast(format!("{}", left_v), "f64".to_string()),
×
204
                        )?,
×
205
                        right_v,
×
206
                    ))),
207
                    // left: UInt, right: Decimal
208
                    Field::Decimal(right_v) => Ok(Field::Decimal($fct(
5✔
209
                        Decimal::from_i64(left_v.to_i64().ok_or(PipelineError::UnableToCast(
5✔
210
                            format!("{}", left_v),
5✔
211
                            "i64".to_string(),
5✔
212
                        ))?)
5✔
213
                        .ok_or(PipelineError::UnableToCast(
5✔
214
                            format!("{}", left_v),
5✔
215
                            "Decimal".to_string(),
5✔
216
                        ))?,
5✔
217
                        right_v,
5✔
218
                    ))),
219
                    _ => Err(PipelineError::InvalidTypeComparison(
×
220
                        left_p,
×
221
                        right_p,
×
222
                        $op.to_string(),
×
223
                    )),
×
224
                },
225
                Field::Decimal(left_v) => {
×
226
                    match right_p {
×
227
                        // left: Decimal, right: Int
228
                        Field::Int(right_v) => Ok(Field::Decimal($fct(
×
229
                            left_v,
×
230
                            Decimal::from_i64(right_v).ok_or(PipelineError::UnableToCast(
×
231
                                format!("{}", left_v),
×
232
                                "Decimal".to_string(),
×
233
                            ))?,
×
234
                        ))),
235
                        // left: Decimal, right: UInt
236
                        Field::UInt(right_v) => Ok(Field::Decimal($fct(
×
237
                            left_v,
×
238
                            Decimal::from_i64(right_v.to_i64().ok_or(
×
239
                                PipelineError::UnableToCast(
×
240
                                    format!("{}", right_v),
×
241
                                    "i64".to_string(),
×
242
                                ),
×
243
                            )?)
×
244
                            .ok_or(PipelineError::UnableToCast(
×
245
                                format!("{}", right_v),
×
246
                                "Decimal".to_string(),
×
247
                            ))?,
×
248
                        ))),
249
                        // left: Decimal, right: Float
250
                        Field::Float(right_v) => Ok(Field::Decimal($fct(
×
251
                            left_v,
×
252
                            Decimal::from_f64(right_v.to_f64().ok_or(
×
253
                                PipelineError::UnableToCast(
×
254
                                    format!("{}", right_v),
×
255
                                    "f64".to_string(),
×
256
                                ),
×
257
                            )?)
×
258
                            .ok_or(PipelineError::UnableToCast(
×
259
                                format!("{}", right_v),
×
260
                                "Decimal".to_string(),
×
261
                            ))?,
×
262
                        ))),
263
                        // left: Decimal, right: Decimal
264
                        Field::Decimal(right_v) => Ok(Field::Decimal($fct(left_v, right_v))),
×
265
                        _ => Err(PipelineError::InvalidTypeComparison(
×
266
                            left_p,
×
267
                            right_p,
×
268
                            $op.to_string(),
×
269
                        )),
×
270
                    }
271
                }
272
                _ => Err(PipelineError::InvalidTypeComparison(
×
273
                    left_p,
×
274
                    right_p,
×
275
                    $op.to_string(),
×
276
                )),
×
277
            }
278
        }
20✔
279
    };
280
}
281

282
define_math_operator!(evaluate_add, "+", |a, b| { a + b }, 0);
5✔
283
define_math_operator!(evaluate_sub, "-", |a, b| { a - b }, 0);
3✔
284
define_math_operator!(evaluate_mul, "*", |a, b| { a * b }, 0);
3✔
285
define_math_operator!(evaluate_div, "/", |a, b| { a / b }, 1);
3✔
286
define_math_operator!(evaluate_mod, "%", |a, b| { a % b }, 0);
3✔
287

288
pub fn evaluate_plus(
×
289
    schema: &Schema,
×
290
    expression: &Expression,
×
291
    record: &Record,
×
292
) -> Result<Field, PipelineError> {
×
293
    let expression_result = expression.evaluate(record, schema)?;
×
294
    match expression_result {
×
295
        Field::UInt(v) => Ok(Field::UInt(v)),
×
296
        Field::Int(v) => Ok(Field::Int(v)),
×
297
        Field::Float(v) => Ok(Field::Float(v)),
×
298
        Field::Decimal(v) => Ok(Field::Decimal(v)),
×
299
        not_supported_field => Err(PipelineError::InvalidType(
×
300
            not_supported_field,
×
301
            "+".to_string(),
×
302
        )),
×
303
    }
304
}
×
305

306
pub fn evaluate_minus(
×
307
    schema: &Schema,
×
308
    expression: &Expression,
×
309
    record: &Record,
×
310
) -> Result<Field, PipelineError> {
×
311
    let expression_result = expression.evaluate(record, schema)?;
×
312
    match expression_result {
×
313
        Field::UInt(v) => Ok(Field::UInt(v)),
×
314
        Field::Int(v) => Ok(Field::Int(-v)),
×
315
        Field::Float(v) => Ok(Field::Float(-v)),
×
316
        Field::Decimal(v) => Ok(Field::Decimal(v.neg())),
×
317
        not_supported_field => Err(PipelineError::InvalidType(
×
318
            not_supported_field,
×
319
            "-".to_string(),
×
320
        )),
×
321
    }
322
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc