surrealdb_core/sql/
subquery.rs

1use crate::ctx::{Context, MutableContext};
2use crate::dbs::Options;
3use crate::doc::CursorDoc;
4use crate::err::Error;
5use crate::sql::statements::rebuild::RebuildStatement;
6use crate::sql::statements::{
7	AlterStatement, CreateStatement, DefineStatement, DeleteStatement, IfelseStatement,
8	InsertStatement, OutputStatement, RelateStatement, RemoveStatement, SelectStatement,
9	UpdateStatement, UpsertStatement,
10};
11use crate::sql::value::Value;
12use reblessive::tree::Stk;
13use revision::revisioned;
14use serde::{Deserialize, Serialize};
15use std::cmp::Ordering;
16use std::fmt::{self, Display, Formatter};
17
18pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Subquery";
19
20#[revisioned(revision = 4)]
21#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
22#[serde(rename = "$surrealdb::private::sql::Subquery")]
23#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
24#[non_exhaustive]
25pub enum Subquery {
26	Value(Value),
27	Ifelse(IfelseStatement),
28	Output(OutputStatement),
29	Select(SelectStatement),
30	Create(CreateStatement),
31	Update(UpdateStatement),
32	Delete(DeleteStatement),
33	Relate(RelateStatement),
34	Insert(InsertStatement),
35	Define(DefineStatement),
36	Remove(RemoveStatement),
37	#[revision(start = 2)]
38	Rebuild(RebuildStatement),
39	#[revision(start = 3)]
40	Upsert(UpsertStatement),
41	#[revision(start = 4)]
42	Alter(AlterStatement),
43}
44
45impl PartialOrd for Subquery {
46	#[inline]
47	fn partial_cmp(&self, _: &Self) -> Option<Ordering> {
48		None
49	}
50}
51
52impl Subquery {
53	/// Check if we require a writeable transaction
54	pub(crate) fn writeable(&self) -> bool {
55		match self {
56			Self::Value(v) => v.writeable(),
57			Self::Ifelse(v) => v.writeable(),
58			Self::Output(v) => v.writeable(),
59			Self::Select(v) => v.writeable(),
60			Self::Create(v) => v.writeable(),
61			Self::Upsert(v) => v.writeable(),
62			Self::Update(v) => v.writeable(),
63			Self::Delete(v) => v.writeable(),
64			Self::Relate(v) => v.writeable(),
65			Self::Insert(v) => v.writeable(),
66			Self::Define(v) => v.writeable(),
67			Self::Remove(v) => v.writeable(),
68			Self::Rebuild(v) => v.writeable(),
69			Self::Alter(v) => v.writeable(),
70		}
71	}
72	/// Process this type returning a computed simple Value
73	pub(crate) async fn compute(
74		&self,
75		stk: &mut Stk,
76		ctx: &Context,
77		opt: &Options,
78		doc: Option<&CursorDoc>,
79	) -> Result<Value, Error> {
80		match self.compute_unbordered(stk, ctx, opt, doc).await {
81			Err(Error::Return {
82				value,
83			}) => Ok(value),
84			res => res,
85		}
86	}
87	/// Process this type returning a computed simple Value, without catching errors
88	pub(crate) async fn compute_unbordered(
89		&self,
90		stk: &mut Stk,
91		ctx: &Context,
92		opt: &Options,
93		doc: Option<&CursorDoc>,
94	) -> Result<Value, Error> {
95		// Duplicate context
96		let mut ctx = MutableContext::new(ctx);
97		// Add parent document
98		if let Some(doc) = doc {
99			ctx.add_value("parent", doc.doc.as_ref().clone().into());
100		}
101		let ctx = ctx.freeze();
102		// Process the subquery
103		match self {
104			Self::Value(ref v) => v.compute(stk, &ctx, opt, doc).await,
105			Self::Ifelse(ref v) => v.compute(stk, &ctx, opt, doc).await,
106			Self::Output(ref v) => v.compute(stk, &ctx, opt, doc).await,
107			Self::Define(ref v) => v.compute(stk, &ctx, opt, doc).await,
108			Self::Rebuild(ref v) => v.compute(stk, &ctx, opt, doc).await,
109			Self::Remove(ref v) => v.compute(&ctx, opt, doc).await,
110			Self::Select(ref v) => v.compute(stk, &ctx, opt, doc).await,
111			Self::Create(ref v) => v.compute(stk, &ctx, opt, doc).await,
112			Self::Upsert(ref v) => v.compute(stk, &ctx, opt, doc).await,
113			Self::Update(ref v) => v.compute(stk, &ctx, opt, doc).await,
114			Self::Delete(ref v) => v.compute(stk, &ctx, opt, doc).await,
115			Self::Relate(ref v) => v.compute(stk, &ctx, opt, doc).await,
116			Self::Insert(ref v) => v.compute(stk, &ctx, opt, doc).await,
117			Self::Alter(ref v) => v.compute(stk, &ctx, opt, doc).await,
118		}
119	}
120}
121
122impl Display for Subquery {
123	fn fmt(&self, f: &mut Formatter) -> fmt::Result {
124		match self {
125			Self::Value(v) => write!(f, "({v})"),
126			Self::Output(v) => write!(f, "({v})"),
127			Self::Select(v) => write!(f, "({v})"),
128			Self::Create(v) => write!(f, "({v})"),
129			Self::Upsert(v) => write!(f, "({v})"),
130			Self::Update(v) => write!(f, "({v})"),
131			Self::Delete(v) => write!(f, "({v})"),
132			Self::Relate(v) => write!(f, "({v})"),
133			Self::Insert(v) => write!(f, "({v})"),
134			Self::Define(v) => write!(f, "({v})"),
135			Self::Remove(v) => write!(f, "({v})"),
136			Self::Rebuild(v) => write!(f, "({v})"),
137			Self::Alter(v) => write!(f, "({v})"),
138			Self::Ifelse(v) => Display::fmt(v, f),
139		}
140	}
141}