csvsql/
functions.rs

1use std::{ops::Deref, str::FromStr};
2
3use crate::{
4    engine::Engine,
5    error::CvsSqlError,
6    group_by::GroupRow,
7    projections::{Projection, SingleConvert},
8    result_set_metadata::Metadata,
9    util::SmartReference,
10    value::Value,
11};
12use bigdecimal::FromPrimitive;
13use bigdecimal::ToPrimitive;
14use bigdecimal::{BigDecimal, Zero};
15use chrono::{TimeZone, Utc, offset::LocalResult};
16use itertools::Itertools;
17use regex::Regex;
18use sqlparser::ast::{
19    DuplicateTreatment, Function, FunctionArg, FunctionArgExpr, FunctionArguments,
20};
21
22impl SingleConvert for Function {
23    fn convert_single(
24        &self,
25        metadata: &Metadata,
26        engine: &Engine,
27    ) -> Result<Box<dyn Projection>, CvsSqlError> {
28        if !self.within_group.is_empty() {
29            return Err(CvsSqlError::Unsupported("WITHIN GROUP".into()));
30        }
31
32        if self.over.is_some() {
33            return Err(CvsSqlError::Unsupported("OVER".into()));
34        }
35
36        if self.null_treatment.is_some() {
37            return Err(CvsSqlError::Unsupported("IGNORE/RESPECT NULLS".into()));
38        }
39
40        if self.filter.is_some() {
41            return Err(CvsSqlError::Unsupported("FILTER".into()));
42        }
43        if self.parameters != FunctionArguments::None {
44            return Err(CvsSqlError::Unsupported("function parameters".into()));
45        }
46
47        let name = self.name.to_string().to_uppercase();
48        build_function_from_name(&name, metadata, engine, &self.args)
49    }
50}
51fn build_function_from_name(
52    name: &str,
53    metadata: &Metadata,
54    engine: &Engine,
55    args: &FunctionArguments,
56) -> Result<Box<dyn Projection>, CvsSqlError> {
57    match name {
58        "COUNT" => build_aggregator_function(metadata, engine, args, Box::new(Count {})),
59        "AVG" => build_aggregator_function(metadata, engine, args, Box::new(Avg {})),
60        "SUM" => build_aggregator_function(metadata, engine, args, Box::new(Sum {})),
61        "MIN" => build_aggregator_function(metadata, engine, args, Box::new(Min {})),
62        "MAX" => build_aggregator_function(metadata, engine, args, Box::new(Max {})),
63        "ANY_VALUE" => build_aggregator_function(metadata, engine, args, Box::new(AnyValue {})),
64
65        "ABS" => build_function(metadata, engine, args, Box::new(Abs {})),
66        "ASCII" => build_function(metadata, engine, args, Box::new(Ascii {})),
67        "CHR" => build_function(metadata, engine, args, Box::new(Chr {})),
68        "LENGTH" | "CHAR_LENGTH" | "CHARACTER_LENGTH" => {
69            build_function(metadata, engine, args, Box::new(Length {}))
70        }
71        "COALESCE" => build_function(metadata, engine, args, Box::new(Coalece {})),
72        "CONCAT" => build_function(metadata, engine, args, Box::new(Concat {})),
73        "CONCAT_WS" => build_function(metadata, engine, args, Box::new(ConcatWs {})),
74        "CURRENT_DATE" | "CURDATE" => {
75            build_function(metadata, engine, args, Box::new(CurrentDate {}))
76        }
77        "NOW" | "CURRENT_TIME" | "CURRENT_TIMESTAMP" | "CURTIME" | "LOCALTIME"
78        | "LOCALTIMESTAMP" => build_function(metadata, engine, args, Box::new(Now {})),
79        "USER" | "CURRENT_USER" => build_function(metadata, engine, args, Box::new(User {})),
80        "FORMAT" | "DATE_FORMAT" | "TIME_FORMAT" | "TO_CHAR" => {
81            build_function(metadata, engine, args, Box::new(Format {}))
82        }
83        "TO_TIMESTAMP" | "FROM_UNIXTIME" => {
84            build_function(metadata, engine, args, Box::new(ToTimestamp {}))
85        }
86        "GREATEST" => build_function(metadata, engine, args, Box::new(Greatest {})),
87        "IF" => build_function(metadata, engine, args, Box::new(If {})),
88        "NULLIF" => build_function(metadata, engine, args, Box::new(NullIf {})),
89        "LOWER" | "LCASE" => build_function(metadata, engine, args, Box::new(Lower {})),
90        "UPPER" | "UCASE" => build_function(metadata, engine, args, Box::new(Upper {})),
91        "LEAST" => build_function(metadata, engine, args, Box::new(Least {})),
92        "LEFT" => build_function(metadata, engine, args, Box::new(Left {})),
93        "RIGHT" => build_function(metadata, engine, args, Box::new(Right {})),
94        "LPAD" => build_function(metadata, engine, args, Box::new(Lpad {})),
95        "RPAD" => build_function(metadata, engine, args, Box::new(Rpad {})),
96        "LTRIM" => build_function(metadata, engine, args, Box::new(Ltrim {})),
97        "RTRIM" => build_function(metadata, engine, args, Box::new(Rtrim {})),
98        "PI" => build_function(metadata, engine, args, Box::new(Pi {})),
99        "RANDOM" | "RAND" => build_function(metadata, engine, args, Box::new(Random {})),
100        "POSITION" | "LOCATE" => build_function(metadata, engine, args, Box::new(Position {})),
101        "REPEAT" => build_function(metadata, engine, args, Box::new(Repeat {})),
102        "REPLACE" => build_function(metadata, engine, args, Box::new(Replace {})),
103        "REGEX_LIKE" => build_function(metadata, engine, args, Box::new(RegexLike {})),
104        "REGEX_REPLACE" => build_function(metadata, engine, args, Box::new(RegexReplace {})),
105        "REGEXP_SUBSTR" => build_function(metadata, engine, args, Box::new(RegexSubstring {})),
106        "REVERSE" => build_function(metadata, engine, args, Box::new(Reverse {})),
107        "LN" => build_function(metadata, engine, args, Box::new(Ln {})),
108        "EXP" => build_function(metadata, engine, args, Box::new(Exp {})),
109        "LOG" => build_function(metadata, engine, args, Box::new(Log {})),
110        "LOG2" => build_function(metadata, engine, args, Box::new(Log2 {})),
111        "LOG10" => build_function(metadata, engine, args, Box::new(Log10 {})),
112        "POW" | "POWER" => build_function(metadata, engine, args, Box::new(Power {})),
113        "ROUND" => build_function(metadata, engine, args, Box::new(Round {})),
114        "SQRT" => build_function(metadata, engine, args, Box::new(Sqrt {})),
115        _ => Err(CvsSqlError::Unsupported(format!("function {name}"))),
116    }
117}
118
119fn build_aggregator_function(
120    metadata: &Metadata,
121    engine: &Engine,
122    args: &FunctionArguments,
123    operator: Box<dyn AggregateOperator>,
124) -> Result<Box<dyn Projection>, CvsSqlError> {
125    let parent_metadata = match metadata {
126        Metadata::Grouped { parent, this: _ } => parent,
127        _ => return Err(CvsSqlError::NoGroupBy),
128    };
129    let lst = match &args {
130        FunctionArguments::List(lst) => lst,
131        FunctionArguments::Subquery(_) => {
132            return Err(CvsSqlError::Unsupported(
133                "function subquery arguments".into(),
134            ));
135        }
136        FunctionArguments::None => {
137            return Err(CvsSqlError::Unsupported(format!(
138                "Function {} must have an argmeunt",
139                operator.name()
140            )));
141        }
142    };
143    let distinct = matches!(lst.duplicate_treatment, Some(DuplicateTreatment::Distinct));
144
145    if let Some(c) = lst.clauses.first() {
146        return Err(CvsSqlError::Unsupported(format!("{c}")));
147    }
148    let first = match lst.args.first() {
149        Some(arg) => arg,
150        None => {
151            return Err(CvsSqlError::Unsupported(format!(
152                "Function {} must have an argmeunt",
153                operator.name()
154            )));
155        }
156    };
157    if lst.args.len() > 1 {
158        return Err(CvsSqlError::Unsupported(format!(
159            "Function {} must have a single argmeunt",
160            operator.name()
161        )));
162    }
163    let argument = match first {
164        FunctionArg::Unnamed(FunctionArgExpr::Expr(e)) => {
165            e.convert_single(parent_metadata, engine)?
166        }
167        FunctionArg::Unnamed(FunctionArgExpr::Wildcard) => {
168            if operator.support_wildcard_argument() {
169                if distinct {
170                    return Err(CvsSqlError::Unsupported("DISTINCT with * argument".into()));
171                }
172                wildcard_operator()
173            } else {
174                return Err(CvsSqlError::Unsupported(format!(
175                    "Function {} with * argument",
176                    operator.name()
177                )));
178            }
179        }
180        _ => return Err(CvsSqlError::Unsupported(format!("{first}"))),
181    };
182    let name = format!("{}({})", operator.name(), argument.name());
183
184    Ok(Box::new(AggregatedFunction {
185        distinct,
186        argument,
187        operator,
188        name,
189    }))
190}
191
192#[cfg(test)]
193struct AggregationExample<'a> {
194    name: &'a str,
195    data: Vec<&'a str>,
196    is_wildcard: bool,
197    is_distinct: bool,
198    expected_results: &'a str,
199}
200trait AggregateOperator {
201    fn name(&self) -> &str;
202    fn support_wildcard_argument(&self) -> bool {
203        false
204    }
205    fn aggregate(&self, data: &mut dyn Iterator<Item = Value>) -> Value;
206    #[cfg(test)]
207    fn examples<'a>(&'a self) -> Vec<AggregationExample<'a>>;
208}
209
210trait Casters {
211    fn to_number(self) -> Option<BigDecimal>;
212}
213
214impl Casters for Value {
215    fn to_number(self) -> Option<BigDecimal> {
216        match self {
217            Value::Number(num) => Some(num),
218            _ => None,
219        }
220    }
221}
222
223struct Count {}
224
225impl AggregateOperator for Count {
226    fn name(&self) -> &str {
227        "COUNT"
228    }
229    fn support_wildcard_argument(&self) -> bool {
230        true
231    }
232    fn aggregate(&self, data: &mut dyn Iterator<Item = Value>) -> Value {
233        let count = data.count();
234        Value::Number((count as u128).into())
235    }
236    #[cfg(test)]
237    fn examples<'a>(&'a self) -> Vec<AggregationExample<'a>> {
238        vec![
239            AggregationExample {
240                name: "simple",
241                data: vec!["1", "2", "3", "4", "1"],
242                is_distinct: false,
243                is_wildcard: false,
244                expected_results: "5",
245            },
246            AggregationExample {
247                name: "wildcard",
248                data: vec!["1", "2", "3", "4", "1"],
249                is_distinct: false,
250                is_wildcard: true,
251                expected_results: "5",
252            },
253            AggregationExample {
254                name: "distinct",
255                data: vec!["1", "2", "3", "4", "1"],
256                is_distinct: true,
257                is_wildcard: false,
258                expected_results: "4",
259            },
260        ]
261    }
262}
263
264struct Avg {}
265
266impl AggregateOperator for Avg {
267    fn name(&self) -> &str {
268        "AVG"
269    }
270
271    fn aggregate(&self, data: &mut dyn Iterator<Item = Value>) -> Value {
272        let mut total = BigDecimal::zero();
273        let mut count: u128 = 0;
274        for num in data.filter_map(|f| f.to_number()) {
275            count += 1;
276            total += num;
277        }
278        if count == 0 {
279            Value::Empty
280        } else {
281            Value::Number(total / count)
282        }
283    }
284
285    #[cfg(test)]
286    fn examples<'a>(&'a self) -> Vec<AggregationExample<'a>> {
287        vec![
288            AggregationExample {
289                name: "simple",
290                is_distinct: false,
291                is_wildcard: false,
292                data: vec!["5", "11", "11", "1"],
293                expected_results: "7",
294            },
295            AggregationExample {
296                name: "distinct",
297                is_distinct: true,
298                is_wildcard: false,
299                data: vec!["30", "12", "12", "9"],
300                expected_results: "17",
301            },
302            AggregationExample {
303                name: "not_only_numbers",
304                is_distinct: true,
305                is_wildcard: false,
306                data: vec!["10", "", "nop", "12"],
307                expected_results: "11",
308            },
309            AggregationExample {
310                name: "no_numbers",
311                is_distinct: true,
312                is_wildcard: false,
313                data: vec!["a", "", "nop", ""],
314                expected_results: "",
315            },
316        ]
317    }
318}
319
320struct Sum {}
321
322impl AggregateOperator for Sum {
323    fn name(&self) -> &str {
324        "SUM"
325    }
326    fn aggregate(&self, data: &mut dyn Iterator<Item = Value>) -> Value {
327        let total = data
328            .filter_map(|f| f.to_number())
329            .fold(BigDecimal::zero(), |a, b| a + b);
330        Value::Number(total)
331    }
332    #[cfg(test)]
333    fn examples<'a>(&'a self) -> Vec<AggregationExample<'a>> {
334        vec![
335            AggregationExample {
336                name: "simple",
337                is_distinct: false,
338                is_wildcard: false,
339                data: vec!["1", "1", "2", "3"],
340                expected_results: "7",
341            },
342            AggregationExample {
343                name: "distinct",
344                is_distinct: true,
345                is_wildcard: false,
346                data: vec!["1", "1", "2", "3"],
347                expected_results: "6",
348            },
349            AggregationExample {
350                name: "not_only_numbers",
351                is_distinct: true,
352                is_wildcard: false,
353                data: vec!["10", "", "nop", "12"],
354                expected_results: "22",
355            },
356            AggregationExample {
357                name: "no_numbers",
358                is_distinct: true,
359                is_wildcard: false,
360                data: vec!["a", "", "nop", ""],
361                expected_results: "0",
362            },
363        ]
364    }
365}
366struct Min {}
367
368impl AggregateOperator for Min {
369    fn name(&self) -> &str {
370        "MIN"
371    }
372    fn aggregate(&self, data: &mut dyn Iterator<Item = Value>) -> Value {
373        let min = data.min();
374        min.unwrap_or(Value::Empty)
375    }
376
377    #[cfg(test)]
378    fn examples<'a>(&'a self) -> Vec<AggregationExample<'a>> {
379        vec![
380            AggregationExample {
381                name: "numbers",
382                is_distinct: false,
383                is_wildcard: false,
384                data: vec!["1", "1", "2", "3"],
385                expected_results: "1",
386            },
387            AggregationExample {
388                name: "letters",
389                is_distinct: true,
390                is_wildcard: false,
391                data: vec!["e", "b", "d", "q"],
392                expected_results: "b",
393            },
394        ]
395    }
396}
397
398struct Max {}
399impl AggregateOperator for Max {
400    fn name(&self) -> &str {
401        "MAX"
402    }
403    fn aggregate(&self, data: &mut dyn Iterator<Item = Value>) -> Value {
404        let min = data.max();
405        min.unwrap_or(Value::Empty)
406    }
407    #[cfg(test)]
408    fn examples<'a>(&'a self) -> Vec<AggregationExample<'a>> {
409        vec![
410            AggregationExample {
411                name: "numbers",
412                is_distinct: false,
413                is_wildcard: false,
414                data: vec!["1", "1", "2", "3"],
415                expected_results: "3",
416            },
417            AggregationExample {
418                name: "letters",
419                is_distinct: true,
420                is_wildcard: false,
421                data: vec!["e", "b", "d", "q"],
422                expected_results: "q",
423            },
424        ]
425    }
426}
427
428struct AnyValue {}
429impl AggregateOperator for AnyValue {
430    fn name(&self) -> &str {
431        "ANY_VALUE"
432    }
433    fn aggregate(&self, data: &mut dyn Iterator<Item = Value>) -> Value {
434        let val = data.next();
435        val.unwrap_or(Value::Empty)
436    }
437    #[cfg(test)]
438    fn examples<'a>(&'a self) -> Vec<AggregationExample<'a>> {
439        vec![AggregationExample {
440            name: "values",
441            is_distinct: false,
442            is_wildcard: false,
443            data: vec!["a", "b", "2", "3"],
444            expected_results: "a",
445        }]
446    }
447}
448
449struct AggregatedFunction {
450    distinct: bool,
451    argument: Box<dyn Projection>,
452    operator: Box<dyn AggregateOperator>,
453    name: String,
454}
455
456impl Projection for AggregatedFunction {
457    fn get<'a>(&'a self, row: &'a GroupRow) -> SmartReference<'a, Value> {
458        let mut iter = row
459            .group_rows
460            .iter()
461            .map(|r| self.argument.get(r))
462            .map(|v| v.clone());
463        let value = if self.distinct {
464            let mut unique = iter.unique();
465            self.operator.aggregate(&mut unique)
466        } else {
467            self.operator.aggregate(&mut iter)
468        };
469        value.into()
470    }
471    fn name(&self) -> &str {
472        &self.name
473    }
474}
475
476struct Wildcard {}
477impl Projection for Wildcard {
478    fn get<'a>(&'a self, _: &'a GroupRow) -> SmartReference<'a, Value> {
479        Value::Bool(true).into()
480    }
481    fn name(&self) -> &str {
482        "*"
483    }
484}
485fn wildcard_operator() -> Box<dyn Projection> {
486    Box::new(Wildcard {})
487}
488
489#[cfg(test)]
490mod test_aggregations {
491    use std::fs::{self, OpenOptions};
492
493    use crate::{args::Args, engine::Engine, error::CvsSqlError, results::Column};
494    use std::io::Write;
495
496    use super::{AggregateOperator, AggregationExample, AnyValue, Avg, Count, Max, Min, Sum};
497
498    fn test_agg(operator: &impl AggregateOperator) -> Result<(), CvsSqlError> {
499        let dir = format!("./target/function_tests/{}", operator.name().to_lowercase());
500        println!("testing: {}", operator.name());
501        fs::remove_dir_all(&dir).ok();
502        fs::create_dir_all(&dir)?;
503        for example in operator.examples() {
504            test_agg_with_example(operator, &example)?;
505        }
506        fs::remove_dir_all(&dir).ok();
507
508        Ok(())
509    }
510
511    fn test_agg_with_example<'a>(
512        operator: &impl AggregateOperator,
513        example: &AggregationExample<'a>,
514    ) -> Result<(), CvsSqlError> {
515        println!("testing: {} with {}", operator.name(), example.name);
516        let dir = format!("./target/function_tests/{}", operator.name().to_lowercase());
517        let file = format!("{}/{}.csv", dir, example.name);
518        let mut writer = OpenOptions::new()
519            .write(true)
520            .create(true)
521            .truncate(true)
522            .open(&file)?;
523        writeln!(writer, "row")?;
524        for data in &example.data {
525            writeln!(writer, "{data}")?;
526        }
527
528        let table_name = format!(
529            "target.function_tests.{}.{}",
530            operator.name().to_lowercase(),
531            &example.name
532        );
533        let selector = if example.is_distinct {
534            "DISTINCT row"
535        } else if example.is_wildcard {
536            "*"
537        } else {
538            "row"
539        };
540
541        let sql = format!(
542            "SELECT {}({}) FROM {}\n",
543            operator.name(),
544            selector,
545            table_name
546        );
547
548        let args = Args::default();
549        let engine = Engine::try_from(&args)?;
550
551        let results = engine.execute_commands(&sql)?;
552
553        fs::remove_file(file)?;
554
555        let col = Column::from_index(0);
556        let result = results
557            .first()
558            .and_then(|d| d.results.data.iter().next())
559            .map(|d| d.get(&col));
560        let expected_results = example.expected_results.into();
561        assert_eq!(result, Some(&expected_results));
562
563        Ok(())
564    }
565
566    #[test]
567    fn test_count() -> Result<(), CvsSqlError> {
568        test_agg(&Count {})
569    }
570
571    #[test]
572    fn test_sum() -> Result<(), CvsSqlError> {
573        test_agg(&Sum {})
574    }
575
576    #[test]
577    fn test_avg() -> Result<(), CvsSqlError> {
578        test_agg(&Avg {})
579    }
580
581    #[test]
582    fn test_min() -> Result<(), CvsSqlError> {
583        test_agg(&Min {})
584    }
585
586    #[test]
587    fn test_max() -> Result<(), CvsSqlError> {
588        test_agg(&Max {})
589    }
590
591    #[test]
592    fn test_any_value() -> Result<(), CvsSqlError> {
593        test_agg(&AnyValue {})
594    }
595}
596
597#[cfg(test)]
598struct FunctionExample<'a> {
599    name: &'a str,
600    arguments: Vec<&'a str>,
601    expected_results: &'a str,
602}
603
604trait Operator {
605    fn name(&self) -> &str;
606    fn min_args(&self) -> usize;
607    fn max_args(&self) -> Option<usize>;
608    fn get<'a>(&'a self, args: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value>;
609    #[cfg(test)]
610    fn examples<'a>(&'a self) -> Vec<FunctionExample<'a>> {
611        vec![]
612    }
613}
614struct SimpleFunction {
615    arguments: Vec<Box<dyn Projection>>,
616    operator: Box<dyn Operator>,
617    name: String,
618}
619impl Projection for SimpleFunction {
620    fn get<'a>(&'a self, row: &'a GroupRow) -> SmartReference<'a, Value> {
621        let mut args = vec![];
622        for a in &self.arguments {
623            args.push(a.get(row));
624        }
625        self.operator.get(&args)
626    }
627    fn name(&self) -> &str {
628        &self.name
629    }
630}
631
632fn build_function(
633    metadata: &Metadata,
634    engine: &Engine,
635    args: &FunctionArguments,
636    operator: Box<dyn Operator>,
637) -> Result<Box<dyn Projection>, CvsSqlError> {
638    let arguments = match &args {
639        FunctionArguments::List(lst) => {
640            if matches!(lst.duplicate_treatment, Some(DuplicateTreatment::Distinct)) {
641                return Err(CvsSqlError::Unsupported(format!(
642                    "Function {} with distinct argument",
643                    operator.name()
644                )));
645            }
646            if let Some(c) = lst.clauses.first() {
647                return Err(CvsSqlError::Unsupported(format!("{c}")));
648            }
649            let mut args = vec![];
650            for a in &lst.args {
651                let a = match a {
652                    FunctionArg::Unnamed(FunctionArgExpr::Expr(e)) => {
653                        e.convert_single(metadata, engine)?
654                    }
655                    _ => {
656                        return Err(CvsSqlError::Unsupported(format!(
657                            "{} as argument in function {}",
658                            a,
659                            operator.name()
660                        )));
661                    }
662                };
663                args.push(a);
664            }
665            args
666        }
667        FunctionArguments::Subquery(_) => {
668            return Err(CvsSqlError::Unsupported(
669                "function subquery arguments".into(),
670            ));
671        }
672        FunctionArguments::None => vec![],
673    };
674    if arguments.len() < operator.min_args() {
675        return Err(CvsSqlError::Unsupported(format!(
676            "Function {} with {} arguments or less",
677            operator.name(),
678            arguments.len()
679        )));
680    }
681    if let Some(max) = operator.max_args()
682        && arguments.len() > max
683    {
684        return Err(CvsSqlError::Unsupported(format!(
685            "Function {} with {} arguments or more",
686            operator.name(),
687            arguments.len()
688        )));
689    }
690    let name = format!(
691        "{}({})",
692        operator.name(),
693        arguments.iter().map(|f| f.name()).join(", ")
694    );
695
696    Ok(Box::new(SimpleFunction {
697        arguments,
698        operator,
699        name,
700    }))
701}
702impl From<Option<BigDecimal>> for SmartReference<'_, Value> {
703    fn from(val: Option<BigDecimal>) -> Self {
704        match val {
705            None => Value::Empty,
706            Some(num) => Value::Number(num),
707        }
708        .into()
709    }
710}
711
712impl From<Option<u32>> for SmartReference<'_, Value> {
713    fn from(val: Option<u32>) -> Self {
714        match val {
715            None => Value::Empty,
716            Some(num) => Value::Number(num.into()),
717        }
718        .into()
719    }
720}
721impl From<f64> for SmartReference<'_, Value> {
722    fn from(val: f64) -> Self {
723        BigDecimal::from_f64(val).into()
724    }
725}
726
727impl From<Option<usize>> for SmartReference<'_, Value> {
728    fn from(val: Option<usize>) -> Self {
729        match val {
730            None => Value::Empty,
731            Some(num) => match BigDecimal::from_usize(num) {
732                Some(num) => Value::Number(num),
733                None => Value::Empty,
734            },
735        }
736        .into()
737    }
738}
739impl From<usize> for SmartReference<'_, Value> {
740    fn from(val: usize) -> Self {
741        match BigDecimal::from_usize(val) {
742            Some(num) => Value::Number(num),
743            None => Value::Empty,
744        }
745        .into()
746    }
747}
748
749impl From<Option<String>> for SmartReference<'_, Value> {
750    fn from(val: Option<String>) -> Self {
751        match val {
752            None => Value::Empty,
753            Some(str) => Value::Str(str),
754        }
755        .into()
756    }
757}
758impl From<Option<&str>> for SmartReference<'_, Value> {
759    fn from(val: Option<&str>) -> Self {
760        match val {
761            None => Value::Empty,
762            Some(str) => Value::Str(str.to_string()),
763        }
764        .into()
765    }
766}
767
768trait Extractor {
769    fn as_num(&self) -> Option<&BigDecimal>;
770    fn as_string(&self) -> Option<&str>;
771    fn as_bool(&self) -> Option<&bool>;
772    fn as_u32(&self) -> Option<u32> {
773        self.as_num().and_then(|s| s.to_u32())
774    }
775    fn as_i64(&self) -> Option<i64> {
776        self.as_num().and_then(|s| s.to_i64())
777    }
778    fn as_usize(&self) -> Option<usize> {
779        self.as_num().and_then(|s| s.to_usize())
780    }
781    fn as_f64(&self) -> Option<f64> {
782        self.as_num().and_then(|s| s.to_f64())
783    }
784}
785impl Extractor for Value {
786    fn as_num(&self) -> Option<&BigDecimal> {
787        match self {
788            Value::Number(num) => Some(num),
789            _ => None,
790        }
791    }
792    fn as_string(&self) -> Option<&str> {
793        match self {
794            Value::Str(str) => Some(str),
795            _ => None,
796        }
797    }
798    fn as_bool(&self) -> Option<&bool> {
799        match self {
800            Value::Bool(b) => Some(b),
801            _ => None,
802        }
803    }
804}
805impl<T: Extractor> Extractor for SmartReference<'_, T> {
806    fn as_num(&self) -> Option<&BigDecimal> {
807        self.deref().as_num()
808    }
809    fn as_string(&self) -> Option<&str> {
810        self.deref().as_string()
811    }
812    fn as_bool(&self) -> Option<&bool> {
813        self.deref().as_bool()
814    }
815}
816impl<T: Extractor> Extractor for Option<&T> {
817    fn as_num(&self) -> Option<&BigDecimal> {
818        self.and_then(|t| t.as_num())
819    }
820    fn as_string(&self) -> Option<&str> {
821        self.and_then(|s| s.as_string())
822    }
823    fn as_bool(&self) -> Option<&bool> {
824        self.and_then(|s| s.as_bool())
825    }
826}
827
828struct Abs {}
829impl Operator for Abs {
830    fn get<'a>(&'a self, args: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
831        args.first().as_num().map(|t| t.abs()).into()
832    }
833    fn max_args(&self) -> Option<usize> {
834        Some(1)
835    }
836    fn min_args(&self) -> usize {
837        1
838    }
839    fn name(&self) -> &str {
840        "ABS"
841    }
842
843    #[cfg(test)]
844    fn examples<'a>(&'a self) -> Vec<FunctionExample<'a>> {
845        vec![
846            FunctionExample {
847                name: "positive_number",
848                arguments: vec!["11.44"],
849                expected_results: "11.44",
850            },
851            FunctionExample {
852                name: "negative_number",
853                arguments: vec!["-0.44"],
854                expected_results: "0.44",
855            },
856            FunctionExample {
857                name: "nan",
858                arguments: vec!["test"],
859                expected_results: "",
860            },
861        ]
862    }
863}
864
865struct Ascii {}
866impl Operator for Ascii {
867    fn get<'a>(&'a self, args: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
868        args.first()
869            .as_string()
870            .and_then(|s| s.chars().next())
871            .map(|i| i as u32)
872            .into()
873    }
874    fn max_args(&self) -> Option<usize> {
875        Some(1)
876    }
877    fn min_args(&self) -> usize {
878        1
879    }
880    fn name(&self) -> &str {
881        "ASCII"
882    }
883
884    #[cfg(test)]
885    fn examples<'a>(&'a self) -> Vec<FunctionExample<'a>> {
886        vec![
887            FunctionExample {
888                name: "simple",
889                arguments: vec!["a"],
890                expected_results: "97",
891            },
892            FunctionExample {
893                name: "word",
894                arguments: vec!["abc"],
895                expected_results: "97",
896            },
897            FunctionExample {
898                name: "number",
899                arguments: vec!["100"],
900                expected_results: "",
901            },
902        ]
903    }
904}
905
906struct Chr {}
907impl Operator for Chr {
908    fn get<'a>(&'a self, args: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
909        args.first()
910            .as_u32()
911            .and_then(char::from_u32)
912            .map(|c| c.to_string())
913            .into()
914    }
915    fn max_args(&self) -> Option<usize> {
916        Some(1)
917    }
918    fn min_args(&self) -> usize {
919        1
920    }
921    fn name(&self) -> &str {
922        "CHR"
923    }
924
925    #[cfg(test)]
926    fn examples<'a>(&'a self) -> Vec<FunctionExample<'a>> {
927        vec![
928            FunctionExample {
929                name: "simple",
930                arguments: vec!["97"],
931                expected_results: "a",
932            },
933            FunctionExample {
934                name: "neg",
935                arguments: vec!["-100"],
936                expected_results: "",
937            },
938            FunctionExample {
939                name: "float",
940                arguments: vec!["97.1"],
941                expected_results: "a",
942            },
943            FunctionExample {
944                name: "str",
945                arguments: vec!["abc"],
946                expected_results: "",
947            },
948        ]
949    }
950}
951
952struct Length {}
953impl Operator for Length {
954    fn get<'a>(&'a self, args: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
955        args.first().as_string().map(|s| s.len()).into()
956    }
957    fn max_args(&self) -> Option<usize> {
958        Some(1)
959    }
960    fn min_args(&self) -> usize {
961        1
962    }
963    fn name(&self) -> &str {
964        "LENGTH"
965    }
966
967    #[cfg(test)]
968    fn examples<'a>(&'a self) -> Vec<FunctionExample<'a>> {
969        vec![
970            FunctionExample {
971                name: "simple",
972                arguments: vec!["hello"],
973                expected_results: "5",
974            },
975            FunctionExample {
976                name: "number",
977                arguments: vec!["-100"],
978                expected_results: "",
979            },
980        ]
981    }
982}
983
984struct Coalece {}
985impl Operator for Coalece {
986    fn get<'a>(&'a self, args: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
987        for a in args.iter() {
988            if !a.is_empty() {
989                return a.deref().clone().into();
990            }
991        }
992        Value::Empty.into()
993    }
994    fn max_args(&self) -> Option<usize> {
995        None
996    }
997    fn min_args(&self) -> usize {
998        0
999    }
1000    fn name(&self) -> &str {
1001        "COALESCE"
1002    }
1003
1004    #[cfg(test)]
1005    fn examples<'a>(&'a self) -> Vec<FunctionExample<'a>> {
1006        vec![
1007            FunctionExample {
1008                name: "simple",
1009                arguments: vec!["", "", "5", "6"],
1010                expected_results: "5",
1011            },
1012            FunctionExample {
1013                name: "nope",
1014                arguments: vec!["", "", "", "", ""],
1015                expected_results: "",
1016            },
1017            FunctionExample {
1018                name: "first",
1019                arguments: vec!["a", "b"],
1020                expected_results: "a",
1021            },
1022            FunctionExample {
1023                name: "empty",
1024                arguments: vec![],
1025                expected_results: "",
1026            },
1027        ]
1028    }
1029}
1030
1031struct Concat {}
1032impl Operator for Concat {
1033    fn get<'a>(&'a self, args: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
1034        let str = args.iter().map(|f| f.to_string()).join("");
1035        Value::Str(str).into()
1036    }
1037    fn max_args(&self) -> Option<usize> {
1038        None
1039    }
1040    fn min_args(&self) -> usize {
1041        0
1042    }
1043    fn name(&self) -> &str {
1044        "CONCAT"
1045    }
1046
1047    #[cfg(test)]
1048    fn examples<'a>(&'a self) -> Vec<FunctionExample<'a>> {
1049        vec![
1050            FunctionExample {
1051                name: "simple",
1052                arguments: vec!["a", "b", "cd", "e"],
1053                expected_results: "abcde",
1054            },
1055            FunctionExample {
1056                name: "with_nums",
1057                arguments: vec!["a", "1", "b"],
1058                expected_results: "a1b",
1059            },
1060        ]
1061    }
1062}
1063
1064struct ConcatWs {}
1065impl Operator for ConcatWs {
1066    fn get<'a>(&'a self, args: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
1067        let Some(sep) = args.first() else {
1068            return Value::Empty.into();
1069        };
1070        let sep = sep.to_string();
1071        let str = args
1072            .iter()
1073            .skip(1)
1074            .filter(|f| !f.is_empty())
1075            .map(|f| f.to_string())
1076            .join(sep.as_str());
1077        Value::Str(str).into()
1078    }
1079    fn max_args(&self) -> Option<usize> {
1080        None
1081    }
1082    fn min_args(&self) -> usize {
1083        1
1084    }
1085    fn name(&self) -> &str {
1086        "CONCAT_WS"
1087    }
1088
1089    #[cfg(test)]
1090    fn examples<'a>(&'a self) -> Vec<FunctionExample<'a>> {
1091        vec![FunctionExample {
1092            name: "simple",
1093            arguments: vec!["|", "a", "b", "cd", "e"],
1094            expected_results: "a|b|cd|e",
1095        }]
1096    }
1097}
1098
1099struct CurrentDate {}
1100impl Operator for CurrentDate {
1101    fn get<'a>(&'a self, _: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
1102        Value::Date(Utc::now().naive_utc().date()).into()
1103    }
1104    fn max_args(&self) -> Option<usize> {
1105        Some(0)
1106    }
1107    fn min_args(&self) -> usize {
1108        0
1109    }
1110    fn name(&self) -> &str {
1111        "CURRENT_DATE"
1112    }
1113}
1114struct Now {}
1115impl Operator for Now {
1116    fn get<'a>(&'a self, _: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
1117        Value::Timestamp(Utc::now().naive_utc()).into()
1118    }
1119    fn max_args(&self) -> Option<usize> {
1120        Some(0)
1121    }
1122    fn min_args(&self) -> usize {
1123        0
1124    }
1125    fn name(&self) -> &str {
1126        "NOW"
1127    }
1128}
1129struct User {}
1130impl Operator for User {
1131    fn get<'a>(&'a self, _: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
1132        Value::Str(whoami::username()).into()
1133    }
1134    fn max_args(&self) -> Option<usize> {
1135        Some(0)
1136    }
1137    fn min_args(&self) -> usize {
1138        0
1139    }
1140    fn name(&self) -> &str {
1141        "CURRENT_USER"
1142    }
1143}
1144
1145struct Format {}
1146impl Operator for Format {
1147    fn get<'a>(&'a self, args: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
1148        let Some(value) = args.first() else {
1149            return Value::Empty.into();
1150        };
1151        let format = args.get(1);
1152        let Some(format) = format.as_string() else {
1153            return Value::Empty.into();
1154        };
1155        let formatted = match value.deref() {
1156            Value::Date(date) => date.format(format),
1157            Value::Timestamp(ts) => ts.format(format),
1158            _ => {
1159                return Value::Empty.into();
1160            }
1161        };
1162        let mut text = String::new();
1163        if formatted.write_to(&mut text).is_err() {
1164            return Value::Empty.into();
1165        }
1166
1167        Value::Str(text).into()
1168    }
1169    fn max_args(&self) -> Option<usize> {
1170        Some(2)
1171    }
1172    fn min_args(&self) -> usize {
1173        2
1174    }
1175    fn name(&self) -> &str {
1176        "FORMAT"
1177    }
1178
1179    #[cfg(test)]
1180    fn examples<'a>(&'a self) -> Vec<FunctionExample<'a>> {
1181        vec![
1182            FunctionExample {
1183                name: "simple_date",
1184                arguments: vec!["2024-11-23", "%d/%m/%Y"],
1185                expected_results: "23/11/2024",
1186            },
1187            FunctionExample {
1188                name: "simple_timestamp",
1189                arguments: vec!["2024-11-23 16:20:21.003", "%v %r"],
1190                expected_results: "23-Nov-2024 04:20:21 PM",
1191            },
1192            FunctionExample {
1193                name: "format_as_number",
1194                arguments: vec!["2024-11-23 16:20:21.003", "123"],
1195                expected_results: "",
1196            },
1197            FunctionExample {
1198                name: "invalid_format",
1199                arguments: vec!["2024-11-23 16:20:21.003", "%Q"],
1200                expected_results: "",
1201            },
1202            FunctionExample {
1203                name: "numeric_value",
1204                arguments: vec!["3", "%v %r"],
1205                expected_results: "",
1206            },
1207        ]
1208    }
1209}
1210
1211struct ToTimestamp {}
1212impl Operator for ToTimestamp {
1213    fn get<'a>(&'a self, args: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
1214        let Some(time) = args.first().as_i64() else {
1215            return Value::Empty.into();
1216        };
1217
1218        let LocalResult::Single(time) = Utc.timestamp_opt(time, 0) else {
1219            return Value::Empty.into();
1220        };
1221
1222        Value::Timestamp(time.naive_utc()).into()
1223    }
1224    fn max_args(&self) -> Option<usize> {
1225        Some(1)
1226    }
1227    fn min_args(&self) -> usize {
1228        1
1229    }
1230    fn name(&self) -> &str {
1231        "TO_TIMESTAMP"
1232    }
1233
1234    #[cfg(test)]
1235    fn examples<'a>(&'a self) -> Vec<FunctionExample<'a>> {
1236        vec![
1237            FunctionExample {
1238                name: "should_work",
1239                arguments: vec!["1400234525"],
1240                expected_results: "2014-05-16 10:02:05",
1241            },
1242            FunctionExample {
1243                name: "nan",
1244                arguments: vec!["test"],
1245                expected_results: "",
1246            },
1247        ]
1248    }
1249}
1250
1251struct Greatest {}
1252impl Operator for Greatest {
1253    fn get<'a>(&'a self, args: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
1254        let mut greatest = None;
1255        for a in args.iter() {
1256            match &greatest {
1257                None => greatest = Some(a.deref().clone()),
1258                Some(val) => {
1259                    if a.deref() > val {
1260                        greatest = Some(a.deref().clone());
1261                    }
1262                }
1263            }
1264        }
1265        match greatest {
1266            None => Value::Empty.into(),
1267            Some(greatest) => greatest.into(),
1268        }
1269    }
1270    fn max_args(&self) -> Option<usize> {
1271        None
1272    }
1273    fn min_args(&self) -> usize {
1274        0
1275    }
1276    fn name(&self) -> &str {
1277        "GREATEST"
1278    }
1279
1280    #[cfg(test)]
1281    fn examples<'a>(&'a self) -> Vec<FunctionExample<'a>> {
1282        vec![
1283            FunctionExample {
1284                name: "greatest",
1285                arguments: vec!["10", "400040", "1044", "-134522352"],
1286                expected_results: "400040",
1287            },
1288            FunctionExample {
1289                name: "empty",
1290                arguments: vec![],
1291                expected_results: "",
1292            },
1293        ]
1294    }
1295}
1296struct If {}
1297impl Operator for If {
1298    fn get<'a>(&'a self, args: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
1299        let first = args.first();
1300        let Some(condition) = first.as_bool() else {
1301            return Value::Empty.into();
1302        };
1303        let value = if *condition { args.get(1) } else { args.get(2) };
1304        match value {
1305            Some(v) => v.deref().clone().into(),
1306            None => Value::Empty.into(),
1307        }
1308    }
1309    fn max_args(&self) -> Option<usize> {
1310        Some(3)
1311    }
1312    fn min_args(&self) -> usize {
1313        3
1314    }
1315    fn name(&self) -> &str {
1316        "IF"
1317    }
1318
1319    #[cfg(test)]
1320    fn examples<'a>(&'a self) -> Vec<FunctionExample<'a>> {
1321        vec![
1322            FunctionExample {
1323                name: "true",
1324                arguments: vec!["TRUE", "100", "-100"],
1325                expected_results: "100",
1326            },
1327            FunctionExample {
1328                name: "false",
1329                arguments: vec!["FALSE", "100", "-100"],
1330                expected_results: "-100",
1331            },
1332            FunctionExample {
1333                name: "not_bool",
1334                arguments: vec!["test", "100", "-100"],
1335                expected_results: "",
1336            },
1337        ]
1338    }
1339}
1340
1341struct NullIf {}
1342impl Operator for NullIf {
1343    fn get<'a>(&'a self, args: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
1344        let Some(value_one) = args.first() else {
1345            return Value::Empty.into();
1346        };
1347        let Some(value_two) = args.get(1) else {
1348            return Value::Empty.into();
1349        };
1350        if *value_one != *value_two {
1351            value_one.deref().clone().into()
1352        } else {
1353            Value::Empty.into()
1354        }
1355    }
1356    fn max_args(&self) -> Option<usize> {
1357        Some(2)
1358    }
1359    fn min_args(&self) -> usize {
1360        2
1361    }
1362    fn name(&self) -> &str {
1363        "NULLIF"
1364    }
1365
1366    #[cfg(test)]
1367    fn examples<'a>(&'a self) -> Vec<FunctionExample<'a>> {
1368        vec![
1369            FunctionExample {
1370                name: "eq",
1371                arguments: vec!["hello", "hello"],
1372                expected_results: "",
1373            },
1374            FunctionExample {
1375                name: "neq",
1376                arguments: vec!["hello", "world"],
1377                expected_results: "hello",
1378            },
1379        ]
1380    }
1381}
1382
1383struct Lower {}
1384impl Operator for Lower {
1385    fn get<'a>(&'a self, args: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
1386        args.first()
1387            .and_then(|f| f.as_string())
1388            .map(|f| f.to_lowercase())
1389            .into()
1390    }
1391    fn max_args(&self) -> Option<usize> {
1392        Some(1)
1393    }
1394    fn min_args(&self) -> usize {
1395        1
1396    }
1397    fn name(&self) -> &str {
1398        "LOWER"
1399    }
1400
1401    #[cfg(test)]
1402    fn examples<'a>(&'a self) -> Vec<FunctionExample<'a>> {
1403        vec![
1404            FunctionExample {
1405                name: "str",
1406                arguments: vec!["HeLLo"],
1407                expected_results: "hello",
1408            },
1409            FunctionExample {
1410                name: "number",
1411                arguments: vec!["123"],
1412                expected_results: "",
1413            },
1414        ]
1415    }
1416}
1417struct Upper {}
1418impl Operator for Upper {
1419    fn get<'a>(&'a self, args: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
1420        args.first()
1421            .and_then(|f| f.as_string())
1422            .map(|f| f.to_uppercase())
1423            .into()
1424    }
1425    fn max_args(&self) -> Option<usize> {
1426        Some(1)
1427    }
1428    fn min_args(&self) -> usize {
1429        1
1430    }
1431    fn name(&self) -> &str {
1432        "UPPER"
1433    }
1434
1435    #[cfg(test)]
1436    fn examples<'a>(&'a self) -> Vec<FunctionExample<'a>> {
1437        vec![
1438            FunctionExample {
1439                name: "str",
1440                arguments: vec!["HeLLo"],
1441                expected_results: "HELLO",
1442            },
1443            FunctionExample {
1444                name: "number",
1445                arguments: vec!["123"],
1446                expected_results: "",
1447            },
1448        ]
1449    }
1450}
1451
1452struct Least {}
1453impl Operator for Least {
1454    fn get<'a>(&'a self, args: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
1455        let mut least = None;
1456        for a in args.iter() {
1457            if !a.is_empty() {
1458                match &least {
1459                    None => least = Some(a.deref().clone()),
1460                    Some(val) => {
1461                        if a.deref() < val {
1462                            least = Some(a.deref().clone());
1463                        }
1464                    }
1465                }
1466            }
1467        }
1468        match least {
1469            None => Value::Empty.into(),
1470            Some(least) => least.into(),
1471        }
1472    }
1473    fn max_args(&self) -> Option<usize> {
1474        None
1475    }
1476    fn min_args(&self) -> usize {
1477        0
1478    }
1479    fn name(&self) -> &str {
1480        "LEAST"
1481    }
1482
1483    #[cfg(test)]
1484    fn examples<'a>(&'a self) -> Vec<FunctionExample<'a>> {
1485        vec![
1486            FunctionExample {
1487                name: "least",
1488                arguments: vec!["10", "400040", "1044", "-4", "-1"],
1489                expected_results: "-4",
1490            },
1491            FunctionExample {
1492                name: "empty",
1493                arguments: vec![],
1494                expected_results: "",
1495            },
1496        ]
1497    }
1498}
1499
1500struct Left {}
1501impl Operator for Left {
1502    fn get<'a>(&'a self, args: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
1503        let text = args.first();
1504        let Some(text) = text.as_string() else {
1505            return Value::Empty.into();
1506        };
1507        let length = args.get(1);
1508        let Some(length) = length.as_usize() else {
1509            return Value::Empty.into();
1510        };
1511        if text.len() < length {
1512            Value::Str(text.to_string()).into()
1513        } else {
1514            Value::Str(text[0..length].to_string()).into()
1515        }
1516    }
1517    fn max_args(&self) -> Option<usize> {
1518        Some(2)
1519    }
1520    fn min_args(&self) -> usize {
1521        2
1522    }
1523    fn name(&self) -> &str {
1524        "LEFT"
1525    }
1526
1527    #[cfg(test)]
1528    fn examples<'a>(&'a self) -> Vec<FunctionExample<'a>> {
1529        vec![
1530            FunctionExample {
1531                name: "simple",
1532                arguments: vec!["test", "2"],
1533                expected_results: "te",
1534            },
1535            FunctionExample {
1536                name: "exact",
1537                arguments: vec!["test", "4"],
1538                expected_results: "test",
1539            },
1540            FunctionExample {
1541                name: "more",
1542                arguments: vec!["test", "12"],
1543                expected_results: "test",
1544            },
1545            FunctionExample {
1546                name: "nan",
1547                arguments: vec!["test", "five"],
1548                expected_results: "",
1549            },
1550            FunctionExample {
1551                name: "not_a_text",
1552                arguments: vec!["10", "10"],
1553                expected_results: "",
1554            },
1555        ]
1556    }
1557}
1558
1559struct Right {}
1560impl Operator for Right {
1561    fn get<'a>(&'a self, args: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
1562        let text = args.first();
1563        let Some(text) = text.as_string() else {
1564            return Value::Empty.into();
1565        };
1566        let length = args.get(1);
1567        let Some(length) = length.as_usize() else {
1568            return Value::Empty.into();
1569        };
1570        if text.len() < length {
1571            Value::Str(text.to_string()).into()
1572        } else {
1573            let start = text.len() - length;
1574            Value::Str(text[start..].to_string()).into()
1575        }
1576    }
1577    fn max_args(&self) -> Option<usize> {
1578        Some(2)
1579    }
1580    fn min_args(&self) -> usize {
1581        2
1582    }
1583    fn name(&self) -> &str {
1584        "RIGHT"
1585    }
1586
1587    #[cfg(test)]
1588    fn examples<'a>(&'a self) -> Vec<FunctionExample<'a>> {
1589        vec![
1590            FunctionExample {
1591                name: "simple",
1592                arguments: vec!["test", "3"],
1593                expected_results: "est",
1594            },
1595            FunctionExample {
1596                name: "exact",
1597                arguments: vec!["test", "4"],
1598                expected_results: "test",
1599            },
1600            FunctionExample {
1601                name: "more",
1602                arguments: vec!["test", "12"],
1603                expected_results: "test",
1604            },
1605            FunctionExample {
1606                name: "nan",
1607                arguments: vec!["test", "five"],
1608                expected_results: "",
1609            },
1610            FunctionExample {
1611                name: "not_a_text",
1612                arguments: vec!["10", "10"],
1613                expected_results: "",
1614            },
1615        ]
1616    }
1617}
1618
1619struct Lpad {}
1620impl Operator for Lpad {
1621    fn get<'a>(&'a self, args: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
1622        let text = args.first();
1623        let Some(text) = text.as_string() else {
1624            return Value::Empty.into();
1625        };
1626        let length = args.get(1);
1627        let Some(length) = length.as_usize() else {
1628            return Value::Empty.into();
1629        };
1630        let pad = args.get(2);
1631
1632        let Some(pad) = pad.as_string() else {
1633            return Value::Empty.into();
1634        };
1635
1636        if text.len() > length {
1637            Value::Str(text[0..length].to_string()).into()
1638        } else if pad.is_empty() {
1639            Value::Str(text.to_string()).into()
1640        } else {
1641            let mut str = String::new();
1642            let mut chars = pad.chars().cycle();
1643            for _ in 0..length - text.len() {
1644                let chr = chars.next().unwrap();
1645                str.push(chr);
1646            }
1647            str.push_str(text);
1648            Value::Str(str).into()
1649        }
1650    }
1651
1652    fn max_args(&self) -> Option<usize> {
1653        Some(3)
1654    }
1655    fn min_args(&self) -> usize {
1656        3
1657    }
1658    fn name(&self) -> &str {
1659        "LPAD"
1660    }
1661
1662    #[cfg(test)]
1663    fn examples<'a>(&'a self) -> Vec<FunctionExample<'a>> {
1664        vec![
1665            FunctionExample {
1666                name: "simple",
1667                arguments: vec!["text", "10", "pad"],
1668                expected_results: "padpadtext",
1669            },
1670            FunctionExample {
1671                name: "more",
1672                arguments: vec!["text", "12", "pad"],
1673                expected_results: "padpadpatext",
1674            },
1675            FunctionExample {
1676                name: "less",
1677                arguments: vec!["text", "3", "pad"],
1678                expected_results: "tex",
1679            },
1680            FunctionExample {
1681                name: "exact",
1682                arguments: vec!["text", "4", "pad"],
1683                expected_results: "text",
1684            },
1685            FunctionExample {
1686                name: "negative",
1687                arguments: vec!["text", "-122", "pad"],
1688                expected_results: "",
1689            },
1690            FunctionExample {
1691                name: "non_text",
1692                arguments: vec!["12", "10", "pad"],
1693                expected_results: "",
1694            },
1695            FunctionExample {
1696                name: "non_number",
1697                arguments: vec!["text", "me", "pad"],
1698                expected_results: "",
1699            },
1700            FunctionExample {
1701                name: "not_pad",
1702                arguments: vec!["text", "10", "2"],
1703                expected_results: "",
1704            },
1705            FunctionExample {
1706                name: "empty_pad",
1707                arguments: vec!["text", "10", "2"],
1708                expected_results: "",
1709            },
1710        ]
1711    }
1712}
1713
1714struct Rpad {}
1715impl Operator for Rpad {
1716    fn get<'a>(&'a self, args: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
1717        let text = args.first();
1718        let Some(text) = text.as_string() else {
1719            return Value::Empty.into();
1720        };
1721        let length = args.get(1);
1722        let Some(length) = length.as_usize() else {
1723            return Value::Empty.into();
1724        };
1725        let pad = args.get(2);
1726
1727        let Some(pad) = pad.as_string() else {
1728            return Value::Empty.into();
1729        };
1730
1731        if text.len() > length {
1732            Value::Str(text[0..length].to_string()).into()
1733        } else if pad.is_empty() {
1734            Value::Str(text.to_string()).into()
1735        } else {
1736            let mut str = text.to_string();
1737            let mut chars = pad.chars().cycle();
1738            for _ in 0..length - text.len() {
1739                let chr = chars.next().unwrap();
1740                str.push(chr);
1741            }
1742            Value::Str(str).into()
1743        }
1744    }
1745
1746    fn max_args(&self) -> Option<usize> {
1747        Some(3)
1748    }
1749    fn min_args(&self) -> usize {
1750        3
1751    }
1752    fn name(&self) -> &str {
1753        "RPAD"
1754    }
1755
1756    #[cfg(test)]
1757    fn examples<'a>(&'a self) -> Vec<FunctionExample<'a>> {
1758        vec![
1759            FunctionExample {
1760                name: "simple",
1761                arguments: vec!["text", "10", "pad"],
1762                expected_results: "textpadpad",
1763            },
1764            FunctionExample {
1765                name: "more",
1766                arguments: vec!["text", "12", "pad"],
1767                expected_results: "textpadpadpa",
1768            },
1769            FunctionExample {
1770                name: "less",
1771                arguments: vec!["text", "3", "pad"],
1772                expected_results: "tex",
1773            },
1774            FunctionExample {
1775                name: "exact",
1776                arguments: vec!["text", "4", "pad"],
1777                expected_results: "text",
1778            },
1779            FunctionExample {
1780                name: "negative",
1781                arguments: vec!["text", "-122", "pad"],
1782                expected_results: "",
1783            },
1784            FunctionExample {
1785                name: "non_text",
1786                arguments: vec!["12", "10", "pad"],
1787                expected_results: "",
1788            },
1789            FunctionExample {
1790                name: "non_number",
1791                arguments: vec!["text", "me", "pad"],
1792                expected_results: "",
1793            },
1794            FunctionExample {
1795                name: "not_pad",
1796                arguments: vec!["text", "10", "2"],
1797                expected_results: "",
1798            },
1799            FunctionExample {
1800                name: "empty_pad",
1801                arguments: vec!["text", "10", "2"],
1802                expected_results: "",
1803            },
1804        ]
1805    }
1806}
1807
1808struct Ltrim {}
1809impl Operator for Ltrim {
1810    fn get<'a>(&'a self, args: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
1811        args.first()
1812            .and_then(|f| f.as_string())
1813            .map(|f| f.trim_start())
1814            .into()
1815    }
1816
1817    fn max_args(&self) -> Option<usize> {
1818        Some(1)
1819    }
1820    fn min_args(&self) -> usize {
1821        1
1822    }
1823    fn name(&self) -> &str {
1824        "LTRIM"
1825    }
1826
1827    #[cfg(test)]
1828    fn examples<'a>(&'a self) -> Vec<FunctionExample<'a>> {
1829        vec![
1830            FunctionExample {
1831                name: "simple",
1832                arguments: vec!["  hello"],
1833                expected_results: "hello",
1834            },
1835            FunctionExample {
1836                name: "not_text",
1837                arguments: vec!["12"],
1838                expected_results: "",
1839            },
1840        ]
1841    }
1842}
1843struct Rtrim {}
1844impl Operator for Rtrim {
1845    fn get<'a>(&'a self, args: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
1846        args.first()
1847            .and_then(|f| f.as_string())
1848            .map(|f| f.trim_end())
1849            .into()
1850    }
1851
1852    fn max_args(&self) -> Option<usize> {
1853        Some(1)
1854    }
1855    fn min_args(&self) -> usize {
1856        1
1857    }
1858    fn name(&self) -> &str {
1859        "RTRIM"
1860    }
1861
1862    #[cfg(test)]
1863    fn examples<'a>(&'a self) -> Vec<FunctionExample<'a>> {
1864        vec![
1865            FunctionExample {
1866                name: "simple",
1867                arguments: vec!["hello\t"],
1868                expected_results: "hello",
1869            },
1870            FunctionExample {
1871                name: "not_text",
1872                arguments: vec!["12"],
1873                expected_results: "",
1874            },
1875        ]
1876    }
1877}
1878
1879struct Position {}
1880impl Operator for Position {
1881    fn get<'a>(&'a self, args: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
1882        let sub = args.first();
1883        let Some(sub) = sub.as_string() else {
1884            return Value::Empty.into();
1885        };
1886        let str = args.get(1);
1887        let Some(str) = str.as_string() else {
1888            return Value::Empty.into();
1889        };
1890        let start = match args.get(2) {
1891            None => 0,
1892            Some(val) => {
1893                let Some(mut start) = val.as_usize() else {
1894                    return Value::Empty.into();
1895                };
1896                if start == 0 {
1897                    start = 1;
1898                }
1899                if start > str.len() {
1900                    return 0.into();
1901                }
1902                start - 1
1903            }
1904        };
1905        let position = str[start..].find(sub).map(|f| f + 1).unwrap_or_default();
1906        (position + start).into()
1907    }
1908
1909    fn max_args(&self) -> Option<usize> {
1910        Some(3)
1911    }
1912    fn min_args(&self) -> usize {
1913        2
1914    }
1915    fn name(&self) -> &str {
1916        "POSITION"
1917    }
1918
1919    #[cfg(test)]
1920    fn examples<'a>(&'a self) -> Vec<FunctionExample<'a>> {
1921        vec![
1922            FunctionExample {
1923                name: "simple",
1924                arguments: vec!["bar", "foobarbar"],
1925                expected_results: "4",
1926            },
1927            FunctionExample {
1928                name: "nop",
1929                arguments: vec!["xbar", "foobarbar"],
1930                expected_results: "0",
1931            },
1932            FunctionExample {
1933                name: "with_start",
1934                arguments: vec!["bar", "foobarbar", "5"],
1935                expected_results: "7",
1936            },
1937            FunctionExample {
1938                name: "not_a_sub",
1939                arguments: vec!["5", "foobarbar", "5"],
1940                expected_results: "",
1941            },
1942            FunctionExample {
1943                name: "with_str_as_num",
1944                arguments: vec!["bar", "20", "5"],
1945                expected_results: "",
1946            },
1947            FunctionExample {
1948                name: "with_start_as_str",
1949                arguments: vec!["bar", "foobarbar", "a"],
1950                expected_results: "",
1951            },
1952            FunctionExample {
1953                name: "with_start_larger",
1954                arguments: vec!["bar", "foobarbar", "25"],
1955                expected_results: "0",
1956            },
1957        ]
1958    }
1959}
1960
1961struct Repeat {}
1962impl Operator for Repeat {
1963    fn get<'a>(&'a self, args: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
1964        let str = args.first();
1965        let Some(str) = str.as_string() else {
1966            return Value::Empty.into();
1967        };
1968        let count = args.get(1);
1969        let Some(count) = count.as_usize() else {
1970            return Value::Empty.into();
1971        };
1972        Value::Str(str.repeat(count)).into()
1973    }
1974
1975    fn max_args(&self) -> Option<usize> {
1976        Some(2)
1977    }
1978    fn min_args(&self) -> usize {
1979        2
1980    }
1981    fn name(&self) -> &str {
1982        "REPEAT"
1983    }
1984
1985    #[cfg(test)]
1986    fn examples<'a>(&'a self) -> Vec<FunctionExample<'a>> {
1987        vec![
1988            FunctionExample {
1989                name: "simple",
1990                arguments: vec!["bar", "3"],
1991                expected_results: "barbarbar",
1992            },
1993            FunctionExample {
1994                name: "not_a_string",
1995                arguments: vec!["4", "3"],
1996                expected_results: "",
1997            },
1998            FunctionExample {
1999                name: "not_a_number",
2000                arguments: vec!["bar", "test"],
2001                expected_results: "",
2002            },
2003        ]
2004    }
2005}
2006
2007struct Replace {}
2008impl Operator for Replace {
2009    fn get<'a>(&'a self, args: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
2010        let str = args.first();
2011        let Some(str) = str.as_string() else {
2012            return Value::Empty.into();
2013        };
2014        let what = args.get(1);
2015        let Some(what) = what.as_string() else {
2016            return Value::Empty.into();
2017        };
2018        let into = args.get(2);
2019        let Some(into) = into.as_string() else {
2020            return Value::Empty.into();
2021        };
2022        Value::Str(str.replace(what, into)).into()
2023    }
2024
2025    fn max_args(&self) -> Option<usize> {
2026        Some(3)
2027    }
2028    fn min_args(&self) -> usize {
2029        3
2030    }
2031    fn name(&self) -> &str {
2032        "REPLACE"
2033    }
2034
2035    #[cfg(test)]
2036    fn examples<'a>(&'a self) -> Vec<FunctionExample<'a>> {
2037        vec![
2038            FunctionExample {
2039                name: "simple",
2040                arguments: vec!["hello", "l", "L"],
2041                expected_results: "heLLo",
2042            },
2043            FunctionExample {
2044                name: "nope",
2045                arguments: vec!["test", "bar", "foo"],
2046                expected_results: "test",
2047            },
2048            FunctionExample {
2049                name: "not_a_string",
2050                arguments: vec!["1", "test", "one"],
2051                expected_results: "",
2052            },
2053            FunctionExample {
2054                name: "not_a_what",
2055                arguments: vec!["bar", "2", "one"],
2056                expected_results: "",
2057            },
2058            FunctionExample {
2059                name: "not_a_with",
2060                arguments: vec!["bar", "test", "3"],
2061                expected_results: "",
2062            },
2063        ]
2064    }
2065}
2066
2067struct RegexReplace {}
2068impl Operator for RegexReplace {
2069    fn get<'a>(&'a self, args: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
2070        let str = args.first();
2071        let Some(str) = str.as_string() else {
2072            return Value::Empty.into();
2073        };
2074        let pattern = args.get(1);
2075        let Some(pattern) = pattern.as_string() else {
2076            return Value::Empty.into();
2077        };
2078        let Ok(pattern) = Regex::new(pattern) else {
2079            return Value::Empty.into();
2080        };
2081        let repl = args.get(2);
2082        let Some(repl) = repl.as_string() else {
2083            return Value::Empty.into();
2084        };
2085        Value::Str(pattern.replace(str, repl).to_string()).into()
2086    }
2087
2088    fn max_args(&self) -> Option<usize> {
2089        Some(3)
2090    }
2091    fn min_args(&self) -> usize {
2092        3
2093    }
2094    fn name(&self) -> &str {
2095        "REGEX_REPLACE"
2096    }
2097
2098    #[cfg(test)]
2099    fn examples<'a>(&'a self) -> Vec<FunctionExample<'a>> {
2100        vec![
2101            FunctionExample {
2102                name: "simple",
2103                arguments: vec!["a b c", "b", "B"],
2104                expected_results: "a B c",
2105            },
2106            FunctionExample {
2107                name: "few",
2108                arguments: vec!["test", "[a-z]", "T"],
2109                expected_results: "Test",
2110            },
2111            FunctionExample {
2112                name: "not_a_string",
2113                arguments: vec!["1", "b", "B"],
2114                expected_results: "",
2115            },
2116            FunctionExample {
2117                name: "not_a_string_pattern",
2118                arguments: vec!["abc", "1", "B"],
2119                expected_results: "",
2120            },
2121            FunctionExample {
2122                name: "invalid_pattern",
2123                arguments: vec!["abc", "[+", "B"],
2124                expected_results: "",
2125            },
2126            FunctionExample {
2127                name: "no_replacement",
2128                arguments: vec!["abc", "b", "4"],
2129                expected_results: "",
2130            },
2131        ]
2132    }
2133}
2134
2135struct RegexLike {}
2136impl Operator for RegexLike {
2137    fn get<'a>(&'a self, args: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
2138        let expr = args.first();
2139        let Some(expr) = expr.as_string() else {
2140            return Value::Empty.into();
2141        };
2142        let pattern = args.get(1);
2143        let Some(pattern) = pattern.as_string() else {
2144            return Value::Empty.into();
2145        };
2146        let flags = args.get(2);
2147        let pattern = if flags.is_some() {
2148            let Some(flags) = flags.as_string() else {
2149                return Value::Empty.into();
2150            };
2151
2152            Regex::new(format!("(?{flags}:{pattern})").as_str())
2153        } else {
2154            Regex::new(pattern)
2155        };
2156
2157        let Ok(pattern) = pattern else {
2158            return Value::Empty.into();
2159        };
2160
2161        Value::Bool(pattern.find(expr).is_some()).into()
2162    }
2163
2164    fn max_args(&self) -> Option<usize> {
2165        Some(3)
2166    }
2167    fn min_args(&self) -> usize {
2168        2
2169    }
2170    fn name(&self) -> &str {
2171        "REGEX_LIKE"
2172    }
2173
2174    #[cfg(test)]
2175    fn examples<'a>(&'a self) -> Vec<FunctionExample<'a>> {
2176        vec![
2177            FunctionExample {
2178                name: "simple_true",
2179                arguments: vec!["test", "es"],
2180                expected_results: "TRUE",
2181            },
2182            FunctionExample {
2183                name: "simple_false",
2184                arguments: vec!["test", "ES"],
2185                expected_results: "FALSE",
2186            },
2187            FunctionExample {
2188                name: "no_string_one",
2189                arguments: vec!["1", "op"],
2190                expected_results: "",
2191            },
2192            FunctionExample {
2193                name: "no_string_pattern",
2194                arguments: vec!["test", "FALSE"],
2195                expected_results: "",
2196            },
2197            FunctionExample {
2198                name: "invalid_pattern",
2199                arguments: vec!["test", "[+"],
2200                expected_results: "",
2201            },
2202            FunctionExample {
2203                name: "with_flags",
2204                arguments: vec!["test", "TEST", "i"],
2205                expected_results: "TRUE",
2206            },
2207            FunctionExample {
2208                name: "with_flags",
2209                arguments: vec!["test", "TEST", "i"],
2210                expected_results: "TRUE",
2211            },
2212            FunctionExample {
2213                name: "with_invalid_flags",
2214                arguments: vec!["test", "TEST", "q"],
2215                expected_results: "",
2216            },
2217            FunctionExample {
2218                name: "with_no_string_flags",
2219                arguments: vec!["test", "TEST", "TRUE"],
2220                expected_results: "",
2221            },
2222        ]
2223    }
2224}
2225
2226struct RegexSubstring {}
2227impl Operator for RegexSubstring {
2228    fn get<'a>(&'a self, args: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
2229        let expr = args.first();
2230        let Some(expr) = expr.as_string() else {
2231            return Value::Empty.into();
2232        };
2233        let pattern = args.get(1);
2234        let Some(pattern) = pattern.as_string() else {
2235            return Value::Empty.into();
2236        };
2237        let pos = args.get(2);
2238        let pos = match pos {
2239            None => Some(1),
2240            Some(pos) => pos.as_usize(),
2241        };
2242        let Some(pos) = pos else {
2243            return Value::Empty.into();
2244        };
2245        if pos == 0 {
2246            return Value::Empty.into();
2247        }
2248        let pos = pos - 1;
2249        let occurrence = args.get(3);
2250        let occurrence = match occurrence {
2251            None => Some(1),
2252            Some(occurrence) => occurrence.as_usize(),
2253        };
2254        let Some(occurrence) = occurrence else {
2255            return Value::Empty.into();
2256        };
2257        if occurrence == 0 {
2258            return Value::Empty.into();
2259        }
2260        let occurrence = occurrence - 1;
2261
2262        let flags = args.get(4);
2263        let pattern = if flags.is_some() {
2264            let Some(flags) = flags.as_string() else {
2265                return Value::Empty.into();
2266            };
2267
2268            Regex::new(format!("(?{flags}:{pattern})").as_str())
2269        } else {
2270            Regex::new(pattern)
2271        };
2272        if pos > expr.len() {
2273            return Value::Str(String::new()).into();
2274        }
2275
2276        let Ok(pattern) = pattern else {
2277            return Value::Empty.into();
2278        };
2279
2280        let matches = pattern
2281            .find_iter(&expr[pos..])
2282            .nth(occurrence)
2283            .map(|f| f.as_str())
2284            .unwrap_or("");
2285
2286        Value::Str(matches.into()).into()
2287    }
2288
2289    fn max_args(&self) -> Option<usize> {
2290        Some(5)
2291    }
2292    fn min_args(&self) -> usize {
2293        2
2294    }
2295    fn name(&self) -> &str {
2296        "REGEXP_SUBSTR"
2297    }
2298
2299    #[cfg(test)]
2300    fn examples<'a>(&'a self) -> Vec<FunctionExample<'a>> {
2301        vec![
2302            FunctionExample {
2303                name: "simple_true",
2304                arguments: vec!["abc def ghi", "[a-z]+"],
2305                expected_results: "abc",
2306            },
2307            FunctionExample {
2308                name: "can_not_find",
2309                arguments: vec!["test", "ES"],
2310                expected_results: "\"\"",
2311            },
2312            FunctionExample {
2313                name: "with_pos",
2314                arguments: vec!["abc def ghi", "[a-z]+", "2"],
2315                expected_results: "bc",
2316            },
2317            FunctionExample {
2318                name: "with_pos_and_oc",
2319                arguments: vec!["abc def ghi", "[a-z]+", "2", "2"],
2320                expected_results: "def",
2321            },
2322            FunctionExample {
2323                name: "with_pos_and_oc_to_large",
2324                arguments: vec!["abc def ghi", "[a-z]+", "2", "10"],
2325                expected_results: "\"\"",
2326            },
2327            FunctionExample {
2328                name: "with_flags",
2329                arguments: vec!["abc def ghi", "[A-Z]+", "1", "1", "i"],
2330                expected_results: "abc",
2331            },
2332            FunctionExample {
2333                name: "invalid_str",
2334                arguments: vec!["1", "[A-Z]+", "1", "1", "i"],
2335                expected_results: "",
2336            },
2337            FunctionExample {
2338                name: "no_regex",
2339                arguments: vec!["abc def ghi", "2", "1", "1", "i"],
2340                expected_results: "",
2341            },
2342            FunctionExample {
2343                name: "invalid_regex",
2344                arguments: vec!["abc def ghi", "[A-", "1", "1", "i"],
2345                expected_results: "",
2346            },
2347            FunctionExample {
2348                name: "invalid_pos",
2349                arguments: vec!["abc def ghi", "[A-Z]+", "a", "1", "i"],
2350                expected_results: "",
2351            },
2352            FunctionExample {
2353                name: "post_zero",
2354                arguments: vec!["abc def ghi", "[A-Z]+", "0", "1", "i"],
2355                expected_results: "",
2356            },
2357            FunctionExample {
2358                name: "invalid_oc",
2359                arguments: vec!["abc def ghi", "[A-Z]+", "1", "A", "i"],
2360                expected_results: "",
2361            },
2362            FunctionExample {
2363                name: "zero_oc",
2364                arguments: vec!["abc def ghi", "[A-Z]+", "1", "0", "i"],
2365                expected_results: "",
2366            },
2367            FunctionExample {
2368                name: "invalid_flags",
2369                arguments: vec!["abc def ghi", "[A-Z]+", "1", "0", "2"],
2370                expected_results: "",
2371            },
2372            FunctionExample {
2373                name: "unknown_flags",
2374                arguments: vec!["abc def ghi", "[A-Z]+", "1", "0", "1"],
2375                expected_results: "",
2376            },
2377        ]
2378    }
2379}
2380
2381struct Reverse {}
2382impl Operator for Reverse {
2383    fn get<'a>(&'a self, args: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
2384        let str = args.first();
2385        let Some(str) = str.as_string() else {
2386            return Value::Empty.into();
2387        };
2388        Value::Str(str.chars().rev().collect()).into()
2389    }
2390
2391    fn max_args(&self) -> Option<usize> {
2392        Some(1)
2393    }
2394    fn min_args(&self) -> usize {
2395        1
2396    }
2397    fn name(&self) -> &str {
2398        "REVERSE"
2399    }
2400
2401    #[cfg(test)]
2402    fn examples<'a>(&'a self) -> Vec<FunctionExample<'a>> {
2403        vec![
2404            FunctionExample {
2405                name: "simple",
2406                arguments: vec!["simple"],
2407                expected_results: "elpmis",
2408            },
2409            FunctionExample {
2410                name: "nopre",
2411                arguments: vec!["323"],
2412                expected_results: "",
2413            },
2414        ]
2415    }
2416}
2417struct Round {}
2418impl Operator for Round {
2419    fn get<'a>(&'a self, args: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
2420        let num = args.first();
2421        let Some(num) = num.as_num() else {
2422            return Value::Empty.into();
2423        };
2424        let digit = args.get(1);
2425        let digit = if digit.is_some() {
2426            digit.as_i64()
2427        } else {
2428            Some(0)
2429        };
2430        let Some(digit) = digit else {
2431            return Value::Empty.into();
2432        };
2433
2434        Value::Number(num.with_scale_round(digit, bigdecimal::RoundingMode::HalfDown)).into()
2435    }
2436
2437    fn max_args(&self) -> Option<usize> {
2438        Some(2)
2439    }
2440    fn min_args(&self) -> usize {
2441        1
2442    }
2443    fn name(&self) -> &str {
2444        "ROUND"
2445    }
2446
2447    #[cfg(test)]
2448    fn examples<'a>(&'a self) -> Vec<FunctionExample<'a>> {
2449        vec![
2450            FunctionExample {
2451                name: "simple",
2452                arguments: vec!["-1.23"],
2453                expected_results: "-1",
2454            },
2455            FunctionExample {
2456                name: "larger",
2457                arguments: vec!["43.123"],
2458                expected_results: "43",
2459            },
2460            FunctionExample {
2461                name: "go_up",
2462                arguments: vec!["43.6123"],
2463                expected_results: "44",
2464            },
2465            FunctionExample {
2466                name: "with_arg",
2467                arguments: vec![".1234567890123456789012345678901234567890", "35"],
2468                expected_results: "0.12345678901234567890123456789012346",
2469            },
2470            FunctionExample {
2471                name: "with_negative_arg",
2472                arguments: vec!["23.298", "-1"],
2473                expected_results: "20",
2474            },
2475            FunctionExample {
2476                name: "nan1",
2477                arguments: vec!["test"],
2478                expected_results: "",
2479            },
2480            FunctionExample {
2481                name: "nan2",
2482                arguments: vec!["1", "test"],
2483                expected_results: "",
2484            },
2485        ]
2486    }
2487}
2488struct Sqrt {}
2489impl Operator for Sqrt {
2490    fn get<'a>(&'a self, args: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
2491        let num = args.first();
2492        let Some(num) = num.as_num() else {
2493            return Value::Empty.into();
2494        };
2495        match num.sqrt() {
2496            Some(num) => Value::Number(num),
2497            None => Value::Empty,
2498        }
2499        .into()
2500    }
2501
2502    fn max_args(&self) -> Option<usize> {
2503        Some(1)
2504    }
2505    fn min_args(&self) -> usize {
2506        1
2507    }
2508    fn name(&self) -> &str {
2509        "SQRT"
2510    }
2511
2512    #[cfg(test)]
2513    fn examples<'a>(&'a self) -> Vec<FunctionExample<'a>> {
2514        vec![
2515            FunctionExample {
2516                name: "simple",
2517                arguments: vec!["16"],
2518                expected_results: "4",
2519            },
2520            FunctionExample {
2521                name: "larger",
2522                arguments: vec!["121"],
2523                expected_results: "11",
2524            },
2525            FunctionExample {
2526                name: "neg",
2527                arguments: vec!["-4"],
2528                expected_results: "",
2529            },
2530            FunctionExample {
2531                name: "nan",
2532                arguments: vec!["test"],
2533                expected_results: "",
2534            },
2535        ]
2536    }
2537}
2538
2539struct Pi {}
2540impl Operator for Pi {
2541    fn get<'a>(&'a self, _: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
2542        let pi = BigDecimal::from_str("3.1415926535897932384626433832795").unwrap();
2543        Value::Number(pi).into()
2544    }
2545
2546    fn max_args(&self) -> Option<usize> {
2547        Some(0)
2548    }
2549    fn min_args(&self) -> usize {
2550        0
2551    }
2552    fn name(&self) -> &str {
2553        "PI"
2554    }
2555}
2556
2557struct Exp {}
2558impl Operator for Exp {
2559    fn get<'a>(&'a self, args: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
2560        let num = args.first();
2561        let Some(num) = num.as_num() else {
2562            return Value::Empty.into();
2563        };
2564
2565        Value::Number(num.exp()).into()
2566    }
2567
2568    fn max_args(&self) -> Option<usize> {
2569        Some(1)
2570    }
2571    fn min_args(&self) -> usize {
2572        1
2573    }
2574    fn name(&self) -> &str {
2575        "EXP"
2576    }
2577}
2578
2579struct Ln {}
2580impl Operator for Ln {
2581    fn get<'a>(&'a self, args: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
2582        let num = args.first();
2583        let Some(num) = num.as_f64() else {
2584            return Value::Empty.into();
2585        };
2586        if num <= 0.0 {
2587            return Value::Empty.into();
2588        }
2589
2590        num.ln().into()
2591    }
2592
2593    fn max_args(&self) -> Option<usize> {
2594        Some(1)
2595    }
2596    fn min_args(&self) -> usize {
2597        1
2598    }
2599    fn name(&self) -> &str {
2600        "LN"
2601    }
2602}
2603struct Log {}
2604impl Operator for Log {
2605    fn get<'a>(&'a self, args: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
2606        let (base, num) = if args.len() == 2 {
2607            let base = args.first();
2608            let Some(base) = base.as_f64() else {
2609                return Value::Empty.into();
2610            };
2611            let num = args.get(1);
2612            let Some(num) = num.as_f64() else {
2613                return Value::Empty.into();
2614            };
2615            if base <= 0.0 {
2616                return Value::Empty.into();
2617            }
2618            (base, num)
2619        } else {
2620            let num = args.first();
2621            let Some(num) = num.as_f64() else {
2622                return Value::Empty.into();
2623            };
2624            (10.0, num)
2625        };
2626        if num <= 0.0 {
2627            return Value::Empty.into();
2628        }
2629
2630        num.log(base).into()
2631    }
2632
2633    fn max_args(&self) -> Option<usize> {
2634        Some(2)
2635    }
2636    fn min_args(&self) -> usize {
2637        1
2638    }
2639    fn name(&self) -> &str {
2640        "LOG"
2641    }
2642    #[cfg(test)]
2643    fn examples<'a>(&'a self) -> Vec<FunctionExample<'a>> {
2644        vec![
2645            FunctionExample {
2646                name: "simple",
2647                arguments: vec!["100"],
2648                expected_results: "2",
2649            },
2650            FunctionExample {
2651                name: "zero",
2652                arguments: vec!["0"],
2653                expected_results: "",
2654            },
2655            FunctionExample {
2656                name: "not_a_num",
2657                arguments: vec!["test"],
2658                expected_results: "",
2659            },
2660            FunctionExample {
2661                name: "two_args",
2662                arguments: vec!["2", "8"],
2663                expected_results: "3",
2664            },
2665            FunctionExample {
2666                name: "invalid_base",
2667                arguments: vec!["0", "8"],
2668                expected_results: "",
2669            },
2670            FunctionExample {
2671                name: "no_base",
2672                arguments: vec!["", "8"],
2673                expected_results: "",
2674            },
2675        ]
2676    }
2677}
2678
2679struct Log2 {}
2680impl Operator for Log2 {
2681    fn get<'a>(&'a self, args: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
2682        let num = args.first();
2683        let Some(num) = num.as_f64() else {
2684            return Value::Empty.into();
2685        };
2686        if num <= 0.0 {
2687            return Value::Empty.into();
2688        }
2689
2690        num.log2().into()
2691    }
2692
2693    fn max_args(&self) -> Option<usize> {
2694        Some(1)
2695    }
2696    fn min_args(&self) -> usize {
2697        1
2698    }
2699    fn name(&self) -> &str {
2700        "LOG2"
2701    }
2702    #[cfg(test)]
2703    fn examples<'a>(&'a self) -> Vec<FunctionExample<'a>> {
2704        vec![
2705            FunctionExample {
2706                name: "simple",
2707                arguments: vec!["16"],
2708                expected_results: "4",
2709            },
2710            FunctionExample {
2711                name: "zero",
2712                arguments: vec!["0"],
2713                expected_results: "",
2714            },
2715            FunctionExample {
2716                name: "not_a_num",
2717                arguments: vec!["test"],
2718                expected_results: "",
2719            },
2720        ]
2721    }
2722}
2723struct Log10 {}
2724impl Operator for Log10 {
2725    fn get<'a>(&'a self, args: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
2726        let num = args.first();
2727        let Some(num) = num.as_f64() else {
2728            return Value::Empty.into();
2729        };
2730        if num <= 0.0 {
2731            return Value::Empty.into();
2732        }
2733
2734        num.log10().into()
2735    }
2736
2737    fn max_args(&self) -> Option<usize> {
2738        Some(1)
2739    }
2740    fn min_args(&self) -> usize {
2741        1
2742    }
2743    fn name(&self) -> &str {
2744        "LOG10"
2745    }
2746    #[cfg(test)]
2747    fn examples<'a>(&'a self) -> Vec<FunctionExample<'a>> {
2748        vec![
2749            FunctionExample {
2750                name: "simple",
2751                arguments: vec!["100"],
2752                expected_results: "2",
2753            },
2754            FunctionExample {
2755                name: "zero",
2756                arguments: vec!["0"],
2757                expected_results: "",
2758            },
2759            FunctionExample {
2760                name: "not_a_num",
2761                arguments: vec!["test"],
2762                expected_results: "",
2763            },
2764        ]
2765    }
2766}
2767
2768struct Power {}
2769impl Operator for Power {
2770    fn get<'a>(&'a self, args: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
2771        let base = args.first();
2772        let Some(base) = base.as_f64() else {
2773            return Value::Empty.into();
2774        };
2775        let num = args.get(1);
2776        let Some(num) = num.as_f64() else {
2777            return Value::Empty.into();
2778        };
2779        if base <= 0.0 {
2780            return Value::Empty.into();
2781        }
2782
2783        base.powf(num).into()
2784    }
2785
2786    fn max_args(&self) -> Option<usize> {
2787        Some(2)
2788    }
2789    fn min_args(&self) -> usize {
2790        2
2791    }
2792    fn name(&self) -> &str {
2793        "POWER"
2794    }
2795    #[cfg(test)]
2796    fn examples<'a>(&'a self) -> Vec<FunctionExample<'a>> {
2797        vec![
2798            FunctionExample {
2799                name: "simple",
2800                arguments: vec!["2", "3"],
2801                expected_results: "8",
2802            },
2803            FunctionExample {
2804                name: "negative",
2805                arguments: vec!["2", "-2"],
2806                expected_results: "0.25",
2807            },
2808            FunctionExample {
2809                name: "not_a_num_base",
2810                arguments: vec!["a", "2"],
2811                expected_results: "",
2812            },
2813            FunctionExample {
2814                name: "not_a_num_exp",
2815                arguments: vec!["2", "a"],
2816                expected_results: "",
2817            },
2818        ]
2819    }
2820}
2821
2822struct Random {}
2823impl Operator for Random {
2824    fn get<'a>(&'a self, args: &[SmartReference<'a, Value>]) -> SmartReference<'a, Value> {
2825        let rnd: f64 = rand::random();
2826        if args.is_empty() {
2827            rnd.into()
2828        } else {
2829            let Some(max) = args.first().as_usize() else {
2830                return Value::Empty.into();
2831            };
2832            if max == 0 {
2833                Value::Number(BigDecimal::zero()).into()
2834            } else {
2835                (rnd * max as f64).floor().into()
2836            }
2837        }
2838    }
2839
2840    fn max_args(&self) -> Option<usize> {
2841        Some(1)
2842    }
2843    fn min_args(&self) -> usize {
2844        0
2845    }
2846    fn name(&self) -> &str {
2847        "RANDOM"
2848    }
2849}
2850
2851#[cfg(test)]
2852mod tests_functions {
2853    use std::fs::{self, OpenOptions};
2854
2855    use bigdecimal::ToPrimitive;
2856    use chrono::{TimeDelta, Utc};
2857    use itertools::Itertools;
2858    use sqlparser::{
2859        ast::{
2860            Expr, Function, FunctionArgumentList, FunctionArguments, Ident, LimitClause,
2861            NullTreatment, Statement,
2862        },
2863        parser::Parser,
2864    };
2865
2866    use crate::{
2867        args::Args,
2868        dialect::FilesDialect,
2869        engine::Engine,
2870        error::CvsSqlError,
2871        projections::SingleConvert,
2872        result_set_metadata::{Metadata, SimpleResultSetMetadata},
2873        results::Column,
2874        value::Value,
2875    };
2876    use std::io::Write;
2877
2878    use super::{
2879        Abs, Ascii, Chr, Coalece, Concat, ConcatWs, CurrentDate, Exp, Format, Greatest, If, Least,
2880        Left, Length, Ln, Log, Log2, Log10, Lower, Lpad, Ltrim, Now, NullIf, Operator, Pi,
2881        Position, Power, Random, RegexLike, RegexReplace, RegexSubstring, Repeat, Replace, Reverse,
2882        Right, Round, Rpad, Rtrim, Sqrt, ToTimestamp, Upper, User,
2883    };
2884
2885    fn test_func(operator: &impl Operator) -> Result<(), CvsSqlError> {
2886        let dir = format!("./target/function_tests/{}", operator.name().to_lowercase());
2887        println!("testing: {}", operator.name());
2888        fs::remove_dir_all(&dir).ok();
2889        for example in operator.examples() {
2890            test_with_details(operator, example.name, &example.arguments, |r| {
2891                let expected_results = if example.expected_results == "\"\"" {
2892                    Value::Str(String::new())
2893                } else {
2894                    example.expected_results.into()
2895                };
2896                if r == Some(&expected_results) {
2897                    true
2898                } else {
2899                    println!(
2900                        "Function {} example {}, results: {:?}, expecting: [{}]",
2901                        operator.name(),
2902                        &example.name,
2903                        r,
2904                        example.expected_results
2905                    );
2906                    false
2907                }
2908            })?;
2909        }
2910        fs::remove_dir_all(&dir).ok();
2911
2912        Ok(())
2913    }
2914
2915    fn test_with_details<F>(
2916        operator: &impl Operator,
2917        name: &str,
2918        arguments: &[&str],
2919        verify_results: F,
2920    ) -> Result<(), CvsSqlError>
2921    where
2922        F: FnOnce(Option<&Value>) -> bool,
2923    {
2924        println!("testing: {} with {}", operator.name(), name);
2925        let dir = format!("./target/function_tests/{}", operator.name().to_lowercase());
2926        fs::create_dir_all(&dir)?;
2927        let file = format!("{dir}/{name}.csv");
2928        let mut writer = OpenOptions::new()
2929            .write(true)
2930            .create(true)
2931            .truncate(true)
2932            .open(&file)?;
2933        let header = ('a'..='z')
2934            .take(arguments.len())
2935            .map(|c| format!("{c}"))
2936            .join(",");
2937        writeln!(writer, "{header},name")?;
2938        let line = arguments.join(",");
2939        writeln!(writer, "{line},{name}")?;
2940
2941        let table_name = format!(
2942            "target.function_tests.{}.{}",
2943            operator.name().to_lowercase(),
2944            name
2945        );
2946        let sql = format!(
2947            "SELECT {}({}) FROM {}\n",
2948            operator.name(),
2949            header,
2950            table_name
2951        );
2952
2953        let args = Args::default();
2954        let engine = Engine::try_from(&args)?;
2955
2956        let results = engine.execute_commands(&sql)?;
2957
2958        fs::remove_file(file)?;
2959
2960        let col = Column::from_index(0);
2961        let result = results
2962            .first()
2963            .and_then(|d| d.results.data.iter().next())
2964            .map(|d| d.get(&col));
2965
2966        assert!(verify_results(result));
2967
2968        Ok(())
2969    }
2970
2971    #[test]
2972    fn test_abs() -> Result<(), CvsSqlError> {
2973        test_func(&Abs {})
2974    }
2975
2976    #[test]
2977    fn test_ascii() -> Result<(), CvsSqlError> {
2978        test_func(&Ascii {})
2979    }
2980
2981    #[test]
2982    fn test_chr() -> Result<(), CvsSqlError> {
2983        test_func(&Chr {})
2984    }
2985
2986    #[test]
2987    fn test_length() -> Result<(), CvsSqlError> {
2988        test_func(&Length {})
2989    }
2990
2991    #[test]
2992    fn test_coalece() -> Result<(), CvsSqlError> {
2993        test_func(&Coalece {})
2994    }
2995
2996    #[test]
2997    fn test_concat() -> Result<(), CvsSqlError> {
2998        test_func(&Concat {})
2999    }
3000
3001    #[test]
3002    fn test_concat_ws() -> Result<(), CvsSqlError> {
3003        test_func(&ConcatWs {})
3004    }
3005
3006    #[test]
3007    fn test_current_date() -> Result<(), CvsSqlError> {
3008        test_with_details(&CurrentDate {}, "current_date", &[], |r| match r {
3009            Some(Value::Date(dt)) => {
3010                let now = Utc::now().naive_utc().date();
3011                let to = now.succ_opt().unwrap();
3012                let from = now.pred_opt().unwrap();
3013
3014                *dt >= from && *dt <= to
3015            }
3016            _ => false,
3017        })
3018    }
3019
3020    #[test]
3021    fn test_now() -> Result<(), CvsSqlError> {
3022        test_with_details(&Now {}, "now", &[], |r| match r {
3023            Some(Value::Timestamp(dt)) => {
3024                let now = Utc::now().naive_utc();
3025                let to = now.checked_add_signed(TimeDelta::seconds(10)).unwrap();
3026                let from = now.checked_add_signed(TimeDelta::seconds(-10)).unwrap();
3027
3028                *dt >= from && *dt <= to
3029            }
3030            _ => false,
3031        })
3032    }
3033
3034    #[test]
3035    fn test_current_user() -> Result<(), CvsSqlError> {
3036        test_with_details(&User {}, "user", &[], |r| match r {
3037            Some(Value::Str(user)) => *user == whoami::username(),
3038            _ => false,
3039        })
3040    }
3041
3042    #[test]
3043    fn test_format() -> Result<(), CvsSqlError> {
3044        test_func(&Format {})
3045    }
3046
3047    #[test]
3048    fn test_to_timestamp() -> Result<(), CvsSqlError> {
3049        test_func(&ToTimestamp {})
3050    }
3051
3052    #[test]
3053    fn test_greatest() -> Result<(), CvsSqlError> {
3054        test_func(&Greatest {})
3055    }
3056
3057    #[test]
3058    fn test_if() -> Result<(), CvsSqlError> {
3059        test_func(&If {})
3060    }
3061
3062    #[test]
3063    fn test_null_if() -> Result<(), CvsSqlError> {
3064        test_func(&NullIf {})
3065    }
3066
3067    #[test]
3068    fn test_lower() -> Result<(), CvsSqlError> {
3069        test_func(&Lower {})
3070    }
3071
3072    #[test]
3073    fn test_upper() -> Result<(), CvsSqlError> {
3074        test_func(&Upper {})
3075    }
3076
3077    #[test]
3078    fn test_least() -> Result<(), CvsSqlError> {
3079        test_func(&Least {})
3080    }
3081
3082    #[test]
3083    fn test_left() -> Result<(), CvsSqlError> {
3084        test_func(&Left {})
3085    }
3086
3087    #[test]
3088    fn test_right() -> Result<(), CvsSqlError> {
3089        test_func(&Right {})
3090    }
3091
3092    #[test]
3093    fn test_lpad() -> Result<(), CvsSqlError> {
3094        test_func(&Lpad {})
3095    }
3096
3097    #[test]
3098    fn test_rpad() -> Result<(), CvsSqlError> {
3099        test_func(&Rpad {})
3100    }
3101
3102    #[test]
3103    fn test_ltrim() -> Result<(), CvsSqlError> {
3104        test_func(&Ltrim {})
3105    }
3106
3107    #[test]
3108    fn test_rtrim() -> Result<(), CvsSqlError> {
3109        test_func(&Rtrim {})
3110    }
3111
3112    #[test]
3113    fn test_pi() -> Result<(), CvsSqlError> {
3114        test_with_details(&Pi {}, "pi", &[], |r| match r {
3115            Some(Value::Number(num)) => {
3116                num.to_f64().unwrap() > std::f64::consts::PI - 0.001
3117                    && num.to_f64().unwrap() < std::f64::consts::PI + 0.001
3118            }
3119            _ => false,
3120        })
3121    }
3122
3123    #[test]
3124    fn test_ln() -> Result<(), CvsSqlError> {
3125        test_with_details(&Ln {}, "ln", &["10"], |r| match r {
3126            Some(Value::Number(num)) => {
3127                num.to_f64().unwrap() > 2.30 && num.to_f64().unwrap() < 2.31
3128            }
3129            _ => false,
3130        })?;
3131        test_with_details(&Ln {}, "neg_ln", &["-10"], |r| r == Some(&Value::Empty))?;
3132        test_with_details(&Ln {}, "nan", &[""], |r| r == Some(&Value::Empty))
3133    }
3134
3135    #[test]
3136    fn test_exp() -> Result<(), CvsSqlError> {
3137        test_with_details(&Exp {}, "exp", &["10"], |r| match r {
3138            Some(Value::Number(num)) => {
3139                num.to_f64().unwrap() > 22026.46 && num.to_f64().unwrap() < 22026.47
3140            }
3141            _ => false,
3142        })?;
3143        test_with_details(&Exp {}, "neg_exp", &["-10"], |r| match r {
3144            Some(Value::Number(num)) => {
3145                num.to_f64().unwrap() > 4.53e-5 && num.to_f64().unwrap() < 4.54e-5
3146            }
3147            _ => false,
3148        })?;
3149        test_with_details(&Exp {}, "nan", &[""], |r| r == Some(&Value::Empty))
3150    }
3151
3152    #[test]
3153    fn test_log() -> Result<(), CvsSqlError> {
3154        test_func(&Log {})
3155    }
3156
3157    #[test]
3158    fn test_log2() -> Result<(), CvsSqlError> {
3159        test_func(&Log2 {})
3160    }
3161
3162    #[test]
3163    fn test_log10() -> Result<(), CvsSqlError> {
3164        test_func(&Log10 {})
3165    }
3166
3167    #[test]
3168    fn test_power() -> Result<(), CvsSqlError> {
3169        test_func(&Power {})
3170    }
3171
3172    #[test]
3173    fn test_position() -> Result<(), CvsSqlError> {
3174        test_func(&Position {})
3175    }
3176
3177    #[test]
3178    fn test_repeat() -> Result<(), CvsSqlError> {
3179        test_func(&Repeat {})
3180    }
3181
3182    #[test]
3183    fn test_replace() -> Result<(), CvsSqlError> {
3184        test_func(&Replace {})
3185    }
3186
3187    #[test]
3188    fn test_regex_replace() -> Result<(), CvsSqlError> {
3189        test_func(&RegexReplace {})
3190    }
3191
3192    #[test]
3193    fn test_regex_like() -> Result<(), CvsSqlError> {
3194        test_func(&RegexLike {})
3195    }
3196
3197    #[test]
3198    fn test_regex_substring() -> Result<(), CvsSqlError> {
3199        test_func(&RegexSubstring {})
3200    }
3201
3202    #[test]
3203    fn test_reverse() -> Result<(), CvsSqlError> {
3204        test_func(&Reverse {})
3205    }
3206    #[test]
3207    fn test_rand() -> Result<(), CvsSqlError> {
3208        test_with_details(&Random {}, "no_args", &[], |r| match r {
3209            Some(Value::Number(num)) => num.to_f64().unwrap() > 0.0 && num.to_f64().unwrap() < 1.0,
3210            _ => false,
3211        })?;
3212        test_with_details(&Random {}, "one_args", &["20"], |r| match r {
3213            Some(Value::Number(num)) => num.to_usize().unwrap() < 20,
3214            _ => false,
3215        })?;
3216        test_with_details(&Random {}, "nan", &["t"], |r| r == Some(&Value::Empty))?;
3217        test_with_details(&Random {}, "neg", &["-10"], |r| r == Some(&Value::Empty))
3218    }
3219
3220    #[test]
3221    fn test_round() -> Result<(), CvsSqlError> {
3222        test_func(&Round {})
3223    }
3224
3225    #[test]
3226    fn test_sqrt() -> Result<(), CvsSqlError> {
3227        test_func(&Sqrt {})
3228    }
3229
3230    fn test_unsupported(change: fn(&mut Function)) -> Result<(), CvsSqlError> {
3231        let args = Args {
3232            write_mode: true,
3233            ..Args::default()
3234        };
3235
3236        let engine = Engine::try_from(&args)?;
3237
3238        let sql = "SELECT * FROM tests.data.dates LIMIT RAND()";
3239        let dialect = FilesDialect {};
3240        let statement = Parser::parse_sql(&dialect, sql)?;
3241        let Some(Statement::Query(query)) = statement.into_iter().next() else {
3242            panic!("Not a select statement");
3243        };
3244        let Some(LimitClause::LimitOffset {
3245            limit,
3246            offset: _,
3247            limit_by: _,
3248        }) = &query.limit_clause
3249        else {
3250            panic!("No limit?")
3251        };
3252        let Some(limit) = limit else {
3253            panic!("No limit?")
3254        };
3255        let Expr::Function(mut func) = limit.clone() else {
3256            panic!("Not a function")
3257        };
3258
3259        change(&mut func);
3260
3261        let metadata = Metadata::Simple(SimpleResultSetMetadata::new(None));
3262        let Err(err) = func.convert_single(&metadata, &engine) else {
3263            panic!("No error");
3264        };
3265
3266        assert!(matches!(err, CvsSqlError::Unsupported(_)));
3267
3268        Ok(())
3269    }
3270
3271    #[test]
3272    fn test_null_treatment_unsupported() -> Result<(), CvsSqlError> {
3273        test_unsupported(|f| f.null_treatment = Some(NullTreatment::IgnoreNulls))
3274    }
3275
3276    #[test]
3277    fn test_filter_unsupported() -> Result<(), CvsSqlError> {
3278        test_unsupported(|f| {
3279            let ext = Box::new(Expr::Identifier(Ident::new("test")));
3280
3281            f.filter = Some(ext);
3282        })
3283    }
3284
3285    #[test]
3286    fn test_parameters_unsupported() -> Result<(), CvsSqlError> {
3287        test_unsupported(|f| {
3288            f.parameters = FunctionArguments::List(FunctionArgumentList {
3289                duplicate_treatment: None,
3290                args: vec![],
3291                clauses: vec![],
3292            });
3293        })
3294    }
3295}