Skip to main content

linkrs_query/parser/ast/stmt/
dql.rs

1use crate::parser::ast::pattern::Pattern;
2use crate::parser::ast::types::{LimitClause, SampleClause, SkipClause};
3use linkrs_core::types::expr::contextual::ContextualExpression;
4use linkrs_core::types::{EdgeDirection, OrderDirection, Span};
5
6use super::Stmt;
7
8#[derive(Debug, Clone)]
9pub struct QueryStmt {
10    pub span: Span,
11    pub statements: Vec<Stmt>,
12}
13
14impl QueryStmt {
15    pub fn new(statements: Vec<Stmt>, span: Span) -> Self {
16        Self { span, statements }
17    }
18}
19
20impl PartialEq for QueryStmt {
21    fn eq(&self, other: &Self) -> bool {
22        self.span == other.span && self.statements.len() == other.statements.len()
23    }
24}
25
26#[derive(Debug, Clone, PartialEq)]
27pub struct MatchStmt {
28    pub span: Span,
29    pub patterns: Vec<Pattern>,
30    pub join_hint: Option<super::super::hint::JoinHintAst>,
31    pub where_clause: Option<ContextualExpression>,
32    pub return_clause: Option<ReturnClause>,
33    pub order_by: Option<OrderByClause>,
34    pub limit: Option<LimitClause>,
35    pub skip: Option<SkipClause>,
36    pub optional: bool,
37    pub delete_clause: Option<MatchDeleteClause>,
38}
39
40#[derive(Debug, Clone, PartialEq)]
41pub struct MatchDeleteClause {
42    pub span: Span,
43    pub target: MatchDeleteTarget,
44    pub with_edge: bool,
45}
46
47#[derive(Debug, Clone, PartialEq)]
48pub enum MatchDeleteTarget {
49    Vertices(Vec<ContextualExpression>),
50    Edges(Vec<ContextualExpression>),
51    EdgeRefs(
52        Vec<(
53            ContextualExpression,
54            ContextualExpression,
55            Option<ContextualExpression>,
56        )>,
57    ),
58}
59
60#[derive(Debug, Clone, PartialEq)]
61pub struct ReturnClause {
62    pub span: Span,
63    pub items: Vec<ReturnItem>,
64    pub distinct: bool,
65    pub order_by: Option<OrderByClause>,
66    pub limit: Option<LimitClause>,
67    pub skip: Option<SkipClause>,
68    pub sample: Option<SampleClause>,
69    pub having_clause: Option<ContextualExpression>,
70}
71
72#[derive(Debug, Clone, PartialEq)]
73pub enum ReturnItem {
74    Expression {
75        expression: ContextualExpression,
76        alias: Option<String>,
77    },
78}
79
80#[derive(Debug, Clone, PartialEq)]
81pub struct OrderByClause {
82    pub span: Span,
83    pub items: Vec<OrderByItem>,
84}
85
86#[derive(Debug, Clone, PartialEq)]
87pub struct OrderByItem {
88    pub expression: ContextualExpression,
89    pub direction: OrderDirection,
90}
91
92#[derive(Debug, Clone, PartialEq)]
93pub struct GoStmt {
94    pub span: Span,
95    pub steps: Steps,
96    pub from: FromClause,
97    pub over: Option<OverClause>,
98    pub where_clause: Option<ContextualExpression>,
99    pub yield_clause: Option<YieldClause>,
100}
101
102#[derive(Debug, Clone, PartialEq)]
103pub enum Steps {
104    Fixed(usize),
105    Range { min: usize, max: usize },
106    Variable(String),
107}
108
109#[derive(Debug, Clone, PartialEq)]
110pub struct StepClause {
111    pub span: Span,
112    pub steps: Steps,
113}
114
115#[derive(Debug, Clone, PartialEq)]
116pub struct WhereClause {
117    pub span: Span,
118    pub condition: ContextualExpression,
119}
120
121#[derive(Debug, Clone, PartialEq)]
122pub struct FromClause {
123    pub span: Span,
124    pub vertices: Vec<ContextualExpression>,
125}
126
127#[derive(Debug, Clone, PartialEq)]
128pub struct OverClause {
129    pub span: Span,
130    pub edge_types: Vec<String>,
131    pub direction: EdgeDirection,
132}
133
134#[derive(Debug, Clone, PartialEq)]
135pub struct YieldClause {
136    pub span: Span,
137    /// `YIELD DISTINCT`: collapse duplicate projected rows.
138    pub distinct: bool,
139    pub items: Vec<YieldItem>,
140    pub where_clause: Option<ContextualExpression>,
141    pub order_by: Option<OrderByClause>,
142    pub limit: Option<LimitClause>,
143    pub skip: Option<SkipClause>,
144    pub sample: Option<SampleClause>,
145}
146
147#[derive(Debug, Clone, PartialEq)]
148pub struct YieldItem {
149    pub expression: ContextualExpression,
150    pub alias: Option<String>,
151}
152
153#[derive(Debug, Clone, PartialEq)]
154pub struct FetchStmt {
155    pub span: Span,
156    pub target: FetchTarget,
157    pub yield_clause: Option<YieldClause>,
158}
159
160#[derive(Debug, Clone, PartialEq)]
161pub enum FetchTarget {
162    Vertices {
163        tag_name: Option<String>,
164        ids: Vec<ContextualExpression>,
165        properties: Option<Vec<String>>,
166    },
167    Edges {
168        src: ContextualExpression,
169        dst: ContextualExpression,
170        edge_type: String,
171        rank: Option<ContextualExpression>,
172        properties: Option<Vec<String>>,
173    },
174}
175
176#[derive(Debug, Clone, PartialEq)]
177pub struct LookupStmt {
178    pub span: Span,
179    pub target: LookupTarget,
180    pub where_clause: Option<ContextualExpression>,
181    pub yield_clause: Option<YieldClause>,
182}
183
184#[derive(Debug, Clone, PartialEq)]
185pub enum LookupTarget {
186    Tag(String),
187    Edge(String),
188    Unspecified(String),
189}
190
191#[derive(Debug, Clone, PartialEq)]
192pub struct SubgraphStmt {
193    pub span: Span,
194    pub steps: Steps,
195    pub from: FromClause,
196    pub over: Option<OverClause>,
197    pub where_clause: Option<ContextualExpression>,
198    pub yield_clause: Option<YieldClause>,
199    pub with_prop: bool,
200}
201
202#[derive(Debug, Clone, PartialEq)]
203pub struct FindPathStmt {
204    pub span: Span,
205    pub from: FromClause,
206    pub to: ContextualExpression,
207    pub over: Option<OverClause>,
208    pub where_clause: Option<ContextualExpression>,
209    pub shortest: bool,
210    pub max_steps: Option<usize>,
211    pub limit: Option<LimitClause>,
212    pub skip: Option<SkipClause>,
213    pub yield_clause: Option<YieldClause>,
214    pub weight_expression: Option<String>,
215    pub heuristic_expression: Option<String>,
216    /// `WITH LOOP`: self-loop edges may be taken as terminal extensions.
217    pub with_loop: bool,
218    /// `WITH TRAIL`: path edges may not repeat; vertices may.
219    pub with_trail: bool,
220    /// `WITH WALK`: path vertices may repeat.
221    pub with_walk: bool,
222}
223
224#[derive(Debug, Clone, PartialEq)]
225pub struct ReturnStmt {
226    pub span: Span,
227    pub items: Vec<ReturnItem>,
228    pub distinct: bool,
229    pub order_by: Option<OrderByClause>,
230    pub skip: Option<SkipClause>,
231    pub limit: Option<LimitClause>,
232}
233
234#[derive(Debug, Clone, PartialEq)]
235pub struct YieldStmt {
236    pub span: Span,
237    pub items: Vec<YieldItem>,
238    pub where_clause: Option<ContextualExpression>,
239    pub distinct: bool,
240    pub order_by: Option<OrderByClause>,
241    pub skip: Option<SkipClause>,
242    pub limit: Option<LimitClause>,
243    pub sample: Option<SampleClause>,
244}
245
246/// `LOAD FROM <source> [OPTIONS (...)] [RETURN ...]` reading clause.
247#[derive(Debug, Clone, PartialEq)]
248pub struct LoadFromStmt {
249    pub span: Span,
250    pub headers: Vec<LoadHeaderColumn>,
251    pub source: ScanSource,
252    pub options: Vec<LoadOption>,
253    pub return_clause: Option<ReturnClause>,
254}
255
256#[derive(Debug, Clone, PartialEq)]
257pub struct LoadHeaderColumn {
258    pub name: String,
259    pub data_type: Option<String>,
260}
261
262#[derive(Debug, Clone)]
263pub enum ScanSource {
264    File(String),
265    Glob(String),
266    TableFunc {
267        name: String,
268        args: Vec<ContextualExpression>,
269    },
270    Query(Box<Stmt>),
271}
272
273impl PartialEq for ScanSource {
274    fn eq(&self, other: &Self) -> bool {
275        match (self, other) {
276            (ScanSource::File(a), ScanSource::File(b)) => a == b,
277            (ScanSource::Glob(a), ScanSource::Glob(b)) => a == b,
278            (
279                ScanSource::TableFunc { name: a, args: aa },
280                ScanSource::TableFunc { name: b, args: ab },
281            ) => a == b && aa == ab,
282            (ScanSource::Query(a), ScanSource::Query(b)) => format!("{a:?}") == format!("{b:?}"),
283            _ => false,
284        }
285    }
286}
287
288#[derive(Debug, Clone, PartialEq)]
289pub struct LoadOption {
290    pub key: String,
291    pub value: String,
292}
293
294/// `CALL <func>(<args>) [YIELD <cols>]` in-query function call.
295#[derive(Debug, Clone, PartialEq)]
296pub struct InQueryCallStmt {
297    pub span: Span,
298    pub func_name: String,
299    pub args: Vec<ContextualExpression>,
300    pub yield_clause: Option<YieldClause>,
301}