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

getdozer / dozer / 4377467257

pending completion
4377467257

push

github

GitHub
implement `HAVING` (#1198)

395 of 395 new or added lines in 6 files covered. (100.0%)

27638 of 38584 relevant lines covered (71.63%)

27777.41 hits per line

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

50.51
/dozer-sql/src/pipeline/expression/cast.rs
1
use std::fmt::{Display, Formatter};
2

3
use dozer_types::{
4
    ordered_float::OrderedFloat,
5
    types::{Field, FieldType, Record, Schema},
6
};
7

8
use crate::pipeline::errors::{FieldTypes, PipelineError};
9

10
use super::execution::{Expression, ExpressionExecutor, ExpressionType};
11

12
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Hash)]
34✔
13
pub enum CastOperatorType {
14
    UInt,
15
    Int,
16
    Float,
17
    Boolean,
18
    String,
19
    Text,
20
    Binary,
21
    Decimal,
22
    Timestamp,
23
    Date,
24
    Bson,
25
}
26

27
impl Display for CastOperatorType {
28
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
×
29
        match self {
×
30
            CastOperatorType::UInt => f.write_str("CAST AS UINT"),
×
31
            CastOperatorType::Int => f.write_str("CAST AS INT"),
×
32
            CastOperatorType::Float => f.write_str("CAST AS FLOAT"),
×
33
            CastOperatorType::Boolean => f.write_str("CAST AS BOOLEAN"),
×
34
            CastOperatorType::String => f.write_str("CAST AS STRING"),
×
35
            CastOperatorType::Text => f.write_str("CAST AS TEXT"),
×
36
            CastOperatorType::Binary => f.write_str("CAST AS BINARY"),
×
37
            CastOperatorType::Decimal => f.write_str("CAST AS DECIMAL"),
×
38
            CastOperatorType::Timestamp => f.write_str("CAST AS TIMESTAMP"),
×
39
            CastOperatorType::Date => f.write_str("CAST AS DATE"),
×
40
            CastOperatorType::Bson => f.write_str("CAST AS BSON"),
×
41
        }
42
    }
×
43
}
44

