1use crate::ast::*;
6use crate::dialect::TokenType::*;
7use std::fmt::{self, Display, Formatter};
8
9use super::functions::{ToTokens, TokenStream};
10use super::functions_4::{comma, double_quote};
11
12impl ToTokens for Expr {
13 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
14 match self {
15 Self::Between {
16 lhs,
17 not,
18 start,
19 end,
20 } => {
21 lhs.to_tokens(s)?;
22 if *not {
23 s.append(TK_NOT, None)?;
24 }
25 s.append(TK_BETWEEN, None)?;
26 start.to_tokens(s)?;
27 s.append(TK_AND, None)?;
28 end.to_tokens(s)
29 }
30 Self::Binary(lhs, op, rhs) => {
31 lhs.to_tokens(s)?;
32 op.to_tokens(s)?;
33 rhs.to_tokens(s)
34 }
35 Self::Case {
36 base,
37 when_then_pairs,
38 else_expr,
39 } => {
40 s.append(TK_CASE, None)?;
41 if let Some(ref base) = base {
42 base.to_tokens(s)?;
43 }
44 for (when, then) in when_then_pairs {
45 s.append(TK_WHEN, None)?;
46 when.to_tokens(s)?;
47 s.append(TK_THEN, None)?;
48 then.to_tokens(s)?;
49 }
50 if let Some(ref else_expr) = else_expr {
51 s.append(TK_ELSE, None)?;
52 else_expr.to_tokens(s)?;
53 }
54 s.append(TK_END, None)
55 }
56 Self::Cast { expr, type_name } => {
57 s.append(TK_CAST, None)?;
58 s.append(TK_LP, None)?;
59 expr.to_tokens(s)?;
60 s.append(TK_AS, None)?;
61 if let Some(ref type_name) = type_name {
62 type_name.to_tokens(s)?;
63 }
64 s.append(TK_RP, None)
65 }
66 Self::Collate(expr, collation) => {
67 expr.to_tokens(s)?;
68 s.append(TK_COLLATE, None)?;
69 double_quote(collation, s)
70 }
71 Self::DoublyQualified(db_name, tbl_name, col_name) => {
72 db_name.to_tokens(s)?;
73 s.append(TK_DOT, None)?;
74 tbl_name.to_tokens(s)?;
75 s.append(TK_DOT, None)?;
76 col_name.to_tokens(s)
77 }
78 Self::Exists(subquery) => {
79 s.append(TK_EXISTS, None)?;
80 s.append(TK_LP, None)?;
81 subquery.to_tokens(s)?;
82 s.append(TK_RP, None)
83 }
84 Self::FunctionCall {
85 name,
86 distinctness,
87 args,
88 order_by,
89 filter_over,
90 } => {
91 name.to_tokens(s)?;
92 s.append(TK_LP, None)?;
93 if let Some(distinctness) = distinctness {
94 distinctness.to_tokens(s)?;
95 }
96 if let Some(args) = args {
97 comma(args, s)?;
98 }
99 if let Some(order_by) = order_by {
100 s.append(TK_ORDER, None)?;
101 s.append(TK_BY, None)?;
102 comma(order_by, s)?;
103 }
104 s.append(TK_RP, None)?;
105 if let Some(filter_over) = filter_over {
106 filter_over.to_tokens(s)?;
107 }
108 Ok(())
109 }
110 Self::FunctionCallStar { name, filter_over } => {
111 name.to_tokens(s)?;
112 s.append(TK_LP, None)?;
113 s.append(TK_STAR, None)?;
114 s.append(TK_RP, None)?;
115 if let Some(filter_over) = filter_over {
116 filter_over.to_tokens(s)?;
117 }
118 Ok(())
119 }
120 Self::Id(id) => id.to_tokens(s),
121 Self::Column { .. } => Ok(()),
122 Self::InList { lhs, not, rhs } => {
123 lhs.to_tokens(s)?;
124 if *not {
125 s.append(TK_NOT, None)?;
126 }
127 s.append(TK_IN, None)?;
128 s.append(TK_LP, None)?;
129 if let Some(rhs) = rhs {
130 comma(rhs, s)?;
131 }
132 s.append(TK_RP, None)
133 }
134 Self::InSelect { lhs, not, rhs } => {
135 lhs.to_tokens(s)?;
136 if *not {
137 s.append(TK_NOT, None)?;
138 }
139 s.append(TK_IN, None)?;
140 s.append(TK_LP, None)?;
141 rhs.to_tokens(s)?;
142 s.append(TK_RP, None)
143 }
144 Self::InTable {
145 lhs,
146 not,
147 rhs,
148 args,
149 } => {
150 lhs.to_tokens(s)?;
151 if *not {
152 s.append(TK_NOT, None)?;
153 }
154 s.append(TK_IN, None)?;
155 rhs.to_tokens(s)?;
156 if let Some(args) = args {
157 s.append(TK_LP, None)?;
158 comma(args, s)?;
159 s.append(TK_RP, None)?;
160 }
161 Ok(())
162 }
163 Self::IsNull(sub_expr) => {
164 sub_expr.to_tokens(s)?;
165 s.append(TK_ISNULL, None)
166 }
167 Self::Like {
168 lhs,
169 not,
170 op,
171 rhs,
172 escape,
173 } => {
174 lhs.to_tokens(s)?;
175 if *not {
176 s.append(TK_NOT, None)?;
177 }
178 op.to_tokens(s)?;
179 rhs.to_tokens(s)?;
180 if let Some(escape) = escape {
181 s.append(TK_ESCAPE, None)?;
182 escape.to_tokens(s)?;
183 }
184 Ok(())
185 }
186 Self::Literal(lit) => lit.to_tokens(s),
187 Self::Name(name) => name.to_tokens(s),
188 Self::NotNull(sub_expr) => {
189 sub_expr.to_tokens(s)?;
190 s.append(TK_NOTNULL, None)
191 }
192 Self::Parenthesized(exprs) => {
193 s.append(TK_LP, None)?;
194 comma(exprs, s)?;
195 s.append(TK_RP, None)
196 }
197 Self::Qualified(qualifier, qualified) => {
198 qualifier.to_tokens(s)?;
199 s.append(TK_DOT, None)?;
200 qualified.to_tokens(s)
201 }
202 Self::Raise(rt, err) => {
203 s.append(TK_RAISE, None)?;
204 s.append(TK_LP, None)?;
205 rt.to_tokens(s)?;
206 if let Some(err) = err {
207 s.append(TK_COMMA, None)?;
208 err.to_tokens(s)?;
209 }
210 s.append(TK_RP, None)
211 }
212 Self::RowId { .. } => Ok(()),
213 Self::Subquery(query) => {
214 s.append(TK_LP, None)?;
215 query.to_tokens(s)?;
216 s.append(TK_RP, None)
217 }
218 Self::Unary(op, sub_expr) => {
219 op.to_tokens(s)?;
220 sub_expr.to_tokens(s)
221 }
222 Self::Variable(var) => match var.chars().next() {
223 Some(c) if c == '$' || c == '@' || c == '#' || c == ':' => {
224 s.append(TK_VARIABLE, Some(var))
225 }
226 Some(_) => s.append(TK_VARIABLE, Some(&("?".to_owned() + var))),
227 None => s.append(TK_VARIABLE, Some("?")),
228 },
229 }
230 }
231}
232
233impl Display for Expr {
234 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
235 self.to_fmt(f)
236 }
237}
238
239impl ToTokens for Literal {
240 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
241 match self {
242 Self::Numeric(ref num) => s.append(TK_FLOAT, Some(num)), Self::String(ref str) => s.append(TK_STRING, Some(str)),
244 Self::Blob(ref blob) => s.append(TK_BLOB, Some(blob)),
245 Self::Keyword(ref str) => s.append(TK_ID, Some(str)), Self::Null => s.append(TK_NULL, None),
247 Self::CurrentDate => s.append(TK_CTIME_KW, Some("CURRENT_DATE")),
248 Self::CurrentTime => s.append(TK_CTIME_KW, Some("CURRENT_TIME")),
249 Self::CurrentTimestamp => s.append(TK_CTIME_KW, Some("CURRENT_TIMESTAMP")),
250 }
251 }
252}
253
254impl ToTokens for LikeOperator {
255 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
256 s.append(
257 TK_LIKE_KW,
258 Some(match self {
259 Self::Glob => "GLOB",
260 Self::Like => "LIKE",
261 Self::Match => "MATCH",
262 Self::Regexp => "REGEXP",
263 }),
264 )
265 }
266}
267
268impl ToTokens for Operator {
269 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
270 match self {
271 Self::Add => s.append(TK_PLUS, None),
272 Self::And => s.append(TK_AND, None),
273 Self::ArrowRight => s.append(TK_PTR, Some("->")),
274 Self::ArrowRightShift => s.append(TK_PTR, Some("->>")),
275 Self::BitwiseAnd => s.append(TK_BITAND, None),
276 Self::BitwiseOr => s.append(TK_BITOR, None),
277 Self::BitwiseNot => s.append(TK_BITNOT, None),
278 Self::Concat => s.append(TK_CONCAT, None),
279 Self::Equals => s.append(TK_EQ, None),
280 Self::Divide => s.append(TK_SLASH, None),
281 Self::Greater => s.append(TK_GT, None),
282 Self::GreaterEquals => s.append(TK_GE, None),
283 Self::Is => s.append(TK_IS, None),
284 Self::IsNot => {
285 s.append(TK_IS, None)?;
286 s.append(TK_NOT, None)
287 }
288 Self::LeftShift => s.append(TK_LSHIFT, None),
289 Self::Less => s.append(TK_LT, None),
290 Self::LessEquals => s.append(TK_LE, None),
291 Self::Modulus => s.append(TK_REM, None),
292 Self::Multiply => s.append(TK_STAR, None),
293 Self::NotEquals => s.append(TK_NE, None),
294 Self::Or => s.append(TK_OR, None),
295 Self::RightShift => s.append(TK_RSHIFT, None),
296 Self::Subtract => s.append(TK_MINUS, None),
297 }
298 }
299}
300
301impl ToTokens for UnaryOperator {
302 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
303 s.append(
304 match self {
305 Self::BitwiseNot => TK_BITNOT,
306 Self::Negative => TK_MINUS,
307 Self::Not => TK_NOT,
308 Self::Positive => TK_PLUS,
309 },
310 None,
311 )
312 }
313}
314
315impl ToTokens for Select {
316 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
317 if let Some(ref with) = self.with {
318 with.to_tokens(s)?;
319 }
320 self.body.to_tokens(s)?;
321 if let Some(ref order_by) = self.order_by {
322 s.append(TK_ORDER, None)?;
323 s.append(TK_BY, None)?;
324 comma(order_by, s)?;
325 }
326 if let Some(ref limit) = self.limit {
327 limit.to_tokens(s)?;
328 }
329 Ok(())
330 }
331}
332
333impl ToTokens for SelectBody {
334 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
335 self.select.to_tokens(s)?;
336 if let Some(ref compounds) = self.compounds {
337 for compound in compounds {
338 compound.to_tokens(s)?;
339 }
340 }
341 Ok(())
342 }
343}
344
345impl ToTokens for CompoundSelect {
346 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
347 self.operator.to_tokens(s)?;
348 self.select.to_tokens(s)
349 }
350}
351
352impl ToTokens for CompoundOperator {
353 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
354 match self {
355 Self::Union => s.append(TK_UNION, None),
356 Self::UnionAll => {
357 s.append(TK_UNION, None)?;
358 s.append(TK_ALL, None)
359 }
360 Self::Except => s.append(TK_EXCEPT, None),
361 Self::Intersect => s.append(TK_INTERSECT, None),
362 }
363 }
364}
365
366impl Display for CompoundOperator {
367 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
368 self.to_fmt(f)
369 }
370}
371
372impl ToTokens for OneSelect {
373 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
374 match self {
375 Self::Select(select) => {
376 let SelectInner {
377 distinctness,
378 columns,
379 from,
380 where_clause,
381 group_by,
382 window_clause,
383 } = &**select;
384 s.append(TK_SELECT, None)?;
385 if let Some(ref distinctness) = distinctness {
386 distinctness.to_tokens(s)?;
387 }
388 comma(columns, s)?;
389 if let Some(ref from) = from {
390 s.append(TK_FROM, None)?;
391 from.to_tokens(s)?;
392 }
393 if let Some(ref where_clause) = where_clause {
394 s.append(TK_WHERE, None)?;
395 where_clause.to_tokens(s)?;
396 }
397 if let Some(ref group_by) = group_by {
398 group_by.to_tokens(s)?;
399 }
400 if let Some(ref window_clause) = window_clause {
401 s.append(TK_WINDOW, None)?;
402 comma(window_clause, s)?;
403 }
404 Ok(())
405 }
406 Self::Values(values) => {
407 for (i, vals) in values.iter().enumerate() {
408 if i == 0 {
409 s.append(TK_VALUES, None)?;
410 } else {
411 s.append(TK_COMMA, None)?;
412 }
413 s.append(TK_LP, None)?;
414 comma(vals, s)?;
415 s.append(TK_RP, None)?;
416 }
417 Ok(())
418 }
419 }
420 }
421}
422
423impl ToTokens for FromClause {
424 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
425 self.select
426 .as_ref()
427 .expect("FromClause select is mandatory per AST invariant")
428 .to_tokens(s)?;
429 if let Some(ref joins) = self.joins {
430 for join in joins {
431 join.to_tokens(s)?;
432 }
433 }
434 Ok(())
435 }
436}
437
438impl ToTokens for Distinctness {
439 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
440 s.append(
441 match self {
442 Self::Distinct => TK_DISTINCT,
443 Self::All => TK_ALL,
444 },
445 None,
446 )
447 }
448}
449
450impl ToTokens for ResultColumn {
451 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
452 match self {
453 Self::Expr(expr, alias) => {
454 expr.to_tokens(s)?;
455 if let Some(alias) = alias {
456 alias.to_tokens(s)?;
457 }
458 Ok(())
459 }
460 Self::Star => s.append(TK_STAR, None),
461 Self::TableStar(tbl_name) => {
462 tbl_name.to_tokens(s)?;
463 s.append(TK_DOT, None)?;
464 s.append(TK_STAR, None)
465 }
466 }
467 }
468}
469
470impl ToTokens for As {
471 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
472 match self {
473 Self::As(ref name) => {
474 s.append(TK_AS, None)?;
475 name.to_tokens(s)
476 }
477 Self::Elided(ref name) => name.to_tokens(s),
478 }
479 }
480}
481
482impl ToTokens for JoinedSelectTable {
483 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
484 self.operator.to_tokens(s)?;
485 self.table.to_tokens(s)?;
486 if let Some(ref constraint) = self.constraint {
487 constraint.to_tokens(s)?;
488 }
489 Ok(())
490 }
491}
492
493impl ToTokens for SelectTable {
494 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
495 match self {
496 Self::Table(name, alias, indexed) => {
497 name.to_tokens(s)?;
498 if let Some(alias) = alias {
499 alias.to_tokens(s)?;
500 }
501 if let Some(indexed) = indexed {
502 indexed.to_tokens(s)?;
503 }
504 Ok(())
505 }
506 Self::TableCall(name, exprs, alias) => {
507 name.to_tokens(s)?;
508 s.append(TK_LP, None)?;
509 if let Some(exprs) = exprs {
510 comma(exprs, s)?;
511 }
512 s.append(TK_RP, None)?;
513 if let Some(alias) = alias {
514 alias.to_tokens(s)?;
515 }
516 Ok(())
517 }
518 Self::Select(select, alias) => {
519 s.append(TK_LP, None)?;
520 select.to_tokens(s)?;
521 s.append(TK_RP, None)?;
522 if let Some(alias) = alias {
523 alias.to_tokens(s)?;
524 }
525 Ok(())
526 }
527 Self::Sub(from, alias) => {
528 s.append(TK_LP, None)?;
529 from.to_tokens(s)?;
530 s.append(TK_RP, None)?;
531 if let Some(alias) = alias {
532 alias.to_tokens(s)?;
533 }
534 Ok(())
535 }
536 }
537 }
538}