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}