surrealdb_core/sql/statements/
create.rs1use crate::ctx::Context;
2use crate::dbs::{Iterator, Options, Statement};
3use crate::doc::CursorDoc;
4use crate::err::Error;
5use crate::idx::planner::{QueryPlanner, RecordStrategy, StatementContext};
6use crate::sql::{Data, Output, Timeout, Value, Values, Version};
7
8use reblessive::tree::Stk;
9use revision::revisioned;
10use serde::{Deserialize, Serialize};
11use std::fmt;
12
13#[revisioned(revision = 3)]
14#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
15#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
16#[non_exhaustive]
17pub struct CreateStatement {
18 #[revision(start = 2)]
20 pub only: bool,
21 pub what: Values,
23 pub data: Option<Data>,
25 pub output: Option<Output>,
27 pub timeout: Option<Timeout>,
29 pub parallel: bool,
31 #[revision(start = 3)]
33 pub version: Option<Version>,
34}
35
36impl CreateStatement {
37 pub(crate) fn writeable(&self) -> bool {
39 true
40 }
41 pub(crate) async fn compute(
43 &self,
44 stk: &mut Stk,
45 ctx: &Context,
46 opt: &Options,
47 doc: Option<&CursorDoc>,
48 ) -> Result<Value, Error> {
49 opt.valid_for_db()?;
51 let mut i = Iterator::new();
53 let stm = Statement::from(self);
55 let version = match &self.version {
57 Some(v) => Some(v.compute(stk, ctx, opt, doc).await?),
58 _ => None,
59 };
60 let opt = &opt.new_with_futures(false).with_version(version);
62 let ctx = stm.setup_timeout(ctx)?;
64 let mut planner = QueryPlanner::new();
66 let stm_ctx = StatementContext::new(&ctx, opt, &stm)?;
67 for w in self.what.0.iter() {
69 let v = w.compute(stk, &ctx, opt, doc).await?;
70 i.prepare(stk, &mut planner, &stm_ctx, v).await.map_err(|e| match e {
71 Error::InvalidStatementTarget {
72 value: v,
73 } => Error::CreateStatement {
74 value: v,
75 },
76 e => e,
77 })?;
78 }
79 let ctx = stm.setup_query_planner(planner, ctx);
81 let res = i.output(stk, &ctx, opt, &stm, RecordStrategy::KeysAndValues).await?;
83 if ctx.is_timedout()? {
85 return Err(Error::QueryTimedout);
86 }
87 match res {
89 Value::Array(mut a) if self.only => match a.len() {
91 1 => Ok(a.remove(0)),
93 _ => Err(Error::SingleOnlyOutput),
95 },
96 v => Ok(v),
98 }
99 }
100}
101
102impl fmt::Display for CreateStatement {
103 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
104 write!(f, "CREATE")?;
105 if self.only {
106 f.write_str(" ONLY")?
107 }
108 write!(f, " {}", self.what)?;
109 if let Some(ref v) = self.data {
110 write!(f, " {v}")?
111 }
112 if let Some(ref v) = self.output {
113 write!(f, " {v}")?
114 }
115 if let Some(ref v) = self.version {
116 write!(f, " {v}")?
117 }
118 if let Some(ref v) = self.timeout {
119 write!(f, " {v}")?
120 }
121 if self.parallel {
122 f.write_str(" PARALLEL")?
123 }
124 Ok(())
125 }
126}