1use crate::sql::{SQL, Token};
4use crate::traits::{SQLParam, ToSQL};
5use crate::types::{Bool, Compatible};
6
7use super::{Expr, NonNull, SQLExpr, Scalar};
8
9pub fn in_array<'a, V, E, I, R>(expr: E, values: I) -> SQLExpr<'a, V, Bool, NonNull, Scalar>
18where
19 V: SQLParam + 'a,
20 E: Expr<'a, V>,
21 I: IntoIterator<Item = R>,
22 R: Expr<'a, V>,
23 E::SQLType: Compatible<R::SQLType>,
24{
25 let left_sql = expr.to_sql();
26 let mut values_iter = values.into_iter();
27
28 let sql = match values_iter.next() {
29 None => left_sql.append(SQL::raw("IN (SELECT NULL WHERE 1=0)")),
31 Some(first_value) => {
32 let mut result = left_sql
33 .push(Token::IN)
34 .push(Token::LPAREN)
35 .append(first_value.to_sql());
36 for value in values_iter {
37 result = result.push(Token::COMMA).append(value.to_sql());
38 }
39 result.push(Token::RPAREN)
40 }
41 };
42 SQLExpr::new(sql)
43}
44
45pub fn not_in_array<'a, V, E, I, R>(expr: E, values: I) -> SQLExpr<'a, V, Bool, NonNull, Scalar>
50where
51 V: SQLParam + 'a,
52 E: Expr<'a, V>,
53 I: IntoIterator<Item = R>,
54 R: Expr<'a, V>,
55 E::SQLType: Compatible<R::SQLType>,
56{
57 let left_sql = expr.to_sql();
58 let mut values_iter = values.into_iter();
59
60 let sql = match values_iter.next() {
61 None => left_sql.append(SQL::raw("NOT IN (SELECT NULL WHERE 1=0)")),
64 Some(first_value) => {
65 let mut result = left_sql
66 .push(Token::NOT)
67 .push(Token::IN)
68 .push(Token::LPAREN)
69 .append(first_value.to_sql());
70 for value in values_iter {
71 result = result.push(Token::COMMA).append(value.to_sql());
72 }
73 result.push(Token::RPAREN)
74 }
75 };
76 SQLExpr::new(sql)
77}
78
79pub fn in_subquery<'a, V, E, S>(expr: E, subquery: S) -> SQLExpr<'a, V, Bool, NonNull, Scalar>
83where
84 V: SQLParam + 'a,
85 E: ToSQL<'a, V>,
86 S: ToSQL<'a, V>,
87{
88 SQLExpr::new(
89 expr.to_sql()
90 .push(Token::IN)
91 .append(subquery.to_sql().parens()),
92 )
93}
94
95pub fn not_in_subquery<'a, V, E, S>(expr: E, subquery: S) -> SQLExpr<'a, V, Bool, NonNull, Scalar>
97where
98 V: SQLParam + 'a,
99 E: ToSQL<'a, V>,
100 S: ToSQL<'a, V>,
101{
102 SQLExpr::new(
103 expr.to_sql()
104 .push(Token::NOT)
105 .push(Token::IN)
106 .append(subquery.to_sql().parens()),
107 )
108}
109
110pub fn exists<'a, V, S>(subquery: S) -> SQLExpr<'a, V, Bool, NonNull, Scalar>
118where
119 V: SQLParam + 'a,
120 S: ToSQL<'a, V>,
121{
122 SQLExpr::new(
123 SQL::from_iter([Token::EXISTS, Token::LPAREN])
124 .append(subquery.to_sql())
125 .push(Token::RPAREN),
126 )
127}
128
129pub fn not_exists<'a, V, S>(subquery: S) -> SQLExpr<'a, V, Bool, NonNull, Scalar>
133where
134 V: SQLParam + 'a,
135 S: ToSQL<'a, V>,
136{
137 SQLExpr::new(
138 SQL::from_iter([Token::NOT, Token::EXISTS, Token::LPAREN])
139 .append(subquery.to_sql())
140 .push(Token::RPAREN),
141 )
142}