surrealdb_sql/
subquery.rs

1use crate::ctx::Context;
2use crate::dbs::{Options, Transaction};
3use crate::doc::CursorDoc;
4use crate::err::Error;
5use crate::statements::{
6	CreateStatement, DefineStatement, DeleteStatement, IfelseStatement, InsertStatement,
7	OutputStatement, RelateStatement, RemoveStatement, SelectStatement, UpdateStatement,
8};
9use crate::value::Value;
10use revision::revisioned;
11use serde::{Deserialize, Serialize};
12use std::cmp::Ordering;
13use std::fmt::{self, Display, Formatter};
14
15pub(crate) const TOKEN: &str = "$surrealdb::private::crate::Subquery";
16
17#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
18#[serde(rename = "$surrealdb::private::crate::Subquery")]
19#[revisioned(revision = 1)]
20pub enum Subquery {
21	Value(Value),
22	Ifelse(IfelseStatement),
23	Output(OutputStatement),
24	Select(SelectStatement),
25	Create(CreateStatement),
26	Update(UpdateStatement),
27	Delete(DeleteStatement),
28	Relate(RelateStatement),
29	Insert(InsertStatement),
30	Define(DefineStatement),
31	Remove(RemoveStatement),
32	// Add new variants here
33}
34
35impl PartialOrd for Subquery {
36	#[inline]
37	fn partial_cmp(&self, _: &Self) -> Option<Ordering> {
38		None
39	}
40}
41
42impl Subquery {
43	/// Check if we require a writeable transaction
44	pub(crate) fn writeable(&self) -> bool {
45		match self {
46			Self::Value(v) => v.writeable(),
47			Self::Ifelse(v) => v.writeable(),
48			Self::Output(v) => v.writeable(),
49			Self::Select(v) => v.writeable(),
50			Self::Create(v) => v.writeable(),
51			Self::Update(v) => v.writeable(),
52			Self::Delete(v) => v.writeable(),
53			Self::Relate(v) => v.writeable(),
54			Self::Insert(v) => v.writeable(),
55			Self::Define(v) => v.writeable(),
56			Self::Remove(v) => v.writeable(),
57		}
58	}
59	/// Process this type returning a computed simple Value
60	pub(crate) async fn compute(
61		&self,
62		ctx: &Context<'_>,
63		opt: &Options,
64		txn: &Transaction,
65		doc: Option<&CursorDoc<'_>>,
66	) -> Result<Value, Error> {
67		// Duplicate context
68		let mut ctx = Context::new(ctx);
69		// Add parent document
70		if let Some(doc) = doc {
71			ctx.add_value("parent", doc.doc.as_ref());
72		}
73		// Process the subquery
74		match self {
75			Self::Value(ref v) => v.compute(&ctx, opt, txn, doc).await,
76			Self::Ifelse(ref v) => v.compute(&ctx, opt, txn, doc).await,
77			Self::Output(ref v) => v.compute(&ctx, opt, txn, doc).await,
78			Self::Define(ref v) => v.compute(&ctx, opt, txn, doc).await,
79			Self::Remove(ref v) => v.compute(&ctx, opt, txn, doc).await,
80			Self::Select(ref v) => v.compute(&ctx, opt, txn, doc).await,
81			Self::Create(ref v) => v.compute(&ctx, opt, txn, doc).await,
82			Self::Update(ref v) => v.compute(&ctx, opt, txn, doc).await,
83			Self::Delete(ref v) => v.compute(&ctx, opt, txn, doc).await,
84			Self::Relate(ref v) => v.compute(&ctx, opt, txn, doc).await,
85			Self::Insert(ref v) => v.compute(&ctx, opt, txn, doc).await,
86		}
87	}
88}
89
90impl Display for Subquery {
91	fn fmt(&self, f: &mut Formatter) -> fmt::Result {
92		match self {
93			Self::Value(v) => write!(f, "({v})"),
94			Self::Output(v) => write!(f, "({v})"),
95			Self::Select(v) => write!(f, "({v})"),
96			Self::Create(v) => write!(f, "({v})"),
97			Self::Update(v) => write!(f, "({v})"),
98			Self::Delete(v) => write!(f, "({v})"),
99			Self::Relate(v) => write!(f, "({v})"),
100			Self::Insert(v) => write!(f, "({v})"),
101			Self::Define(v) => write!(f, "({v})"),
102			Self::Remove(v) => write!(f, "({v})"),
103			Self::Ifelse(v) => Display::fmt(v, f),
104		}
105	}
106}