Skip to main content

surrealdb_expr/expr/statements/
select.rs

1use crate::expr::order::Ordering;
2use crate::expr::{Cond, Explain, Expr, Fetchs, Fields, Groups, Limit, Splits, Start, With};
3
4#[derive(Clone, Debug, Eq, PartialEq, Hash)]
5pub struct SelectStatement {
6	/// The fields to extract from the records.
7	///
8	/// The foo,bar part in `SELECT foo,bar FROM baz`.
9	pub fields: Fields,
10	/// The fields to omit from the records. This is used to exclude fields from wildcard
11	/// selection.
12	///
13	/// The OMIT foo,bar part in `SELECT foo,bar OMIT baz,qux FROM baz`.
14	pub omit: Vec<Expr>,
15	/// Whether to only return a single record.
16	///
17	/// The ONLY part in `SELECT * FROM ONLY foo`.
18	pub only: bool,
19	/// The expressions (tables, record IDs, arrays, etc) to select from.
20	///
21	/// The baz part in SELECT foo,bar FROM baz.
22	pub what: Vec<Expr>,
23	pub with: Option<With>,
24	/// The WHERE clause.
25	pub cond: Option<Cond>,
26	/// The SPLIT clause.
27	///
28	/// This is used to produce the cartesian product of the values in split fields.
29	pub split: Option<Splits>,
30	pub group: Option<Groups>,
31	pub order: Option<Ordering>,
32	pub limit: Option<Limit>,
33	pub start: Option<Start>,
34	pub fetch: Option<Fetchs>,
35	pub version: Expr,
36	pub timeout: Expr,
37	pub explain: Option<Explain>,
38	pub tempfiles: bool,
39	/// Whether the read locks the selected records for the duration of
40	/// the transaction.
41	///
42	/// The FOR UPDATE part in `SELECT * FROM foo FOR UPDATE`.
43	pub for_update: bool,
44}
45
46impl SelectStatement {
47	/// Check if computing this type can be done on a read only transaction.
48	/// Whether computing this statement can be done on a read-only
49	/// transaction.
50	///
51	/// Every clause that can carry a user expression is inspected. The
52	/// executor picks the transaction type from this before the statement is
53	/// planned, so a clause omitted here would let a mutation reach a
54	/// read-only transaction and fail partway through the statement.
55	/// A `FOR UPDATE` read always requires a write transaction: the locked
56	/// reads register the fetched keys for commit-time conflict detection,
57	/// which storage engines only support on writeable transactions.
58	pub fn read_only(&self) -> bool {
59		!self.for_update
60			&& self.fields.read_only()
61			&& self.omit.iter().all(|v| v.read_only())
62			&& self.what.iter().all(|v| v.read_only())
63			&& self.cond.as_ref().map(|x| x.0.read_only()).unwrap_or(true)
64			&& self.split.as_ref().map(|x| x.read_only()).unwrap_or(true)
65			&& self.group.as_ref().map(|x| x.read_only()).unwrap_or(true)
66			&& self.order.as_ref().map(|x| x.read_only()).unwrap_or(true)
67			&& self.limit.as_ref().map(|x| x.read_only()).unwrap_or(true)
68			&& self.start.as_ref().map(|x| x.read_only()).unwrap_or(true)
69			&& self.fetch.as_ref().map(|x| x.read_only()).unwrap_or(true)
70			&& self.version.read_only()
71			&& self.timeout.read_only()
72	}
73}