sea_query/func.rs
1//! For calling built-in SQL functions.
2
3use crate::{expr::*, types::*};
4
5#[cfg(feature = "backend-postgres")]
6pub use crate::extension::postgres::PgFunc;
7
8/// Known SQL functions.
9///
10/// If something is not supported here, you can use [`Function::Custom`].
11#[derive(Debug, Clone, PartialEq)]
12#[non_exhaustive]
13pub enum Func {
14 Max,
15 Min,
16 Sum,
17 Avg,
18 Abs,
19 Count,
20 IfNull,
21 Greatest,
22 Least,
23 CharLength,
24 Cast,
25 Custom(DynIden),
26 Coalesce,
27 Lower,
28 Upper,
29 BitAnd,
30 BitOr,
31 Random,
32 Round,
33 Md5,
34 #[cfg(feature = "backend-postgres")]
35 PgFunction(PgFunc),
36}
37
38/// Type alias of [`Func`] for compatibility.
39/// Previously, [`Func`] is a namespace for building [`FunctionCall`].
40#[deprecated(since = "1.0.0", note = "use `Func` instead")]
41pub type Function = Func;
42
43impl Func {
44 /// Call a custom function.
45 ///
46 /// # Examples
47 ///
48 /// ```
49 /// use sea_query::{tests_cfg::*, *};
50 ///
51 /// #[derive(Iden)]
52 /// #[iden = "MY_FUNCTION"]
53 /// struct MyFunction;
54 ///
55 /// let query = Query::select()
56 /// .expr(Func::cust(MyFunction).arg("hello"))
57 /// .to_owned();
58 ///
59 /// assert_eq!(
60 /// query.to_string(MysqlQueryBuilder),
61 /// r#"SELECT MY_FUNCTION('hello')"#
62 /// );
63 /// assert_eq!(
64 /// query.to_string(PostgresQueryBuilder),
65 /// r#"SELECT MY_FUNCTION('hello')"#
66 /// );
67 /// assert_eq!(
68 /// query.to_string(SqliteQueryBuilder),
69 /// r#"SELECT MY_FUNCTION('hello')"#
70 /// );
71 /// ```
72 pub fn cust<T>(func: T) -> FunctionCall
73 where
74 T: IntoIden,
75 {
76 FunctionCall::new(Func::Custom(func.into_iden()))
77 }
78
79 /// Call `MAX` function.
80 ///
81 /// # Examples
82 ///
83 /// ```
84 /// use sea_query::{tests_cfg::*, *};
85 ///
86 /// let query = Query::select()
87 /// .expr(Func::max(Expr::col((Char::Table, Char::SizeW))))
88 /// .from(Char::Table)
89 /// .to_owned();
90 ///
91 /// assert_eq!(
92 /// query.to_string(MysqlQueryBuilder),
93 /// r#"SELECT MAX(`character`.`size_w`) FROM `character`"#
94 /// );
95 /// assert_eq!(
96 /// query.to_string(PostgresQueryBuilder),
97 /// r#"SELECT MAX("character"."size_w") FROM "character""#
98 /// );
99 /// assert_eq!(
100 /// query.to_string(SqliteQueryBuilder),
101 /// r#"SELECT MAX("character"."size_w") FROM "character""#
102 /// );
103 /// ```
104 pub fn max<T>(expr: T) -> FunctionCall
105 where
106 T: Into<Expr>,
107 {
108 FunctionCall::new(Func::Max).arg(expr)
109 }
110
111 /// Call `MIN` function.
112 ///
113 /// # Examples
114 ///
115 /// ```
116 /// use sea_query::{tests_cfg::*, *};
117 ///
118 /// let query = Query::select()
119 /// .expr(Func::min(Expr::col((Char::Table, Char::SizeH))))
120 /// .from(Char::Table)
121 /// .to_owned();
122 ///
123 /// assert_eq!(
124 /// query.to_string(MysqlQueryBuilder),
125 /// r#"SELECT MIN(`character`.`size_h`) FROM `character`"#
126 /// );
127 /// assert_eq!(
128 /// query.to_string(PostgresQueryBuilder),
129 /// r#"SELECT MIN("character"."size_h") FROM "character""#
130 /// );
131 /// assert_eq!(
132 /// query.to_string(SqliteQueryBuilder),
133 /// r#"SELECT MIN("character"."size_h") FROM "character""#
134 /// );
135 /// ```
136 pub fn min<T>(expr: T) -> FunctionCall
137 where
138 T: Into<Expr>,
139 {
140 FunctionCall::new(Func::Min).arg(expr)
141 }
142
143 /// Call `SUM` function.
144 ///
145 /// # Examples
146 ///
147 /// ```
148 /// use sea_query::{tests_cfg::*, *};
149 ///
150 /// let query = Query::select()
151 /// .expr(Func::sum(Expr::col((Char::Table, Char::SizeH))))
152 /// .from(Char::Table)
153 /// .to_owned();
154 ///
155 /// assert_eq!(
156 /// query.to_string(MysqlQueryBuilder),
157 /// r#"SELECT SUM(`character`.`size_h`) FROM `character`"#
158 /// );
159 /// assert_eq!(
160 /// query.to_string(PostgresQueryBuilder),
161 /// r#"SELECT SUM("character"."size_h") FROM "character""#
162 /// );
163 /// assert_eq!(
164 /// query.to_string(SqliteQueryBuilder),
165 /// r#"SELECT SUM("character"."size_h") FROM "character""#
166 /// );
167 /// ```
168 pub fn sum<T>(expr: T) -> FunctionCall
169 where
170 T: Into<Expr>,
171 {
172 FunctionCall::new(Func::Sum).arg(expr)
173 }
174
175 /// Call `AVG` function.
176 ///
177 /// # Examples
178 ///
179 /// ```
180 /// use sea_query::{tests_cfg::*, *};
181 ///
182 /// let query = Query::select()
183 /// .expr(Func::avg(Expr::col((Char::Table, Char::SizeH))))
184 /// .from(Char::Table)
185 /// .to_owned();
186 ///
187 /// assert_eq!(
188 /// query.to_string(MysqlQueryBuilder),
189 /// r#"SELECT AVG(`character`.`size_h`) FROM `character`"#
190 /// );
191 /// assert_eq!(
192 /// query.to_string(PostgresQueryBuilder),
193 /// r#"SELECT AVG("character"."size_h") FROM "character""#
194 /// );
195 /// assert_eq!(
196 /// query.to_string(SqliteQueryBuilder),
197 /// r#"SELECT AVG("character"."size_h") FROM "character""#
198 /// );
199 /// ```
200 pub fn avg<T>(expr: T) -> FunctionCall
201 where
202 T: Into<Expr>,
203 {
204 FunctionCall::new(Func::Avg).arg(expr)
205 }
206
207 /// Call `ABS` function.
208 ///
209 /// # Examples
210 ///
211 /// ```
212 /// use sea_query::{tests_cfg::*, *};
213 ///
214 /// let query = Query::select()
215 /// .expr(Func::abs(Expr::col((Char::Table, Char::SizeH))))
216 /// .from(Char::Table)
217 /// .to_owned();
218 ///
219 /// assert_eq!(
220 /// query.to_string(MysqlQueryBuilder),
221 /// r#"SELECT ABS(`character`.`size_h`) FROM `character`"#
222 /// );
223 /// assert_eq!(
224 /// query.to_string(PostgresQueryBuilder),
225 /// r#"SELECT ABS("character"."size_h") FROM "character""#
226 /// );
227 /// assert_eq!(
228 /// query.to_string(SqliteQueryBuilder),
229 /// r#"SELECT ABS("character"."size_h") FROM "character""#
230 /// );
231 /// ```
232 pub fn abs<T>(expr: T) -> FunctionCall
233 where
234 T: Into<Expr>,
235 {
236 FunctionCall::new(Func::Abs).arg(expr)
237 }
238
239 /// Call `COUNT` function.
240 ///
241 /// # Examples
242 ///
243 /// ```
244 /// use sea_query::{tests_cfg::*, *};
245 ///
246 /// let query = Query::select()
247 /// .expr(Func::count(Expr::col((Char::Table, Char::Id))))
248 /// .from(Char::Table)
249 /// .to_owned();
250 ///
251 /// assert_eq!(
252 /// query.to_string(MysqlQueryBuilder),
253 /// r#"SELECT COUNT(`character`.`id`) FROM `character`"#
254 /// );
255 /// assert_eq!(
256 /// query.to_string(PostgresQueryBuilder),
257 /// r#"SELECT COUNT("character"."id") FROM "character""#
258 /// );
259 /// assert_eq!(
260 /// query.to_string(SqliteQueryBuilder),
261 /// r#"SELECT COUNT("character"."id") FROM "character""#
262 /// );
263 /// ```
264 pub fn count<T>(expr: T) -> FunctionCall
265 where
266 T: Into<Expr>,
267 {
268 FunctionCall::new(Func::Count).arg(expr)
269 }
270
271 /// Call `COUNT` function with the `DISTINCT` modifier.
272 ///
273 /// # Examples
274 ///
275 /// ```
276 /// use sea_query::{tests_cfg::*, *};
277 ///
278 /// let query = Query::select()
279 /// .expr(Func::count_distinct(Expr::col((Char::Table, Char::Id))))
280 /// .from(Char::Table)
281 /// .to_owned();
282 ///
283 /// assert_eq!(
284 /// query.to_string(MysqlQueryBuilder),
285 /// r#"SELECT COUNT(DISTINCT `character`.`id`) FROM `character`"#
286 /// );
287 /// assert_eq!(
288 /// query.to_string(PostgresQueryBuilder),
289 /// r#"SELECT COUNT(DISTINCT "character"."id") FROM "character""#
290 /// );
291 /// assert_eq!(
292 /// query.to_string(SqliteQueryBuilder),
293 /// r#"SELECT COUNT(DISTINCT "character"."id") FROM "character""#
294 /// );
295 /// ```
296 pub fn count_distinct<T>(expr: T) -> FunctionCall
297 where
298 T: Into<Expr>,
299 {
300 FunctionCall::new(Func::Count).arg_with(expr, FuncArgMod { distinct: true })
301 }
302
303 /// Call `CHAR_LENGTH` function.
304 ///
305 /// # Examples
306 ///
307 /// ```
308 /// use sea_query::{tests_cfg::*, *};
309 ///
310 /// let query = Query::select()
311 /// .expr(Func::char_length(Expr::col((Char::Table, Char::Character))))
312 /// .from(Char::Table)
313 /// .to_owned();
314 ///
315 /// assert_eq!(
316 /// query.to_string(MysqlQueryBuilder),
317 /// r#"SELECT CHAR_LENGTH(`character`.`character`) FROM `character`"#
318 /// );
319 /// assert_eq!(
320 /// query.to_string(PostgresQueryBuilder),
321 /// r#"SELECT CHAR_LENGTH("character"."character") FROM "character""#
322 /// );
323 /// assert_eq!(
324 /// query.to_string(SqliteQueryBuilder),
325 /// r#"SELECT LENGTH("character"."character") FROM "character""#
326 /// );
327 /// ```
328 pub fn char_length<T>(expr: T) -> FunctionCall
329 where
330 T: Into<Expr>,
331 {
332 FunctionCall::new(Func::CharLength).arg(expr)
333 }
334
335 /// Call `GREATEST` function.
336 ///
337 /// # Examples
338 ///
339 /// ```
340 /// use sea_query::{tests_cfg::*, *};
341 ///
342 /// let query = Query::select()
343 /// .expr(Func::greatest([
344 /// Expr::col(Char::SizeW).into(),
345 /// Expr::col(Char::SizeH).into(),
346 /// ]))
347 /// .from(Char::Table)
348 /// .to_owned();
349 ///
350 /// assert_eq!(
351 /// query.to_string(MysqlQueryBuilder),
352 /// r#"SELECT GREATEST(`size_w`, `size_h`) FROM `character`"#
353 /// );
354 /// assert_eq!(
355 /// query.to_string(PostgresQueryBuilder),
356 /// r#"SELECT GREATEST("size_w", "size_h") FROM "character""#
357 /// );
358 /// assert_eq!(
359 /// query.to_string(SqliteQueryBuilder),
360 /// r#"SELECT MAX("size_w", "size_h") FROM "character""#
361 /// );
362 /// ```
363 pub fn greatest<I>(args: I) -> FunctionCall
364 where
365 I: IntoIterator<Item = Expr>,
366 {
367 FunctionCall::new(Func::Greatest).args(args)
368 }
369
370 /// Call `LEAST` function.
371 ///
372 /// # Examples
373 ///
374 /// ```
375 /// use sea_query::{tests_cfg::*, *};
376 ///
377 /// let query = Query::select()
378 /// .expr(Func::least([
379 /// Expr::col(Char::SizeW).into(),
380 /// Expr::col(Char::SizeH).into(),
381 /// ]))
382 /// .from(Char::Table)
383 /// .to_owned();
384 ///
385 /// assert_eq!(
386 /// query.to_string(MysqlQueryBuilder),
387 /// r#"SELECT LEAST(`size_w`, `size_h`) FROM `character`"#
388 /// );
389 /// assert_eq!(
390 /// query.to_string(PostgresQueryBuilder),
391 /// r#"SELECT LEAST("size_w", "size_h") FROM "character""#
392 /// );
393 /// assert_eq!(
394 /// query.to_string(SqliteQueryBuilder),
395 /// r#"SELECT MIN("size_w", "size_h") FROM "character""#
396 /// );
397 /// ```
398 pub fn least<I>(args: I) -> FunctionCall
399 where
400 I: IntoIterator<Item = Expr>,
401 {
402 FunctionCall::new(Func::Least).args(args)
403 }
404
405 /// Call `IF NULL` function.
406 ///
407 /// # Examples
408 ///
409 /// ```
410 /// use sea_query::{tests_cfg::*, *};
411 ///
412 /// let query = Query::select()
413 /// .expr(Func::if_null(
414 /// Expr::col(Char::SizeW),
415 /// Expr::col(Char::SizeH),
416 /// ))
417 /// .from(Char::Table)
418 /// .to_owned();
419 ///
420 /// assert_eq!(
421 /// query.to_string(MysqlQueryBuilder),
422 /// r#"SELECT IFNULL(`size_w`, `size_h`) FROM `character`"#
423 /// );
424 /// assert_eq!(
425 /// query.to_string(PostgresQueryBuilder),
426 /// r#"SELECT COALESCE("size_w", "size_h") FROM "character""#
427 /// );
428 /// assert_eq!(
429 /// query.to_string(SqliteQueryBuilder),
430 /// r#"SELECT IFNULL("size_w", "size_h") FROM "character""#
431 /// );
432 /// ```
433 pub fn if_null<A, B>(a: A, b: B) -> FunctionCall
434 where
435 A: Into<Expr>,
436 B: Into<Expr>,
437 {
438 FunctionCall::new(Func::IfNull).args([a.into(), b.into()])
439 }
440
441 /// Call `CAST` function with a custom type.
442 ///
443 /// # Examples
444 ///
445 /// ```
446 /// use sea_query::{tests_cfg::*, *};
447 ///
448 /// let query = Query::select()
449 /// .expr(Func::cast_as("hello", "MyType"))
450 /// .to_owned();
451 ///
452 /// assert_eq!(
453 /// query.to_string(MysqlQueryBuilder),
454 /// r#"SELECT CAST('hello' AS MyType)"#
455 /// );
456 /// assert_eq!(
457 /// query.to_string(PostgresQueryBuilder),
458 /// r#"SELECT CAST('hello' AS MyType)"#
459 /// );
460 /// assert_eq!(
461 /// query.to_string(SqliteQueryBuilder),
462 /// r#"SELECT CAST('hello' AS MyType)"#
463 /// );
464 /// ```
465 pub fn cast_as<V, I>(expr: V, iden: I) -> FunctionCall
466 where
467 V: Into<Expr>,
468 I: IntoIden,
469 {
470 let expr: Expr = expr.into();
471 FunctionCall::new(Func::Cast).arg(expr.binary(
472 BinOper::As,
473 Expr::cust(iden.into_iden().to_string().as_str()),
474 ))
475 }
476
477 /// Call `CAST` function with a case-sensitive custom type.
478 ///
479 /// Type can be qualified with a schema name.
480 ///
481 /// # Examples
482 ///
483 /// ```
484 /// use sea_query::{tests_cfg::*, *};
485 ///
486 /// let query = Query::select()
487 /// .expr(Func::cast_as_quoted("hello", "MyType"))
488 /// .to_owned();
489 ///
490 /// assert_eq!(
491 /// query.to_string(MysqlQueryBuilder),
492 /// r#"SELECT CAST('hello' AS `MyType`)"#
493 /// );
494 /// assert_eq!(
495 /// query.to_string(PostgresQueryBuilder),
496 /// r#"SELECT CAST('hello' AS "MyType")"#
497 /// );
498 /// assert_eq!(
499 /// query.to_string(SqliteQueryBuilder),
500 /// r#"SELECT CAST('hello' AS "MyType")"#
501 /// );
502 ///
503 /// // Also works with a schema-qualified type name:
504 ///
505 /// let query = Query::select()
506 /// .expr(Func::cast_as_quoted("hello", ("MySchema", "MyType")))
507 /// .to_owned();
508 ///
509 /// assert_eq!(
510 /// query.to_string(MysqlQueryBuilder),
511 /// r#"SELECT CAST('hello' AS `MySchema`.`MyType`)"#
512 /// );
513 /// assert_eq!(
514 /// query.to_string(PostgresQueryBuilder),
515 /// r#"SELECT CAST('hello' AS "MySchema"."MyType")"#
516 /// );
517 /// assert_eq!(
518 /// query.to_string(SqliteQueryBuilder),
519 /// r#"SELECT CAST('hello' AS "MySchema"."MyType")"#
520 /// );
521 /// ```
522 pub fn cast_as_quoted<V, I>(expr: V, r#type: I) -> FunctionCall
523 where
524 V: Into<Expr>,
525 I: Into<TypeRef>,
526 {
527 let expr: Expr = expr.into();
528 FunctionCall::new(Func::Cast).arg(expr.binary(BinOper::As, Expr::TypeName(r#type.into())))
529 }
530
531 /// Call `COALESCE` function.
532 ///
533 /// # Examples
534 ///
535 /// ```
536 /// use sea_query::{tests_cfg::*, *};
537 ///
538 /// let query = Query::select()
539 /// .expr(Func::coalesce([
540 /// Expr::col(Char::SizeW).into(),
541 /// Expr::col(Char::SizeH).into(),
542 /// Expr::val(12).into(),
543 /// ]))
544 /// .from(Char::Table)
545 /// .to_owned();
546 ///
547 /// assert_eq!(
548 /// query.to_string(MysqlQueryBuilder),
549 /// r#"SELECT COALESCE(`size_w`, `size_h`, 12) FROM `character`"#
550 /// );
551 /// assert_eq!(
552 /// query.to_string(PostgresQueryBuilder),
553 /// r#"SELECT COALESCE("size_w", "size_h", 12) FROM "character""#
554 /// );
555 /// assert_eq!(
556 /// query.to_string(SqliteQueryBuilder),
557 /// r#"SELECT COALESCE("size_w", "size_h", 12) FROM "character""#
558 /// );
559 /// ```
560 pub fn coalesce<I>(args: I) -> FunctionCall
561 where
562 I: IntoIterator<Item = Expr>,
563 {
564 FunctionCall::new(Func::Coalesce).args(args)
565 }
566
567 /// Call `LOWER` function.
568 ///
569 /// # Examples
570 ///
571 /// ```
572 /// use sea_query::{tests_cfg::*, *};
573 ///
574 /// let query = Query::select()
575 /// .expr(Func::lower(Expr::col(Char::Character)))
576 /// .from(Char::Table)
577 /// .to_owned();
578 ///
579 /// assert_eq!(
580 /// query.to_string(MysqlQueryBuilder),
581 /// r#"SELECT LOWER(`character`) FROM `character`"#
582 /// );
583 /// assert_eq!(
584 /// query.to_string(PostgresQueryBuilder),
585 /// r#"SELECT LOWER("character") FROM "character""#
586 /// );
587 /// assert_eq!(
588 /// query.to_string(SqliteQueryBuilder),
589 /// r#"SELECT LOWER("character") FROM "character""#
590 /// );
591 /// ```
592 ///
593 /// ```
594 /// use sea_query::{tests_cfg::*, *};
595 ///
596 /// let query = Query::select()
597 /// .column(Font::Id)
598 /// .from(Font::Table)
599 /// .and_where(Func::lower(Expr::col(Font::Name)).eq("abc".trim().to_lowercase()))
600 /// .take();
601 ///
602 /// assert_eq!(
603 /// query.to_string(MysqlQueryBuilder),
604 /// "SELECT `id` FROM `font` WHERE LOWER(`name`) = 'abc'"
605 /// );
606 /// assert_eq!(
607 /// query.to_string(PostgresQueryBuilder),
608 /// r#"SELECT "id" FROM "font" WHERE LOWER("name") = 'abc'"#
609 /// );
610 /// assert_eq!(
611 /// query.to_string(SqliteQueryBuilder),
612 /// r#"SELECT "id" FROM "font" WHERE LOWER("name") = 'abc'"#
613 /// );
614 /// ```
615 pub fn lower<T>(expr: T) -> FunctionCall
616 where
617 T: Into<Expr>,
618 {
619 FunctionCall::new(Func::Lower).arg(expr)
620 }
621
622 /// Call `UPPER` function.
623 ///
624 /// # Examples
625 ///
626 /// ```
627 /// use sea_query::{tests_cfg::*, *};
628 ///
629 /// let query = Query::select()
630 /// .expr(Func::upper(Expr::col(Char::Character)))
631 /// .from(Char::Table)
632 /// .to_owned();
633 ///
634 /// assert_eq!(
635 /// query.to_string(MysqlQueryBuilder),
636 /// r#"SELECT UPPER(`character`) FROM `character`"#
637 /// );
638 /// assert_eq!(
639 /// query.to_string(PostgresQueryBuilder),
640 /// r#"SELECT UPPER("character") FROM "character""#
641 /// );
642 /// assert_eq!(
643 /// query.to_string(SqliteQueryBuilder),
644 /// r#"SELECT UPPER("character") FROM "character""#
645 /// );
646 /// ```
647 pub fn upper<T>(expr: T) -> FunctionCall
648 where
649 T: Into<Expr>,
650 {
651 FunctionCall::new(Func::Upper).arg(expr)
652 }
653
654 /// Call `BIT_AND` function, this is not supported on SQLite.
655 ///
656 /// # Examples
657 ///
658 /// ```
659 /// use sea_query::{tests_cfg::*, *};
660 ///
661 /// let query = Query::select()
662 /// .expr(Func::bit_and(Expr::col(Char::FontSize)))
663 /// .from(Char::Table)
664 /// .to_owned();
665 ///
666 /// assert_eq!(
667 /// query.to_string(MysqlQueryBuilder),
668 /// r#"SELECT BIT_AND(`font_size`) FROM `character`"#
669 /// );
670 /// assert_eq!(
671 /// query.to_string(PostgresQueryBuilder),
672 /// r#"SELECT BIT_AND("font_size") FROM "character""#
673 /// );
674 /// ```
675 pub fn bit_and<T>(expr: T) -> FunctionCall
676 where
677 T: Into<Expr>,
678 {
679 FunctionCall::new(Func::BitAnd).arg(expr)
680 }
681
682 /// Call `BIT_OR` function, this is not supported on SQLite.
683 ///
684 /// # Examples
685 ///
686 /// ```
687 /// use sea_query::{tests_cfg::*, *};
688 ///
689 /// let query = Query::select()
690 /// .expr(Func::bit_or(Expr::col(Char::FontSize)))
691 /// .from(Char::Table)
692 /// .to_owned();
693 ///
694 /// assert_eq!(
695 /// query.to_string(MysqlQueryBuilder),
696 /// r#"SELECT BIT_OR(`font_size`) FROM `character`"#
697 /// );
698 /// assert_eq!(
699 /// query.to_string(PostgresQueryBuilder),
700 /// r#"SELECT BIT_OR("font_size") FROM "character""#
701 /// );
702 /// ```
703 pub fn bit_or<T>(expr: T) -> FunctionCall
704 where
705 T: Into<Expr>,
706 {
707 FunctionCall::new(Func::BitOr).arg(expr)
708 }
709
710 /// Call `ROUND` function.
711 ///
712 /// # Examples
713 ///
714 /// ```
715 /// use sea_query::tests_cfg::Character::Character;
716 /// use sea_query::{tests_cfg::*, *};
717 ///
718 /// let query = Query::select().expr(Func::round(5.654)).to_owned();
719 ///
720 /// assert_eq!(query.to_string(MysqlQueryBuilder), r#"SELECT ROUND(5.654)"#);
721 ///
722 /// assert_eq!(
723 /// query.to_string(PostgresQueryBuilder),
724 /// r#"SELECT ROUND(5.654)"#
725 /// );
726 ///
727 /// assert_eq!(
728 /// query.to_string(SqliteQueryBuilder),
729 /// r#"SELECT ROUND(5.654)"#
730 /// );
731 /// ```
732 pub fn round<A>(expr: A) -> FunctionCall
733 where
734 A: Into<Expr>,
735 {
736 FunctionCall::new(Func::Round).arg(expr)
737 }
738
739 /// Call `ROUND` function with the precision.
740 ///
741 /// # Examples
742 ///
743 /// ```
744 /// use sea_query::tests_cfg::Character::Character;
745 /// use sea_query::{tests_cfg::*, *};
746 ///
747 /// let query = Query::select()
748 /// .expr(Func::round_with_precision(5.654, 2))
749 /// .to_owned();
750 ///
751 /// assert_eq!(
752 /// query.to_string(MysqlQueryBuilder),
753 /// r#"SELECT ROUND(5.654, 2)"#
754 /// );
755 ///
756 /// assert_eq!(
757 /// query.to_string(PostgresQueryBuilder),
758 /// r#"SELECT ROUND(5.654, 2)"#
759 /// );
760 ///
761 /// assert_eq!(
762 /// query.to_string(SqliteQueryBuilder),
763 /// r#"SELECT ROUND(5.654, 2)"#
764 /// );
765 /// ```
766 pub fn round_with_precision<A, B>(a: A, b: B) -> FunctionCall
767 where
768 A: Into<Expr>,
769 B: Into<Expr>,
770 {
771 FunctionCall::new(Func::Round).args([a.into(), b.into()])
772 }
773
774 /// Call `RANDOM` function.
775 ///
776 /// # Examples
777 ///
778 /// ```
779 /// use sea_query::tests_cfg::Character::Character;
780 /// use sea_query::{tests_cfg::*, *};
781 ///
782 /// let query = Query::select().expr(Func::random()).to_owned();
783 ///
784 /// assert_eq!(query.to_string(MysqlQueryBuilder), r#"SELECT RAND()"#);
785 ///
786 /// assert_eq!(query.to_string(PostgresQueryBuilder), r#"SELECT RANDOM()"#);
787 ///
788 /// assert_eq!(query.to_string(SqliteQueryBuilder), r#"SELECT RANDOM()"#);
789 /// ```
790 pub fn random() -> FunctionCall {
791 FunctionCall::new(Func::Random)
792 }
793
794 /// Call `MD5` function, this is only available in Postgres and MySQL.
795 ///
796 /// # Examples
797 ///
798 /// ```
799 /// use sea_query::{tests_cfg::*, *};
800 ///
801 /// let query = Query::select()
802 /// .expr(Func::md5(Expr::col((Char::Table, Char::Character))))
803 /// .from(Char::Table)
804 /// .to_owned();
805 ///
806 /// assert_eq!(
807 /// query.to_string(MysqlQueryBuilder),
808 /// r#"SELECT MD5(`character`.`character`) FROM `character`"#
809 /// );
810 ///
811 /// assert_eq!(
812 /// query.to_string(PostgresQueryBuilder),
813 /// r#"SELECT MD5("character"."character") FROM "character""#
814 /// );
815 /// ```
816 pub fn md5<T>(expr: T) -> FunctionCall
817 where
818 T: Into<Expr>,
819 {
820 FunctionCall::new(Func::Md5).arg(expr)
821 }
822}
823
824/// Function call.
825#[derive(Debug, Clone, PartialEq)]
826pub struct FunctionCall {
827 pub(crate) func: Func,
828 pub(crate) args: Vec<Expr>,
829 pub(crate) mods: Vec<FuncArgMod>,
830}
831
832#[derive(Debug, Default, Copy, Clone, PartialEq)]
833pub struct FuncArgMod {
834 pub distinct: bool,
835}
836
837impl FunctionCall {
838 pub(crate) fn new(func: Func) -> Self {
839 Self {
840 func,
841 args: Vec::new(),
842 mods: Vec::new(),
843 }
844 }
845
846 /// Append an argument to the function call
847 pub fn arg<T>(self, arg: T) -> Self
848 where
849 T: Into<Expr>,
850 {
851 self.arg_with(arg, Default::default())
852 }
853
854 pub(crate) fn arg_with<T>(mut self, arg: T, mod_: FuncArgMod) -> Self
855 where
856 T: Into<Expr>,
857 {
858 self.args.push(arg.into());
859 self.mods.push(mod_);
860 self
861 }
862
863 /// Replace the arguments of the function call
864 pub fn args<I>(mut self, args: I) -> Self
865 where
866 I: IntoIterator<Item = Expr>,
867 {
868 self.args = args.into_iter().collect();
869 self.mods = vec![Default::default(); self.args.len()];
870 self
871 }
872
873 pub fn get_func(&self) -> &Func {
874 &self.func
875 }
876
877 pub fn get_args(&self) -> &[Expr] {
878 &self.args
879 }
880
881 pub fn get_mods(&self) -> &[FuncArgMod] {
882 &self.mods
883 }
884}