Skip to main content

surrealdb_expr/expr/
plan.rs

1use crate::expr::Expr;
2use crate::expr::statements::{
3	AccessStatement, KillStatement, LiveStatement, OptionStatement, ShowStatement, UseStatement,
4};
5
6#[derive(Clone, Debug)]
7pub struct LogicalPlan {
8	pub expressions: Vec<TopLevelExpr>,
9}
10
11#[derive(Clone, Eq, PartialEq, Hash, Debug)]
12pub enum TopLevelExpr {
13	Begin,
14	Cancel,
15	Commit,
16	Access(Box<AccessStatement>),
17	Kill(KillStatement),
18	Live(Box<LiveStatement>),
19	Option(OptionStatement),
20	Use(UseStatement),
21	Show(ShowStatement),
22	Expr(Expr),
23}
24
25impl TopLevelExpr {
26	/// Check if we require a writeable transaction
27	pub fn read_only(&self) -> bool {
28		match self {
29			TopLevelExpr::Begin
30			| TopLevelExpr::Cancel
31			| TopLevelExpr::Commit
32			| TopLevelExpr::Show(_) => true,
33			TopLevelExpr::Kill(_)
34			| TopLevelExpr::Live(_)
35			| TopLevelExpr::Option(_)
36			| TopLevelExpr::Use(_)
37			| TopLevelExpr::Access(_) => false,
38			TopLevelExpr::Expr(expr) => expr.read_only(),
39		}
40	}
41}
42
43impl surrealdb_types::ToSql for TopLevelExpr {
44	fn fmt_sql(&self, f: &mut String, fmt: surrealdb_types::SqlFormat) {
45		// Render a bare expression through `Expr`'s own `ToSql`, which carves
46		// out the forms that have no SurrealQL surface to convert back to —
47		// `Expr::Match`, which GQL lowers to and which the conversion below
48		// would replace with a `NONE` placeholder after a `debug_assert!`.
49		// `sql::TopLevelExpr::Expr` renders as its inner expression, so this
50		// arm produces the same text the conversion would for everything else.
51		if let TopLevelExpr::Expr(expr) = self {
52			expr.fmt_sql(f, fmt);
53			return;
54		}
55		let sql_expr: crate::sql::TopLevelExpr = self.clone().into();
56		sql_expr.fmt_sql(f, fmt);
57	}
58}
59
60impl surrealdb_types::ToSql for LogicalPlan {
61	fn fmt_sql(&self, f: &mut String, fmt: surrealdb_types::SqlFormat) {
62		let sql_ast: crate::sql::Ast = self.clone().into();
63		sql_ast.fmt_sql(f, fmt);
64	}
65}