1use {
2 super::{
3 TranslateError,
4 ast_literal::{translate_datetime_field, translate_trim_where_field},
5 expr::translate_expr,
6 translate_data_type, translate_object_name,
7 },
8 crate::{
9 ast::{Aggregate, CountArgExpr, Expr, Function},
10 result::Result,
11 },
12 sqlparser::ast::{
13 CastFormat as SqlCastFormat, CastKind as SqlCastKind, DataType as SqlDataType,
14 DateTimeField as SqlDateTimeField, DuplicateTreatment as SqlDuplicateTreatment,
15 Expr as SqlExpr, Function as SqlFunction, FunctionArg as SqlFunctionArg,
16 FunctionArgExpr as SqlFunctionArgExpr, FunctionArguments as SqlFunctionArguments,
17 TrimWhereField as SqlTrimWhereField,
18 },
19};
20
21pub fn translate_trim(
22 expr: &SqlExpr,
23 trim_where: &Option<SqlTrimWhereField>,
24 trim_what: &Option<Box<SqlExpr>>,
25) -> Result<Expr> {
26 let expr = translate_expr(expr)?;
27 let trim_where_field = trim_where.as_ref().map(translate_trim_where_field);
28 let filter_chars = trim_what
29 .as_ref()
30 .map(|expr| translate_expr(expr.as_ref()))
31 .transpose()?;
32
33 Ok(Expr::Function(Box::new(Function::Trim {
34 expr,
35 filter_chars,
36 trim_where_field,
37 })))
38}
39
40pub fn translate_floor(expr: &SqlExpr) -> Result<Expr> {
41 let expr = translate_expr(expr)?;
42
43 Ok(Expr::Function(Box::new(Function::Floor(expr))))
44}
45
46pub fn translate_ceil(expr: &SqlExpr) -> Result<Expr> {
47 let expr = translate_expr(expr)?;
48
49 Ok(Expr::Function(Box::new(Function::Ceil(expr))))
50}
51
52pub fn translate_position(sub_expr: &SqlExpr, from_expr: &SqlExpr) -> Result<Expr> {
53 let from_expr = translate_expr(from_expr)?;
54 let sub_expr = translate_expr(sub_expr)?;
55 Ok(Expr::Function(Box::new(Function::Position {
56 from_expr,
57 sub_expr,
58 })))
59}
60
61pub fn translate_cast(
62 kind: &SqlCastKind,
63 expr: &SqlExpr,
64 data_type: &SqlDataType,
65 format: Option<&SqlCastFormat>,
66) -> Result<Expr> {
67 if kind == &SqlCastKind::TryCast {
68 return Err(TranslateError::TryCastNotSupported.into());
69 } else if kind == &SqlCastKind::SafeCast {
70 return Err(TranslateError::SafeCastNotSupported.into());
71 } else if let Some(format) = format {
72 return Err(TranslateError::UnsupportedCastFormat(format.to_string()).into());
73 }
74
75 let expr = translate_expr(expr)?;
76 let data_type = translate_data_type(data_type)?;
77 Ok(Expr::Function(Box::new(Function::Cast { expr, data_type })))
78}
79
80pub fn translate_extract(field: &SqlDateTimeField, expr: &SqlExpr) -> Result<Expr> {
81 let field = translate_datetime_field(field)?;
82 let expr = translate_expr(expr)?;
83 Ok(Expr::Function(Box::new(Function::Extract { field, expr })))
84}
85
86fn check_len(name: String, found: usize, expected: usize) -> Result<()> {
87 if found == expected {
88 Ok(())
89 } else {
90 Err(TranslateError::FunctionArgsLengthNotMatching {
91 name,
92 found,
93 expected,
94 }
95 .into())
96 }
97}
98
99fn check_len_range(
100 name: String,
101 found: usize,
102 expected_minimum: usize,
103 expected_maximum: usize,
104) -> Result<()> {
105 if found >= expected_minimum && found <= expected_maximum {
106 Ok(())
107 } else {
108 Err(TranslateError::FunctionArgsLengthNotWithinRange {
109 name,
110 expected_minimum,
111 expected_maximum,
112 found,
113 }
114 .into())
115 }
116}
117
118fn check_len_min(name: String, found: usize, expected_minimum: usize) -> Result<()> {
119 if found >= expected_minimum {
120 Ok(())
121 } else {
122 Err(TranslateError::FunctionArgsLengthNotMatchingMin {
123 name,
124 expected_minimum,
125 found,
126 }
127 .into())
128 }
129}
130
131fn translate_function_zero_arg(func: Function, args: Vec<&SqlExpr>, name: String) -> Result<Expr> {
132 check_len(name, args.len(), 0)?;
133
134 Ok(Expr::Function(Box::new(func)))
135}
136
137fn translate_function_one_arg<T: FnOnce(Expr) -> Function>(
138 func: T,
139 args: Vec<&SqlExpr>,
140 name: String,
141) -> Result<Expr> {
142 check_len(name, args.len(), 1)?;
143
144 translate_expr(args[0])
145 .map(func)
146 .map(Box::new)
147 .map(Expr::Function)
148}
149
150fn translate_aggregate_one_arg<T: FnOnce(Expr, bool) -> Aggregate>(
151 func: T,
152 args: Vec<&SqlExpr>,
153 name: String,
154 distinct: bool,
155) -> Result<Expr> {
156 check_len(name, args.len(), 1)?;
157
158 translate_expr(args[0])
159 .map(|expr| func(expr, distinct))
160 .map(Box::new)
161 .map(Expr::Aggregate)
162}
163
164fn translate_function_trim<T: FnOnce(Expr, Option<Expr>) -> Function>(
165 func: T,
166 args: Vec<&SqlExpr>,
167 name: String,
168) -> Result<Expr> {
169 check_len_range(name, args.len(), 1, 2)?;
170
171 let expr = translate_expr(args[0])?;
172 let chars = if args.len() == 1 {
173 None
174 } else {
175 Some(translate_expr(args[1])?)
176 };
177
178 let result = func(expr, chars);
179
180 Ok(Expr::Function(Box::new(result)))
181}
182
183pub fn translate_function_arg_exprs(
184 function_arg_exprs: Vec<&SqlFunctionArgExpr>,
185) -> Result<Vec<&SqlExpr>> {
186 function_arg_exprs
187 .into_iter()
188 .map(|function_arg| match function_arg {
189 SqlFunctionArgExpr::Expr(expr) => Ok(expr),
190 SqlFunctionArgExpr::Wildcard | SqlFunctionArgExpr::QualifiedWildcard(_) => {
191 Err(TranslateError::WildcardFunctionArgNotAccepted.into())
192 }
193 })
194 .collect::<Result<Vec<_>>>()
195}
196
197pub fn translate_function(sql_function: &SqlFunction) -> Result<Expr> {
198 let SqlFunction { name, args, .. } = sql_function;
199 let name = translate_object_name(name)?.to_uppercase();
200 let (args, distinct) = match args {
201 SqlFunctionArguments::None => (Vec::new(), false),
202 SqlFunctionArguments::Subquery(_) => {
203 return Err(TranslateError::UnreachableSubqueryFunctionArgNotSupported.into());
204 }
205 SqlFunctionArguments::List(list) => {
206 let distinct = list
207 .duplicate_treatment
208 .is_some_and(|dt| matches!(dt, SqlDuplicateTreatment::Distinct));
209 (list.args.iter().collect(), distinct)
210 }
211 };
212
213 let function_arg_exprs = args
214 .iter()
215 .map(|arg| match arg {
216 SqlFunctionArg::Named { .. } => {
217 Err(TranslateError::NamedFunctionArgNotSupported.into())
218 }
219 SqlFunctionArg::Unnamed(arg_expr) => Ok(arg_expr),
220 })
221 .collect::<Result<Vec<_>>>()?;
222
223 if name.as_str() == "COUNT" {
224 check_len(name, args.len(), 1)?;
225
226 let count_arg = match function_arg_exprs[0] {
227 SqlFunctionArgExpr::Expr(expr) => CountArgExpr::Expr(translate_expr(expr)?),
228 SqlFunctionArgExpr::QualifiedWildcard(idents) => {
229 let table_name = translate_object_name(idents)?;
230 let idents = format!("{table_name}.*");
231
232 return Err(TranslateError::QualifiedWildcardInCountNotSupported(idents).into());
233 }
234 SqlFunctionArgExpr::Wildcard => CountArgExpr::Wildcard,
235 };
236
237 return Ok(Expr::Aggregate(Box::new(Aggregate::count(
238 count_arg, distinct,
239 ))));
240 }
241
242 let args = translate_function_arg_exprs(function_arg_exprs)?;
243
244 match name.as_str() {
245 "SUM" => translate_aggregate_one_arg(Aggregate::sum, args, name, distinct),
246 "MIN" => translate_aggregate_one_arg(Aggregate::min, args, name, distinct),
247 "MAX" => translate_aggregate_one_arg(Aggregate::max, args, name, distinct),
248 "AVG" => translate_aggregate_one_arg(Aggregate::avg, args, name, distinct),
249 "VARIANCE" => translate_aggregate_one_arg(Aggregate::variance, args, name, distinct),
250 "STDEV" => translate_aggregate_one_arg(Aggregate::stdev, args, name, distinct),
251 "COALESCE" => {
252 let exprs = args
253 .into_iter()
254 .map(translate_expr)
255 .collect::<Result<Vec<_>>>()?;
256 Ok(Expr::Function(Box::new(Function::Coalesce(exprs))))
257 }
258 "CONCAT" => {
259 let exprs = args
260 .into_iter()
261 .map(translate_expr)
262 .collect::<Result<Vec<_>>>()?;
263 Ok(Expr::Function(Box::new(Function::Concat(exprs))))
264 }
265 "CONCAT_WS" => {
266 check_len_min(name, args.len(), 2)?;
267 let separator = translate_expr(args[0])?;
268 let exprs = args
269 .into_iter()
270 .skip(1)
271 .map(translate_expr)
272 .collect::<Result<Vec<_>>>()?;
273 Ok(Expr::Function(Box::new(Function::ConcatWs {
274 separator,
275 exprs,
276 })))
277 }
278 "FIND_IDX" => {
279 check_len_range(name, args.len(), 2, 3)?;
280
281 let from_expr = translate_expr(args[0])?;
282 let sub_expr = translate_expr(args[1])?;
283 let start = (args.len() > 2)
284 .then(|| translate_expr(args[2]))
285 .transpose()?;
286
287 Ok(Expr::Function(Box::new(Function::FindIdx {
288 from_expr,
289 sub_expr,
290 start,
291 })))
292 }
293 "LOWER" => translate_function_one_arg(Function::Lower, args, name),
294 "INITCAP" => translate_function_one_arg(Function::Initcap, args, name),
295 "UPPER" => translate_function_one_arg(Function::Upper, args, name),
296 "LEFT" => {
297 check_len(name, args.len(), 2)?;
298
299 let expr = translate_expr(args[0])?;
300 let size = translate_expr(args[1])?;
301
302 Ok(Expr::Function(Box::new(Function::Left { expr, size })))
303 }
304 "IFNULL" => {
305 check_len(name, args.len(), 2)?;
306 let expr = translate_expr(args[0])?;
307 let then = translate_expr(args[1])?;
308 Ok(Expr::Function(Box::new(Function::IfNull { expr, then })))
309 }
310 "NULLIF" => {
311 check_len(name, args.len(), 2)?;
312 let expr1 = translate_expr(args[0])?;
313 let expr2 = translate_expr(args[1])?;
314 Ok(Expr::Function(Box::new(Function::NullIf { expr1, expr2 })))
315 }
316 "RIGHT" => {
317 check_len(name, args.len(), 2)?;
318
319 let expr = translate_expr(args[0])?;
320 let size = translate_expr(args[1])?;
321
322 Ok(Expr::Function(Box::new(Function::Right { expr, size })))
323 }
324 "SQRT" => {
325 check_len(name, args.len(), 1)?;
326
327 translate_expr(args[0])
328 .map(Function::Sqrt)
329 .map(Box::new)
330 .map(Expr::Function)
331 }
332 "POWER" => {
333 check_len(name, args.len(), 2)?;
334
335 let expr = translate_expr(args[0])?;
336 let power = translate_expr(args[1])?;
337
338 Ok(Expr::Function(Box::new(Function::Power { expr, power })))
339 }
340 "LPAD" => {
341 check_len_range(name, args.len(), 2, 3)?;
342
343 let expr = translate_expr(args[0])?;
344 let size = translate_expr(args[1])?;
345 let fill = if args.len() == 2 {
346 None
347 } else {
348 Some(translate_expr(args[2])?)
349 };
350
351 Ok(Expr::Function(Box::new(Function::Lpad {
352 expr,
353 size,
354 fill,
355 })))
356 }
357 "RPAD" => {
358 check_len_range(name, args.len(), 2, 3)?;
359
360 let expr = translate_expr(args[0])?;
361 let size = translate_expr(args[1])?;
362 let fill = if args.len() == 2 {
363 None
364 } else {
365 Some(translate_expr(args[2])?)
366 };
367
368 Ok(Expr::Function(Box::new(Function::Rpad {
369 expr,
370 size,
371 fill,
372 })))
373 }
374 "RAND" => {
375 check_len_range(name, args.len(), 0, 1)?;
376 let v = if args.is_empty() {
377 None
378 } else {
379 Some(translate_expr(args[0])?)
380 };
381 Ok(Expr::Function(Box::new(Function::Rand(v))))
382 }
383 "ROUND" => translate_function_one_arg(Function::Round, args, name),
384 "TRUNC" => translate_function_one_arg(Function::Trunc, args, name),
385 "EXP" => translate_function_one_arg(Function::Exp, args, name),
386 "LN" => translate_function_one_arg(Function::Ln, args, name),
387 "LOG" => {
388 check_len(name, args.len(), 2)?;
389
390 let antilog = translate_expr(args[0])?;
391 let base = translate_expr(args[1])?;
392
393 Ok(Expr::Function(Box::new(Function::Log { antilog, base })))
394 }
395 "LOG2" => translate_function_one_arg(Function::Log2, args, name),
396 "LOG10" => translate_function_one_arg(Function::Log10, args, name),
397 "SIN" => translate_function_one_arg(Function::Sin, args, name),
398 "COS" => translate_function_one_arg(Function::Cos, args, name),
399 "TAN" => translate_function_one_arg(Function::Tan, args, name),
400 "ASIN" => translate_function_one_arg(Function::Asin, args, name),
401 "ACOS" => translate_function_one_arg(Function::Acos, args, name),
402 "ATAN" => translate_function_one_arg(Function::Atan, args, name),
403 "RADIANS" => translate_function_one_arg(Function::Radians, args, name),
404 "DEGREES" => translate_function_one_arg(Function::Degrees, args, name),
405 "PI" => translate_function_zero_arg(Function::Pi(), args, name),
406 "NOW" => translate_function_zero_arg(Function::Now(), args, name),
407 "CURRENT_DATE" => translate_function_zero_arg(Function::CurrentDate(), args, name),
408 "CURRENT_TIME" => translate_function_zero_arg(Function::CurrentTime(), args, name),
409 "CURRENT_TIMESTAMP" => {
410 translate_function_zero_arg(Function::CurrentTimestamp(), args, name)
411 }
412 "GCD" => {
413 check_len(name, args.len(), 2)?;
414
415 let left = translate_expr(args[0])?;
416 let right = translate_expr(args[1])?;
417
418 Ok(Expr::Function(Box::new(Function::Gcd { left, right })))
419 }
420 "LAST_DAY" => {
421 check_len(name, args.len(), 1)?;
422
423 let expr = translate_expr(args[0])?;
424
425 Ok(Expr::Function(Box::new(Function::LastDay(expr))))
426 }
427 "LCM" => {
428 check_len(name, args.len(), 2)?;
429
430 let left = translate_expr(args[0])?;
431 let right = translate_expr(args[1])?;
432
433 Ok(Expr::Function(Box::new(Function::Lcm { left, right })))
434 }
435 "LTRIM" => {
436 translate_function_trim(|expr, chars| Function::Ltrim { expr, chars }, args, name)
437 }
438 "RTRIM" => {
439 translate_function_trim(|expr, chars| Function::Rtrim { expr, chars }, args, name)
440 }
441 "DIV" => {
442 check_len(name, args.len(), 2)?;
443
444 let dividend = translate_expr(args[0])?;
445 let divisor = translate_expr(args[1])?;
446
447 Ok(Expr::Function(Box::new(Function::Div {
448 dividend,
449 divisor,
450 })))
451 }
452 "MOD" => {
453 check_len(name, args.len(), 2)?;
454
455 let dividend = translate_expr(args[0])?;
456 let divisor = translate_expr(args[1])?;
457
458 Ok(Expr::Function(Box::new(Function::Mod {
459 dividend,
460 divisor,
461 })))
462 }
463 "REVERSE" => translate_function_one_arg(Function::Reverse, args, name),
464 "REPLACE" => {
465 check_len(name, args.len(), 3)?;
466 let expr = translate_expr(args[0])?;
467 let old = translate_expr(args[1])?;
468 let new = translate_expr(args[2])?;
469
470 Ok(Expr::Function(Box::new(Function::Replace {
471 expr,
472 old,
473 new,
474 })))
475 }
476 "REPEAT" => {
477 check_len(name, args.len(), 2)?;
478
479 let expr = translate_expr(args[0])?;
480 let num = translate_expr(args[1])?;
481
482 Ok(Expr::Function(Box::new(Function::Repeat { expr, num })))
483 }
484 "SUBSTR" => {
485 check_len_range(name, args.len(), 2, 3)?;
486
487 let expr = translate_expr(args[0])?;
488 let start = translate_expr(args[1])?;
489 let count = (args.len() > 2)
490 .then(|| translate_expr(args[2]))
491 .transpose()?;
492
493 Ok(Expr::Function(Box::new(Function::Substr {
494 expr,
495 start,
496 count,
497 })))
498 }
499 "UNWRAP" => {
500 check_len(name, args.len(), 2)?;
501
502 let expr = translate_expr(args[0])?;
503 let selector = translate_expr(args[1])?;
504
505 Ok(Expr::Function(Box::new(Function::Unwrap {
506 expr,
507 selector,
508 })))
509 }
510 "ABS" => translate_function_one_arg(Function::Abs, args, name),
511 "SIGN" => translate_function_one_arg(Function::Sign, args, name),
512 "GENERATE_UUID" => translate_function_zero_arg(Function::GenerateUuid(), args, name),
513 "FORMAT" => {
514 check_len(name, args.len(), 2)?;
515
516 let expr = translate_expr(args[0])?;
517 let format = translate_expr(args[1])?;
518
519 Ok(Expr::Function(Box::new(Function::Format { expr, format })))
520 }
521 "TO_DATE" => {
522 check_len(name, args.len(), 2)?;
523
524 let expr = translate_expr(args[0])?;
525 let format = translate_expr(args[1])?;
526
527 Ok(Expr::Function(Box::new(Function::ToDate { expr, format })))
528 }
529
530 "TO_TIMESTAMP" => {
531 check_len(name, args.len(), 2)?;
532
533 let expr = translate_expr(args[0])?;
534 let format = translate_expr(args[1])?;
535
536 Ok(Expr::Function(Box::new(Function::ToTimestamp {
537 expr,
538 format,
539 })))
540 }
541 "TO_TIME" => {
542 check_len(name, args.len(), 2)?;
543
544 let expr = translate_expr(args[0])?;
545 let format = translate_expr(args[1])?;
546
547 Ok(Expr::Function(Box::new(Function::ToTime { expr, format })))
548 }
549 "ADD_MONTH" => {
550 check_len(name, args.len(), 2)?;
551
552 let expr = translate_expr(args[0])?;
553 let size = translate_expr(args[1])?;
554
555 Ok(Expr::Function(Box::new(Function::AddMonth { expr, size })))
556 }
557 "ASCII" => {
558 check_len(name, args.len(), 1)?;
559
560 let expr = translate_expr(args[0])?;
561 Ok(Expr::Function(Box::new(Function::Ascii(expr))))
562 }
563 "CHR" => {
564 check_len(name, args.len(), 1)?;
565
566 let expr = translate_expr(args[0])?;
567 Ok(Expr::Function(Box::new(Function::Chr(expr))))
568 }
569 "MD5" => {
570 check_len(name, args.len(), 1)?;
571
572 let expr = translate_expr(args[0])?;
573 Ok(Expr::Function(Box::new(Function::Md5(expr))))
574 }
575 "HEX" => {
576 check_len(name, args.len(), 1)?;
577
578 let expr = translate_expr(args[0])?;
579 Ok(Expr::Function(Box::new(Function::Hex(expr))))
580 }
581 "LENGTH" => {
582 check_len(name, args.len(), 1)?;
583
584 let expr = translate_expr(args[0])?;
585 Ok(Expr::Function(Box::new(Function::Length(expr))))
586 }
587 "APPEND" => {
588 check_len(name, args.len(), 2)?;
589 let expr = translate_expr(args[0])?;
590 let value = translate_expr(args[1])?;
591
592 Ok(Expr::Function(Box::new(Function::Append { expr, value })))
593 }
594 "PREPEND" => {
595 check_len(name, args.len(), 2)?;
596 let expr = translate_expr(args[0])?;
597 let value = translate_expr(args[1])?;
598
599 Ok(Expr::Function(Box::new(Function::Prepend { expr, value })))
600 }
601 "SKIP" => {
602 check_len(name, args.len(), 2)?;
603 let expr = translate_expr(args[0])?;
604 let size = translate_expr(args[1])?;
605
606 Ok(Expr::Function(Box::new(Function::Skip { expr, size })))
607 }
608 "SORT" => {
609 check_len_range(name, args.len(), 1, 2)?;
610 let expr = translate_expr(args[0])?;
611 let order = (args.len() > 1)
612 .then(|| translate_expr(args[1]))
613 .transpose()?;
614
615 Ok(Expr::Function(Box::new(Function::Sort { expr, order })))
616 }
617 "TAKE" => {
618 check_len(name, args.len(), 2)?;
619 let expr = translate_expr(args[0])?;
620 let size = translate_expr(args[1])?;
621
622 Ok(Expr::Function(Box::new(Function::Take { expr, size })))
623 }
624 "POINT" => {
625 check_len(name, args.len(), 2)?;
626 let x = translate_expr(args[0])?;
627 let y = translate_expr(args[1])?;
628 Ok(Expr::Function(Box::new(Function::Point { x, y })))
629 }
630 "GET_X" => {
631 check_len(name, args.len(), 1)?;
632
633 let expr = translate_expr(args[0])?;
634 Ok(Expr::Function(Box::new(Function::GetX(expr))))
635 }
636 "GET_Y" => {
637 check_len(name, args.len(), 1)?;
638
639 let expr = translate_expr(args[0])?;
640 Ok(Expr::Function(Box::new(Function::GetY(expr))))
641 }
642 "CALC_DISTANCE" => {
643 check_len(name, args.len(), 2)?;
644
645 let geometry1 = translate_expr(args[0])?;
646 let geometry2 = translate_expr(args[1])?;
647 Ok(Expr::Function(Box::new(Function::CalcDistance {
648 geometry1,
649 geometry2,
650 })))
651 }
652 "IS_EMPTY" => {
653 check_len(name, args.len(), 1)?;
654
655 let expr = translate_expr(args[0])?;
656 Ok(Expr::Function(Box::new(Function::IsEmpty(expr))))
657 }
658 "SLICE" => {
659 check_len(name, args.len(), 3)?;
660 let expr = translate_expr(args[0])?;
661 let start = translate_expr(args[1])?;
662 let length = translate_expr(args[2])?;
663
664 Ok(Expr::Function(Box::new(Function::Slice {
665 expr,
666 start,
667 length,
668 })))
669 }
670 "GREATEST" => {
671 check_len_min(name, args.len(), 2)?;
672 let exprs = args
673 .into_iter()
674 .map(translate_expr)
675 .collect::<Result<Vec<_>>>()?;
676 Ok(Expr::Function(Box::new(Function::Greatest(exprs))))
677 }
678 "ENTRIES" => {
679 check_len(name, args.len(), 1)?;
680
681 let expr = translate_expr(args[0])?;
682 Ok(Expr::Function(Box::new(Function::Entries(expr))))
683 }
684 "KEYS" => {
685 check_len(name, args.len(), 1)?;
686
687 let expr = translate_expr(args[0])?;
688 Ok(Expr::Function(Box::new(Function::Keys(expr))))
689 }
690 "VALUES" => {
691 check_len(name, args.len(), 1)?;
692
693 let expr = translate_expr(args[0])?;
694 Ok(Expr::Function(Box::new(Function::Values(expr))))
695 }
696 "SPLICE" => {
697 check_len_range(name, args.len(), 3, 4)?;
698 let list_data = translate_expr(args[0])?;
699 let begin_index = translate_expr(args[1])?;
700 let end_index = translate_expr(args[2])?;
701 let values = if args.len() == 4 {
702 Some(translate_expr(args[3])?)
703 } else {
704 None
705 };
706 Ok(Expr::Function(Box::new(Function::Splice {
707 list_data,
708 begin_index,
709 end_index,
710 values,
711 })))
712 }
713 "DEDUP" => {
714 check_len(name, args.len(), 1)?;
715 let list = translate_expr(args[0])?;
716 Ok(Expr::Function(Box::new(Function::Dedup(list))))
717 }
718 _ => {
719 let exprs = args
720 .into_iter()
721 .map(translate_expr)
722 .collect::<Result<Vec<_>>>()?;
723 Ok(Expr::Function(Box::new(Function::Custom { name, exprs })))
724 }
725 }
726}
727
728#[cfg(test)]
729mod tests {
730 use {
731 super::*,
732 crate::{ast::DataType, parse_sql::parse_expr},
733 };
734
735 #[test]
736 fn cast() {
737 let expr = |sql| parse_expr(sql).and_then(|parsed| translate_expr(&parsed));
738
739 let actual = expr("CAST(name AS TEXT)");
740 let expected = Ok(Expr::Function(Box::new(Function::Cast {
741 expr: Expr::Identifier("name".to_owned()),
742 data_type: DataType::Text,
743 })));
744 assert_eq!(actual, expected);
745
746 let actual = expr("name::TEXT");
747 let expected = Ok(Expr::Function(Box::new(Function::Cast {
748 expr: Expr::Identifier("name".to_owned()),
749 data_type: DataType::Text,
750 })));
751 assert_eq!(actual, expected);
752
753 let actual = expr("TRY_CAST(id AS BOOLEAN)");
754 let expected = Err(TranslateError::TryCastNotSupported.into());
755 assert_eq!(actual, expected);
756
757 let actual = expr("SAFE_CAST(id AS UINT8)");
758 let expected = Err(TranslateError::SafeCastNotSupported.into());
759 assert_eq!(actual, expected);
760 }
761}