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 for average.
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(BinOper::As, Expr::cust(iden.into_iden().0)))
472 }
473
474 /// Call `CAST` function with a case-sensitive custom type.
475 ///
476 /// Type can be qualified with a schema name.
477 ///
478 /// # Examples
479 ///
480 /// ```
481 /// use sea_query::{tests_cfg::*, *};
482 ///
483 /// let query = Query::select()
484 /// .expr(Func::cast_as_quoted("hello", "MyType"))
485 /// .to_owned();
486 ///
487 /// assert_eq!(
488 /// query.to_string(MysqlQueryBuilder),
489 /// r#"SELECT CAST('hello' AS `MyType`)"#
490 /// );
491 /// assert_eq!(
492 /// query.to_string(PostgresQueryBuilder),
493 /// r#"SELECT CAST('hello' AS "MyType")"#
494 /// );
495 /// assert_eq!(
496 /// query.to_string(SqliteQueryBuilder),
497 /// r#"SELECT CAST('hello' AS "MyType")"#
498 /// );
499 ///
500 /// // Also works with a schema-qualified type name:
501 ///
502 /// let query = Query::select()
503 /// .expr(Func::cast_as_quoted("hello", ("MySchema", "MyType")))
504 /// .to_owned();
505 ///
506 /// assert_eq!(
507 /// query.to_string(MysqlQueryBuilder),
508 /// r#"SELECT CAST('hello' AS `MySchema`.`MyType`)"#
509 /// );
510 /// assert_eq!(
511 /// query.to_string(PostgresQueryBuilder),
512 /// r#"SELECT CAST('hello' AS "MySchema"."MyType")"#
513 /// );
514 /// assert_eq!(
515 /// query.to_string(SqliteQueryBuilder),
516 /// r#"SELECT CAST('hello' AS "MySchema"."MyType")"#
517 /// );
518 /// ```
519 pub fn cast_as_quoted<V, I>(expr: V, r#type: I) -> FunctionCall
520 where
521 V: Into<Expr>,
522 I: Into<TypeRef>,
523 {
524 let expr: Expr = expr.into();
525 FunctionCall::new(Func::Cast).arg(expr.binary(BinOper::As, Expr::TypeName(r#type.into())))
526 }
527
528 /// Call `COALESCE` function.
529 ///
530 /// # Examples
531 ///
532 /// ```
533 /// use sea_query::{tests_cfg::*, *};
534 ///
535 /// let query = Query::select()
536 /// .expr(Func::coalesce([
537 /// Query::select()
538 /// .from(Char::Table)
539 /// .expr(Func::max(Expr::col(Char::SizeW)))
540 /// .take()
541 /// .into(),
542 /// Expr::col(Char::SizeH),
543 /// Expr::val(12),
544 /// ]))
545 /// .from(Char::Table)
546 /// .to_owned();
547 ///
548 /// assert_eq!(
549 /// query.to_string(MysqlQueryBuilder),
550 /// r#"SELECT COALESCE((SELECT MAX(`size_w`) FROM `character`), `size_h`, 12) FROM `character`"#
551 /// );
552 /// assert_eq!(
553 /// query.to_string(PostgresQueryBuilder),
554 /// r#"SELECT COALESCE((SELECT MAX("size_w") FROM "character"), "size_h", 12) FROM "character""#
555 /// );
556 /// assert_eq!(
557 /// query.to_string(SqliteQueryBuilder),
558 /// r#"SELECT COALESCE((SELECT MAX("size_w") FROM "character"), "size_h", 12) FROM "character""#
559 /// );
560 /// ```
561 pub fn coalesce<I, T>(args: I) -> FunctionCall
562 where
563 I: IntoIterator<Item = T>,
564 T: Into<Expr>,
565 {
566 FunctionCall::new(Func::Coalesce).args(args.into_iter().map(Into::into))
567 }
568
569 /// Call `LOWER` function.
570 ///
571 /// # Examples
572 ///
573 /// ```
574 /// use sea_query::{tests_cfg::*, *};
575 ///
576 /// let query = Query::select()
577 /// .expr(Func::lower(Expr::col(Char::Character)))
578 /// .from(Char::Table)
579 /// .to_owned();
580 ///
581 /// assert_eq!(
582 /// query.to_string(MysqlQueryBuilder),
583 /// r#"SELECT LOWER(`character`) FROM `character`"#
584 /// );
585 /// assert_eq!(
586 /// query.to_string(PostgresQueryBuilder),
587 /// r#"SELECT LOWER("character") FROM "character""#
588 /// );
589 /// assert_eq!(
590 /// query.to_string(SqliteQueryBuilder),
591 /// r#"SELECT LOWER("character") FROM "character""#
592 /// );
593 /// ```
594 ///
595 /// ```
596 /// use sea_query::{tests_cfg::*, *};
597 ///
598 /// let query = Query::select()
599 /// .column(Font::Id)
600 /// .from(Font::Table)
601 /// .and_where(Func::lower(Expr::col(Font::Name)).eq("abc".trim().to_lowercase()))
602 /// .take();
603 ///
604 /// assert_eq!(
605 /// query.to_string(MysqlQueryBuilder),
606 /// "SELECT `id` FROM `font` WHERE LOWER(`name`) = 'abc'"
607 /// );
608 /// assert_eq!(
609 /// query.to_string(PostgresQueryBuilder),
610 /// r#"SELECT "id" FROM "font" WHERE LOWER("name") = 'abc'"#
611 /// );
612 /// assert_eq!(
613 /// query.to_string(SqliteQueryBuilder),
614 /// r#"SELECT "id" FROM "font" WHERE LOWER("name") = 'abc'"#
615 /// );
616 /// ```
617 pub fn lower<T>(expr: T) -> FunctionCall
618 where
619 T: Into<Expr>,
620 {
621 FunctionCall::new(Func::Lower).arg(expr)
622 }
623
624 /// Call `UPPER` function.
625 ///
626 /// # Examples
627 ///
628 /// ```
629 /// use sea_query::{tests_cfg::*, *};
630 ///
631 /// let query = Query::select()
632 /// .expr(Func::upper(Expr::col(Char::Character)))
633 /// .from(Char::Table)
634 /// .to_owned();
635 ///
636 /// assert_eq!(
637 /// query.to_string(MysqlQueryBuilder),
638 /// r#"SELECT UPPER(`character`) FROM `character`"#
639 /// );
640 /// assert_eq!(
641 /// query.to_string(PostgresQueryBuilder),
642 /// r#"SELECT UPPER("character") FROM "character""#
643 /// );
644 /// assert_eq!(
645 /// query.to_string(SqliteQueryBuilder),
646 /// r#"SELECT UPPER("character") FROM "character""#
647 /// );
648 /// ```
649 pub fn upper<T>(expr: T) -> FunctionCall
650 where
651 T: Into<Expr>,
652 {
653 FunctionCall::new(Func::Upper).arg(expr)
654 }
655
656 /// Call `BIT_AND` function, this is not supported on SQLite.
657 ///
658 /// # Examples
659 ///
660 /// ```
661 /// use sea_query::{tests_cfg::*, *};
662 ///
663 /// let query = Query::select()
664 /// .expr(Func::bit_and(Expr::col(Char::FontSize)))
665 /// .from(Char::Table)
666 /// .to_owned();
667 ///
668 /// assert_eq!(
669 /// query.to_string(MysqlQueryBuilder),
670 /// r#"SELECT BIT_AND(`font_size`) FROM `character`"#
671 /// );
672 /// assert_eq!(
673 /// query.to_string(PostgresQueryBuilder),
674 /// r#"SELECT BIT_AND("font_size") FROM "character""#
675 /// );
676 /// ```
677 pub fn bit_and<T>(expr: T) -> FunctionCall
678 where
679 T: Into<Expr>,
680 {
681 FunctionCall::new(Func::BitAnd).arg(expr)
682 }
683
684 /// Call `BIT_OR` function, this is not supported on SQLite.
685 ///
686 /// # Examples
687 ///
688 /// ```
689 /// use sea_query::{tests_cfg::*, *};
690 ///
691 /// let query = Query::select()
692 /// .expr(Func::bit_or(Expr::col(Char::FontSize)))
693 /// .from(Char::Table)
694 /// .to_owned();
695 ///
696 /// assert_eq!(
697 /// query.to_string(MysqlQueryBuilder),
698 /// r#"SELECT BIT_OR(`font_size`) FROM `character`"#
699 /// );
700 /// assert_eq!(
701 /// query.to_string(PostgresQueryBuilder),
702 /// r#"SELECT BIT_OR("font_size") FROM "character""#
703 /// );
704 /// ```
705 pub fn bit_or<T>(expr: T) -> FunctionCall
706 where
707 T: Into<Expr>,
708 {
709 FunctionCall::new(Func::BitOr).arg(expr)
710 }
711
712 /// Call `ROUND` function.
713 ///
714 /// # Examples
715 ///
716 /// ```
717 /// use sea_query::tests_cfg::Character::Character;
718 /// use sea_query::{tests_cfg::*, *};
719 ///
720 /// let query = Query::select().expr(Func::round(5.654)).to_owned();
721 ///
722 /// assert_eq!(query.to_string(MysqlQueryBuilder), r#"SELECT ROUND(5.654)"#);
723 ///
724 /// assert_eq!(
725 /// query.to_string(PostgresQueryBuilder),
726 /// r#"SELECT ROUND(5.654)"#
727 /// );
728 ///
729 /// assert_eq!(
730 /// query.to_string(SqliteQueryBuilder),
731 /// r#"SELECT ROUND(5.654)"#
732 /// );
733 /// ```
734 pub fn round<A>(expr: A) -> FunctionCall
735 where
736 A: Into<Expr>,
737 {
738 FunctionCall::new(Func::Round).arg(expr)
739 }
740
741 /// Call `ROUND` function with the precision.
742 ///
743 /// # Examples
744 ///
745 /// ```
746 /// use sea_query::tests_cfg::Character::Character;
747 /// use sea_query::{tests_cfg::*, *};
748 ///
749 /// let query = Query::select()
750 /// .expr(Func::round_with_precision(5.654, 2))
751 /// .to_owned();
752 ///
753 /// assert_eq!(
754 /// query.to_string(MysqlQueryBuilder),
755 /// r#"SELECT ROUND(5.654, 2)"#
756 /// );
757 ///
758 /// assert_eq!(
759 /// query.to_string(PostgresQueryBuilder),
760 /// r#"SELECT ROUND(5.654, 2)"#
761 /// );
762 ///
763 /// assert_eq!(
764 /// query.to_string(SqliteQueryBuilder),
765 /// r#"SELECT ROUND(5.654, 2)"#
766 /// );
767 /// ```
768 pub fn round_with_precision<A, B>(a: A, b: B) -> FunctionCall
769 where
770 A: Into<Expr>,
771 B: Into<Expr>,
772 {
773 FunctionCall::new(Func::Round).args([a.into(), b.into()])
774 }
775
776 /// Call `RANDOM` function.
777 ///
778 /// # Examples
779 ///
780 /// ```
781 /// use sea_query::tests_cfg::Character::Character;
782 /// use sea_query::{tests_cfg::*, *};
783 ///
784 /// let query = Query::select().expr(Func::random()).to_owned();
785 ///
786 /// assert_eq!(query.to_string(MysqlQueryBuilder), r#"SELECT RAND()"#);
787 ///
788 /// assert_eq!(query.to_string(PostgresQueryBuilder), r#"SELECT RANDOM()"#);
789 ///
790 /// assert_eq!(query.to_string(SqliteQueryBuilder), r#"SELECT RANDOM()"#);
791 /// ```
792 pub fn random() -> FunctionCall {
793 FunctionCall::new(Func::Random)
794 }
795
796 /// Call `MD5` function, this is only available in Postgres and MySQL.
797 ///
798 /// # Examples
799 ///
800 /// ```
801 /// use sea_query::{tests_cfg::*, *};
802 ///
803 /// let query = Query::select()
804 /// .expr(Func::md5(Expr::col((Char::Table, Char::Character))))
805 /// .from(Char::Table)
806 /// .to_owned();
807 ///
808 /// assert_eq!(
809 /// query.to_string(MysqlQueryBuilder),
810 /// r#"SELECT MD5(`character`.`character`) FROM `character`"#
811 /// );
812 ///
813 /// assert_eq!(
814 /// query.to_string(PostgresQueryBuilder),
815 /// r#"SELECT MD5("character"."character") FROM "character""#
816 /// );
817 /// ```
818 pub fn md5<T>(expr: T) -> FunctionCall
819 where
820 T: Into<Expr>,
821 {
822 FunctionCall::new(Func::Md5).arg(expr)
823 }
824}
825
826/// Function call.
827#[derive(Debug, Clone, PartialEq)]
828pub struct FunctionCall {
829 pub(crate) func: Func,
830 pub(crate) args: Vec<Expr>,
831 pub(crate) mods: Vec<FuncArgMod>,
832}
833
834#[derive(Debug, Default, Copy, Clone, PartialEq)]
835pub struct FuncArgMod {
836 pub distinct: bool,
837}
838
839impl FunctionCall {
840 pub(crate) fn new(func: Func) -> Self {
841 Self {
842 func,
843 args: Vec::new(),
844 mods: Vec::new(),
845 }
846 }
847
848 /// Append an argument to the function call
849 pub fn arg<T>(self, arg: T) -> Self
850 where
851 T: Into<Expr>,
852 {
853 self.arg_with(arg, Default::default())
854 }
855
856 pub(crate) fn arg_with<T>(mut self, arg: T, mod_: FuncArgMod) -> Self
857 where
858 T: Into<Expr>,
859 {
860 self.args.push(arg.into());
861 self.mods.push(mod_);
862 self
863 }
864
865 /// Replace the arguments of the function call
866 pub fn args<I>(mut self, args: I) -> Self
867 where
868 I: IntoIterator<Item = Expr>,
869 {
870 self.args = args.into_iter().collect();
871 self.mods = vec![Default::default(); self.args.len()];
872 self
873 }
874
875 pub fn get_func(&self) -> &Func {
876 &self.func
877 }
878
879 pub fn get_args(&self) -> &[Expr] {
880 &self.args
881 }
882
883 pub fn get_mods(&self) -> &[FuncArgMod] {
884 &self.mods
885 }
886}