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