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

getdozer / dozer / 4007818786

pending completion
4007818786

Pull #733

github

GitHub
Merge baf5c38aa into 6c0ac2b2c
Pull Request #733: Bump diesel from 2.0.2 to 2.0.3

23389 of 34432 relevant lines covered (67.93%)

40326.78 hits per line

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

77.97
/dozer-sql/src/pipeline/expression/scalar/string.rs
1
use crate::arg_str;
2

3
use crate::pipeline::errors::PipelineError;
4

5
use crate::pipeline::expression::execution::{Expression, ExpressionExecutor, ExpressionType};
6

7
use crate::pipeline::expression::arg_utils::validate_arg_type;
8
use crate::pipeline::expression::scalar::common::ScalarFunctionType;
9

10
use dozer_types::types::{Field, FieldType, Record, Schema};
11
use like::{Escape, Like};
12

13
pub(crate) fn validate_ucase(
2✔
14
    arg: &Expression,
2✔
15
    schema: &Schema,
2✔
16
) -> Result<ExpressionType, PipelineError> {
2✔
17
    validate_arg_type(
2✔
18
        arg,
2✔
19
        vec![FieldType::String, FieldType::Text],
2✔
20
        schema,
2✔
21
        ScalarFunctionType::Ucase,
2✔
22
        0,
2✔
23
    )
2✔
24
}
2✔
25

26
pub(crate) fn evaluate_ucase(
2✔
27
    schema: &Schema,
2✔
28
    arg: &Expression,
2✔
29
    record: &Record,
2✔
30
) -> Result<Field, PipelineError> {
2✔
31
    let f = arg.evaluate(record, schema)?;
2✔
32
    let v = arg_str!(f, ScalarFunctionType::Ucase, 0)?;
2✔
33
    let ret = v.to_uppercase();
2✔
34

2✔
35
    Ok(match arg.get_type(schema)?.return_type {
2✔
36
        FieldType::String => Field::String(ret),
1✔
37
        _ => Field::Text(ret),
1✔
38
    })
39
}
2✔
40

41
pub(crate) fn validate_concat(
4✔
42
    args: &[Expression],
4✔
43
    schema: &Schema,
4✔
44
) -> Result<ExpressionType, PipelineError> {
4✔
45
    let mut ret_type = FieldType::String;
4✔
46
    for exp in args {
11✔
47
        let r = validate_arg_type(
8✔
48
            exp,
8✔
49
            vec![FieldType::String, FieldType::Text],
8✔
50
            schema,
8✔
51
            ScalarFunctionType::Concat,
8✔
52
            0,
8✔
53
        )?;
8✔
54
        if matches!(r.return_type, FieldType::Text) {
7✔
55
            ret_type = FieldType::Text;
2✔
56
        }
5✔
57
    }
58
    Ok(ExpressionType::new(
3✔
59
        ret_type,
3✔
60
        false,
3✔
61
        dozer_types::types::SourceDefinition::Dynamic,
3✔
62
    ))
3✔
63
}
4✔
64

×
65
pub(crate) fn evaluate_concat(
3✔
66
    schema: &Schema,
3✔
67
    args: &[Expression],
3✔
68
    record: &Record,
3✔
69
) -> Result<Field, PipelineError> {
3✔
70
    let mut res_type = FieldType::String;
3✔
71
    let mut res_vec: Vec<String> = Vec::with_capacity(args.len());
3✔
72

×
73
    for e in args {
9✔
74
        if matches!(e.get_type(schema)?.return_type, FieldType::Text) {
6✔
75
            res_type = FieldType::Text;
2✔
76
        }
4✔
77
        let f = e.evaluate(record, schema)?;
6✔
78
        let val = arg_str!(f, ScalarFunctionType::Concat, 0)?;
6✔
79
        res_vec.push(val);
6✔
80
    }
×
81

×
82
    let res_str = res_vec.iter().fold(String::new(), |a, b| a + b.as_str());
6✔
83
    Ok(match res_type {
3✔
84
        FieldType::Text => Field::Text(res_str),
1✔
85
        _ => Field::String(res_str),
2✔
86
    })
×
87
}
3✔
88

×
89
pub(crate) fn evaluate_length(
1✔
90
    schema: &Schema,
1✔
91
    arg0: &Expression,
1✔
92
    record: &Record,
1✔
93
) -> Result<Field, PipelineError> {
1✔
94
    let f0 = arg0.evaluate(record, schema)?;
1✔
95
    let v0 = arg_str!(f0, ScalarFunctionType::Concat, 0)?;
1✔
96
    Ok(Field::UInt(v0.len() as u64))
1✔
97
}
1✔
98

