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 }
34
35impl PartialOrd for Subquery {
36 #[inline]
37 fn partial_cmp(&self, _: &Self) -> Option<Ordering> {
38 None
39 }
40}
41
42impl Subquery {
43 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 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 let mut ctx = Context::new(ctx);
69 if let Some(doc) = doc {
71 ctx.add_value("parent", doc.doc.as_ref());
72 }
73 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}