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::Register(_) => Ok(()),
217 Self::RowId { .. } => Ok(()),
218 Self::Subquery(query) => {
219 s.append(TK_LP, None)?;
220 query.to_tokens(s)?;
221 s.append(TK_RP, None)
222 }
223 Self::Unary(op, sub_expr) => {
224 op.to_tokens(s)?;
225 sub_expr.to_tokens(s)
226 }
227 Self::Variable(var) => match var.chars().next() {
228 Some(c) if c == '$' || c == '@' || c == '#' || c == ':' => {
229 s.append(TK_VARIABLE, Some(var))
230 }
231 Some(_) => s.append(TK_VARIABLE, Some(&("?".to_owned() + var))),
232 None => s.append(TK_VARIABLE, Some("?")),
233 },
234 }
235 }
236}
237
238impl Display for Expr {
239 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
240 self.to_fmt(f)
241 }
242}
243
244impl ToTokens for Literal {
245 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
246 match self {
247 Self::Numeric(ref num) => s.append(TK_FLOAT, Some(num)), Self::String(ref str) => s.append(TK_STRING, Some(str)),
249 Self::Blob(ref blob) => s.append(TK_BLOB, Some(blob)),
250 Self::Keyword(ref str) => s.append(TK_ID, Some(str)), Self::Null => s.append(TK_NULL, None),
252 Self::CurrentDate => s.append(TK_CTIME_KW, Some("CURRENT_DATE")),
253 Self::CurrentTime => s.append(TK_CTIME_KW, Some("CURRENT_TIME")),
254 Self::CurrentTimestamp => s.append(TK_CTIME_KW, Some("CURRENT_TIMESTAMP")),
255 }
256 }
257}
258
259impl ToTokens for LikeOperator {
260 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
261 s.append(
262 TK_LIKE_KW,
263 Some(match self {
264 Self::Glob => "GLOB",
265 Self::Like => "LIKE",
266 Self::Match => "MATCH",
267 Self::Regexp => "REGEXP",
268 }),
269 )
270 }
271}
272
273impl ToTokens for Operator {
274 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
275 match self {
276 Self::Add => s.append(TK_PLUS, None),
277 Self::And => s.append(TK_AND, None),
278 Self::ArrowRight => s.append(TK_PTR, Some("->")),
279 Self::ArrowRightShift => s.append(TK_PTR, Some("->>")),
280 Self::BitwiseAnd => s.append(TK_BITAND, None),
281 Self::BitwiseOr => s.append(TK_BITOR, None),
282 Self::BitwiseNot => s.append(TK_BITNOT, None),
283 Self::Concat => s.append(TK_CONCAT, None),
284 Self::Equals => s.append(TK_EQ, None),
285 Self::Divide => s.append(TK_SLASH, None),
286 Self::Greater => s.append(TK_GT, None),
287 Self::GreaterEquals => s.append(TK_GE, None),
288 Self::Is => s.append(TK_IS, None),
289 Self::IsNot => {
290 s.append(TK_IS, None)?;
291 s.append(TK_NOT, None)
292 }
293 Self::LeftShift => s.append(TK_LSHIFT, None),
294 Self::Less => s.append(TK_LT, None),
295 Self::LessEquals => s.append(TK_LE, None),
296 Self::Modulus => s.append(TK_REM, None),
297 Self::Multiply => s.append(TK_STAR, None),
298 Self::NotEquals => s.append(TK_NE, None),
299 Self::Or => s.append(TK_OR, None),
300 Self::RightShift => s.append(TK_RSHIFT, None),
301 Self::Subtract => s.append(TK_MINUS, None),
302 }
303 }
304}
305
306impl ToTokens for UnaryOperator {
307 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
308 s.append(
309 match self {
310 Self::BitwiseNot => TK_BITNOT,
311 Self::Negative => TK_MINUS,
312 Self::Not => TK_NOT,
313 Self::Positive => TK_PLUS,
314 },
315 None,
316 )
317 }
318}
319
320impl ToTokens for Select {
321 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
322 if let Some(ref with) = self.with {
323 with.to_tokens(s)?;
324 }
325 self.body.to_tokens(s)?;
326 if let Some(ref order_by) = self.order_by {
327 s.append(TK_ORDER, None)?;
328 s.append(TK_BY, None)?;
329 comma(order_by, s)?;
330 }
331 if let Some(ref limit) = self.limit {
332 limit.to_tokens(s)?;
333 }
334 Ok(())
335 }
336}
337
338impl ToTokens for SelectBody {
339 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
340 self.select.to_tokens(s)?;
341 if let Some(ref compounds) = self.compounds {
342 for compound in compounds {
343 compound.to_tokens(s)?;
344 }
345 }
346 Ok(())
347 }
348}
349
350impl ToTokens for CompoundSelect {
351 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
352 self.operator.to_tokens(s)?;
353 self.select.to_tokens(s)
354 }
355}
356
357impl ToTokens for CompoundOperator {
358 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
359 match self {
360 Self::Union => s.append(TK_UNION, None),
361 Self::UnionAll => {
362 s.append(TK_UNION, None)?;
363 s.append(TK_ALL, None)
364 }
365 Self::Except => s.append(TK_EXCEPT, None),
366 Self::Intersect => s.append(TK_INTERSECT, None),
367 }
368 }
369}
370
371impl Display for CompoundOperator {
372 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
373 self.to_fmt(f)
374 }
375}
376
377impl ToTokens for OneSelect {
378 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
379 match self {
380 Self::Select(select) => {
381 let SelectInner {
382 distinctness,
383 columns,
384 from,
385 where_clause,
386 group_by,
387 window_clause,
388 } = &**select;
389 s.append(TK_SELECT, None)?;
390 if let Some(ref distinctness) = distinctness {
391 distinctness.to_tokens(s)?;
392 }
393 comma(columns, s)?;
394 if let Some(ref from) = from {
395 s.append(TK_FROM, None)?;
396 from.to_tokens(s)?;
397 }
398 if let Some(ref where_clause) = where_clause {
399 s.append(TK_WHERE, None)?;
400 where_clause.to_tokens(s)?;
401 }
402 if let Some(ref group_by) = group_by {
403 group_by.to_tokens(s)?;
404 }
405 if let Some(ref window_clause) = window_clause {
406 s.append(TK_WINDOW, None)?;
407 comma(window_clause, s)?;
408 }
409 Ok(())
410 }
411 Self::Values(values) => {
412 for (i, vals) in values.iter().enumerate() {
413 if i == 0 {
414 s.append(TK_VALUES, None)?;
415 } else {
416 s.append(TK_COMMA, None)?;
417 }
418 s.append(TK_LP, None)?;
419 comma(vals, s)?;
420 s.append(TK_RP, None)?;
421 }
422 Ok(())
423 }
424 }
425 }
426}
427
428impl ToTokens for FromClause {
429 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
430 self.select
431 .as_ref()
432 .expect("FromClause select is mandatory per AST invariant")
433 .to_tokens(s)?;
434 if let Some(ref joins) = self.joins {
435 for join in joins {
436 join.to_tokens(s)?;
437 }
438 }
439 Ok(())
440 }
441}
442
443impl ToTokens for Distinctness {
444 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
445 s.append(
446 match self {
447 Self::Distinct => TK_DISTINCT,
448 Self::All => TK_ALL,
449 },
450 None,
451 )
452 }
453}
454
455impl ToTokens for ResultColumn {
456 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
457 match self {
458 Self::Expr(expr, alias) => {
459 expr.to_tokens(s)?;
460 if let Some(alias) = alias {
461 alias.to_tokens(s)?;
462 }
463 Ok(())
464 }
465 Self::Star => s.append(TK_STAR, None),
466 Self::TableStar(tbl_name) => {
467 tbl_name.to_tokens(s)?;
468 s.append(TK_DOT, None)?;
469 s.append(TK_STAR, None)
470 }
471 }
472 }
473}
474
475impl ToTokens for As {
476 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
477 match self {
478 Self::As(ref name) => {
479 s.append(TK_AS, None)?;
480 name.to_tokens(s)
481 }
482 Self::Elided(ref name) => name.to_tokens(s),
483 }
484 }
485}
486
487impl ToTokens for JoinedSelectTable {
488 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
489 self.operator.to_tokens(s)?;
490 self.table.to_tokens(s)?;
491 if let Some(ref constraint) = self.constraint {
492 constraint.to_tokens(s)?;
493 }
494 Ok(())
495 }
496}
497
498impl ToTokens for SelectTable {
499 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
500 match self {
501 Self::Table(name, alias, indexed) => {
502 name.to_tokens(s)?;
503 if let Some(alias) = alias {
504 alias.to_tokens(s)?;
505 }
506 if let Some(indexed) = indexed {
507 indexed.to_tokens(s)?;
508 }
509 Ok(())
510 }
511 Self::TableCall(name, exprs, alias) => {
512 name.to_tokens(s)?;
513 s.append(TK_LP, None)?;
514 if let Some(exprs) = exprs {
515 comma(exprs, s)?;
516 }
517 s.append(TK_RP, None)?;
518 if let Some(alias) = alias {
519 alias.to_tokens(s)?;
520 }
521 Ok(())
522 }
523 Self::Select(select, alias) => {
524 s.append(TK_LP, None)?;
525 select.to_tokens(s)?;
526 s.append(TK_RP, None)?;
527 if let Some(alias) = alias {
528 alias.to_tokens(s)?;
529 }
530 Ok(())
531 }
532 Self::Sub(from, alias) => {
533 s.append(TK_LP, None)?;
534 from.to_tokens(s)?;
535 s.append(TK_RP, None)?;
536 if let Some(alias) = alias {
537 alias.to_tokens(s)?;
538 }
539 Ok(())
540 }
541 }
542 }
543}