99
#[derive(Clone, Debug, PartialEq, Eq)]
3✔
100
pub enum TrimType {
101
    Trailing,
102
    Leading,
×
103
    Both,
×
104
}
×
105

×
106
pub(crate) fn validate_trim(
19✔
107
    arg: &Expression,
19✔
108
    schema: &Schema,
19✔
109
) -> Result<ExpressionType, PipelineError> {
19✔
110
    validate_arg_type(
19✔
111
        arg,
19✔
112
        vec![FieldType::String, FieldType::Text],
19✔
113
        schema,
19✔
114
        ScalarFunctionType::Concat,
19✔
115
        0,
19✔
116
    )
19✔
117
}
19✔
118

×
119
pub(crate) fn evaluate_trim(
28✔
120
    schema: &Schema,
28✔
121
    arg: &Expression,
28✔
122
    what: &Option<Box<Expression>>,
28✔
123
    typ: &Option<TrimType>,
28✔
124
    record: &Record,
28✔
125
) -> Result<Field, PipelineError> {
28✔
126
    let arg_field = arg.evaluate(record, schema)?;
28✔
127
    let arg_value = arg_str!(arg_field, "TRIM", 0)?;
28✔
128

×
129
    let v1: Vec<_> = match what {
28✔
130
        Some(e) => {
4✔
131
            let f = e.evaluate(record, schema)?;
4✔
132
            arg_str!(f, "TRIM", 1)?.chars().collect()
4✔
133
        }
×
134
        _ => vec![' '],
24✔
135
    };
×
136

×
137
    let retval = match typ {
28✔
138
        Some(TrimType::Both) => arg_value.trim_matches::<&[char]>(&v1).to_string(),
1✔
139
        Some(TrimType::Leading) => arg_value.trim_start_matches::<&[char]>(&v1).to_string(),
1✔
140
        Some(TrimType::Trailing) => arg_value.trim_end_matches::<&[char]>(&v1).to_string(),
1✔
141
        None => arg_value.trim_matches::<&[char]>(&v1).to_string(),
25✔
142
    };
×
143

144
    Ok(match arg.get_type(schema)?.return_type {
28✔
145
        FieldType::String => Field::String(retval),
27✔
146
        _ => Field::Text(retval),
1✔
147
    })
148
}
28✔
149

150
pub(crate) fn get_like_operator_type(
151
    arg: &Expression,
×
152
    pattern: &Expression,
×
153
    schema: &Schema,
×
154
) -> Result<ExpressionType, PipelineError> {
×
155
    validate_arg_type(
×
156
        pattern,
×
157
        vec![FieldType::String, FieldType::Text],
×
158
        schema,
×
159
        ScalarFunctionType::Concat,
×
160
        0,
×
161
    )?;
×
162

×
163
    validate_arg_type(
×
164
        arg,
×
165
        vec![FieldType::String, FieldType::Text],
×
166
        schema,
×
167
        ScalarFunctionType::Concat,
×
168
        0,
×
169
    )
×
170
}
×
171

×
172
pub(crate) fn evaluate_like(
5✔
173
    schema: &Schema,
5✔
174
    arg: &Expression,
5✔
175
    pattern: &Expression,
5✔
176
    escape: Option<char>,
5✔
177
    record: &Record,
5✔
178
) -> Result<Field, PipelineError> {
5✔
179
    let arg_field = arg.evaluate(record, schema)?;
5✔
180
    let arg_value = arg_str!(arg_field, "LIKE", 0)?;
5✔
181
    let arg_string = arg_value.as_str();
5✔
182

183
    let pattern_field = pattern.evaluate(record, schema)?;
5✔
184
    let pattern_value = arg_str!(pattern_field, "LIKE", 1)?;
5✔
185
    let pattern_string = pattern_value.as_str();
5✔
186

×
187
    if let Some(escape_char) = escape {
5✔
188
        let arg_escape = &arg_string
1✔
189
            .escape(&escape_char.to_string())
1✔
190
            .map_err(|e| PipelineError::InvalidArgument(e.to_string()))?;
1✔
191
        let result = Like::<false>::like(arg_escape.as_str(), pattern_string)
1✔
192
            .map(Field::Boolean)
1✔
193
            .map_err(|e| PipelineError::InvalidArgument(e.to_string()))?;
1✔
194
        return Ok(result);
1✔
195
    }
4✔
196

×
197
    let result = Like::<false>::like(arg_string, pattern_string)
4✔
198
        .map(Field::Boolean)
4✔
199
        .map_err(|e| PipelineError::InvalidArgument(e.to_string()))?;
4✔
200
    Ok(result)
4✔
201
}
5✔
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