Skip to main content

surrealdb_sql/
cover.rs

1use surrealdb_types::{SqlFormat, ToSql};
2
3use crate::Expr;
4
5/// Renders an [`Expr`] in a position where a statement-shaped expression would
6/// be ambiguous, parenthesising it when required.
7///
8/// Value-shaped expressions render bare. Statement-shaped ones (SELECT, CREATE,
9/// IF, ...) are wrapped in parentheses so the result reparses to the same tree
10/// when spliced into a larger query. `RETURN` is the one conditional case: it
11/// only needs covering when it carries a FETCH clause.
12pub struct CoverStmts<'a>(pub &'a Expr);
13
14impl ToSql for CoverStmts<'_> {
15	fn fmt_sql(&self, f: &mut String, fmt: SqlFormat) {
16		match self.0 {
17			Expr::Literal(_)
18			| Expr::Param(_)
19			| Expr::Idiom(_)
20			| Expr::Table(_)
21			| Expr::Mock(_)
22			| Expr::Block(_)
23			| Expr::Constant(_)
24			| Expr::Prefix {
25				..
26			}
27			| Expr::Postfix {
28				..
29			}
30			| Expr::Binary {
31				..
32			}
33			| Expr::FunctionCall(_)
34			| Expr::Closure(_)
35			| Expr::Break
36			| Expr::Continue
37			| Expr::Throw(_) => self.0.fmt_sql(f, fmt),
38			Expr::Return(x) => {
39				if x.fetch.is_some() {
40					f.push('(');
41					self.0.fmt_sql(f, fmt);
42					f.push(')')
43				} else {
44					self.0.fmt_sql(f, fmt);
45				}
46			}
47
48			Expr::IfElse(_)
49			| Expr::Select(_)
50			| Expr::Create(_)
51			| Expr::Update(_)
52			| Expr::Upsert(_)
53			| Expr::Delete(_)
54			| Expr::Relate(_)
55			| Expr::Insert(_)
56			| Expr::Define(_)
57			| Expr::Remove(_)
58			| Expr::Rebuild(_)
59			| Expr::Alter(_)
60			| Expr::Info(_)
61			| Expr::Foreach(_)
62			| Expr::Let(_)
63			| Expr::Sleep(_)
64			| Expr::Explain {
65				..
66			} => {
67				f.push('(');
68				self.0.fmt_sql(f, fmt);
69				f.push(')')
70			}
71		}
72	}
73}