grafbase_sql_ast/
renderer.rs

1//! Visitors for reading an abstract SQL syntax tree, generating the query and
2//! gathering parameters in the right order.
3//!
4//! The visitor module should not know how to construct an AST, just how to read
5//! one. Everything related to the tree generation is in the
6//! [ast](../ast/index.html) module.
7#[cfg(feature = "postgresql")]
8mod postgres;
9
10use serde_json::Value;
11
12#[cfg(feature = "postgresql")]
13pub use self::postgres::Postgres;
14
15use crate::ast::*;
16use std::fmt;
17
18/// A function travelling through the query AST, building the final query string
19/// and gathering parameters sent to the database together with the query.
20pub trait Renderer<'a> {
21    /// Opening backtick character to surround identifiers, such as column and table names.
22    const C_BACKTICK_OPEN: &'static str;
23    /// Closing backtick character to surround identifiers, such as column and table names.
24    const C_BACKTICK_CLOSE: &'static str;
25    /// Wildcard character to be used in `LIKE` queries.
26    const C_WILDCARD: &'static str;
27
28    /// Convert the given `Query` to an SQL string and a vector of parameters.
29    /// When certain parameters are replaced with the `C_PARAM` character in the
30    /// query, the vector should contain the parameter value in the right position.
31    fn build<Q>(query: Q) -> (String, Vec<Value>)
32    where
33        Q: Into<Query<'a>>;
34
35    /// Write to the query.
36    fn write<D: fmt::Display>(&mut self, s: D);
37
38    /// A point to modify an incoming query to make it compatible with the
39    /// underlying database.
40    fn compatibility_modifications(&self, query: Query<'a>) -> Query<'a> {
41        query
42    }
43
44    fn surround_with<F>(&mut self, begin: &str, end: &str, f: F)
45    where
46        F: FnOnce(&mut Self),
47    {
48        self.write(begin);
49        f(self);
50        self.write(end)
51    }
52
53    fn columns_to_bracket_list(&mut self, columns: Vec<Column<'a>>) {
54        let len = columns.len();
55
56        self.write(" (");
57        for (i, c) in columns.into_iter().enumerate() {
58            self.visit_column(c.name.into_owned().into());
59
60            if i < (len - 1) {
61                self.write(",");
62            }
63        }
64        self.write(")");
65    }
66
67    /// When called, the visitor decided to not render the parameter into the query,
68    /// replacing it with the `C_PARAM`, calling `add_parameter` with the replaced value.
69    fn add_parameter(&mut self, value: Value);
70
71    /// The `LIMIT` and `OFFSET` statement in the query
72    fn visit_limit_and_offset(&mut self, limit: Option<u32>, offset: Option<u32>);
73
74    /// A visit in the `ORDER BY` section of the query
75    fn visit_ordering(&mut self, ordering: Ordering<'a>);
76
77    /// A walk through an `INSERT` statement
78    fn visit_insert(&mut self, insert: Insert<'a>);
79
80    /// What to use to substitute a parameter in the query.
81    fn parameter_substitution(&mut self);
82
83    /// What to use to substitute a parameter in the query.
84    fn visit_aggregate_to_string(&mut self, value: Expression<'a>);
85
86    #[cfg(any(feature = "postgresql", feature = "mysql"))]
87    fn visit_json_extract(&mut self, json_extract: JsonExtract<'a>);
88
89    #[cfg(any(feature = "postgresql", feature = "mysql"))]
90    fn visit_json_extract_last_array_item(&mut self, extract: JsonExtractLastArrayElem<'a>);
91
92    #[cfg(any(feature = "postgresql", feature = "mysql"))]
93    fn visit_json_extract_first_array_item(&mut self, extract: JsonExtractFirstArrayElem<'a>);
94
95    #[cfg(any(feature = "postgresql", feature = "mysql"))]
96    fn visit_array_contains(&mut self, left: Expression<'a>, right: Expression<'a>, not: bool);
97
98    #[cfg(any(feature = "postgresql", feature = "mysql"))]
99    fn visit_array_contained(&mut self, left: Expression<'a>, right: Expression<'a>, not: bool);
100
101    #[cfg(any(feature = "postgresql", feature = "mysql"))]
102    fn visit_array_overlaps(&mut self, left: Expression<'a>, right: Expression<'a>);
103
104    #[cfg(any(feature = "postgresql", feature = "mysql"))]
105    fn visit_json_type_equals(&mut self, left: Expression<'a>, right: JsonType<'a>, not: bool);
106
107    #[cfg(any(feature = "postgresql", feature = "mysql"))]
108    fn visit_json_unquote(&mut self, json_unquote: JsonUnquote<'a>);
109
110    #[cfg(feature = "postgresql")]
111    fn visit_to_jsonb(&mut self, to_jsonb: ToJsonb<'a>);
112
113    #[cfg(feature = "postgresql")]
114    fn visit_json_build_object(&mut self, json_build_object: JsonBuildObject<'a>);
115
116    #[cfg(feature = "postgresql")]
117    fn visit_json_agg(&mut self, to_jsonb: JsonAgg<'a>);
118
119    #[cfg(feature = "postgresql")]
120    fn visit_encode(&mut self, encode: Encode<'a>);
121
122    /// A walk through an `DELETE` statement
123    fn visit_delete(&mut self, delete: Delete<'a>);
124
125    /// A visit to a value we parameterize
126    fn visit_parameterized(&mut self, value: Value) {
127        self.add_parameter(value);
128        self.parameter_substitution()
129    }
130
131    /// The join statements in the query
132    fn visit_joins(&mut self, joins: Vec<Join<'a>>) {
133        for j in joins {
134            match j {
135                Join::Inner(data) => {
136                    self.write(" INNER JOIN ");
137                    self.visit_join_data(data);
138                }
139                Join::Left(data) => {
140                    self.write(" LEFT JOIN ");
141                    self.visit_join_data(data);
142                }
143                Join::Right(data) => {
144                    self.write(" RIGHT JOIN ");
145                    self.visit_join_data(data);
146                }
147                Join::Full(data) => {
148                    self.write(" FULL JOIN ");
149                    self.visit_join_data(data);
150                }
151            }
152        }
153    }
154
155    fn visit_join_data(&mut self, data: JoinData<'a>) {
156        self.visit_table(data.table, true);
157        self.write(" ON ");
158        self.visit_conditions(data.conditions)
159    }
160
161    fn visit_common_table_expression(&mut self, cte: CommonTableExpression<'a>) {
162        self.visit_table(Table::from(cte.name.into_owned()), false);
163        self.write(" AS ");
164
165        let query = cte.query;
166        self.surround_with("(", ")", |ref mut s| s.visit_query(query));
167    }
168
169    /// A walk through a `SELECT` statement
170    fn visit_select(&mut self, select: Select<'a>) {
171        let number_of_ctes = select.ctes.len();
172
173        if number_of_ctes > 0 {
174            self.write("WITH ");
175
176            for (i, cte) in select.ctes.into_iter().enumerate() {
177                self.visit_common_table_expression(cte);
178
179                if i < (number_of_ctes - 1) {
180                    self.write(", ");
181                }
182            }
183
184            self.write(" ");
185        }
186
187        self.write("SELECT ");
188
189        if select.distinct {
190            self.write("DISTINCT ");
191        }
192
193        if !select.tables.is_empty() {
194            if select.columns.is_empty() {
195                for (i, table) in select.tables.iter().enumerate() {
196                    if i > 0 {
197                        self.write(", ");
198                    }
199
200                    match &table.typ {
201                        TableType::Query(_) | TableType::Values(_) => match table.alias {
202                            Some(ref alias) => {
203                                self.surround_with(
204                                    Self::C_BACKTICK_OPEN,
205                                    Self::C_BACKTICK_CLOSE,
206                                    |ref mut s| s.write(alias),
207                                );
208                                self.write(".*");
209                            }
210                            None => self.write("*"),
211                        },
212                        TableType::Table(_) => match table.alias.clone() {
213                            Some(ref alias) => {
214                                self.surround_with(
215                                    Self::C_BACKTICK_OPEN,
216                                    Self::C_BACKTICK_CLOSE,
217                                    |ref mut s| s.write(alias),
218                                );
219                                self.write(".*");
220                            }
221                            None => {
222                                self.visit_table(table.clone(), false);
223                                self.write(".*");
224                            }
225                        },
226                        TableType::JoinedTable(jt) => match table.alias.clone() {
227                            Some(ref alias) => {
228                                self.surround_with(
229                                    Self::C_BACKTICK_OPEN,
230                                    Self::C_BACKTICK_CLOSE,
231                                    |ref mut s| s.write(alias),
232                                );
233                                self.write(".*");
234                            }
235                            None => {
236                                let mut unjoined_table = table.clone();
237                                // Convert the table typ to a `TableType::Table` for the SELECT statement print
238                                // We only want the join to appear in the FROM clause
239                                unjoined_table.typ = TableType::Table(jt.0.clone());
240
241                                self.visit_table(unjoined_table, false);
242                                self.write(".*");
243                            }
244                        },
245                    }
246                }
247            } else {
248                self.visit_columns(select.columns);
249            }
250
251            self.write(" FROM ");
252
253            for (i, table) in select.tables.into_iter().enumerate() {
254                if i > 0 {
255                    self.write(", ");
256                }
257
258                self.visit_table(table, true);
259            }
260
261            if !select.joins.is_empty() {
262                self.visit_joins(select.joins);
263            }
264
265            if let Some(conditions) = select.conditions {
266                self.write(" WHERE ");
267                self.visit_conditions(conditions);
268            }
269            if !select.grouping.is_empty() {
270                self.write(" GROUP BY ");
271                self.visit_grouping(select.grouping);
272            }
273            if let Some(conditions) = select.having {
274                self.write(" HAVING ");
275                self.visit_conditions(conditions);
276            }
277            if !select.ordering.is_empty() {
278                self.write(" ORDER BY ");
279                self.visit_ordering(select.ordering);
280            }
281
282            self.visit_limit_and_offset(select.limit, select.offset);
283        } else if select.columns.is_empty() {
284            self.write(" *");
285        } else {
286            self.visit_columns(select.columns);
287        }
288    }
289
290    /// A walk through an `UPDATE` statement
291    fn visit_update(&mut self, update: Update<'a>) {
292        self.write("UPDATE ");
293        self.visit_table(update.table, true);
294
295        {
296            self.write(" SET ");
297            let pairs = update.columns.into_iter().zip(update.values);
298            let len = pairs.len();
299
300            for (i, (key, value)) in pairs.enumerate() {
301                self.visit_column(key);
302                self.write(" = ");
303                self.visit_expression(value);
304
305                if i < (len - 1) {
306                    self.write(", ");
307                }
308            }
309        }
310
311        if let Some(conditions) = update.conditions {
312            self.write(" WHERE ");
313            self.visit_conditions(conditions);
314        }
315
316        if let Some(returning) = update.returning {
317            if !returning.is_empty() {
318                let values = returning.into_iter().map(|r| r.into()).collect();
319                self.write(" RETURNING ");
320                self.visit_columns(values);
321            }
322        }
323    }
324
325    fn visit_upsert(&mut self, update: Update<'a>) {
326        self.write("UPDATE ");
327
328        self.write("SET ");
329        self.visit_update_set(update.clone());
330
331        if let Some(conditions) = update.conditions {
332            self.write(" WHERE ");
333            self.visit_conditions(conditions);
334        }
335    }
336
337    fn visit_update_set(&mut self, update: Update<'a>) {
338        let pairs = update.columns.into_iter().zip(update.values);
339        let len = pairs.len();
340
341        for (i, (key, value)) in pairs.enumerate() {
342            self.visit_column(key);
343            self.write(" = ");
344            self.visit_expression(value);
345
346            if i < (len - 1) {
347                self.write(", ");
348            }
349        }
350    }
351
352    /// A helper for delimiting an identifier, surrounding every part with `C_BACKTICK`
353    /// and delimiting the values with a `.`
354    fn delimited_identifiers(&mut self, parts: &[&str]) {
355        let len = parts.len();
356
357        for (i, part) in parts.iter().enumerate() {
358            self.surround_with_backticks(part);
359
360            if i < (len - 1) {
361                self.write(".");
362            }
363        }
364    }
365
366    /// A helper for delimiting a part of an identifier, surrounding it with `C_BACKTICK`
367    fn surround_with_backticks(&mut self, part: &str) {
368        self.surround_with(
369            Self::C_BACKTICK_OPEN,
370            Self::C_BACKTICK_CLOSE,
371            |ref mut s| s.write(part),
372        );
373    }
374
375    /// A walk through a complete `Query` statement
376    fn visit_query(&mut self, mut query: Query<'a>) {
377        query = self.compatibility_modifications(query);
378
379        match query {
380            Query::Select(select) => self.visit_select(*select),
381            Query::Insert(insert) => self.visit_insert(*insert),
382            Query::Update(update) => self.visit_update(*update),
383            Query::Delete(delete) => self.visit_delete(*delete),
384        }
385    }
386
387    /// The selected columns
388    fn visit_columns(&mut self, columns: Vec<Expression<'a>>) {
389        let len = columns.len();
390
391        for (i, column) in columns.into_iter().enumerate() {
392            self.visit_expression(column);
393
394            if i < (len - 1) {
395                self.write(", ");
396            }
397        }
398    }
399
400    fn visit_operation(&mut self, op: SqlOp<'a>) {
401        match op {
402            SqlOp::Add(left, right) => self.surround_with("(", ")", |ref mut se| {
403                se.visit_expression(left);
404                se.write(" + ");
405                se.visit_expression(right)
406            }),
407            SqlOp::Sub(left, right) => self.surround_with("(", ")", |ref mut se| {
408                se.visit_expression(left);
409                se.write(" - ");
410                se.visit_expression(right)
411            }),
412            SqlOp::Mul(left, right) => self.surround_with("(", ")", |ref mut se| {
413                se.visit_expression(left);
414                se.write(" * ");
415                se.visit_expression(right)
416            }),
417            SqlOp::Div(left, right) => self.surround_with("(", ")", |ref mut se| {
418                se.visit_expression(left);
419                se.write(" / ");
420                se.visit_expression(right)
421            }),
422            SqlOp::Rem(left, right) => self.surround_with("(", ")", |ref mut se| {
423                se.visit_expression(left);
424                se.write(" % ");
425                se.visit_expression(right)
426            }),
427            SqlOp::Append(left, right) => self.surround_with("(", ")", |ref mut se| {
428                se.visit_expression(left);
429                se.write(" || ");
430                se.visit_expression(right)
431            }),
432            SqlOp::JsonDeleteAtPath(left, right) => self.surround_with("(", ")", |ref mut se| {
433                se.visit_expression(left);
434                se.write(" #- ");
435                se.visit_expression(right);
436            }),
437        }
438    }
439
440    /// A visit to a value used in an expression
441    fn visit_expression(&mut self, value: Expression<'a>) {
442        match value.kind {
443            ExpressionKind::Value(value) => self.visit_expression(*value),
444            ExpressionKind::Raw(value) => self.write(value),
445            ExpressionKind::ConditionTree(tree) => self.visit_conditions(tree),
446            ExpressionKind::Compare(compare) => self.visit_compare(compare),
447            ExpressionKind::Parameterized(val) => self.visit_parameterized(val),
448            ExpressionKind::Column(column) => self.visit_column(*column),
449            ExpressionKind::Row(row) => self.visit_row(row),
450            ExpressionKind::Selection(selection) => {
451                self.surround_with("(", ")", |ref mut s| s.visit_select(*selection))
452            }
453            ExpressionKind::Function(function) => self.visit_function(*function),
454            ExpressionKind::Op(op) => self.visit_operation(*op),
455            ExpressionKind::Values(values) => self.visit_values(values),
456            ExpressionKind::Asterisk(table) => match table {
457                Some(table) => {
458                    self.visit_table(*table, false);
459                    self.write(".*")
460                }
461                None => self.write("*"),
462            },
463            ExpressionKind::Default => self.write("DEFAULT"),
464            ExpressionKind::Table(table) => self.visit_table(*table, false),
465        }
466
467        if let Some(alias) = value.alias {
468            self.write(" AS ");
469
470            self.delimited_identifiers(&[&*alias]);
471        };
472    }
473
474    fn visit_multiple_tuple_comparison(&mut self, left: Row<'a>, right: Values<'a>, negate: bool) {
475        self.visit_row(left);
476        self.write(if negate { " NOT IN " } else { " IN " });
477        self.visit_values(right)
478    }
479
480    fn visit_values(&mut self, values: Values<'a>) {
481        self.surround_with("(", ")", |ref mut s| {
482            let len = values.len();
483            for (i, row) in values.into_iter().enumerate() {
484                s.visit_row(row);
485
486                if i < (len - 1) {
487                    s.write(",");
488                }
489            }
490        })
491    }
492
493    /// A database table identifier
494    fn visit_table(&mut self, table: Table<'a>, include_alias: bool) {
495        match table.typ {
496            TableType::Table(table_name) => match table.database {
497                Some(database) => self.delimited_identifiers(&[&*database, &*table_name]),
498                None => self.delimited_identifiers(&[&*table_name]),
499            },
500            TableType::Values(values) => self.visit_values(values),
501            TableType::Query(select) => {
502                self.surround_with("(", ")", |ref mut s| s.visit_select(*select))
503            }
504            TableType::JoinedTable(jt) => {
505                match table.database {
506                    Some(database) => self.delimited_identifiers(&[&*database, &*jt.0]),
507                    None => self.delimited_identifiers(&[&*jt.0]),
508                }
509                self.visit_joins(jt.1)
510            }
511        };
512
513        if include_alias {
514            if let Some(alias) = table.alias {
515                self.write(" AS ");
516
517                self.delimited_identifiers(&[&*alias]);
518            };
519        }
520    }
521
522    /// A database column identifier
523    fn visit_column(&mut self, column: Column<'a>) {
524        match column.table {
525            Some(table) => {
526                self.visit_table(table, false);
527                self.write(".");
528                self.delimited_identifiers(&[&*column.name]);
529            }
530            _ => self.delimited_identifiers(&[&*column.name]),
531        };
532
533        if let Some(alias) = column.alias {
534            self.write(" AS ");
535            self.delimited_identifiers(&[&*alias]);
536        }
537    }
538
539    /// A row of data used as an expression
540    fn visit_row(&mut self, row: Row<'a>) {
541        self.surround_with("(", ")", |ref mut s| {
542            let len = row.values.len();
543            for (i, value) in row.values.into_iter().enumerate() {
544                s.visit_expression(value);
545
546                if i < (len - 1) {
547                    s.write(",");
548                }
549            }
550        })
551    }
552
553    /// A walk through the query conditions
554    fn visit_conditions(&mut self, tree: ConditionTree<'a>) {
555        match tree {
556            ConditionTree::And(expressions) => self.surround_with("(", ")", |ref mut s| {
557                let len = expressions.len();
558
559                for (i, expr) in expressions.into_iter().enumerate() {
560                    s.visit_expression(expr);
561
562                    if i < (len - 1) {
563                        s.write(" AND ");
564                    }
565                }
566            }),
567            ConditionTree::Or(expressions) => self.surround_with("(", ")", |ref mut s| {
568                let len = expressions.len();
569
570                for (i, expr) in expressions.into_iter().enumerate() {
571                    s.visit_expression(expr);
572
573                    if i < (len - 1) {
574                        s.write(" OR ");
575                    }
576                }
577            }),
578            ConditionTree::Not(expression) => self.surround_with("(", ")", |ref mut s| {
579                s.write("NOT ");
580                s.visit_expression(*expression)
581            }),
582            ConditionTree::Single(expression) => self.visit_expression(*expression),
583            ConditionTree::NoCondition => self.write("1=1"),
584            ConditionTree::NegativeCondition => self.write("1=0"),
585            ConditionTree::Exists(table) => self.surround_with("(", ")", |ref mut s| {
586                s.write("EXISTS ");
587
588                s.surround_with("(", ")", |ref mut s| {
589                    s.visit_table(*table, false);
590                })
591            }),
592        }
593    }
594
595    fn visit_greater_than(&mut self, left: Expression<'a>, right: Expression<'a>) {
596        self.visit_expression(left);
597        self.write(" > ");
598        self.visit_expression(right)
599    }
600
601    fn visit_greater_than_or_equals(&mut self, left: Expression<'a>, right: Expression<'a>) {
602        self.visit_expression(left);
603        self.write(" >= ");
604        self.visit_expression(right)
605    }
606
607    fn visit_less_than(&mut self, left: Expression<'a>, right: Expression<'a>) {
608        self.visit_expression(left);
609        self.write(" < ");
610        self.visit_expression(right)
611    }
612
613    fn visit_less_than_or_equals(&mut self, left: Expression<'a>, right: Expression<'a>) {
614        self.visit_expression(left);
615        self.write(" <= ");
616        self.visit_expression(right)
617    }
618
619    fn visit_like(&mut self, left: Expression<'a>, right: Expression<'a>) {
620        self.visit_expression(left);
621        self.write(" LIKE ");
622        self.visit_expression(right);
623    }
624
625    fn visit_not_like(&mut self, left: Expression<'a>, right: Expression<'a>) {
626        self.visit_expression(left);
627        self.write(" NOT LIKE ");
628        self.visit_expression(right);
629    }
630
631    /// A comparison expression
632    fn visit_compare(&mut self, compare: Compare<'a>) {
633        match compare {
634            Compare::Equals(left, right) => self.visit_equals(*left, *right),
635            Compare::NotEquals(left, right) => self.visit_not_equals(*left, *right),
636            Compare::LessThan(left, right) => self.visit_less_than(*left, *right),
637            Compare::LessThanOrEquals(left, right) => self.visit_less_than_or_equals(*left, *right),
638            Compare::GreaterThan(left, right) => self.visit_greater_than(*left, *right),
639            Compare::GreaterThanOrEquals(left, right) => {
640                self.visit_greater_than_or_equals(*left, *right)
641            }
642            Compare::In(left, right) => match (*left, *right) {
643                // To prevent `x IN ()` from happening.
644                (
645                    _,
646                    Expression {
647                        kind: ExpressionKind::Row(ref row),
648                        ..
649                    },
650                ) if row.is_empty() => self.write("1=0"),
651
652                // To prevent `x IN ()` from happening.
653                (
654                    Expression {
655                        kind: ExpressionKind::Row(_),
656                        ..
657                    },
658                    Expression {
659                        kind: ExpressionKind::Values(ref vals),
660                        ..
661                    },
662                ) if vals.row_len() == 0 => self.write("1=0"),
663
664                // Flattening out a row.
665                (
666                    Expression {
667                        kind: ExpressionKind::Row(mut cols),
668                        ..
669                    },
670                    Expression {
671                        kind: ExpressionKind::Values(vals),
672                        ..
673                    },
674                ) if cols.len() == 1 && vals.row_len() == 1 => {
675                    let col = cols.pop().unwrap();
676                    let vals = vals.flatten_row().unwrap();
677
678                    self.visit_expression(col);
679                    self.write(" IN ");
680                    self.visit_row(vals)
681                }
682
683                // No need to do `IN` if right side is only one value,
684                (
685                    left,
686                    Expression {
687                        kind: ExpressionKind::Parameterized(pv),
688                        ..
689                    },
690                ) => {
691                    self.visit_expression(left);
692                    self.write(" = ");
693                    self.visit_parameterized(pv)
694                }
695
696                (
697                    Expression {
698                        kind: ExpressionKind::Row(row),
699                        ..
700                    },
701                    Expression {
702                        kind: ExpressionKind::Values(values),
703                        ..
704                    },
705                ) => self.visit_multiple_tuple_comparison(row, values, false),
706
707                // expr IN (..)
708                (left, right) => {
709                    self.visit_expression(left);
710                    self.write(" IN ");
711                    self.visit_expression(right)
712                }
713            },
714            Compare::NotIn(left, right) => match (*left, *right) {
715                // To prevent `x NOT IN ()` from happening.
716                (
717                    _,
718                    Expression {
719                        kind: ExpressionKind::Row(ref row),
720                        ..
721                    },
722                ) if row.is_empty() => self.write("1=1"),
723
724                // To prevent `x NOT IN ()` from happening.
725                (
726                    Expression {
727                        kind: ExpressionKind::Row(_),
728                        ..
729                    },
730                    Expression {
731                        kind: ExpressionKind::Values(ref vals),
732                        ..
733                    },
734                ) if vals.row_len() == 0 => self.write("1=1"),
735
736                // Flattening out a row.
737                (
738                    Expression {
739                        kind: ExpressionKind::Row(mut cols),
740                        ..
741                    },
742                    Expression {
743                        kind: ExpressionKind::Values(vals),
744                        ..
745                    },
746                ) if cols.len() == 1 && vals.row_len() == 1 => {
747                    let col = cols.pop().unwrap();
748                    let vals = vals.flatten_row().unwrap();
749
750                    self.visit_expression(col);
751                    self.write(" NOT IN ");
752                    self.visit_row(vals)
753                }
754
755                // No need to do `IN` if right side is only one value,
756                (
757                    left,
758                    Expression {
759                        kind: ExpressionKind::Parameterized(pv),
760                        ..
761                    },
762                ) => {
763                    self.visit_expression(left);
764                    self.write(" <> ");
765                    self.visit_parameterized(pv)
766                }
767
768                (
769                    Expression {
770                        kind: ExpressionKind::Row(row),
771                        ..
772                    },
773                    Expression {
774                        kind: ExpressionKind::Values(values),
775                        ..
776                    },
777                ) => self.visit_multiple_tuple_comparison(row, values, true),
778
779                // expr IN (..)
780                (left, right) => {
781                    self.visit_expression(left);
782                    self.write(" NOT IN ");
783                    self.visit_expression(right)
784                }
785            },
786            Compare::Like(left, right) => self.visit_like(*left, *right),
787            Compare::NotLike(left, right) => self.visit_not_like(*left, *right),
788            Compare::Null(column) => {
789                self.visit_expression(*column);
790                self.write(" IS NULL")
791            }
792            Compare::NotNull(column) => {
793                self.visit_expression(*column);
794                self.write(" IS NOT NULL")
795            }
796            Compare::Between(val, left, right) => {
797                self.visit_expression(*val);
798                self.write(" BETWEEN ");
799                self.visit_expression(*left);
800                self.write(" AND ");
801                self.visit_expression(*right)
802            }
803            Compare::NotBetween(val, left, right) => {
804                self.visit_expression(*val);
805                self.write(" NOT BETWEEN ");
806                self.visit_expression(*left);
807                self.write(" AND ");
808                self.visit_expression(*right)
809            }
810            Compare::Raw(left, comp, right) => {
811                self.visit_expression(*left);
812                self.write(" ");
813                self.write(comp);
814                self.write(" ");
815                self.visit_expression(*right)
816            }
817            #[cfg(any(feature = "mysql", feature = "postgresql"))]
818            Compare::JsonCompare(json_compare) => match json_compare {
819                JsonCompare::ArrayContains(left, right) => {
820                    self.visit_array_contains(*left, *right, false)
821                }
822                JsonCompare::ArrayContained(left, right) => {
823                    self.visit_array_contained(*left, *right, false)
824                }
825                JsonCompare::ArrayOverlaps(left, right) => self.visit_array_overlaps(*left, *right),
826                JsonCompare::ArrayNotContains(left, right) => {
827                    self.visit_array_contains(*left, *right, true)
828                }
829                JsonCompare::TypeEquals(left, json_type) => {
830                    self.visit_json_type_equals(*left, json_type, false)
831                }
832                JsonCompare::TypeNotEquals(left, json_type) => {
833                    self.visit_json_type_equals(*left, json_type, true)
834                }
835            },
836            #[cfg(feature = "postgresql")]
837            Compare::Any(left) => {
838                self.write("ANY");
839                self.surround_with("(", ")", |s| s.visit_expression(*left))
840            }
841            #[cfg(feature = "postgresql")]
842            Compare::All(left) => {
843                self.write("ALL");
844                self.surround_with("(", ")", |s| s.visit_expression(*left))
845            }
846        }
847    }
848
849    fn visit_equals(&mut self, left: Expression<'a>, right: Expression<'a>) {
850        self.visit_expression(left);
851        self.write(" = ");
852        self.visit_expression(right);
853    }
854
855    fn visit_not_equals(&mut self, left: Expression<'a>, right: Expression<'a>) {
856        self.visit_expression(left);
857        self.write(" <> ");
858        self.visit_expression(right);
859    }
860
861    /// A visit in the `GROUP BY` section of the query
862    fn visit_grouping(&mut self, grouping: Grouping<'a>) {
863        let len = grouping.0.len();
864
865        for (i, value) in grouping.0.into_iter().enumerate() {
866            self.visit_expression(value);
867
868            if i < (len - 1) {
869                self.write(", ");
870            }
871        }
872    }
873
874    fn visit_average(&mut self, avg: Average<'a>) {
875        self.write("AVG");
876        self.surround_with("(", ")", |ref mut s| s.visit_column(avg.column));
877    }
878
879    fn visit_function(&mut self, fun: Function<'a>) {
880        match fun.typ_ {
881            FunctionType::Count(fun_count) => {
882                if fun_count.exprs.is_empty() {
883                    self.write("COUNT(*)");
884                } else {
885                    self.write("COUNT");
886                    self.surround_with("(", ")", |ref mut s| s.visit_columns(fun_count.exprs));
887                }
888            }
889            FunctionType::AggregateToString(agg) => {
890                self.visit_aggregate_to_string(agg.value.as_ref().clone());
891            }
892            #[cfg(feature = "postgresql")]
893            FunctionType::RowToJson(row_to_json) => {
894                self.write("ROW_TO_JSON");
895                self.surround_with("(", ")", |ref mut s| s.visit_table(row_to_json.expr, false))
896            }
897            FunctionType::Average(avg) => {
898                self.visit_average(avg);
899            }
900            FunctionType::Sum(sum) => {
901                self.write("SUM");
902                self.surround_with("(", ")", |ref mut s| s.visit_expression(*sum.expr));
903            }
904            FunctionType::Lower(lower) => {
905                self.write("LOWER");
906                self.surround_with("(", ")", |ref mut s| s.visit_expression(*lower.expression));
907            }
908            FunctionType::Upper(upper) => {
909                self.write("UPPER");
910                self.surround_with("(", ")", |ref mut s| s.visit_expression(*upper.expression));
911            }
912            FunctionType::Minimum(min) => {
913                self.write("MIN");
914                self.surround_with("(", ")", |ref mut s| s.visit_column(min.column));
915            }
916            FunctionType::Maximum(max) => {
917                self.write("MAX");
918                self.surround_with("(", ")", |ref mut s| s.visit_column(max.column));
919            }
920            FunctionType::Coalesce(coalesce) => {
921                self.write("COALESCE");
922                self.surround_with("(", ")", |s| s.visit_columns(coalesce.exprs));
923            }
924            #[cfg(any(feature = "postgresql", feature = "mysql"))]
925            FunctionType::JsonExtract(json_extract) => {
926                self.visit_json_extract(json_extract);
927            }
928            #[cfg(any(feature = "postgresql", feature = "mysql"))]
929            FunctionType::JsonExtractFirstArrayElem(extract) => {
930                self.visit_json_extract_first_array_item(extract);
931            }
932            #[cfg(any(feature = "postgresql", feature = "mysql"))]
933            FunctionType::JsonExtractLastArrayElem(extract) => {
934                self.visit_json_extract_last_array_item(extract);
935            }
936            #[cfg(any(feature = "postgresql", feature = "mysql"))]
937            FunctionType::JsonUnquote(unquote) => {
938                self.visit_json_unquote(unquote);
939            }
940            #[cfg(feature = "postgresql")]
941            FunctionType::ToJsonb(to_jsonb) => self.visit_to_jsonb(to_jsonb),
942            #[cfg(feature = "postgresql")]
943            FunctionType::JsonAgg(json_agg) => self.visit_json_agg(json_agg),
944            #[cfg(feature = "postgresql")]
945            FunctionType::Encode(encode) => self.visit_encode(encode),
946            #[cfg(feature = "postgresql")]
947            FunctionType::JsonBuildObject(encode) => self.visit_json_build_object(encode),
948            FunctionType::Concat(concat) => {
949                self.visit_concat(concat);
950            }
951        };
952
953        if let Some(alias) = fun.alias {
954            self.write(" AS ");
955            self.delimited_identifiers(&[&*alias]);
956        }
957    }
958
959    fn visit_concat(&mut self, concat: Concat<'a>) {
960        let len = concat.exprs.len();
961
962        self.write("CONCAT");
963        self.surround_with("(", ")", |s| {
964            for (i, expr) in concat.exprs.into_iter().enumerate() {
965                s.visit_expression(expr);
966
967                if i < (len - 1) {
968                    s.write(", ");
969                }
970            }
971        });
972    }
973
974    fn visit_partitioning(&mut self, over: Over<'a>) {
975        if !over.partitioning.is_empty() {
976            let len = over.partitioning.len();
977            self.write("PARTITION BY ");
978
979            for (i, partition) in over.partitioning.into_iter().enumerate() {
980                self.visit_column(partition);
981
982                if i < (len - 1) {
983                    self.write(", ");
984                }
985            }
986
987            if !over.ordering.is_empty() {
988                self.write(" ");
989            }
990        }
991
992        if !over.ordering.is_empty() {
993            self.write("ORDER BY ");
994            self.visit_ordering(over.ordering);
995        }
996    }
997}