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 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 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 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 let mut ctx = MutableContext::new(ctx);
97 if let Some(doc) = doc {
99 ctx.add_value("parent", doc.doc.as_ref().clone().into());
100 }
101 let ctx = ctx.freeze();
102 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}