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}