Skip to main content

surrealguard_syntax/ast/
clause.rs

1//! Clauses shared across statement kinds.
2
3use super::{Expr, Idiom, PartialNode, Spanned};
4use crate::span::ByteRange;
5
6/// One output column of a SELECT projection list or a mutation
7/// `RETURN <fields>` list.
8#[derive(Clone, Debug, PartialEq)]
9pub enum Projection {
10    /// `*`
11    Wildcard(ByteRange),
12    /// A projected expression, optionally aliased with `AS`.
13    Expr {
14        /// The projected value expression.
15        expr: Spanned<Expr>,
16        /// `AS <name>` — the output column name, if renamed.
17        alias: Option<Spanned<String>>,
18    },
19    /// A projection that failed to lower.
20    Partial(PartialNode),
21}
22
23/// A mutation's `RETURN` clause.
24#[derive(Clone, Debug, PartialEq)]
25pub enum ReturnMode {
26    /// `RETURN NONE` — suppress the result.
27    None,
28    /// `RETURN NULL`.
29    Null,
30    /// `RETURN DIFF` — the JSON-patch delta of each row.
31    Diff,
32    /// `RETURN BEFORE` — the row as it was before the mutation.
33    Before,
34    /// `RETURN AFTER` — the row after the mutation (the default).
35    After,
36    /// `RETURN <fields>` — an explicit projection list.
37    Fields(Vec<Projection>),
38}
39
40/// A mutation's payload clause.
41#[derive(Clone, Debug, PartialEq)]
42pub enum DataClause {
43    /// `SET a = 1, b = 2` — per-field assignments.
44    Set(Vec<Assignment>),
45    /// `UNSET a, b` — fields to remove.
46    Unset(Vec<Spanned<Idiom>>),
47    /// `CONTENT <expr>` — replace the row with the object.
48    Content(Spanned<Expr>),
49    /// `MERGE <expr>` — shallow-merge the object into the row.
50    Merge(Spanned<Expr>),
51    /// `PATCH <expr>` — apply a JSON-patch array.
52    Patch(Spanned<Expr>),
53    /// `REPLACE <expr>` — overwrite the row with the object.
54    Replace(Spanned<Expr>),
55    /// A bare value payload (e.g. `INSERT INTO t $object`).
56    Single(Spanned<Expr>),
57    /// A payload clause that failed to lower.
58    Partial(PartialNode),
59}
60
61/// `target op value` inside a SET clause.
62#[derive(Clone, Debug, PartialEq)]
63pub struct Assignment {
64    /// The field path being assigned to.
65    pub target: Spanned<Idiom>,
66    /// The assignment operator (`=`, `+=`, ...).
67    pub op: Spanned<AssignOp>,
68    /// The right-hand-side value expression.
69    pub value: Spanned<Expr>,
70}
71
72/// The operator of a `SET` assignment.
73#[derive(Clone, Debug, PartialEq, Eq)]
74pub enum AssignOp {
75    /// `=`
76    Assign,
77    /// `+=`
78    Add,
79    /// `-=`
80    Sub,
81    /// `+?=` (add-if-missing)
82    Extend,
83    /// Any other operator, kept as raw text rather than guessed.
84    Other(String),
85}
86
87/// `ORDER BY` — one or more sort keys.
88#[derive(Clone, Debug, PartialEq)]
89pub struct OrderClause {
90    /// The sort keys, in precedence order.
91    pub keys: Vec<OrderKey>,
92}
93
94/// One `ORDER BY` key and its direction.
95#[derive(Clone, Debug, PartialEq)]
96pub struct OrderKey {
97    /// The key expression to sort on.
98    pub expr: Spanned<Expr>,
99    /// `DESC` — descending order, otherwise ascending.
100    pub descending: bool,
101}
102
103/// `GROUP BY <keys>` / `GROUP ALL`.
104#[derive(Clone, Debug, PartialEq)]
105pub struct GroupClause {
106    /// `GROUP ALL` (aggregate to a single row) vs `GROUP BY <keys>`.
107    pub all: bool,
108    /// The grouping keys (empty for `GROUP ALL`).
109    pub keys: Vec<Spanned<Idiom>>,
110}