1use crate::ast::{
6 Cage, CageKind, Condition, Expr, Join, JoinKind, LockMode, LogicalOp, Operator,
7 OverridingKind, Qail, SampleMethod, SortOrder, Value, CTEDef,
8};
9
10impl Qail {
11 pub fn column_expr(mut self, expr: Expr) -> Self {
12 self.columns.push(expr);
13 self
14 }
15
16 pub fn columns_expr<I>(mut self, exprs: I) -> Self
17 where
18 I: IntoIterator<Item = Expr>,
19 {
20 self.columns.extend(exprs);
21 self
22 }
23
24 pub fn distinct_on<I, S>(mut self, cols: I) -> Self
25 where
26 I: IntoIterator<Item = S>,
27 S: AsRef<str>,
28 {
29 self.distinct_on = cols
30 .into_iter()
31 .map(|c| Expr::Named(c.as_ref().to_string()))
32 .collect();
33 self
34 }
35
36 pub fn distinct_on_expr<I>(mut self, exprs: I) -> Self
37 where
38 I: IntoIterator<Item = Expr>,
39 {
40 self.distinct_on = exprs.into_iter().collect();
41 self
42 }
43
44 pub fn filter_cond(mut self, condition: Condition) -> Self {
45 let filter_cage = self
46 .cages
47 .iter_mut()
48 .find(|c| matches!(c.kind, CageKind::Filter));
49
50 if let Some(cage) = filter_cage {
51 cage.conditions.push(condition);
52 } else {
53 self.cages.push(Cage {
54 kind: CageKind::Filter,
55 conditions: vec![condition],
56 logical_op: LogicalOp::And,
57 });
58 }
59 self
60 }
61
62 pub fn having_cond(mut self, condition: Condition) -> Self {
63 self.having.push(condition);
64 self
65 }
66
67 pub fn having_conds(mut self, conditions: impl IntoIterator<Item = Condition>) -> Self {
68 self.having.extend(conditions);
69 self
70 }
71
72 pub fn with_ctes(mut self, ctes: Vec<CTEDef>) -> Self {
73 self.ctes = ctes;
74 self
75 }
76
77 pub fn update_from<I, S>(mut self, tables: I) -> Self
78 where
79 I: IntoIterator<Item = S>,
80 S: AsRef<str>,
81 {
82 self.from_tables.extend(tables.into_iter().map(|s| s.as_ref().to_string()));
83 self
84 }
85
86 pub fn delete_using<I, S>(mut self, tables: I) -> Self
87 where
88 I: IntoIterator<Item = S>,
89 S: AsRef<str>,
90 {
91 self.using_tables.extend(tables.into_iter().map(|s| s.as_ref().to_string()));
92 self
93 }
94
95 pub fn for_update(mut self) -> Self {
96 self.lock_mode = Some(LockMode::Update);
97 self
98 }
99
100 pub fn for_no_key_update(mut self) -> Self {
101 self.lock_mode = Some(LockMode::NoKeyUpdate);
102 self
103 }
104
105 pub fn for_share(mut self) -> Self {
106 self.lock_mode = Some(LockMode::Share);
107 self
108 }
109
110 pub fn for_key_share(mut self) -> Self {
111 self.lock_mode = Some(LockMode::KeyShare);
112 self
113 }
114
115 pub fn fetch_first(mut self, count: u64) -> Self {
116 self.fetch = Some((count, false));
117 self
118 }
119
120 pub fn fetch_with_ties(mut self, count: u64) -> Self {
121 self.fetch = Some((count, true));
122 self
123 }
124
125 pub fn default_values(mut self) -> Self {
126 self.default_values = true;
127 self
128 }
129
130 pub fn overriding_system_value(mut self) -> Self {
131 self.overriding = Some(OverridingKind::SystemValue);
132 self
133 }
134
135 pub fn overriding_user_value(mut self) -> Self {
136 self.overriding = Some(OverridingKind::UserValue);
137 self
138 }
139
140 pub fn tablesample_bernoulli(mut self, percent: f64) -> Self {
141 self.sample = Some((SampleMethod::Bernoulli, percent, None));
142 self
143 }
144
145 pub fn tablesample_system(mut self, percent: f64) -> Self {
146 self.sample = Some((SampleMethod::System, percent, None));
147 self
148 }
149
150 pub fn repeatable(mut self, seed: u64) -> Self {
151 if let Some((method, percent, _)) = self.sample {
152 self.sample = Some((method, percent, Some(seed)));
153 }
154 self
155 }
156
157 pub fn only(mut self) -> Self {
158 self.only_table = true;
159 self
160 }
161
162 pub fn left_join_as(
163 mut self,
164 table: impl AsRef<str>,
165 alias: impl AsRef<str>,
166 left_col: impl AsRef<str>,
167 right_col: impl AsRef<str>,
168 ) -> Self {
169 self.joins.push(Join {
170 kind: JoinKind::Left,
171 table: format!("{} {}", table.as_ref(), alias.as_ref()),
172 on: Some(vec![Condition {
173 left: Expr::Named(left_col.as_ref().to_string()),
174 op: Operator::Eq,
175 value: Value::Column(right_col.as_ref().to_string()),
176 is_array_unnest: false,
177 }]),
178 on_true: false,
179 });
180 self
181 }
182
183 pub fn inner_join_as(
184 mut self,
185 table: impl AsRef<str>,
186 alias: impl AsRef<str>,
187 left_col: impl AsRef<str>,
188 right_col: impl AsRef<str>,
189 ) -> Self {
190 self.joins.push(Join {
191 kind: JoinKind::Inner,
192 table: format!("{} {}", table.as_ref(), alias.as_ref()),
193 on: Some(vec![Condition {
194 left: Expr::Named(left_col.as_ref().to_string()),
195 op: Operator::Eq,
196 value: Value::Column(right_col.as_ref().to_string()),
197 is_array_unnest: false,
198 }]),
199 on_true: false,
200 });
201 self
202 }
203
204 pub fn table_alias(mut self, alias: impl AsRef<str>) -> Self {
205 self.table = format!("{} {}", self.table, alias.as_ref());
206 self
207 }
208
209 pub fn order_by_expr(mut self, expr: Expr, order: SortOrder) -> Self {
210 self.cages.push(Cage {
211 kind: CageKind::Sort(order),
212 conditions: vec![Condition {
213 left: expr,
214 op: Operator::Eq,
215 value: Value::Null,
216 is_array_unnest: false,
217 }],
218 logical_op: LogicalOp::And,
219 });
220 self
221 }
222
223 pub fn group_by_expr<I>(mut self, exprs: I) -> Self
224 where
225 I: IntoIterator<Item = Expr>,
226 {
227 let conditions: Vec<Condition> = exprs
228 .into_iter()
229 .map(|e| Condition {
230 left: e,
231 op: Operator::Eq,
232 value: Value::Null,
233 is_array_unnest: false,
234 })
235 .collect();
236
237 self.cages.push(Cage {
238 kind: CageKind::Partition,
239 conditions,
240 logical_op: LogicalOp::And,
241 });
242 self
243 }
244}