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