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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
//! Graph pattern AST types for MATCH clause (Graph Pattern Matching).
//!
//! This module contains AST types for Cypher-like graph queries in VelesQL.
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use super::ast::{Condition, Value};
/// A MATCH clause for graph pattern matching.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct MatchClause {
/// Graph patterns to match.
pub patterns: Vec<GraphPattern>,
/// Optional WHERE clause.
pub where_clause: Option<Condition>,
/// RETURN clause.
pub return_clause: ReturnClause,
}
/// A graph pattern (path or named path).
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct GraphPattern {
/// Optional path name (for `p = (a)-[*]->(b)`).
pub name: Option<String>,
/// Nodes in the pattern.
pub nodes: Vec<NodePattern>,
/// Relationships between nodes.
pub relationships: Vec<RelationshipPattern>,
}
/// A node pattern in a graph query.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct NodePattern {
/// Optional alias (e.g., `n` in `(n:Person)`).
pub alias: Option<String>,
/// Node labels (e.g., `["Person", "Author"]`).
pub labels: Vec<String>,
/// Node properties for filtering.
pub properties: HashMap<String, Value>,
/// Optional source collection override for cross-collection MATCH.
///
/// When set, this node's data is resolved from the named collection
/// instead of the MATCH query's default collection. Enables patterns like:
/// `MATCH (p:Product@products)-[:STORED_IN]->(inv:Inventory@inventory)`
///
/// When `None`, the node is resolved from the default collection.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub collection: Option<String>,
}
impl NodePattern {
/// Creates a new empty node pattern.
#[must_use]
pub fn new() -> Self {
Self {
alias: None,
labels: Vec::new(),
properties: HashMap::new(),
collection: None,
}
}
/// Sets the alias.
#[must_use]
pub fn with_alias(mut self, alias: impl Into<String>) -> Self {
self.alias = Some(alias.into());
self
}
/// Adds a label.
#[must_use]
pub fn with_label(mut self, label: impl Into<String>) -> Self {
self.labels.push(label.into());
self
}
/// Sets the source collection for cross-collection MATCH.
#[must_use]
pub fn with_collection(mut self, collection: impl Into<String>) -> Self {
self.collection = Some(collection.into());
self
}
}
impl Default for NodePattern {
fn default() -> Self {
Self::new()
}
}
/// A relationship pattern in a graph query.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct RelationshipPattern {
/// Optional alias (e.g., `r` in `-[r:WROTE]->`).
pub alias: Option<String>,
/// Relationship types (e.g., `["WROTE", "CREATED"]` for `[:WROTE|CREATED]`).
pub types: Vec<String>,
/// Direction of the relationship.
pub direction: Direction,
/// Variable length range (e.g., `(1, 3)` for `*1..3`).
pub range: Option<(u32, u32)>,
/// Relationship properties for filtering.
pub properties: HashMap<String, Value>,
}
impl RelationshipPattern {
/// Creates a new relationship pattern with direction.
#[must_use]
pub fn new(direction: Direction) -> Self {
Self {
alias: None,
types: Vec::new(),
direction,
range: None,
properties: HashMap::new(),
}
}
}
/// Direction of a relationship.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[non_exhaustive]
pub enum Direction {
/// Outgoing: `-->`
Outgoing,
/// Incoming: `<--`
Incoming,
/// Both/undirected: `--`
Both,
}
/// RETURN clause for specifying output.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ReturnClause {
/// Items to return.
pub items: Vec<ReturnItem>,
/// Optional ORDER BY.
pub order_by: Option<Vec<OrderByItem>>,
/// Optional LIMIT.
pub limit: Option<u64>,
}
/// A single item in the RETURN clause.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ReturnItem {
/// Expression to return (e.g., `n.name`).
pub expression: String,
/// Optional alias (e.g., `AS name`).
pub alias: Option<String>,
}
/// ORDER BY item.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct OrderByItem {
/// Expression to order by.
pub expression: String,
/// Sort order.
pub descending: bool,
}