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}