surrealdb_sql/statements/
select.rs1use crate::ctx::Context;
2use crate::dbs::{Iterable, Iterator, Options, Statement, Transaction};
3use crate::doc::CursorDoc;
4use crate::err::Error;
5use crate::idx::planner::QueryPlanner;
6use crate::{
7 Cond, Explain, Fetchs, Field, Fields, Groups, Idioms, Limit, Orders, Splits, Start, Timeout,
8 Value, Values, Version, With,
9};
10use derive::Store;
11use revision::revisioned;
12use serde::{Deserialize, Serialize};
13use std::fmt;
14
15#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Store, Hash)]
16#[revisioned(revision = 2)]
17pub struct SelectStatement {
18 pub expr: Fields,
19 pub omit: Option<Idioms>,
20 #[revision(start = 2)]
21 pub only: bool,
22 pub what: Values,
23 pub with: Option<With>,
24 pub cond: Option<Cond>,
25 pub split: Option<Splits>,
26 pub group: Option<Groups>,
27 pub order: Option<Orders>,
28 pub limit: Option<Limit>,
29 pub start: Option<Start>,
30 pub fetch: Option<Fetchs>,
31 pub version: Option<Version>,
32 pub timeout: Option<Timeout>,
33 pub parallel: bool,
34 pub explain: Option<Explain>,
35}
36
37impl SelectStatement {
38 pub(crate) fn writeable(&self) -> bool {
40 if self.expr.iter().any(|v| match v {
41 Field::All => false,
42 Field::Single {
43 expr,
44 ..
45 } => expr.writeable(),
46 }) {
47 return true;
48 }
49 if self.what.iter().any(|v| v.writeable()) {
50 return true;
51 }
52 self.cond.as_ref().map_or(false, |v| v.writeable())
53 }
54
55 pub(crate) async fn compute(
57 &self,
58 ctx: &Context<'_>,
59 opt: &Options,
60 txn: &Transaction,
61 doc: Option<&CursorDoc<'_>>,
62 ) -> Result<Value, Error> {
63 opt.valid_for_db()?;
65 let mut i = Iterator::new();
67 let opt = &opt.new_with_futures(false).with_projections(true);
69 let mut planner = QueryPlanner::new(opt, &self.with, &self.cond);
71 let limit_is_one_or_zero = match &self.limit {
73 Some(l) => l.process(ctx, opt, txn, doc).await? <= 1,
74 _ => false,
75 };
76 if self.only && !limit_is_one_or_zero && self.what.0.len() > 1 {
78 return Err(Error::SingleOnlyOutput);
79 }
80 for w in self.what.0.iter() {
82 let v = w.compute(ctx, opt, txn, doc).await?;
83 match v {
84 Value::Table(t) => {
85 if self.only && !limit_is_one_or_zero {
86 return Err(Error::SingleOnlyOutput);
87 }
88
89 planner.add_iterables(ctx, txn, t, &mut i).await?;
90 }
91 Value::Thing(v) => i.ingest(Iterable::Thing(v)),
92 Value::Range(v) => {
93 if self.only && !limit_is_one_or_zero {
94 return Err(Error::SingleOnlyOutput);
95 }
96
97 i.ingest(Iterable::Range(*v))
98 }
99 Value::Edges(v) => {
100 if self.only && !limit_is_one_or_zero {
101 return Err(Error::SingleOnlyOutput);
102 }
103
104 i.ingest(Iterable::Edges(*v))
105 }
106 Value::Mock(v) => {
107 if self.only && !limit_is_one_or_zero {
108 return Err(Error::SingleOnlyOutput);
109 }
110
111 for v in v {
112 i.ingest(Iterable::Thing(v));
113 }
114 }
115 Value::Array(v) => {
116 if self.only && !limit_is_one_or_zero {
117 return Err(Error::SingleOnlyOutput);
118 }
119
120 for v in v {
121 match v {
122 Value::Table(t) => {
123 planner.add_iterables(ctx, txn, t, &mut i).await?;
124 }
125 Value::Thing(v) => i.ingest(Iterable::Thing(v)),
126 Value::Edges(v) => i.ingest(Iterable::Edges(*v)),
127 Value::Mock(v) => {
128 for v in v {
129 i.ingest(Iterable::Thing(v));
130 }
131 }
132 _ => i.ingest(Iterable::Value(v)),
133 }
134 }
135 }
136 v => i.ingest(Iterable::Value(v)),
137 };
138 }
139 let mut ctx = Context::new(ctx);
141 let stm = Statement::from(self);
143 if planner.has_executors() {
145 ctx.set_query_planner(&planner);
146 }
147 match i.output(&ctx, opt, txn, &stm).await? {
149 Value::Array(mut a) if self.only => match a.len() {
151 0 => Ok(Value::None),
153 1 => Ok(a.remove(0)),
155 _ => Err(Error::SingleOnlyOutput),
157 },
158 v => Ok(v),
160 }
161 }
162}
163
164impl fmt::Display for SelectStatement {
165 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
166 write!(f, "SELECT {}", self.expr)?;
167 if let Some(ref v) = self.omit {
168 write!(f, " OMIT {v}")?
169 }
170 write!(f, " FROM")?;
171 if self.only {
172 f.write_str(" ONLY")?
173 }
174 write!(f, " {}", self.what)?;
175 if let Some(ref v) = self.with {
176 write!(f, " {v}")?
177 }
178 if let Some(ref v) = self.cond {
179 write!(f, " {v}")?
180 }
181 if let Some(ref v) = self.split {
182 write!(f, " {v}")?
183 }
184 if let Some(ref v) = self.group {
185 write!(f, " {v}")?
186 }
187 if let Some(ref v) = self.order {
188 write!(f, " {v}")?
189 }
190 if let Some(ref v) = self.limit {
191 write!(f, " {v}")?
192 }
193 if let Some(ref v) = self.start {
194 write!(f, " {v}")?
195 }
196 if let Some(ref v) = self.fetch {
197 write!(f, " {v}")?
198 }
199 if let Some(ref v) = self.version {
200 write!(f, " {v}")?
201 }
202 if let Some(ref v) = self.timeout {
203 write!(f, " {v}")?
204 }
205 if self.parallel {
206 f.write_str(" PARALLEL")?
207 }
208 if let Some(ref v) = self.explain {
209 write!(f, " {v}")?
210 }
211 Ok(())
212 }
213}