45
impl CastOperatorType {
46
    pub(crate) fn evaluate(
35✔
47
        &self,
35✔
48
        schema: &Schema,
35✔
49
        arg: &Expression,
35✔
50
        record: &Record,
35✔
51
    ) -> Result<Field, PipelineError> {
35✔
52
        let field = arg.evaluate(record, schema)?;
35✔
53
        match self {
35✔
54
            CastOperatorType::UInt => {
55
                if let Some(value) = field.to_uint() {
×
56
                    Ok(Field::UInt(value))
×
57
                } else {
58
                    Err(PipelineError::InvalidCast {
×
59
                        from: field,
×
60
                        to: FieldType::UInt,
×
61
                    })
×
62
                }
63
            }
64
            CastOperatorType::Int => {
65
                if let Some(value) = field.to_int() {
3✔
66
                    Ok(Field::Int(value))
3✔
67
                } else {
68
                    Err(PipelineError::InvalidCast {
×
69
                        from: field,
×
70
                        to: FieldType::Int,
×
71
                    })
×
72
                }
73
            }
74
            CastOperatorType::Float => {
75
                if let Some(value) = field.to_float() {
5✔
76
                    Ok(Field::Float(OrderedFloat(value)))
5✔
77
                } else {
78
                    Err(PipelineError::InvalidCast {
×
79
                        from: field,
×
80
                        to: FieldType::Float,
×
81
                    })
×
82
                }
83
            }
84
            CastOperatorType::Boolean => {
85
                if let Some(value) = field.to_boolean() {
6✔
86
                    Ok(Field::Boolean(value))
6✔
87
                } else {
88
                    Err(PipelineError::InvalidCast {
×
89
                        from: field,
×
90
                        to: FieldType::Boolean,
×
91
                    })
×
92
                }
93
            }
94
            CastOperatorType::String => {
95
                if let Some(value) = field.to_string() {
12✔
96
                    Ok(Field::String(value))
12✔
97
                } else {
98
                    Err(PipelineError::InvalidCast {
×
99
                        from: field,
×
100
                        to: FieldType::String,
×
101
                    })
×
102
                }
103
            }
104
            CastOperatorType::Text => {
105
                if let Some(value) = field.to_text() {
9✔
106
                    Ok(Field::Text(value))
9✔
107
                } else {
108
                    Err(PipelineError::InvalidCast {
×
109
                        from: field,
×
110
                        to: FieldType::Text,
×
111
                    })
×
112
                }
113
            }
114
            CastOperatorType::Binary => {
115
                if let Some(value) = field.to_binary() {
×
116
                    Ok(Field::Binary(value.to_vec()))
×
117
                } else {
118
                    Err(PipelineError::InvalidCast {
×
119
                        from: field,
×
120
                        to: FieldType::Binary,
×
121
                    })
×
122
                }
123
            }
124
            CastOperatorType::Decimal => {
125
                if let Some(value) = field.to_decimal() {
×
126
                    Ok(Field::Decimal(value))
×
127
                } else {
128
                    Err(PipelineError::InvalidCast {
×
129
                        from: field,
×
130
                        to: FieldType::Decimal,
×
131
                    })
×
132
                }
133
            }
134
            CastOperatorType::Timestamp => {
135
                if let Some(value) = field.to_timestamp()? {
×
136
                    Ok(Field::Timestamp(value))
×
137
                } else {
138
                    Err(PipelineError::InvalidCast {
×
139
                        from: field,
×
140
                        to: FieldType::Timestamp,
×
141
                    })
×
142
                }
143
            }
144
            CastOperatorType::Date => {
145
                if let Some(value) = field.to_date()? {
×
146
                    Ok(Field::Date(value))
×
147
                } else {
148
                    Err(PipelineError::InvalidCast {
×
149
                        from: field,
×
150
                        to: FieldType::Date,
×
151
                    })
×
152
                }
153
            }
154
            CastOperatorType::Bson => {
155
                if let Some(value) = field.to_bson() {
×
156
                    Ok(Field::Bson(value.to_vec()))
×
157
                } else {
158
                    Err(PipelineError::InvalidCast {
×
159
                        from: field,
×
160
                        to: FieldType::Bson,
×
161
                    })
×
162
                }
163
            }
164
        }
165
    }
35✔
166

167
    pub(crate) fn get_return_type(
36✔
168
        &self,
36✔
169
        schema: &Schema,
36✔
170
        arg: &Expression,
36✔
171
    ) -> Result<ExpressionType, PipelineError> {
36✔
172
        let (expected_input_type, return_type) = match self {
36✔
173
            CastOperatorType::UInt => (
×
174
                vec![FieldType::Int, FieldType::String, FieldType::UInt],
×
175
                FieldType::UInt,
×
176
            ),
×
177
            CastOperatorType::Int => (
3✔
178
                vec![FieldType::Int, FieldType::String, FieldType::UInt],
3✔
179
                FieldType::Int,
3✔
180
            ),
3✔
181
            CastOperatorType::Float => (
5✔
182
                vec![
5✔
183
                    FieldType::Decimal,
5✔
184
                    FieldType::Float,
5✔
185
                    FieldType::Int,
5✔
186
                    FieldType::String,
5✔
187
                    FieldType::UInt,
5✔
188
                ],
5✔
189
                FieldType::Float,
5✔
190
            ),
5✔
191
            CastOperatorType::Boolean => (
6✔
192
                vec![
6✔
193
                    FieldType::Boolean,
6✔
194
                    FieldType::Decimal,
6✔
195
                    FieldType::Float,
6✔
196
                    FieldType::Int,
6✔
197
                    FieldType::UInt,
6✔
198
                ],
6✔
199
                FieldType::Boolean,
6✔
200
            ),
6✔
201
            CastOperatorType::String => (
13✔
202
                vec![
13✔
203
                    FieldType::Binary,
13✔
204
                    FieldType::Boolean,
13✔
205
                    FieldType::Date,
13✔
206
                    FieldType::Decimal,
13✔
207
                    FieldType::Float,
13✔
208
                    FieldType::Int,
13✔
209
                    FieldType::String,
13✔
210
                    FieldType::Text,
13✔
211
                    FieldType::Timestamp,
13✔
212
                    FieldType::UInt,
13✔
213
                ],
13✔
214
                FieldType::String,
13✔
215
            ),
13✔
216
            CastOperatorType::Text => (
9✔
217
                vec![
9✔
218
                    FieldType::Binary,
9✔
219
                    FieldType::Boolean,
9✔
220
                    FieldType::Date,
9✔
221
                    FieldType::Decimal,
9✔
222
                    FieldType::Float,
9✔
223
                    FieldType::Int,
9✔
224
                    FieldType::String,
9✔
225
                    FieldType::Text,
9✔
226
                    FieldType::Timestamp,
9✔
227
                    FieldType::UInt,
9✔
228
                ],
9✔
229
                FieldType::Text,
9✔
230
            ),
9✔
231
            CastOperatorType::Binary => (vec![FieldType::Binary], FieldType::Binary),
×
232
            CastOperatorType::Decimal => (
×
233
                vec![
×
234
                    FieldType::Decimal,
×
235
                    FieldType::Float,
×
236
                    FieldType::Int,
×
237
                    FieldType::String,
×
238
                    FieldType::UInt,
×
239
                ],
×
240
                FieldType::Decimal,
×
241
            ),
×
242
            CastOperatorType::Timestamp => (
×
243
                vec![FieldType::String, FieldType::Timestamp],
×
244
                FieldType::Timestamp,
×
245
            ),
×
246
            CastOperatorType::Date => (vec![FieldType::Date, FieldType::String], FieldType::Date),
×
247
            CastOperatorType::Bson => (vec![FieldType::Bson], FieldType::Bson),
×
248
        };
249

250
        let expression_type = validate_arg_type(arg, expected_input_type, schema, self, 0)?;
36✔
251
        Ok(ExpressionType {
36✔
252
            return_type,
36✔
253
            nullable: expression_type.nullable,
36✔
254
            source: expression_type.source,
36✔
255
            is_primary_key: expression_type.is_primary_key,
36✔
256
        })
36✔
257
    }
36✔
258
}
259

260
pub(crate) fn validate_arg_type(
36✔
261
    arg: &Expression,
36✔
262
    expected: Vec<FieldType>,
36✔
263
    schema: &Schema,
36✔
264
    fct: &CastOperatorType,
36✔
265
    idx: usize,
36✔
266
) -> Result<ExpressionType, PipelineError> {
36✔
267
    let arg_t = arg.get_type(schema)?;
36✔
268
    if !expected.contains(&arg_t.return_type) {
36✔
269
        Err(PipelineError::InvalidFunctionArgumentType(
×
270
            fct.to_string(),
×
271
            arg_t.return_type,
×
272
            FieldTypes::new(expected),
×
273
            idx,
×
274
        ))
×
275
    } else {
276
        Ok(arg_t)
36✔
277
    }
278
}
36✔
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

© 2025 Coveralls, Inc