sea_query/expr/
trait.rs

1use crate::{Expr, func::*, query::*, types::*, value::*};
2
3/// "Operator" methods for building expressions.
4///
5/// Before `sea_query` 0.32.0 (`sea_orm` 1.1.1),
6/// these methods were awailable only on [`Expr`]/[`SimpleExpr`]
7/// and you needed to manually construct these types first.
8///
9/// Now, you can call them directly on any expression type:
10///
11/// ```no_run
12/// # use sea_query::*;
13/// #
14/// let expr = 1_i32.cast_as("REAL");
15/// let expr = Func::char_length("abc").eq(3_i32);
16/// let expr = Expr::current_date().cast_as("TEXT").like("2024%");
17/// ```
18///
19/// If some methods are missing, look into [`BinOper::Custom`], [`Func::cust`],
20/// or [`Expr::cust*`][`Expr::cust_with_values`] as a workaround, and consider
21/// reporting your issue.
22pub trait ExprTrait: Sized {
23    /// Express an arithmetic addition operation.
24    ///
25    /// # Examples
26    ///
27    /// Adding literal values
28    ///
29    /// ```
30    /// use sea_query::{tests_cfg::*, *};
31    ///
32    /// let query = Query::select()
33    ///     .columns([Char::Character, Char::SizeW, Char::SizeH])
34    ///     .from(Char::Table)
35    ///     .and_where(1.add(1).eq(2))
36    ///     .to_owned();
37    ///
38    /// assert_eq!(
39    ///     query.to_string(MysqlQueryBuilder),
40    ///     r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE 1 + 1 = 2"#
41    /// );
42    /// assert_eq!(
43    ///     query.to_string(PostgresQueryBuilder),
44    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE 1 + 1 = 2"#
45    /// );
46    /// assert_eq!(
47    ///     query.to_string(SqliteQueryBuilder),
48    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE 1 + 1 = 2"#
49    /// );
50    /// ```
51    ///
52    /// Adding columns and values
53    ///
54    /// ```
55    /// use sea_query::{tests_cfg::*, *};
56    ///
57    /// let query = Query::select()
58    ///     .expr(Expr::col(Char::SizeW).add(1))
59    ///     .from(Char::Table)
60    ///     .to_owned();
61    ///
62    /// assert_eq!(
63    ///     query.to_string(MysqlQueryBuilder),
64    ///     r#"SELECT `size_w` + 1 FROM `character`"#
65    /// );
66    /// assert_eq!(
67    ///     query.to_string(PostgresQueryBuilder),
68    ///     r#"SELECT "size_w" + 1 FROM "character""#
69    /// );
70    /// assert_eq!(
71    ///     query.to_string(SqliteQueryBuilder),
72    ///     r#"SELECT "size_w" + 1 FROM "character""#
73    /// );
74    /// ```
75    ///
76    /// Adding columns
77    ///
78    /// ```
79    /// use sea_query::{tests_cfg::*, *};
80    ///
81    /// let query = Query::select()
82    ///     .expr(Expr::col(Char::SizeW).add(Expr::col(Char::SizeH)))
83    ///     .from(Char::Table)
84    ///     .to_owned();
85    ///
86    /// assert_eq!(
87    ///     query.to_string(MysqlQueryBuilder),
88    ///     r#"SELECT `size_w` + `size_h` FROM `character`"#
89    /// );
90    /// assert_eq!(
91    ///     query.to_string(PostgresQueryBuilder),
92    ///     r#"SELECT "size_w" + "size_h" FROM "character""#
93    /// );
94    /// assert_eq!(
95    ///     query.to_string(SqliteQueryBuilder),
96    ///     r#"SELECT "size_w" + "size_h" FROM "character""#
97    /// );
98    /// ```
99    fn add<R>(self, right: R) -> Expr
100    where
101        R: Into<Expr>,
102    {
103        self.binary(BinOper::Add, right)
104    }
105
106    /// Express a `AS enum` expression.
107    ///
108    /// # Examples
109    ///
110    /// ```
111    /// use sea_query::{tests_cfg::*, *};
112    ///
113    /// let query = Query::insert()
114    ///     .into_table(Char::Table)
115    ///     .columns([Char::FontSize])
116    ///     .values_panic(["large".as_enum("FontSizeEnum")])
117    ///     .to_owned();
118    ///
119    /// assert_eq!(
120    ///     query.to_string(MysqlQueryBuilder),
121    ///     r#"INSERT INTO `character` (`font_size`) VALUES ('large')"#
122    /// );
123    /// assert_eq!(
124    ///     query.to_string(PostgresQueryBuilder),
125    ///     r#"INSERT INTO "character" ("font_size") VALUES (CAST('large' AS "FontSizeEnum"))"#
126    /// );
127    /// assert_eq!(
128    ///     query.to_string(SqliteQueryBuilder),
129    ///     r#"INSERT INTO "character" ("font_size") VALUES ('large')"#
130    /// );
131    ///
132    /// let query = Query::select()
133    ///     .expr(Expr::col(Char::FontSize).as_enum("FontSizeEnum[]"))
134    ///     .from(Char::Table)
135    ///     .to_owned();
136    ///
137    /// assert_eq!(
138    ///     query.to_string(PostgresQueryBuilder),
139    ///     r#"SELECT CAST("font_size" AS "FontSizeEnum"[]) FROM "character""#
140    /// );
141    /// ```
142    #[allow(clippy::wrong_self_convention)]
143    fn as_enum<N>(self, type_name: N) -> Expr
144    where
145        N: IntoIden;
146
147    /// Express a logical `AND` operation.
148    ///
149    /// # Examples
150    ///
151    /// ```
152    /// use sea_query::{*, tests_cfg::*};
153    ///
154    /// let query = Query::select()
155    ///     .columns([Char::Character, Char::SizeW, Char::SizeH])
156    ///     .from(Char::Table)
157    ///     .cond_where(any![
158    ///         Expr::col(Char::SizeW).eq(1).and(Expr::col(Char::SizeH).eq(2)),
159    ///         Expr::col(Char::SizeW).eq(3).and(Expr::col(Char::SizeH).eq(4)),
160    ///     ])
161    ///     .to_owned();
162    ///
163    /// assert_eq!(
164    ///     query.to_string(MysqlQueryBuilder),
165    ///     r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE (`size_w` = 1 AND `size_h` = 2) OR (`size_w` = 3 AND `size_h` = 4)"#
166    /// );
167    /// assert_eq!(
168    ///     query.to_string(PostgresQueryBuilder),
169    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE ("size_w" = 1 AND "size_h" = 2) OR ("size_w" = 3 AND "size_h" = 4)"#
170    /// );
171    /// assert_eq!(
172    ///     query.to_string(SqliteQueryBuilder),
173    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE ("size_w" = 1 AND "size_h" = 2) OR ("size_w" = 3 AND "size_h" = 4)"#
174    /// );
175    /// ```
176    fn and<R>(self, right: R) -> Expr
177    where
178        R: Into<Expr>,
179    {
180        self.binary(BinOper::And, right)
181    }
182
183    /// Express a `BETWEEN` expression.
184    ///
185    /// # Examples
186    ///
187    /// ```
188    /// use sea_query::{*, tests_cfg::*};
189    ///
190    /// let query = Query::select()
191    ///     .columns([Char::Character, Char::SizeW, Char::SizeH])
192    ///     .from(Char::Table)
193    ///     .and_where((Char::Table, Char::SizeW).into_column_ref().between(1, 10))
194    ///     .to_owned();
195    ///
196    /// assert_eq!(
197    ///     query.to_string(MysqlQueryBuilder),
198    ///     r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE `character`.`size_w` BETWEEN 1 AND 10"#
199    /// );
200    /// assert_eq!(
201    ///     query.to_string(PostgresQueryBuilder),
202    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "character"."size_w" BETWEEN 1 AND 10"#
203    /// );
204    /// assert_eq!(
205    ///     query.to_string(SqliteQueryBuilder),
206    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "character"."size_w" BETWEEN 1 AND 10"#
207    /// );
208    /// ```
209    fn between<A, B>(self, a: A, b: B) -> Expr
210    where
211        A: Into<Expr>,
212        B: Into<Expr>,
213    {
214        self.binary(
215            BinOper::Between,
216            Expr::Binary(Box::new(a.into()), BinOper::And, Box::new(b.into())),
217        )
218    }
219
220    /// Create any binary operation
221    ///
222    /// # Examples
223    /// ```
224    /// use sea_query::{*, tests_cfg::*};
225    ///
226    /// let query = Query::select()
227    ///     .columns([Char::Character, Char::SizeW, Char::SizeH])
228    ///     .from(Char::Table)
229    ///     .cond_where(all![
230    ///         Char::SizeW.into_column_ref().binary(BinOper::SmallerThan, 10),
231    ///         Char::SizeW.into_column_ref().binary(BinOper::GreaterThan, Char::SizeH.into_column_ref())
232    ///     ])
233    ///     .to_owned();
234    /// assert_eq!(
235    ///     query.to_string(MysqlQueryBuilder),
236    ///     r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE `size_w` < 10 AND `size_w` > `size_h`"#
237    /// );
238    /// assert_eq!(
239    ///     query.to_string(PostgresQueryBuilder),
240    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "size_w" < 10 AND "size_w" > "size_h""#
241    /// );
242    /// assert_eq!(
243    ///     query.to_string(SqliteQueryBuilder),
244    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "size_w" < 10 AND "size_w" > "size_h""#
245    /// );
246    /// ```
247    fn binary<O, R>(self, op: O, right: R) -> Expr
248    where
249        O: Into<BinOper>,
250        R: Into<Expr>;
251
252    /// Express a `CAST AS` expression.
253    ///
254    /// # Examples
255    ///
256    /// ```
257    /// use sea_query::{tests_cfg::*, *};
258    ///
259    /// let query = Query::select().expr("1".cast_as("integer")).to_owned();
260    ///
261    /// assert_eq!(
262    ///     query.to_string(MysqlQueryBuilder),
263    ///     r#"SELECT CAST('1' AS integer)"#
264    /// );
265    /// assert_eq!(
266    ///     query.to_string(PostgresQueryBuilder),
267    ///     r#"SELECT CAST('1' AS integer)"#
268    /// );
269    /// assert_eq!(
270    ///     query.to_string(SqliteQueryBuilder),
271    ///     r#"SELECT CAST('1' AS integer)"#
272    /// );
273    /// ```
274    fn cast_as<N>(self, type_name: N) -> Expr
275    where
276        N: IntoIden;
277
278    /// Express an arithmetic division operation.
279    ///
280    /// # Examples
281    ///
282    /// ```
283    /// use sea_query::{tests_cfg::*, *};
284    ///
285    /// let query = Query::select()
286    ///     .columns([Char::Character, Char::SizeW, Char::SizeH])
287    ///     .from(Char::Table)
288    ///     .and_where(1.div(1).eq(2))
289    ///     .to_owned();
290    ///
291    /// assert_eq!(
292    ///     query.to_string(MysqlQueryBuilder),
293    ///     r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE 1 / 1 = 2"#
294    /// );
295    /// assert_eq!(
296    ///     query.to_string(PostgresQueryBuilder),
297    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE 1 / 1 = 2"#
298    /// );
299    /// assert_eq!(
300    ///     query.to_string(SqliteQueryBuilder),
301    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE 1 / 1 = 2"#
302    /// );
303    /// ```
304    fn div<R>(self, right: R) -> Expr
305    where
306        R: Into<Expr>,
307    {
308        self.binary(BinOper::Div, right)
309    }
310
311    /// Express an equal (`=`) expression.
312    ///
313    /// # Examples
314    ///
315    /// ```
316    /// use sea_query::{tests_cfg::*, *};
317    ///
318    /// let query = Query::select()
319    ///     .columns([Char::Character, Char::SizeW, Char::SizeH])
320    ///     .from(Char::Table)
321    ///     .and_where(Expr::val("What!").eq("Nothing"))
322    ///     .and_where(Char::Id.into_column_ref().eq(1))
323    ///     .to_owned();
324    ///
325    /// assert_eq!(
326    ///     query.to_string(MysqlQueryBuilder),
327    ///     r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE 'What!' = 'Nothing' AND `id` = 1"#
328    /// );
329    /// assert_eq!(
330    ///     query.to_string(PostgresQueryBuilder),
331    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE 'What!' = 'Nothing' AND "id" = 1"#
332    /// );
333    /// assert_eq!(
334    ///     query.to_string(SqliteQueryBuilder),
335    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE 'What!' = 'Nothing' AND "id" = 1"#
336    /// );
337    /// ```
338    ///
339    /// Note how you should express a string being a literal vs an identifier.
340    ///
341    /// ```
342    /// use sea_query::{tests_cfg::*, *};
343    ///
344    /// let query = Query::select()
345    ///     .column(Char::Character)
346    ///     .from(Char::Table)
347    ///     .and_where(Expr::col("name").eq("Something"))
348    ///     .to_owned();
349    ///
350    /// assert_eq!(
351    ///     query.to_string(MysqlQueryBuilder),
352    ///     r#"SELECT `character` FROM `character` WHERE `name` = 'Something'"#
353    /// );
354    /// assert_eq!(
355    ///     query.to_string(PostgresQueryBuilder),
356    ///     r#"SELECT "character" FROM "character" WHERE "name" = 'Something'"#
357    /// );
358    /// assert_eq!(
359    ///     query.to_string(SqliteQueryBuilder),
360    ///     r#"SELECT "character" FROM "character" WHERE "name" = 'Something'"#
361    /// );
362    /// ```
363    fn eq<R>(self, right: R) -> Expr
364    where
365        R: Into<Expr>,
366    {
367        self.binary(BinOper::Equal, right)
368    }
369
370    /// Express a equal expression between two table columns,
371    /// you will mainly use this to relate identical value between two table columns.
372    ///
373    /// # Examples
374    ///
375    /// ```
376    /// use sea_query::{*, tests_cfg::*};
377    ///
378    /// let query = Query::select()
379    ///     .columns([Char::Character, Char::SizeW, Char::SizeH])
380    ///     .from(Char::Table)
381    ///     .and_where((Char::Table, Char::FontId).into_column_ref().equals((Font::Table, Font::Id)))
382    ///     .to_owned();
383    ///
384    /// assert_eq!(
385    ///     query.to_string(MysqlQueryBuilder),
386    ///     r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE `character`.`font_id` = `font`.`id`"#
387    /// );
388    /// assert_eq!(
389    ///     query.to_string(PostgresQueryBuilder),
390    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "character"."font_id" = "font"."id""#
391    /// );
392    /// assert_eq!(
393    ///     query.to_string(SqliteQueryBuilder),
394    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "character"."font_id" = "font"."id""#
395    /// );
396    /// ```
397    fn equals<C>(self, col: C) -> Expr
398    where
399        C: IntoColumnRef,
400    {
401        self.binary(BinOper::Equal, col.into_column_ref())
402    }
403
404    /// Express a greater than (`>`) expression.
405    ///
406    /// # Examples
407    ///
408    /// ```
409    /// use sea_query::{tests_cfg::*, *};
410    ///
411    /// let query = Query::select()
412    ///     .columns([Char::Character, Char::SizeW, Char::SizeH])
413    ///     .from(Char::Table)
414    ///     .and_where((Char::Table, Char::SizeW).into_column_ref().gt(2))
415    ///     .to_owned();
416    ///
417    /// assert_eq!(
418    ///     query.to_string(MysqlQueryBuilder),
419    ///     r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE `character`.`size_w` > 2"#
420    /// );
421    /// assert_eq!(
422    ///     query.to_string(PostgresQueryBuilder),
423    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "character"."size_w" > 2"#
424    /// );
425    /// assert_eq!(
426    ///     query.to_string(SqliteQueryBuilder),
427    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "character"."size_w" > 2"#
428    /// );
429    /// ```
430    fn gt<R>(self, right: R) -> Expr
431    where
432        R: Into<Expr>,
433    {
434        self.binary(BinOper::GreaterThan, right)
435    }
436
437    /// Express a greater than or equal (`>=`) expression.
438    ///
439    /// # Examples
440    ///
441    /// ```
442    /// use sea_query::{tests_cfg::*, *};
443    ///
444    /// let query = Query::select()
445    ///     .columns([Char::Character, Char::SizeW, Char::SizeH])
446    ///     .from(Char::Table)
447    ///     .and_where((Char::Table, Char::SizeW).into_column_ref().gte(2))
448    ///     .to_owned();
449    ///
450    /// assert_eq!(
451    ///     query.to_string(MysqlQueryBuilder),
452    ///     r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE `character`.`size_w` >= 2"#
453    /// );
454    /// assert_eq!(
455    ///     query.to_string(PostgresQueryBuilder),
456    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "character"."size_w" >= 2"#
457    /// );
458    /// assert_eq!(
459    ///     query.to_string(SqliteQueryBuilder),
460    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "character"."size_w" >= 2"#
461    /// );
462    /// ```
463    fn gte<R>(self, right: R) -> Expr
464    where
465        R: Into<Expr>,
466    {
467        self.binary(BinOper::GreaterThanOrEqual, right)
468    }
469
470    /// Express a `IN` sub-query expression.
471    ///
472    /// # Examples
473    ///
474    /// ```
475    /// use sea_query::{*, tests_cfg::*};
476    ///
477    /// let query = Query::select()
478    ///     .columns([Char::Character, Char::SizeW, Char::SizeH])
479    ///     .from(Char::Table)
480    ///     .and_where(Char::SizeW.into_column_ref().in_subquery(
481    ///         Query::select()
482    ///             .expr(Expr::cust("3 + 2 * 2"))
483    ///             .take()
484    ///     ))
485    ///     .to_owned();
486    ///
487    /// assert_eq!(
488    ///     query.to_string(MysqlQueryBuilder),
489    ///     r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE `size_w` IN (SELECT 3 + 2 * 2)"#
490    /// );
491    /// assert_eq!(
492    ///     query.to_string(PostgresQueryBuilder),
493    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "size_w" IN (SELECT 3 + 2 * 2)"#
494    /// );
495    /// assert_eq!(
496    ///     query.to_string(SqliteQueryBuilder),
497    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "size_w" IN (SELECT 3 + 2 * 2)"#
498    /// );
499    /// ```
500    fn in_subquery(self, sel: SelectStatement) -> Expr {
501        self.binary(BinOper::In, Expr::SubQuery(None, Box::new(sel.into())))
502    }
503
504    /// Express a `IN` sub expression.
505    ///
506    /// # Examples
507    ///
508    /// ```
509    /// use sea_query::{*, tests_cfg::*};
510    ///
511    /// let query = Query::select()
512    ///     .columns([Char::Character, Char::FontId])
513    ///     .from(Char::Table)
514    ///     .and_where(
515    ///         Expr::tuple([
516    ///             Expr::col(Char::Character).into(),
517    ///             Expr::col(Char::FontId).into(),
518    ///         ]).in_tuples([(1, String::from("1")), (2, String::from("2"))])
519    ///     )
520    ///     .to_owned();
521    ///
522    /// assert_eq!(
523    ///     query.to_string(MysqlQueryBuilder),
524    ///     r#"SELECT `character`, `font_id` FROM `character` WHERE (`character`, `font_id`) IN ((1, '1'), (2, '2'))"#
525    /// );
526    ///
527    /// assert_eq!(
528    ///     query.to_string(PostgresQueryBuilder),
529    ///     r#"SELECT "character", "font_id" FROM "character" WHERE ("character", "font_id") IN ((1, '1'), (2, '2'))"#
530    /// );
531    ///
532    /// assert_eq!(
533    ///     query.to_string(SqliteQueryBuilder),
534    ///     r#"SELECT "character", "font_id" FROM "character" WHERE ("character", "font_id") IN ((1, '1'), (2, '2'))"#
535    /// );
536    /// ```
537    fn in_tuples<V, I>(self, v: I) -> Expr
538    where
539        V: IntoValueTuple,
540        I: IntoIterator<Item = V>,
541    {
542        self.binary(
543            BinOper::In,
544            Expr::Tuple(
545                v.into_iter()
546                    .map(|m| Expr::Values(m.into_value_tuple().into_iter().collect()))
547                    .collect(),
548            ),
549        )
550    }
551
552    /// Express a `IS` expression.
553    ///
554    /// # Examples
555    ///
556    /// ```
557    /// use sea_query::{*, tests_cfg::*};
558    ///
559    /// let query = Query::select()
560    ///     .columns([Char::Character, Char::SizeW, Char::SizeH])
561    ///     .from(Char::Table)
562    ///     .and_where((Char::Table, Char::Ascii).into_column_ref().is(true))
563    ///     .to_owned();
564    ///
565    /// assert_eq!(
566    ///     query.to_string(MysqlQueryBuilder),
567    ///     r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE `character`.`ascii` IS TRUE"#
568    /// );
569    /// assert_eq!(
570    ///     query.to_string(PostgresQueryBuilder),
571    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "character"."ascii" IS TRUE"#
572    /// );
573    /// assert_eq!(
574    ///     query.to_string(SqliteQueryBuilder),
575    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "character"."ascii" IS TRUE"#
576    /// );
577    /// ```
578    fn is<R>(self, right: R) -> Expr
579    where
580        R: Into<Expr>,
581    {
582        self.binary(BinOper::Is, right)
583    }
584
585    /// Express a `IN` expression.
586    ///
587    /// # Examples
588    ///
589    /// ```
590    /// use sea_query::{tests_cfg::*, *};
591    ///
592    /// let query = Query::select()
593    ///     .columns([Char::Id])
594    ///     .from(Char::Table)
595    ///     .and_where(
596    ///         (Char::Table, Char::SizeW)
597    ///             .into_column_ref()
598    ///             .is_in([1, 2, 3]),
599    ///     )
600    ///     .to_owned();
601    ///
602    /// assert_eq!(
603    ///     query.to_string(MysqlQueryBuilder),
604    ///     r#"SELECT `id` FROM `character` WHERE `character`.`size_w` IN (1, 2, 3)"#
605    /// );
606    /// assert_eq!(
607    ///     query.to_string(PostgresQueryBuilder),
608    ///     r#"SELECT "id" FROM "character" WHERE "character"."size_w" IN (1, 2, 3)"#
609    /// );
610    /// assert_eq!(
611    ///     query.to_string(SqliteQueryBuilder),
612    ///     r#"SELECT "id" FROM "character" WHERE "character"."size_w" IN (1, 2, 3)"#
613    /// );
614    /// ```
615    ///
616    /// The same query can be constructed using the `raw_query!` macro.
617    ///
618    /// ```
619    /// use sea_query::Values;
620    ///
621    /// let ids: Vec<i32> = vec![1, 2, 3];
622    /// let query = sea_query::raw_query!(
623    ///     SqliteQueryBuilder,
624    ///     r#"SELECT "id" FROM "character" WHERE "character"."size_w" IN ({..ids})"#
625    /// );
626    ///
627    /// assert_eq!(
628    ///     query.sql,
629    ///     r#"SELECT "id" FROM "character" WHERE "character"."size_w" IN (?, ?, ?)"#
630    /// );
631    /// assert_eq!(query.values, Values(vec![1.into(), 2.into(), 3.into()]));
632    /// ```
633    ///
634    /// Empty value list is converted to an always false expression due to SQL syntax.
635    ///
636    /// ```
637    /// use sea_query::{tests_cfg::*, *};
638    ///
639    /// let query = Query::select()
640    ///     .columns([Char::Id])
641    ///     .from(Char::Table)
642    ///     .and_where(
643    ///         (Char::Table, Char::SizeW)
644    ///             .into_column_ref()
645    ///             .is_in(Vec::<u8>::new()),
646    ///     )
647    ///     .to_owned();
648    ///
649    /// assert_eq!(
650    ///     query.to_string(MysqlQueryBuilder),
651    ///     r#"SELECT `id` FROM `character` WHERE 1 = 2"#
652    /// );
653    /// assert_eq!(
654    ///     query.to_string(PostgresQueryBuilder),
655    ///     r#"SELECT "id" FROM "character" WHERE 1 = 2"#
656    /// );
657    /// assert_eq!(
658    ///     query.to_string(SqliteQueryBuilder),
659    ///     r#"SELECT "id" FROM "character" WHERE 1 = 2"#
660    /// );
661    /// ```
662    #[allow(clippy::wrong_self_convention)]
663    fn is_in<V, I>(self, v: I) -> Expr
664    where
665        V: Into<Expr>,
666        I: IntoIterator<Item = V>,
667    {
668        self.binary(
669            BinOper::In,
670            Expr::Tuple(v.into_iter().map(|v| v.into()).collect()),
671        )
672    }
673
674    /// Express a `IS NOT` expression.
675    ///
676    /// # Examples
677    ///
678    /// ```
679    /// use sea_query::{*, tests_cfg::*};
680    ///
681    /// let query = Query::select()
682    ///     .columns([Char::Character, Char::SizeW, Char::SizeH])
683    ///     .from(Char::Table)
684    ///     .and_where((Char::Table, Char::Ascii).into_column_ref().is_not(true))
685    ///     .to_owned();
686    ///
687    /// assert_eq!(
688    ///     query.to_string(MysqlQueryBuilder),
689    ///     r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE `character`.`ascii` IS NOT TRUE"#
690    /// );
691    /// assert_eq!(
692    ///     query.to_string(PostgresQueryBuilder),
693    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "character"."ascii" IS NOT TRUE"#
694    /// );
695    /// assert_eq!(
696    ///     query.to_string(SqliteQueryBuilder),
697    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "character"."ascii" IS NOT TRUE"#
698    /// );
699    /// ```
700    #[allow(clippy::wrong_self_convention)]
701    fn is_not<R>(self, right: R) -> Expr
702    where
703        R: Into<Expr>,
704    {
705        self.binary(BinOper::IsNot, right)
706    }
707
708    /// Express a `NOT IN` expression.
709    ///
710    /// # Examples
711    ///
712    /// ```
713    /// use sea_query::{tests_cfg::*, *};
714    ///
715    /// let query = Query::select()
716    ///     .columns([Char::Id])
717    ///     .from(Char::Table)
718    ///     .and_where(
719    ///         (Char::Table, Char::SizeW)
720    ///             .into_column_ref()
721    ///             .is_not_in([1, 2, 3]),
722    ///     )
723    ///     .to_owned();
724    ///
725    /// assert_eq!(
726    ///     query.to_string(MysqlQueryBuilder),
727    ///     r#"SELECT `id` FROM `character` WHERE `character`.`size_w` NOT IN (1, 2, 3)"#
728    /// );
729    /// assert_eq!(
730    ///     query.to_string(PostgresQueryBuilder),
731    ///     r#"SELECT "id" FROM "character" WHERE "character"."size_w" NOT IN (1, 2, 3)"#
732    /// );
733    /// assert_eq!(
734    ///     query.to_string(SqliteQueryBuilder),
735    ///     r#"SELECT "id" FROM "character" WHERE "character"."size_w" NOT IN (1, 2, 3)"#
736    /// );
737    /// ```
738    /// Empty value list
739    /// ```
740    /// use sea_query::{tests_cfg::*, *};
741    ///
742    /// let query = Query::select()
743    ///     .columns([Char::Id])
744    ///     .from(Char::Table)
745    ///     .and_where(
746    ///         (Char::Table, Char::SizeW)
747    ///             .into_column_ref()
748    ///             .is_not_in(Vec::<u8>::new()),
749    ///     )
750    ///     .to_owned();
751    ///
752    /// assert_eq!(
753    ///     query.to_string(MysqlQueryBuilder),
754    ///     r#"SELECT `id` FROM `character` WHERE 1 = 1"#
755    /// );
756    /// assert_eq!(
757    ///     query.to_string(PostgresQueryBuilder),
758    ///     r#"SELECT "id" FROM "character" WHERE 1 = 1"#
759    /// );
760    /// assert_eq!(
761    ///     query.to_string(SqliteQueryBuilder),
762    ///     r#"SELECT "id" FROM "character" WHERE 1 = 1"#
763    /// );
764    /// ```
765    #[allow(clippy::wrong_self_convention)]
766    fn is_not_in<V, I>(self, v: I) -> Expr
767    where
768        V: Into<Expr>,
769        I: IntoIterator<Item = V>,
770    {
771        self.binary(
772            BinOper::NotIn,
773            Expr::Tuple(v.into_iter().map(|v| v.into()).collect()),
774        )
775    }
776
777    /// Express a `IS NOT NULL` expression.
778    ///
779    /// # Examples
780    ///
781    /// ```
782    /// use sea_query::{*, tests_cfg::*};
783    ///
784    /// let query = Query::select()
785    ///     .columns([Char::Character, Char::SizeW, Char::SizeH])
786    ///     .from(Char::Table)
787    ///     .and_where((Char::Table, Char::SizeW).into_column_ref().is_not_null())
788    ///     .to_owned();
789    ///
790    /// assert_eq!(
791    ///     query.to_string(MysqlQueryBuilder),
792    ///     r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE `character`.`size_w` IS NOT NULL"#
793    /// );
794    /// assert_eq!(
795    ///     query.to_string(PostgresQueryBuilder),
796    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "character"."size_w" IS NOT NULL"#
797    /// );
798    /// assert_eq!(
799    ///     query.to_string(SqliteQueryBuilder),
800    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "character"."size_w" IS NOT NULL"#
801    /// );
802    /// ```
803    #[allow(clippy::wrong_self_convention)]
804    fn is_not_null(self) -> Expr {
805        self.binary(BinOper::IsNot, Keyword::Null)
806    }
807
808    /// Express a `IS NULL` expression.
809    ///
810    /// # Examples
811    ///
812    /// ```
813    /// use sea_query::{*, tests_cfg::*};
814    ///
815    /// let query = Query::select()
816    ///     .columns([Char::Character, Char::SizeW, Char::SizeH])
817    ///     .from(Char::Table)
818    ///     .and_where((Char::Table, Char::SizeW).into_column_ref().is_null())
819    ///     .to_owned();
820    ///
821    /// assert_eq!(
822    ///     query.to_string(MysqlQueryBuilder),
823    ///     r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE `character`.`size_w` IS NULL"#
824    /// );
825    /// assert_eq!(
826    ///     query.to_string(PostgresQueryBuilder),
827    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "character"."size_w" IS NULL"#
828    /// );
829    /// assert_eq!(
830    ///     query.to_string(SqliteQueryBuilder),
831    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "character"."size_w" IS NULL"#
832    /// );
833    /// ```
834    #[allow(clippy::wrong_self_convention)]
835    fn is_null(self) -> Expr {
836        self.binary(BinOper::Is, Keyword::Null)
837    }
838
839    /// Express a bitwise left shift.
840    ///
841    /// # Examples
842    ///
843    /// ```
844    /// use sea_query::{tests_cfg::*, *};
845    ///
846    /// let query = Query::select()
847    ///     .columns([Char::Character, Char::SizeW, Char::SizeH])
848    ///     .from(Char::Table)
849    ///     .and_where(1.left_shift(1).eq(2))
850    ///     .to_owned();
851    ///
852    /// assert_eq!(
853    ///     query.to_string(MysqlQueryBuilder),
854    ///     r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE 1 << 1 = 2"#
855    /// );
856    /// assert_eq!(
857    ///     query.to_string(PostgresQueryBuilder),
858    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE 1 << 1 = 2"#
859    /// );
860    /// assert_eq!(
861    ///     query.to_string(SqliteQueryBuilder),
862    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE 1 << 1 = 2"#
863    /// );
864    /// ```
865    fn left_shift<R>(self, right: R) -> Expr
866    where
867        R: Into<Expr>,
868    {
869        self.binary(BinOper::LShift, right)
870    }
871
872    /// Express a `LIKE` expression.
873    ///
874    /// # Examples
875    ///
876    /// ```
877    /// use sea_query::{*, tests_cfg::*};
878    ///
879    /// let query = Query::select()
880    ///     .columns([Char::Character, Char::SizeW, Char::SizeH])
881    ///     .from(Char::Table)
882    ///     .and_where((Char::Table, Char::Character).into_column_ref().like("Ours'%"))
883    ///     .to_owned();
884    ///
885    /// assert_eq!(
886    ///     query.to_string(MysqlQueryBuilder),
887    ///     r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE `character`.`character` LIKE 'Ours\'%'"#
888    /// );
889    /// assert_eq!(
890    ///     query.to_string(PostgresQueryBuilder),
891    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "character"."character" LIKE E'Ours\'%'"#
892    /// );
893    /// assert_eq!(
894    ///     query.to_string(SqliteQueryBuilder),
895    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "character"."character" LIKE 'Ours''%'"#
896    /// );
897    /// ```
898    ///
899    /// Like with ESCAPE
900    ///
901    /// ```
902    /// use sea_query::{*, tests_cfg::*};
903    ///
904    /// let query = Query::select()
905    ///     .columns([Char::Character, Char::SizeW, Char::SizeH])
906    ///     .from(Char::Table)
907    ///     .and_where((Char::Table, Char::Character).into_column_ref().like(LikeExpr::new(r"|_Our|_").escape('|')))
908    ///     .to_owned();
909    ///
910    /// assert_eq!(
911    ///     query.to_string(MysqlQueryBuilder),
912    ///     r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE `character`.`character` LIKE '|_Our|_' ESCAPE '|'"#
913    /// );
914    /// assert_eq!(
915    ///     query.to_string(PostgresQueryBuilder),
916    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "character"."character" LIKE '|_Our|_' ESCAPE '|'"#
917    /// );
918    /// assert_eq!(
919    ///     query.to_string(SqliteQueryBuilder),
920    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "character"."character" LIKE '|_Our|_' ESCAPE '|'"#
921    /// );
922    /// ```
923    fn like<L>(self, like: L) -> Expr
924    where
925        L: IntoLikeExpr,
926    {
927        self.binary(BinOper::Like, like.into_like_expr())
928    }
929
930    /// Express a less than (`<`) expression.
931    ///
932    /// # Examples
933    ///
934    /// ```
935    /// use sea_query::{tests_cfg::*, *};
936    ///
937    /// let query = Query::select()
938    ///     .columns([Char::Character, Char::SizeW, Char::SizeH])
939    ///     .from(Char::Table)
940    ///     .and_where((Char::Table, Char::SizeW).into_column_ref().lt(2))
941    ///     .to_owned();
942    ///
943    /// assert_eq!(
944    ///     query.to_string(MysqlQueryBuilder),
945    ///     r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE `character`.`size_w` < 2"#
946    /// );
947    /// assert_eq!(
948    ///     query.to_string(PostgresQueryBuilder),
949    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "character"."size_w" < 2"#
950    /// );
951    /// assert_eq!(
952    ///     query.to_string(SqliteQueryBuilder),
953    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "character"."size_w" < 2"#
954    /// );
955    /// ```
956    fn lt<R>(self, right: R) -> Expr
957    where
958        R: Into<Expr>,
959    {
960        self.binary(BinOper::SmallerThan, right)
961    }
962
963    /// Express a less than or equal (`<=`) expression.
964    ///
965    /// # Examples
966    ///
967    /// ```
968    /// use sea_query::{tests_cfg::*, *};
969    ///
970    /// let query = Query::select()
971    ///     .columns([Char::Character, Char::SizeW, Char::SizeH])
972    ///     .from(Char::Table)
973    ///     .and_where((Char::Table, Char::SizeW).into_column_ref().lte(2))
974    ///     .to_owned();
975    ///
976    /// assert_eq!(
977    ///     query.to_string(MysqlQueryBuilder),
978    ///     r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE `character`.`size_w` <= 2"#
979    /// );
980    /// assert_eq!(
981    ///     query.to_string(PostgresQueryBuilder),
982    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "character"."size_w" <= 2"#
983    /// );
984    /// assert_eq!(
985    ///     query.to_string(SqliteQueryBuilder),
986    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "character"."size_w" <= 2"#
987    /// );
988    /// ```
989    fn lte<R>(self, right: R) -> Expr
990    where
991        R: Into<Expr>,
992    {
993        self.binary(BinOper::SmallerThanOrEqual, right)
994    }
995
996    /// Express an arithmetic modulo operation.
997    ///
998    /// # Examples
999    ///
1000    /// ```
1001    /// use sea_query::{tests_cfg::*, *};
1002    ///
1003    /// let query = Query::select()
1004    ///     .columns([Char::Character, Char::SizeW, Char::SizeH])
1005    ///     .from(Char::Table)
1006    ///     .and_where(1.modulo(1).eq(2))
1007    ///     .to_owned();
1008    ///
1009    /// assert_eq!(
1010    ///     query.to_string(MysqlQueryBuilder),
1011    ///     r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE 1 % 1 = 2"#
1012    /// );
1013    /// assert_eq!(
1014    ///     query.to_string(PostgresQueryBuilder),
1015    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE 1 % 1 = 2"#
1016    /// );
1017    /// assert_eq!(
1018    ///     query.to_string(SqliteQueryBuilder),
1019    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE 1 % 1 = 2"#
1020    /// );
1021    /// ```
1022    fn modulo<R>(self, right: R) -> Expr
1023    where
1024        R: Into<Expr>,
1025    {
1026        self.binary(BinOper::Mod, right)
1027    }
1028
1029    /// Express an arithmetic multiplication operation.
1030    ///
1031    /// # Examples
1032    ///
1033    /// ```
1034    /// use sea_query::{tests_cfg::*, *};
1035    ///
1036    /// let query = Query::select()
1037    ///     .columns([Char::Character, Char::SizeW, Char::SizeH])
1038    ///     .from(Char::Table)
1039    ///     .and_where(1.mul(1).eq(2))
1040    ///     .to_owned();
1041    ///
1042    /// assert_eq!(
1043    ///     query.to_string(MysqlQueryBuilder),
1044    ///     r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE 1 * 1 = 2"#
1045    /// );
1046    /// assert_eq!(
1047    ///     query.to_string(PostgresQueryBuilder),
1048    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE 1 * 1 = 2"#
1049    /// );
1050    /// assert_eq!(
1051    ///     query.to_string(SqliteQueryBuilder),
1052    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE 1 * 1 = 2"#
1053    /// );
1054    /// ```
1055    fn mul<R>(self, right: R) -> Expr
1056    where
1057        R: Into<Expr>,
1058    {
1059        self.binary(BinOper::Mul, right)
1060    }
1061
1062    /// Express a not equal (`<>`) expression.
1063    ///
1064    /// # Examples
1065    ///
1066    /// ```
1067    /// use sea_query::{*, tests_cfg::*};
1068    ///
1069    /// let query = Query::select()
1070    ///     .columns([Char::Character, Char::SizeW, Char::SizeH])
1071    ///     .from(Char::Table)
1072    ///     // Sometimes, you'll have to qualify the call because of conflicting std traits.
1073    ///     .and_where(ExprTrait::ne("Morning", "Good"))
1074    ///     .and_where(Char::Id.into_column_ref().ne(1))
1075    ///     .to_owned();
1076    ///
1077    /// assert_eq!(
1078    ///     query.to_string(MysqlQueryBuilder),
1079    ///     r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE 'Morning' <> 'Good' AND `id` <> 1"#
1080    /// );
1081    /// assert_eq!(
1082    ///     query.to_string(PostgresQueryBuilder),
1083    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE 'Morning' <> 'Good' AND "id" <> 1"#
1084    /// );
1085    /// assert_eq!(
1086    ///     query.to_string(SqliteQueryBuilder),
1087    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE 'Morning' <> 'Good' AND "id" <> 1"#
1088    /// );
1089    /// ```
1090    fn ne<R>(self, right: R) -> Expr
1091    where
1092        R: Into<Expr>,
1093    {
1094        self.binary(BinOper::NotEqual, right)
1095    }
1096
1097    /// Negates an expression with `NOT`.
1098    ///
1099    /// # Examples
1100    ///
1101    /// ```
1102    /// use sea_query::{*, tests_cfg::*};
1103    ///
1104    /// let query = Query::select()
1105    ///     .columns([Char::Character, Char::SizeW, Char::SizeH])
1106    ///     .from(Char::Table)
1107    ///     .and_where(Expr::col((Char::Table, Char::SizeW)).is_null().not())
1108    ///     .to_owned();
1109    ///
1110    /// assert_eq!(
1111    ///     query.to_string(MysqlQueryBuilder),
1112    ///     r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE NOT `character`.`size_w` IS NULL"#
1113    /// );
1114    /// assert_eq!(
1115    ///     query.to_string(PostgresQueryBuilder),
1116    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE NOT "character"."size_w" IS NULL"#
1117    /// );
1118    /// assert_eq!(
1119    ///     query.to_string(SqliteQueryBuilder),
1120    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE NOT "character"."size_w" IS NULL"#
1121    /// );
1122    /// ```
1123    fn not(self) -> Expr {
1124        self.unary(UnOper::Not)
1125    }
1126
1127    /// Express a `NOT BETWEEN` expression.
1128    ///
1129    /// # Examples
1130    ///
1131    /// ```
1132    /// use sea_query::{*, tests_cfg::*};
1133    ///
1134    /// let query = Query::select()
1135    ///     .columns([Char::Character, Char::SizeW, Char::SizeH])
1136    ///     .from(Char::Table)
1137    ///     .and_where((Char::Table, Char::SizeW).into_column_ref().not_between(1, 10))
1138    ///     .to_owned();
1139    ///
1140    /// assert_eq!(
1141    ///     query.to_string(MysqlQueryBuilder),
1142    ///     r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE `character`.`size_w` NOT BETWEEN 1 AND 10"#
1143    /// );
1144    /// assert_eq!(
1145    ///     query.to_string(PostgresQueryBuilder),
1146    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "character"."size_w" NOT BETWEEN 1 AND 10"#
1147    /// );
1148    /// assert_eq!(
1149    ///     query.to_string(SqliteQueryBuilder),
1150    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "character"."size_w" NOT BETWEEN 1 AND 10"#
1151    /// );
1152    /// ```
1153    fn not_between<A, B>(self, a: A, b: B) -> Expr
1154    where
1155        A: Into<Expr>,
1156        B: Into<Expr>,
1157    {
1158        self.binary(
1159            BinOper::NotBetween,
1160            Expr::Binary(Box::new(a.into()), BinOper::And, Box::new(b.into())),
1161        )
1162    }
1163
1164    /// Express a not equal expression between two table columns,
1165    /// you will mainly use this to relate identical value between two table columns.
1166    ///
1167    /// # Examples
1168    ///
1169    /// ```
1170    /// use sea_query::{*, tests_cfg::*};
1171    ///
1172    /// let query = Query::select()
1173    ///     .columns([Char::Character, Char::SizeW, Char::SizeH])
1174    ///     .from(Char::Table)
1175    ///     .and_where((Char::Table, Char::FontId).into_column_ref().not_equals((Font::Table, Font::Id)))
1176    ///     .to_owned();
1177    ///
1178    /// assert_eq!(
1179    ///     query.to_string(MysqlQueryBuilder),
1180    ///     r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE `character`.`font_id` <> `font`.`id`"#
1181    /// );
1182    /// assert_eq!(
1183    ///     query.to_string(PostgresQueryBuilder),
1184    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "character"."font_id" <> "font"."id""#
1185    /// );
1186    /// assert_eq!(
1187    ///     query.to_string(SqliteQueryBuilder),
1188    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "character"."font_id" <> "font"."id""#
1189    /// );
1190    /// ```
1191    fn not_equals<C>(self, col: C) -> Expr
1192    where
1193        C: IntoColumnRef,
1194    {
1195        self.binary(BinOper::NotEqual, col.into_column_ref())
1196    }
1197
1198    /// Express a `NOT IN` sub-query expression.
1199    ///
1200    /// # Examples
1201    ///
1202    /// ```
1203    /// use sea_query::{*, tests_cfg::*};
1204    ///
1205    /// let query = Query::select()
1206    ///     .columns([Char::Character, Char::SizeW, Char::SizeH])
1207    ///     .from(Char::Table)
1208    ///     .and_where(Char::SizeW.into_column_ref().not_in_subquery(
1209    ///         Query::select()
1210    ///             .expr(Expr::cust("3 + 2 * 2"))
1211    ///             .take()
1212    ///     ))
1213    ///     .to_owned();
1214    ///
1215    /// assert_eq!(
1216    ///     query.to_string(MysqlQueryBuilder),
1217    ///     r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE `size_w` NOT IN (SELECT 3 + 2 * 2)"#
1218    /// );
1219    /// assert_eq!(
1220    ///     query.to_string(PostgresQueryBuilder),
1221    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "size_w" NOT IN (SELECT 3 + 2 * 2)"#
1222    /// );
1223    /// assert_eq!(
1224    ///     query.to_string(SqliteQueryBuilder),
1225    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "size_w" NOT IN (SELECT 3 + 2 * 2)"#
1226    /// );
1227    /// ```
1228    fn not_in_subquery(self, sel: SelectStatement) -> Expr {
1229        self.binary(BinOper::NotIn, Expr::SubQuery(None, Box::new(sel.into())))
1230    }
1231
1232    /// Express a `NOT LIKE` expression.
1233    ///
1234    /// # Examples
1235    ///
1236    /// ```
1237    /// use sea_query::{*, tests_cfg::*};
1238    ///
1239    /// let query = Query::select()
1240    ///     .columns([Char::Character, Char::SizeW, Char::SizeH])
1241    ///     .from(Char::Table)
1242    ///     .and_where((Char::Table, Char::Character).into_column_ref().not_like("Ours'%"))
1243    ///     .to_owned();
1244    ///
1245    /// assert_eq!(
1246    ///     query.to_string(MysqlQueryBuilder),
1247    ///     r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE `character`.`character` NOT LIKE 'Ours\'%'"#
1248    /// );
1249    /// assert_eq!(
1250    ///     query.to_string(PostgresQueryBuilder),
1251    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "character"."character" NOT LIKE E'Ours\'%'"#
1252    /// );
1253    /// assert_eq!(
1254    ///     query.to_string(SqliteQueryBuilder),
1255    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "character"."character" NOT LIKE 'Ours''%'"#
1256    /// );
1257    /// ```
1258    fn not_like<L>(self, like: L) -> Expr
1259    where
1260        L: IntoLikeExpr,
1261    {
1262        self.binary(BinOper::NotLike, like.into_like_expr())
1263    }
1264
1265    /// Express a logical `OR` operation.
1266    ///
1267    /// # Examples
1268    ///
1269    /// ```
1270    /// use sea_query::{tests_cfg::*, *};
1271    ///
1272    /// let query = Query::select()
1273    ///     .columns([Char::Character, Char::SizeW, Char::SizeH])
1274    ///     .from(Char::Table)
1275    ///     .and_where(false.or(true))
1276    ///     .to_owned();
1277    ///
1278    /// assert_eq!(
1279    ///     query.to_string(MysqlQueryBuilder),
1280    ///     r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE FALSE OR TRUE"#
1281    /// );
1282    /// assert_eq!(
1283    ///     query.to_string(PostgresQueryBuilder),
1284    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE FALSE OR TRUE"#
1285    /// );
1286    /// assert_eq!(
1287    ///     query.to_string(SqliteQueryBuilder),
1288    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE FALSE OR TRUE"#
1289    /// );
1290    /// ```
1291    fn or<R>(self, right: R) -> Expr
1292    where
1293        R: Into<Expr>,
1294    {
1295        self.binary(BinOper::Or, right)
1296    }
1297
1298    /// Express a bitwise right shift.
1299    ///
1300    /// # Examples
1301    ///
1302    /// ```
1303    /// use sea_query::{tests_cfg::*, *};
1304    ///
1305    /// let query = Query::select()
1306    ///     .columns([Char::Character, Char::SizeW, Char::SizeH])
1307    ///     .from(Char::Table)
1308    ///     .and_where(1.right_shift(1).eq(2))
1309    ///     .to_owned();
1310    ///
1311    /// assert_eq!(
1312    ///     query.to_string(MysqlQueryBuilder),
1313    ///     r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE 1 >> 1 = 2"#
1314    /// );
1315    /// assert_eq!(
1316    ///     query.to_string(PostgresQueryBuilder),
1317    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE 1 >> 1 = 2"#
1318    /// );
1319    /// assert_eq!(
1320    ///     query.to_string(SqliteQueryBuilder),
1321    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE 1 >> 1 = 2"#
1322    /// );
1323    /// ```
1324    fn right_shift<R>(self, right: R) -> Expr
1325    where
1326        R: Into<Expr>,
1327    {
1328        self.binary(BinOper::RShift, right)
1329    }
1330
1331    /// Express an arithmetic subtraction operation.
1332    ///
1333    /// # Examples
1334    ///
1335    /// ```
1336    /// use sea_query::{tests_cfg::*, *};
1337    ///
1338    /// let query = Query::select()
1339    ///     .columns([Char::Character, Char::SizeW, Char::SizeH])
1340    ///     .from(Char::Table)
1341    ///     .and_where(1.sub(1).eq(2))
1342    ///     .to_owned();
1343    ///
1344    /// assert_eq!(
1345    ///     query.to_string(MysqlQueryBuilder),
1346    ///     r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE 1 - 1 = 2"#
1347    /// );
1348    /// assert_eq!(
1349    ///     query.to_string(PostgresQueryBuilder),
1350    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE 1 - 1 = 2"#
1351    /// );
1352    /// assert_eq!(
1353    ///     query.to_string(SqliteQueryBuilder),
1354    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE 1 - 1 = 2"#
1355    /// );
1356    /// ```
1357    fn sub<R>(self, right: R) -> Expr
1358    where
1359        R: Into<Expr>,
1360    {
1361        self.binary(BinOper::Sub, right)
1362    }
1363
1364    /// Apply any unary operator to the expression.
1365    ///
1366    /// # Examples
1367    ///
1368    /// ```
1369    /// use sea_query::{*, tests_cfg::*};
1370    ///
1371    /// let query = Query::select()
1372    ///     .columns([Char::Character, Char::SizeW, Char::SizeH])
1373    ///     .from(Char::Table)
1374    ///     .and_where(Expr::col((Char::Table, Char::SizeW)).is_null().unary(UnOper::Not))
1375    ///     .to_owned();
1376    ///
1377    /// assert_eq!(
1378    ///     query.to_string(MysqlQueryBuilder),
1379    ///     r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE NOT `character`.`size_w` IS NULL"#
1380    /// );
1381    /// assert_eq!(
1382    ///     query.to_string(PostgresQueryBuilder),
1383    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE NOT "character"."size_w" IS NULL"#
1384    /// );
1385    /// assert_eq!(
1386    ///     query.to_string(SqliteQueryBuilder),
1387    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE NOT "character"."size_w" IS NULL"#
1388    /// );
1389    /// ```
1390    fn unary(self, o: UnOper) -> Expr;
1391
1392    /// Express a bitwise AND operation.
1393    ///
1394    /// # Examples
1395    ///
1396    /// ```
1397    /// use sea_query::{tests_cfg::*, *};
1398    ///
1399    /// let query = Query::select().expr(1.bit_and(2).eq(3)).to_owned();
1400    ///
1401    /// assert_eq!(
1402    ///     query.to_string(PostgresQueryBuilder),
1403    ///     r#"SELECT (1 & 2) = 3"#
1404    /// );
1405    ///
1406    /// let query = Query::select()
1407    ///     .columns([Char::Character, Char::SizeW, Char::SizeH])
1408    ///     .from(Char::Table)
1409    ///     .and_where(1.bit_and(1).eq(1))
1410    ///     .to_owned();
1411    ///
1412    /// assert_eq!(
1413    ///     query.to_string(MysqlQueryBuilder),
1414    ///     r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE (1 & 1) = 1"#
1415    /// );
1416    /// assert_eq!(
1417    ///     query.to_string(PostgresQueryBuilder),
1418    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE (1 & 1) = 1"#
1419    /// );
1420    /// assert_eq!(
1421    ///     query.to_string(SqliteQueryBuilder),
1422    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE (1 & 1) = 1"#
1423    /// );
1424    /// ```
1425    fn bit_and<R>(self, right: R) -> Expr
1426    where
1427        R: Into<Expr>,
1428    {
1429        self.binary(BinOper::BitAnd, right)
1430    }
1431
1432    /// Express a bitwise OR operation.
1433    ///
1434    /// # Examples
1435    ///
1436    /// ```
1437    /// use sea_query::{tests_cfg::*, *};
1438    ///
1439    /// let query = Query::select()
1440    ///     .columns([Char::Character, Char::SizeW, Char::SizeH])
1441    ///     .from(Char::Table)
1442    ///     .and_where(1.bit_or(1).eq(1))
1443    ///     .to_owned();
1444    ///
1445    /// assert_eq!(
1446    ///     query.to_string(MysqlQueryBuilder),
1447    ///     r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE (1 | 1) = 1"#
1448    /// );
1449    /// assert_eq!(
1450    ///     query.to_string(PostgresQueryBuilder),
1451    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE (1 | 1) = 1"#
1452    /// );
1453    /// assert_eq!(
1454    ///     query.to_string(SqliteQueryBuilder),
1455    ///     r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE (1 | 1) = 1"#
1456    /// );
1457    /// ```
1458    fn bit_or<R>(self, right: R) -> Expr
1459    where
1460        R: Into<Expr>,
1461    {
1462        self.binary(BinOper::BitOr, right)
1463    }
1464}
1465
1466/// This generic implementation covers all expression types,
1467/// including [ColumnRef], [Value], [FunctionCall], [Expr]...
1468impl<T> ExprTrait for T
1469where
1470    T: Into<Expr>,
1471{
1472    fn as_enum<N>(self, type_name: N) -> Expr
1473    where
1474        N: IntoIden,
1475    {
1476        Expr::AsEnum(type_name.into_iden(), Box::new(self.into()))
1477    }
1478
1479    fn binary<O, R>(self, op: O, right: R) -> Expr
1480    where
1481        O: Into<BinOper>,
1482        R: Into<Expr>,
1483    {
1484        Expr::Binary(Box::new(self.into()), op.into(), Box::new(right.into()))
1485    }
1486
1487    fn cast_as<N>(self, type_name: N) -> Expr
1488    where
1489        N: IntoIden,
1490    {
1491        Expr::FunctionCall(Func::cast_as(self, type_name))
1492    }
1493
1494    fn unary(self, op: UnOper) -> Expr {
1495        Expr::Unary(op, Box::new(self.into()))
1496    }
1497}