quaint_forked/ast/
compare.rs

1use super::ExpressionKind;
2use crate::ast::{Column, ConditionTree, Expression};
3use std::borrow::Cow;
4
5/// For modeling comparison expressions.
6#[derive(Debug, Clone, PartialEq)]
7pub enum Compare<'a> {
8    /// `left = right`
9    Equals(Box<Expression<'a>>, Box<Expression<'a>>),
10    /// `left <> right`
11    NotEquals(Box<Expression<'a>>, Box<Expression<'a>>),
12    /// `left < right`
13    LessThan(Box<Expression<'a>>, Box<Expression<'a>>),
14    /// `left <= right`
15    LessThanOrEquals(Box<Expression<'a>>, Box<Expression<'a>>),
16    /// `left > right`
17    GreaterThan(Box<Expression<'a>>, Box<Expression<'a>>),
18    /// `left >= right`
19    GreaterThanOrEquals(Box<Expression<'a>>, Box<Expression<'a>>),
20    /// `left IN (..)`
21    In(Box<Expression<'a>>, Box<Expression<'a>>),
22    /// `left NOT IN (..)`
23    NotIn(Box<Expression<'a>>, Box<Expression<'a>>),
24    /// `left LIKE %..%`
25    Like(Box<Expression<'a>>, Box<Expression<'a>>),
26    /// `left NOT LIKE %..%`
27    NotLike(Box<Expression<'a>>, Box<Expression<'a>>),
28    /// `value IS NULL`
29    Null(Box<Expression<'a>>),
30    /// `value IS NOT NULL`
31    NotNull(Box<Expression<'a>>),
32    /// `value` BETWEEN `left` AND `right`
33    Between(Box<Expression<'a>>, Box<Expression<'a>>, Box<Expression<'a>>),
34    /// `value` NOT BETWEEN `left` AND `right`
35    NotBetween(Box<Expression<'a>>, Box<Expression<'a>>, Box<Expression<'a>>),
36    /// Raw comparator, allows to use an operator `left <raw> right` as is,
37    /// without visitor transformation in between.
38    Raw(Box<Expression<'a>>, Cow<'a, str>, Box<Expression<'a>>),
39    /// All json related comparators
40    #[cfg(all(feature = "json", any(feature = "postgresql", feature = "mysql")))]
41    JsonCompare(JsonCompare<'a>),
42    /// `left` @@ to_tsquery(`value`)
43    #[cfg(feature = "postgresql")]
44    Matches(Box<Expression<'a>>, Cow<'a, str>),
45    /// (NOT `left` @@ to_tsquery(`value`))
46    #[cfg(feature = "postgresql")]
47    NotMatches(Box<Expression<'a>>, Cow<'a, str>),
48    /// ANY (`left`)
49    #[cfg(feature = "postgresql")]
50    Any(Box<Expression<'a>>),
51    /// ALL (`left`)
52    #[cfg(feature = "postgresql")]
53    All(Box<Expression<'a>>),
54}
55
56#[derive(Debug, Clone, PartialEq)]
57pub enum JsonCompare<'a> {
58    ArrayContains(Box<Expression<'a>>, Box<Expression<'a>>),
59    ArrayNotContains(Box<Expression<'a>>, Box<Expression<'a>>),
60    TypeEquals(Box<Expression<'a>>, JsonType<'a>),
61    TypeNotEquals(Box<Expression<'a>>, JsonType<'a>),
62}
63
64#[derive(Debug, Clone, PartialEq)]
65pub enum JsonType<'a> {
66    Array,
67    Object,
68    String,
69    Number,
70    Boolean,
71    Null,
72    ColumnRef(Box<Column<'a>>),
73}
74
75impl<'a> From<Column<'a>> for JsonType<'a> {
76    fn from(col: Column<'a>) -> Self {
77        JsonType::ColumnRef(Box::new(col))
78    }
79}
80
81impl<'a> Compare<'a> {
82    /// Finds a possible `(a,y) IN (SELECT x,z FROM B)`, takes the select out and
83    /// converts the comparison into `a IN (SELECT x FROM cte_n where z = y)`.
84    ///
85    /// Left side means a match and the CTE should be handled, right side is a
86    /// no-op.
87    #[cfg(feature = "mssql")]
88    pub(crate) fn convert_tuple_select_to_cte(
89        self,
90        level: &mut usize,
91    ) -> either::Either<Self, (Self, Vec<super::CommonTableExpression<'a>>)> {
92        use super::IntoCommonTableExpression;
93
94        fn convert<'a>(
95            row: super::Row<'a>,
96            select: super::SelectQuery<'a>,
97            mut selected_columns: Vec<String>,
98            level: &mut usize,
99        ) -> (
100            super::Column<'a>,
101            super::Select<'a>,
102            Vec<super::CommonTableExpression<'a>>,
103        ) {
104            // Get the columns out from the row.
105            let mut cols = row.into_columns();
106
107            // The name of the CTE in the query
108            let ident = format!("cte_{level}");
109
110            let (select, ctes) = select.convert_tuple_selects_to_ctes(level);
111
112            let mut combined_ctes = Vec::with_capacity(ctes.len() + 1);
113            combined_ctes.push(select.into_cte(ident.clone()));
114            combined_ctes.extend(ctes);
115
116            // The left side column of the comparison, `*this* IN (...)`. We can
117            // support a single value comparisons in all databases, so we try to
118            // find the first value of the tuple, converting the select to hold
119            // the rest of the values in its comparison.
120            let comp_col = cols.remove(0);
121
122            // The right side `SELECT` of the comparison, replacing the original
123            // `SELECT`.  At this point we just select the first column from the
124            // original select, changing the `SELECT` into
125            // `(SELECT first_col FROM cte_n)`.
126            let base_select = super::Select::from_table(ident).column(selected_columns.remove(0));
127
128            // We know we have the same amount of columns on both sides,
129            let column_pairs = cols.into_iter().zip(selected_columns.into_iter());
130
131            // Adding to the new select a condition to filter out the rest of
132            // the tuple, so if our tuple is `(a, b) IN (SELECT x, y ..)`, this
133            // will then turn into `a IN (SELECT x WHERE b = y)`.
134            let inner_select = column_pairs.fold(base_select, |acc, (left_col, right_col)| {
135                acc.and_where(right_col.equals(left_col))
136            });
137
138            // Now we added one cte, so we must increment the count for the
139            // possible other expressions.
140            *level += 1;
141
142            // Return the comparison data to the caller.
143            (comp_col, inner_select, combined_ctes)
144        }
145
146        match self {
147            Self::In(left, right) if left.is_row() && right.is_selection() => {
148                let row = left.into_row().unwrap();
149                let select = right.into_selection().unwrap();
150                let selection = select.named_selection();
151
152                if row.len() != selection.len() {
153                    let left = Expression::row(row);
154                    let right = Expression::selection(select);
155
156                    return either::Either::Left(left.in_selection(right));
157                }
158
159                if row.is_only_columns() && row.len() > 1 {
160                    let (comp_col, inner_select, ctes) = convert(row, select, selection, level);
161                    let cond = comp_col.in_selection(inner_select);
162
163                    either::Either::Right((cond, ctes))
164                } else if row.len() == 1 {
165                    let left = Expression::row(row);
166                    let (select, ctes) = select.convert_tuple_selects_to_ctes(level);
167
168                    let select = Expression::selection(select);
169                    let cond = Self::In(Box::new(left), Box::new(select));
170
171                    either::Either::Right((cond, ctes))
172                } else {
173                    let left = Expression::row(row);
174                    let select = Expression::selection(select);
175                    let cond = Self::In(Box::new(left), Box::new(select));
176
177                    either::Either::Left(cond)
178                }
179            }
180            Self::In(left, right) if right.is_selection() => {
181                let (selection, ctes) = right.into_selection().unwrap().convert_tuple_selects_to_ctes(level);
182                let cond = Self::In(left, Box::new(Expression::selection(selection)));
183
184                either::Either::Right((cond, ctes))
185            }
186            Self::NotIn(left, right) if left.is_row() && right.is_selection() => {
187                let row = left.into_row().unwrap();
188                let select = right.into_selection().unwrap();
189                let selection = select.named_selection();
190
191                if row.len() != selection.len() {
192                    let left = Expression::row(row);
193                    let right = Expression::selection(select);
194
195                    return either::Either::Left(left.not_in_selection(right));
196                }
197
198                if row.is_only_columns() && row.len() > 1 {
199                    let (comp_col, inner_select, ctes) = convert(row, select, selection, level);
200                    let cond = comp_col.not_in_selection(inner_select);
201
202                    either::Either::Right((cond, ctes))
203                } else if row.len() == 1 {
204                    let left = Expression::row(row);
205                    let (select, ctes) = select.convert_tuple_selects_to_ctes(level);
206
207                    let select = Expression::selection(select);
208                    let cond = Self::NotIn(Box::new(left), Box::new(select));
209
210                    either::Either::Right((cond, ctes))
211                } else {
212                    let left = Expression::row(row);
213                    let select = Expression::selection(select);
214                    let cond = Self::NotIn(Box::new(left), Box::new(select));
215
216                    either::Either::Left(cond)
217                }
218            }
219            Self::NotIn(left, right) if right.is_selection() => {
220                let (selection, ctes) = right.into_selection().unwrap().convert_tuple_selects_to_ctes(level);
221                let cond = Self::NotIn(left, Box::new(Expression::selection(selection)));
222
223                either::Either::Right((cond, ctes))
224            }
225            _ => either::Either::Left(self),
226        }
227    }
228}
229
230impl<'a> From<Compare<'a>> for ConditionTree<'a> {
231    fn from(cmp: Compare<'a>) -> Self {
232        ConditionTree::single(Expression::from(cmp))
233    }
234}
235
236impl<'a> From<Compare<'a>> for Expression<'a> {
237    fn from(cmp: Compare<'a>) -> Self {
238        Expression {
239            kind: ExpressionKind::Compare(cmp),
240            alias: None,
241        }
242    }
243}
244
245/// An item that can be compared against other values in the database.
246pub trait Comparable<'a> {
247    /// Tests if both sides are the same value.
248    ///
249    /// ```rust
250    /// # use quaint::{ast::*, visitor::{Visitor, Sqlite}};
251    /// # fn main() -> Result<(), quaint::error::Error> {
252    /// let query = Select::from_table("users").so_that("foo".equals("bar"));
253    /// let (sql, params) = Sqlite::build(query)?;
254    ///
255    /// assert_eq!("SELECT `users`.* FROM `users` WHERE `foo` = ?", sql);
256    ///
257    /// assert_eq!(
258    ///     vec![
259    ///         Value::from("bar"),
260    ///     ],
261    ///     params
262    /// );
263    /// # Ok(())
264    /// # }
265    /// ```
266    fn equals<T>(self, comparison: T) -> Compare<'a>
267    where
268        T: Into<Expression<'a>>;
269
270    /// Tests if both sides are not the same value.
271    ///
272    /// ```rust
273    /// # use quaint::{ast::*, visitor::{Visitor, Sqlite}};
274    /// # fn main() -> Result<(), quaint::error::Error> {
275    /// let query = Select::from_table("users").so_that("foo".not_equals("bar"));
276    /// let (sql, params) = Sqlite::build(query)?;
277    ///
278    /// assert_eq!("SELECT `users`.* FROM `users` WHERE `foo` <> ?", sql);
279    ///
280    /// assert_eq!(
281    ///     vec![
282    ///         Value::from("bar"),
283    ///     ],
284    ///     params
285    /// );
286    /// # Ok(())
287    /// # }
288    /// ```
289    fn not_equals<T>(self, comparison: T) -> Compare<'a>
290    where
291        T: Into<Expression<'a>>;
292
293    /// Tests if the left side is smaller than the right side.
294    ///
295    /// ```rust
296    /// # fn main() -> Result<(), quaint::error::Error> {
297    /// # use quaint::{ast::*, visitor::{Visitor, Sqlite}};
298    /// let query = Select::from_table("users").so_that("foo".less_than(10));
299    /// let (sql, params) = Sqlite::build(query)?;
300    ///
301    /// assert_eq!("SELECT `users`.* FROM `users` WHERE `foo` < ?", sql);
302    ///
303    /// assert_eq!(
304    ///     vec![
305    ///         Value::from(10),
306    ///     ],
307    ///     params
308    /// );
309    /// # Ok(())
310    /// # }
311    /// ```
312    fn less_than<T>(self, comparison: T) -> Compare<'a>
313    where
314        T: Into<Expression<'a>>;
315
316    /// Tests if the left side is smaller than the right side or the same.
317    ///
318    /// ```rust
319    /// # use quaint::{ast::*, visitor::{Visitor, Sqlite}};
320    /// # fn main() -> Result<(), quaint::error::Error> {
321    /// let query = Select::from_table("users").so_that("foo".less_than_or_equals(10));
322    /// let (sql, params) = Sqlite::build(query)?;
323    ///
324    /// assert_eq!("SELECT `users`.* FROM `users` WHERE `foo` <= ?", sql);
325    ///
326    /// assert_eq!(
327    ///     vec![
328    ///         Value::from(10),
329    ///     ],
330    ///     params
331    /// );
332    /// # Ok(())
333    /// # }
334    /// ```
335    fn less_than_or_equals<T>(self, comparison: T) -> Compare<'a>
336    where
337        T: Into<Expression<'a>>;
338
339    /// Tests if the left side is bigger than the right side.
340    ///
341    /// ```rust
342    /// # use quaint::{ast::*, visitor::{Visitor, Sqlite}};
343    /// # fn main() -> Result<(), quaint::error::Error> {
344    /// let query = Select::from_table("users").so_that("foo".greater_than(10));
345    /// let (sql, params) = Sqlite::build(query)?;
346    ///
347    /// assert_eq!("SELECT `users`.* FROM `users` WHERE `foo` > ?", sql);
348    ///
349    /// assert_eq!(
350    ///     vec![
351    ///         Value::from(10),
352    ///     ],
353    ///     params
354    /// );
355    /// # Ok(())
356    /// # }
357    /// ```
358    fn greater_than<T>(self, comparison: T) -> Compare<'a>
359    where
360        T: Into<Expression<'a>>;
361
362    /// Tests if the left side is bigger than the right side or the same.
363    ///
364    /// ```rust
365    /// # use quaint::{ast::*, visitor::{Visitor, Sqlite}};
366    /// # fn main() -> Result<(), quaint::error::Error> {
367    /// let query = Select::from_table("users").so_that("foo".greater_than_or_equals(10));
368    /// let (sql, params) = Sqlite::build(query)?;
369    ///
370    /// assert_eq!("SELECT `users`.* FROM `users` WHERE `foo` >= ?", sql);
371    ///
372    /// assert_eq!(
373    ///     vec![
374    ///         Value::from(10),
375    ///     ],
376    ///     params
377    /// );
378    /// # Ok(())
379    /// # }
380    /// ```
381    fn greater_than_or_equals<T>(self, comparison: T) -> Compare<'a>
382    where
383        T: Into<Expression<'a>>;
384
385    /// Tests if the left side is included in the right side collection.
386    ///
387    /// ```rust
388    /// # use quaint::{ast::*, visitor::{Visitor, Sqlite}};
389    /// # fn main() -> Result<(), quaint::error::Error> {
390    /// let query = Select::from_table("users").so_that("foo".in_selection(vec![1, 2]));
391    /// let (sql, params) = Sqlite::build(query)?;
392    ///
393    /// assert_eq!("SELECT `users`.* FROM `users` WHERE `foo` IN (?,?)", sql);
394    /// assert_eq!(vec![
395    ///     Value::from(1),
396    ///     Value::from(2),
397    /// ], params);
398    /// # Ok(())
399    /// # }
400    /// ```
401    fn in_selection<T>(self, selection: T) -> Compare<'a>
402    where
403        T: Into<Expression<'a>>;
404
405    /// Tests if the left side is not included in the right side collection.
406    ///
407    /// ```rust
408    /// # use quaint::{ast::*, visitor::{Visitor, Sqlite}};
409    /// # fn main() -> Result<(), quaint::error::Error> {
410    /// let query = Select::from_table("users").so_that("foo".not_in_selection(vec![1, 2]));
411    /// let (sql, params) = Sqlite::build(query)?;
412    ///
413    /// assert_eq!("SELECT `users`.* FROM `users` WHERE `foo` NOT IN (?,?)", sql);
414    ///
415    /// assert_eq!(vec![
416    ///     Value::from(1),
417    ///     Value::from(2),
418    /// ], params);
419    /// # Ok(())
420    /// # }
421    /// ```
422    fn not_in_selection<T>(self, selection: T) -> Compare<'a>
423    where
424        T: Into<Expression<'a>>;
425
426    /// Tests if the left side includes the right side string.
427    ///
428    /// ```rust
429    /// # use quaint::{ast::*, visitor::{Visitor, Sqlite}};
430    /// # fn main() -> Result<(), quaint::error::Error> {
431    /// let query = Select::from_table("users").so_that("foo".like("%bar%"));
432    /// let (sql, params) = Sqlite::build(query)?;
433    ///
434    /// assert_eq!("SELECT `users`.* FROM `users` WHERE `foo` LIKE ?", sql);
435    ///
436    /// assert_eq!(
437    ///     vec![
438    ///         Value::from("%bar%"),
439    ///     ],
440    ///     params
441    /// );
442    /// # Ok(())
443    /// # }
444    /// ```
445    fn like<T>(self, pattern: T) -> Compare<'a>
446    where
447        T: Into<Expression<'a>>;
448
449    /// Tests if the left side does not include the right side string.
450    ///
451    /// ```rust
452    /// # use quaint::{ast::*, visitor::{Visitor, Sqlite}};
453    /// # fn main() -> Result<(), quaint::error::Error> {
454    /// let query = Select::from_table("users").so_that("foo".not_like("%bar%"));
455    /// let (sql, params) = Sqlite::build(query)?;
456    ///
457    /// assert_eq!("SELECT `users`.* FROM `users` WHERE `foo` NOT LIKE ?", sql);
458    ///
459    /// assert_eq!(
460    ///     vec![
461    ///         Value::from("%bar%"),
462    ///     ],
463    ///     params
464    /// );
465    /// # Ok(())
466    /// # }
467    /// ```
468    fn not_like<T>(self, pattern: T) -> Compare<'a>
469    where
470        T: Into<Expression<'a>>;
471
472    /// Tests if the left side is `NULL`.
473    ///
474    /// ```rust
475    /// # use quaint::{ast::*, visitor::{Visitor, Sqlite}};
476    /// # fn main() -> Result<(), quaint::error::Error> {
477    /// let query = Select::from_table("users").so_that("foo".is_null());
478    /// let (sql, _) = Sqlite::build(query)?;
479    ///
480    /// assert_eq!("SELECT `users`.* FROM `users` WHERE `foo` IS NULL", sql);
481    /// # Ok(())
482    /// # }
483    /// ```
484    #[allow(clippy::wrong_self_convention)]
485    fn is_null(self) -> Compare<'a>;
486
487    /// Tests if the left side is not `NULL`.
488    ///
489    /// ```rust
490    /// # use quaint::{ast::*, visitor::{Visitor, Sqlite}};
491    /// # fn main() -> Result<(), quaint::error::Error> {
492    /// let query = Select::from_table("users").so_that("foo".is_not_null());
493    /// let (sql, _) = Sqlite::build(query)?;
494    ///
495    /// assert_eq!("SELECT `users`.* FROM `users` WHERE `foo` IS NOT NULL", sql);
496    /// # Ok(())
497    /// # }
498    /// ```
499    #[allow(clippy::wrong_self_convention)]
500    fn is_not_null(self) -> Compare<'a>;
501
502    /// Tests if the value is between two given values.
503    ///
504    /// ```rust
505    /// # use quaint::{ast::*, visitor::{Visitor, Sqlite}};
506    /// # fn main() -> Result<(), quaint::error::Error> {
507    /// let query = Select::from_table("users").so_that("foo".between(420, 666));
508    /// let (sql, params) = Sqlite::build(query)?;
509    ///
510    /// assert_eq!("SELECT `users`.* FROM `users` WHERE `foo` BETWEEN ? AND ?", sql);
511    ///
512    /// assert_eq!(vec![
513    ///     Value::from(420),
514    ///     Value::from(666),
515    /// ], params);
516    /// # Ok(())
517    /// # }
518    /// ```
519    fn between<T, V>(self, left: T, right: V) -> Compare<'a>
520    where
521        T: Into<Expression<'a>>,
522        V: Into<Expression<'a>>;
523
524    /// Tests if the value is not between two given values.
525    ///
526    /// ```rust
527    /// # use quaint::{ast::*, visitor::{Visitor, Sqlite}};
528    /// # fn main() -> Result<(), quaint::error::Error> {
529    /// let query = Select::from_table("users").so_that("foo".not_between(420, 666));
530    /// let (sql, params) = Sqlite::build(query)?;
531    ///
532    /// assert_eq!("SELECT `users`.* FROM `users` WHERE `foo` NOT BETWEEN ? AND ?", sql);
533    ///
534    /// assert_eq!(vec![
535    ///     Value::from(420),
536    ///     Value::from(666),
537    /// ], params);
538    /// # Ok(())
539    /// # }
540    /// ```
541    fn not_between<T, V>(self, left: T, right: V) -> Compare<'a>
542    where
543        T: Into<Expression<'a>>,
544        V: Into<Expression<'a>>;
545
546    /// Tests if the JSON array contains a value.
547    ///
548    /// ```rust
549    /// # use quaint::{ast::*, visitor::{Visitor, Mysql}};
550    /// # fn main() -> Result<(), quaint::error::Error> {
551    /// let query = Select::from_table("users")
552    ///     .so_that("json".json_array_contains(serde_json::json!(1)));
553    /// let (sql, params) = Mysql::build(query)?;
554    ///
555    /// assert_eq!("SELECT `users`.* FROM `users` WHERE JSON_CONTAINS(`json`, ?)", sql);
556    ///
557    /// assert_eq!(vec![Value::from(serde_json::json!(1))], params);
558    /// # Ok(())
559    /// # }
560    /// ```
561    #[cfg(all(feature = "json", any(feature = "postgresql", feature = "mysql")))]
562    fn json_array_contains<T>(self, item: T) -> Compare<'a>
563    where
564        T: Into<Expression<'a>>;
565
566    /// Tests if the JSON array does not contain a value.
567    ///
568    /// ```rust
569    /// # use quaint::{ast::*, visitor::{Visitor, Mysql}};
570    /// # fn main() -> Result<(), quaint::error::Error> {
571    /// let query = Select::from_table("users")
572    ///     .so_that("json".json_array_not_contains(serde_json::json!(1)));
573    /// let (sql, params) = Mysql::build(query)?;
574    ///
575    /// assert_eq!("SELECT `users`.* FROM `users` WHERE JSON_CONTAINS(`json`, ?) = FALSE", sql);
576    /// assert_eq!(vec![Value::from(serde_json::json!(1))], params);
577    ///
578    /// # Ok(())
579    /// # }
580    /// ```
581    #[cfg(all(feature = "json", any(feature = "postgresql", feature = "mysql")))]
582    fn json_array_not_contains<T>(self, item: T) -> Compare<'a>
583    where
584        T: Into<Expression<'a>>;
585
586    /// Tests if the JSON array starts with a value.
587    ///
588    /// ```rust
589    /// # use quaint::{ast::*, visitor::{Visitor, Mysql}};
590    /// # fn main() -> Result<(), quaint::error::Error> {
591    /// let query = Select::from_table("users")
592    ///     .so_that("json".json_array_begins_with(serde_json::json!(1)));
593    /// let (sql, params) = Mysql::build(query)?;
594    ///
595    /// assert_eq!(
596    ///   "SELECT `users`.* FROM `users` WHERE \
597    ///      (JSON_CONTAINS(JSON_EXTRACT(`json`, ?), ?) AND \
598    ///      JSON_CONTAINS(?, JSON_EXTRACT(`json`, ?)))",
599    ///   sql
600    /// );
601    /// assert_eq!(vec![
602    ///     Value::from("$[0]"),
603    ///     Value::from(serde_json::json!(1)),
604    ///     Value::from(serde_json::json!(1)),
605    ///     Value::from("$[0]"),
606    /// ], params);
607    ///
608    /// # Ok(())
609    /// # }
610    /// ```
611    #[cfg(all(feature = "json", any(feature = "postgresql", feature = "mysql")))]
612    fn json_array_begins_with<T>(self, item: T) -> Compare<'a>
613    where
614        T: Into<Expression<'a>>;
615
616    /// Tests if the JSON array does not start with a value.
617    ///
618    /// ```rust
619    /// # use quaint::{ast::*, visitor::{Visitor, Mysql}};
620    /// # fn main() -> Result<(), quaint::error::Error> {
621    /// let query = Select::from_table("users")
622    ///   .so_that("json".json_array_not_begins_with(serde_json::json!(1)));
623    /// let (sql, params) = Mysql::build(query)?;
624    ///
625    /// assert_eq!(
626    ///   "SELECT `users`.* FROM `users` WHERE \
627    ///      (NOT JSON_CONTAINS(JSON_EXTRACT(`json`, ?), ?) OR \
628    ///      NOT JSON_CONTAINS(?, JSON_EXTRACT(`json`, ?)))",
629    ///   sql
630    /// );
631    /// assert_eq!(vec![
632    ///     Value::from("$[0]"),
633    ///     Value::from(serde_json::json!(1)),
634    ///     Value::from(serde_json::json!(1)),
635    ///     Value::from("$[0]"),
636    /// ], params);
637    ///
638    /// # Ok(())
639    /// # }
640    /// ```
641    #[cfg(all(feature = "json", any(feature = "postgresql", feature = "mysql")))]
642    fn json_array_not_begins_with<T>(self, item: T) -> Compare<'a>
643    where
644        T: Into<Expression<'a>>;
645
646    /// Tests if the JSON array ends with a value.
647    ///
648    /// ```rust
649    /// # use quaint::{ast::*, visitor::{Visitor, Mysql}};
650    /// # fn main() -> Result<(), quaint::error::Error> {
651    /// let query = Select::from_table("users")
652    ///     .so_that("json".json_array_ends_into(serde_json::json!(1)));
653    /// let (sql, params) = Mysql::build(query)?;
654    ///
655    /// assert_eq!(
656    ///   "SELECT `users`.* FROM `users` WHERE \
657    ///      (JSON_CONTAINS(JSON_EXTRACT(`json`, CONCAT('$[', JSON_LENGTH(`json`) - 1, ']')), ?) AND \
658    ///      JSON_CONTAINS(?, JSON_EXTRACT(`json`, CONCAT('$[', JSON_LENGTH(`json`) - 1, ']'))))",
659    ///   sql
660    /// );
661    /// assert_eq!(vec![
662    ///    Value::from(serde_json::json!(1)),
663    ///    Value::from(serde_json::json!(1)),
664    /// ], params);
665    ///
666    /// # Ok(())
667    /// # }
668    /// ```
669    #[cfg(all(feature = "json", any(feature = "postgresql", feature = "mysql")))]
670    fn json_array_ends_into<T>(self, item: T) -> Compare<'a>
671    where
672        T: Into<Expression<'a>>;
673
674    /// Tests if the JSON array does not end with a value.
675    ///
676    /// ```rust
677    /// # use quaint::{ast::*, visitor::{Visitor, Mysql}};
678    /// # fn main() -> Result<(), quaint::error::Error> {
679    /// let query = Select::from_table("users").so_that("json".json_array_not_ends_into(serde_json::json!(1)));
680    /// let (sql, params) = Mysql::build(query)?;
681    ///
682    /// assert_eq!(
683    ///   "SELECT `users`.* FROM `users` WHERE \
684    ///      (NOT JSON_CONTAINS(JSON_EXTRACT(`json`, CONCAT('$[', JSON_LENGTH(`json`) - 1, ']')), ?) OR \
685    ///      NOT JSON_CONTAINS(?, JSON_EXTRACT(`json`, CONCAT('$[', JSON_LENGTH(`json`) - 1, ']'))))",
686    ///   sql
687    /// );
688    ///
689    /// assert_eq!(vec![
690    ///    Value::from(serde_json::json!(1)),
691    ///    Value::from(serde_json::json!(1)),
692    /// ], params);
693    ///
694    /// # Ok(())
695    /// # }
696    /// ```
697    #[cfg(all(feature = "json", any(feature = "postgresql", feature = "mysql")))]
698    fn json_array_not_ends_into<T>(self, item: T) -> Compare<'a>
699    where
700        T: Into<Expression<'a>>;
701
702    /// Tests if the JSON value is of a certain type.
703    ///
704    /// ```rust
705    /// # use quaint::{ast::*, visitor::{Visitor, Mysql}};
706    /// # fn main() -> Result<(), quaint::error::Error> {
707    /// let query = Select::from_table("users").so_that("json".json_type_equals(JsonType::Array));
708    /// let (sql, params) = Mysql::build(query)?;
709    ///
710    /// assert_eq!("SELECT `users`.* FROM `users` WHERE (JSON_TYPE(`json`) = ?)", sql);
711    ///
712    /// assert_eq!(vec![Value::from("ARRAY")], params);
713    /// # Ok(())
714    /// # }
715    /// ```
716    #[cfg(all(feature = "json", any(feature = "postgresql", feature = "mysql")))]
717    fn json_type_equals<T>(self, json_type: T) -> Compare<'a>
718    where
719        T: Into<JsonType<'a>>;
720
721    /// Tests if the JSON value is not of a certain type.
722    ///
723    /// ```rust
724    /// # use quaint::{ast::*, visitor::{Visitor, Mysql}};
725    /// # fn main() -> Result<(), quaint::error::Error> {
726    /// let query = Select::from_table("users").so_that("json".json_type_not_equals(JsonType::Array));
727    /// let (sql, params) = Mysql::build(query)?;
728    ///
729    /// assert_eq!("SELECT `users`.* FROM `users` WHERE (JSON_TYPE(`json`) != ?)", sql);
730    ///
731    /// assert_eq!(vec![Value::from("ARRAY")], params);
732    /// # Ok(())
733    /// # }
734    /// ```
735    #[cfg(all(feature = "json", any(feature = "postgresql", feature = "mysql")))]
736    fn json_type_not_equals<T>(self, json_type: T) -> Compare<'a>
737    where
738        T: Into<JsonType<'a>>;
739
740    /// Tests if a full-text search matches a certain query. Use it in combination with the `text_search()` function
741    ///
742    /// ```rust
743    /// # use quaint::{ast::*, visitor::{Visitor, Postgres}};
744    /// # fn main() -> Result<(), quaint::error::Error> {
745    /// let search: Expression = text_search(&[Column::from("name"), Column::from("ingredients")]).into();
746    /// let query = Select::from_table("recipes").so_that(search.matches("chicken"));
747    /// let (sql, params) = Postgres::build(query)?;
748    ///
749    /// assert_eq!(
750    ///    "SELECT \"recipes\".* FROM \"recipes\" \
751    ///     WHERE to_tsvector(concat_ws(' ', \"name\",\"ingredients\")) @@ to_tsquery($1)", sql
752    /// );
753    ///
754    /// assert_eq!(params, vec![Value::from("chicken")]);
755    ///
756    /// # Ok(())    
757    /// # }
758    /// ```
759    #[cfg(feature = "postgresql")]
760    fn matches<T>(self, query: T) -> Compare<'a>
761    where
762        T: Into<Cow<'a, str>>;
763
764    /// Tests if a full-text search does not match a certain query. Use it in combination with the `text_search()` function
765    ///
766    /// ```rust
767    /// # use quaint::{ast::*, visitor::{Visitor, Postgres}};
768    /// # fn main() -> Result<(), quaint::error::Error> {
769    /// let search: Expression = text_search(&[Column::from("name"), Column::from("ingredients")]).into();
770    /// let query = Select::from_table("recipes").so_that(search.not_matches("chicken"));
771    /// let (sql, params) = Postgres::build(query)?;
772    ///
773    /// assert_eq!(
774    ///    "SELECT \"recipes\".* FROM \"recipes\" \
775    ///     WHERE (NOT to_tsvector(concat_ws(' ', \"name\",\"ingredients\")) @@ to_tsquery($1))", sql
776    /// );
777    ///
778    /// assert_eq!(params, vec![Value::from("chicken")]);
779    ///
780    /// # Ok(())    
781    /// # }
782    /// ```
783    #[cfg(feature = "postgresql")]
784    fn not_matches<T>(self, query: T) -> Compare<'a>
785    where
786        T: Into<Cow<'a, str>>;
787
788    /// Matches at least one elem of a list of values.
789    ///
790    /// ```rust
791    /// # use quaint::{ast::*, col, visitor::{Visitor, Postgres}};
792    /// # fn main() -> Result<(), quaint::error::Error> {
793    /// let query = Select::from_table("users").so_that(col!("name").equals(col!("list").any()));
794    /// let (sql, _) = Postgres::build(query)?;
795    /// assert_eq!(r#"SELECT "users".* FROM "users" WHERE "name" = ANY("list")"#, sql);
796    /// # Ok(())
797    /// # }
798    /// ```
799    #[cfg(feature = "postgresql")]
800    fn any(self) -> Compare<'a>;
801
802    /// Matches all elem of a list of values.
803    ///
804    /// ```rust
805    /// # use quaint::{ast::*, col, visitor::{Visitor, Postgres}};
806    /// # fn main() -> Result<(), quaint::error::Error> {
807    /// let query = Select::from_table("users").so_that(col!("name").equals(col!("list").all()));
808    /// let (sql, _) = Postgres::build(query)?;
809    /// assert_eq!(r#"SELECT "users".* FROM "users" WHERE "name" = ALL("list")"#, sql);
810    /// # Ok(())
811    /// # }
812    /// ```
813    #[cfg(feature = "postgresql")]
814    fn all(self) -> Compare<'a>;
815
816    /// Compares two expressions with a custom operator.
817    ///
818    /// ```rust
819    /// # use quaint::{ast::*, visitor::{Visitor, Sqlite}};
820    /// # fn main() -> Result<(), quaint::error::Error> {
821    /// let query = Select::from_table("users").so_that("foo".compare_raw("ILIKE", "%bar%"));
822    /// let (sql, params) = Sqlite::build(query)?;
823    ///
824    /// assert_eq!("SELECT `users`.* FROM `users` WHERE `foo` ILIKE ?", sql);
825    ///
826    /// assert_eq!(vec![
827    ///     Value::from("%bar%"),
828    /// ], params);
829    ///
830    /// # Ok(())
831    /// # }
832    /// ```
833    fn compare_raw<T, V>(self, raw_comparator: T, right: V) -> Compare<'a>
834    where
835        T: Into<Cow<'a, str>>,
836        V: Into<Expression<'a>>;
837}
838
839impl<'a, U> Comparable<'a> for U
840where
841    U: Into<Column<'a>>,
842{
843    fn equals<T>(self, comparison: T) -> Compare<'a>
844    where
845        T: Into<Expression<'a>>,
846    {
847        let col: Column<'a> = self.into();
848        let val: Expression<'a> = col.into();
849
850        val.equals(comparison)
851    }
852
853    fn not_equals<T>(self, comparison: T) -> Compare<'a>
854    where
855        T: Into<Expression<'a>>,
856    {
857        let col: Column<'a> = self.into();
858        let val: Expression<'a> = col.into();
859        val.not_equals(comparison)
860    }
861
862    fn less_than<T>(self, comparison: T) -> Compare<'a>
863    where
864        T: Into<Expression<'a>>,
865    {
866        let col: Column<'a> = self.into();
867        let val: Expression<'a> = col.into();
868        val.less_than(comparison)
869    }
870
871    fn less_than_or_equals<T>(self, comparison: T) -> Compare<'a>
872    where
873        T: Into<Expression<'a>>,
874    {
875        let col: Column<'a> = self.into();
876        let val: Expression<'a> = col.into();
877        val.less_than_or_equals(comparison)
878    }
879
880    fn greater_than<T>(self, comparison: T) -> Compare<'a>
881    where
882        T: Into<Expression<'a>>,
883    {
884        let col: Column<'a> = self.into();
885        let val: Expression<'a> = col.into();
886        val.greater_than(comparison)
887    }
888
889    fn greater_than_or_equals<T>(self, comparison: T) -> Compare<'a>
890    where
891        T: Into<Expression<'a>>,
892    {
893        let col: Column<'a> = self.into();
894        let val: Expression<'a> = col.into();
895        val.greater_than_or_equals(comparison)
896    }
897
898    fn in_selection<T>(self, selection: T) -> Compare<'a>
899    where
900        T: Into<Expression<'a>>,
901    {
902        let col: Column<'a> = self.into();
903        let val: Expression<'a> = col.into();
904        val.in_selection(selection)
905    }
906
907    fn not_in_selection<T>(self, selection: T) -> Compare<'a>
908    where
909        T: Into<Expression<'a>>,
910    {
911        let col: Column<'a> = self.into();
912        let val: Expression<'a> = col.into();
913        val.not_in_selection(selection)
914    }
915
916    fn like<T>(self, pattern: T) -> Compare<'a>
917    where
918        T: Into<Expression<'a>>,
919    {
920        let col: Column<'a> = self.into();
921        let val: Expression<'a> = col.into();
922        val.like(pattern)
923    }
924
925    fn not_like<T>(self, pattern: T) -> Compare<'a>
926    where
927        T: Into<Expression<'a>>,
928    {
929        let col: Column<'a> = self.into();
930        let val: Expression<'a> = col.into();
931        val.not_like(pattern)
932    }
933
934    #[allow(clippy::wrong_self_convention)]
935    fn is_null(self) -> Compare<'a> {
936        let col: Column<'a> = self.into();
937        let val: Expression<'a> = col.into();
938        val.is_null()
939    }
940
941    #[allow(clippy::wrong_self_convention)]
942    fn is_not_null(self) -> Compare<'a> {
943        let col: Column<'a> = self.into();
944        let val: Expression<'a> = col.into();
945        val.is_not_null()
946    }
947
948    fn between<T, V>(self, left: T, right: V) -> Compare<'a>
949    where
950        T: Into<Expression<'a>>,
951        V: Into<Expression<'a>>,
952    {
953        let col: Column<'a> = self.into();
954        let val: Expression<'a> = col.into();
955        val.between(left, right)
956    }
957
958    fn not_between<T, V>(self, left: T, right: V) -> Compare<'a>
959    where
960        T: Into<Expression<'a>>,
961        V: Into<Expression<'a>>,
962    {
963        let col: Column<'a> = self.into();
964        let val: Expression<'a> = col.into();
965        val.not_between(left, right)
966    }
967
968    fn compare_raw<T, V>(self, raw_comparator: T, right: V) -> Compare<'a>
969    where
970        T: Into<Cow<'a, str>>,
971        V: Into<Expression<'a>>,
972    {
973        let left: Column<'a> = self.into();
974        let left: Expression<'a> = left.into();
975        let right: Expression<'a> = right.into();
976
977        left.compare_raw(raw_comparator.into(), right)
978    }
979
980    #[cfg(all(feature = "json", any(feature = "postgresql", feature = "mysql")))]
981    fn json_array_contains<T>(self, item: T) -> Compare<'a>
982    where
983        T: Into<Expression<'a>>,
984    {
985        let col: Column<'a> = self.into();
986        let val: Expression<'a> = col.into();
987
988        val.json_array_contains(item)
989    }
990
991    #[cfg(all(feature = "json", any(feature = "postgresql", feature = "mysql")))]
992    fn json_array_not_contains<T>(self, item: T) -> Compare<'a>
993    where
994        T: Into<Expression<'a>>,
995    {
996        let col: Column<'a> = self.into();
997        let val: Expression<'a> = col.into();
998
999        val.json_array_not_contains(item)
1000    }
1001
1002    #[cfg(all(feature = "json", any(feature = "postgresql", feature = "mysql")))]
1003    fn json_array_begins_with<T>(self, item: T) -> Compare<'a>
1004    where
1005        T: Into<Expression<'a>>,
1006    {
1007        let col: Column<'a> = self.into();
1008        let val: Expression<'a> = col.into();
1009
1010        val.json_array_begins_with(item)
1011    }
1012
1013    #[cfg(all(feature = "json", any(feature = "postgresql", feature = "mysql")))]
1014    fn json_array_not_begins_with<T>(self, item: T) -> Compare<'a>
1015    where
1016        T: Into<Expression<'a>>,
1017    {
1018        let col: Column<'a> = self.into();
1019        let val: Expression<'a> = col.into();
1020
1021        val.json_array_not_begins_with(item)
1022    }
1023
1024    #[cfg(all(feature = "json", any(feature = "postgresql", feature = "mysql")))]
1025    fn json_array_ends_into<T>(self, item: T) -> Compare<'a>
1026    where
1027        T: Into<Expression<'a>>,
1028    {
1029        let col: Column<'a> = self.into();
1030        let val: Expression<'a> = col.into();
1031
1032        val.json_array_ends_into(item)
1033    }
1034
1035    #[cfg(all(feature = "json", any(feature = "postgresql", feature = "mysql")))]
1036    fn json_array_not_ends_into<T>(self, item: T) -> Compare<'a>
1037    where
1038        T: Into<Expression<'a>>,
1039    {
1040        let col: Column<'a> = self.into();
1041        let val: Expression<'a> = col.into();
1042
1043        val.json_array_not_ends_into(item)
1044    }
1045
1046    #[cfg(all(feature = "json", any(feature = "postgresql", feature = "mysql")))]
1047    fn json_type_equals<T>(self, json_type: T) -> Compare<'a>
1048    where
1049        T: Into<JsonType<'a>>,
1050    {
1051        let col: Column<'a> = self.into();
1052        let val: Expression<'a> = col.into();
1053
1054        val.json_type_equals(json_type)
1055    }
1056
1057    #[cfg(all(feature = "json", any(feature = "postgresql", feature = "mysql")))]
1058    fn json_type_not_equals<T>(self, json_type: T) -> Compare<'a>
1059    where
1060        T: Into<JsonType<'a>>,
1061    {
1062        let col: Column<'a> = self.into();
1063        let val: Expression<'a> = col.into();
1064
1065        val.json_type_not_equals(json_type)
1066    }
1067
1068    #[cfg(feature = "postgresql")]
1069    fn matches<T>(self, query: T) -> Compare<'a>
1070    where
1071        T: Into<Cow<'a, str>>,
1072    {
1073        let col: Column<'a> = self.into();
1074        let val: Expression<'a> = col.into();
1075
1076        val.matches(query)
1077    }
1078
1079    #[cfg(feature = "postgresql")]
1080    fn not_matches<T>(self, query: T) -> Compare<'a>
1081    where
1082        T: Into<Cow<'a, str>>,
1083    {
1084        let col: Column<'a> = self.into();
1085        let val: Expression<'a> = col.into();
1086
1087        val.not_matches(query)
1088    }
1089
1090    #[cfg(feature = "postgresql")]
1091    fn any(self) -> Compare<'a> {
1092        let col: Column<'a> = self.into();
1093        let val: Expression<'a> = col.into();
1094
1095        val.any()
1096    }
1097
1098    #[cfg(feature = "postgresql")]
1099    fn all(self) -> Compare<'a> {
1100        let col: Column<'a> = self.into();
1101        let val: Expression<'a> = col.into();
1102
1103        val.all()
1104    }
1105}