|
| 1 | +use crate::ast::{AstNode, Expr, SymbolPrimitive}; |
| 2 | +use partiql_ast_macros::Visit; |
| 3 | +#[cfg(feature = "serde")] |
| 4 | +use serde::{Deserialize, Serialize}; |
| 5 | +use std::num::NonZeroU32; |
| 6 | + |
| 7 | +#[derive(Visit, Clone, Debug, PartialEq)] |
| 8 | +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] |
| 9 | +pub struct GraphTable { |
| 10 | + pub graph_match: AstNode<GraphMatch>, |
| 11 | +} |
| 12 | + |
| 13 | +/// `<expr> MATCH <graph_pattern>` |
| 14 | +#[derive(Visit, Clone, Debug, PartialEq)] |
| 15 | +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] |
| 16 | +pub struct GraphMatch { |
| 17 | + pub expr: Box<Expr>, |
| 18 | + pub pattern: AstNode<GraphPattern>, |
| 19 | + #[visit(skip)] |
| 20 | + pub shape: GraphTableShape, |
| 21 | +} |
| 22 | + |
| 23 | +#[derive(Visit, Clone, Debug, PartialEq)] |
| 24 | +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] |
| 25 | +pub struct GraphPattern { |
| 26 | + #[visit(skip)] |
| 27 | + pub mode: Option<GraphMatchMode>, |
| 28 | + pub patterns: Vec<AstNode<GraphPathPattern>>, |
| 29 | + #[visit(skip)] |
| 30 | + pub keep: Option<GraphPathPrefix>, |
| 31 | + pub where_clause: Option<Box<Expr>>, |
| 32 | +} |
| 33 | + |
| 34 | +#[derive(Clone, Debug, PartialEq, Eq)] |
| 35 | +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] |
| 36 | +pub enum GraphMatchMode { |
| 37 | + DifferentEdges, |
| 38 | + RepeatableElements, |
| 39 | +} |
| 40 | + |
| 41 | +#[derive(Clone, Debug, PartialEq)] |
| 42 | +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] |
| 43 | +pub struct GraphTableShape { |
| 44 | + pub rows: Option<AstNode<GraphTableRows>>, |
| 45 | + pub cols: Option<AstNode<GraphTableColumns>>, |
| 46 | + pub export: Option<AstNode<GraphTableExport>>, |
| 47 | +} |
| 48 | + |
| 49 | +#[derive(Clone, Default, Debug, PartialEq, Eq)] |
| 50 | +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] |
| 51 | +pub enum GraphTableRows { |
| 52 | + #[default] |
| 53 | + OneRowPerMatch, |
| 54 | + OneRowPerVertex { |
| 55 | + v: SymbolPrimitive, |
| 56 | + in_paths: Option<Vec<SymbolPrimitive>>, |
| 57 | + }, |
| 58 | + OneRowPerStep { |
| 59 | + v1: SymbolPrimitive, |
| 60 | + e: SymbolPrimitive, |
| 61 | + v2: SymbolPrimitive, |
| 62 | + in_paths: Option<Vec<SymbolPrimitive>>, |
| 63 | + }, |
| 64 | +} |
| 65 | + |
| 66 | +#[derive(Clone, Debug, PartialEq)] |
| 67 | +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] |
| 68 | +pub struct GraphTableColumns { |
| 69 | + pub columns: Vec<GraphTableColumnDef>, |
| 70 | +} |
| 71 | + |
| 72 | +#[derive(Clone, Debug, PartialEq)] |
| 73 | +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] |
| 74 | +pub enum GraphTableColumnDef { |
| 75 | + Expr(Box<Expr>, Option<SymbolPrimitive>), |
| 76 | + AllProperties(SymbolPrimitive), |
| 77 | +} |
| 78 | + |
| 79 | +#[derive(Clone, Debug, PartialEq, Eq)] |
| 80 | +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] |
| 81 | +pub enum GraphTableExport { |
| 82 | + AllSingletons { |
| 83 | + except: Option<Vec<SymbolPrimitive>>, |
| 84 | + }, |
| 85 | + Singletons { |
| 86 | + exports: Vec<SymbolPrimitive>, |
| 87 | + }, |
| 88 | + NoSingletons, |
| 89 | +} |
| 90 | + |
| 91 | +/// The direction of an edge |
| 92 | +/// | Orientation | Edge pattern | Abbreviation | |
| 93 | +/// |---------------------------+--------------+--------------| |
| 94 | +/// | Pointing left | <−[ spec ]− | <− | |
| 95 | +/// | Undirected | ~[ spec ]~ | ~ | |
| 96 | +/// | Pointing right | −[ spec ]−> | −> | |
| 97 | +/// | Left or undirected | <~[ spec ]~ | <~ | |
| 98 | +/// | Undirected or right | ~[ spec ]~> | ~> | |
| 99 | +/// | Left or right | <−[ spec ]−> | <−> | |
| 100 | +/// | Left, undirected or right | −[ spec ]− | − | |
| 101 | +#[derive(Clone, Debug, PartialEq, Eq)] |
| 102 | +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] |
| 103 | +pub enum GraphMatchDirection { |
| 104 | + Left, |
| 105 | + Undirected, |
| 106 | + Right, |
| 107 | + LeftOrUndirected, |
| 108 | + UndirectedOrRight, |
| 109 | + LeftOrRight, |
| 110 | + LeftOrUndirectedOrRight, |
| 111 | +} |
| 112 | + |
| 113 | +/// A quantifier for graph edges or patterns. (e.g., the `{2,5}` in `MATCH (x)->{2,5}(y)`) |
| 114 | +#[derive(Clone, Debug, PartialEq, Eq)] |
| 115 | +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] |
| 116 | +pub struct GraphMatchQuantifier { |
| 117 | + pub lower: u32, |
| 118 | + pub upper: Option<NonZeroU32>, |
| 119 | +} |
| 120 | + |
| 121 | +/// A path mode |
| 122 | +/// | Keyword | Description |
| 123 | +/// |----------------+-------------- |
| 124 | +/// | WALK | |
| 125 | +/// | TRAIL | No repeated edges. |
| 126 | +/// | ACYCLIC | No repeated nodes. |
| 127 | +/// | SIMPLE | No repeated nodes, except that the first and last nodes may be the same. |
| 128 | +
|
| 129 | +#[derive(Clone, Debug, PartialEq, Eq)] |
| 130 | +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] |
| 131 | +pub enum GraphPathMode { |
| 132 | + Walk, |
| 133 | + Trail, |
| 134 | + Acyclic, |
| 135 | + Simple, |
| 136 | +} |
| 137 | + |
| 138 | +/// A single node in a graph pattern. |
| 139 | +#[derive(Visit, Clone, Debug, PartialEq)] |
| 140 | +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] |
| 141 | +pub struct GraphMatchNode { |
| 142 | + /// the optional element variable of the node match, e.g.: `x` in `MATCH (x)` |
| 143 | + #[visit(skip)] |
| 144 | + pub variable: Option<SymbolPrimitive>, |
| 145 | + /// the optional label(s) to match for the node, e.g.: `Entity` in `MATCH (x:Entity)` |
| 146 | + #[visit(skip)] |
| 147 | + pub label: Option<AstNode<GraphMatchLabel>>, |
| 148 | + /// an optional node where clause, e.g.: `WHERE c.name='Alarm'` in `MATCH (c WHERE c.name='Alarm')` |
| 149 | + pub where_clause: Option<Box<Expr>>, |
| 150 | +} |
| 151 | + |
| 152 | +/// A single edge in a graph pattern. |
| 153 | +#[derive(Visit, Clone, Debug, PartialEq)] |
| 154 | +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] |
| 155 | +pub struct GraphMatchEdge { |
| 156 | + /// edge direction |
| 157 | + #[visit(skip)] |
| 158 | + pub direction: GraphMatchDirection, |
| 159 | + /// an optional quantifier for the edge match |
| 160 | + #[visit(skip)] |
| 161 | + pub quantifier: Option<AstNode<GraphMatchQuantifier>>, |
| 162 | + /// the optional element variable of the edge match, e.g.: `t` in `MATCH −[t]−>` |
| 163 | + #[visit(skip)] |
| 164 | + pub variable: Option<SymbolPrimitive>, |
| 165 | + /// the optional label(s) to match for the edge. e.g.: `Target` in `MATCH −[t:Target]−>` |
| 166 | + #[visit(skip)] |
| 167 | + pub label: Option<AstNode<GraphMatchLabel>>, |
| 168 | + /// an optional edge where clause, e.g.: `WHERE t.capacity>100` in `MATCH −[t:hasSupply WHERE t.capacity>100]−>` |
| 169 | + pub where_clause: Option<Box<Expr>>, |
| 170 | +} |
| 171 | + |
| 172 | +#[derive(Clone, Debug, PartialEq)] |
| 173 | +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] |
| 174 | +pub enum GraphMatchLabel { |
| 175 | + Name(SymbolPrimitive), |
| 176 | + Wildcard, |
| 177 | + Negated(Box<AstNode<GraphMatchLabel>>), |
| 178 | + Conjunction(Vec<AstNode<GraphMatchLabel>>), |
| 179 | + Disjunction(Vec<AstNode<GraphMatchLabel>>), |
| 180 | +} |
| 181 | + |
| 182 | +#[derive(Visit, Clone, Debug, PartialEq)] |
| 183 | +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] |
| 184 | +pub struct GraphPathPattern { |
| 185 | + /// the optional element variable of the pattern, e.g.: `p` in `MATCH p = (a) −[t]−> (b)` |
| 186 | + #[visit(skip)] |
| 187 | + pub variable: Option<SymbolPrimitive>, |
| 188 | + #[visit(skip)] |
| 189 | + pub prefix: Option<GraphPathPrefix>, |
| 190 | + /// the ordered pattern parts |
| 191 | + pub path: AstNode<GraphMatchPathPattern>, |
| 192 | +} |
| 193 | + |
| 194 | +#[derive(Visit, Clone, Debug, PartialEq)] |
| 195 | +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] |
| 196 | +pub struct GraphPathSubPattern { |
| 197 | + /// the optional element variable of the pattern, e.g.: `p` in `MATCH p = (a) −[t]−> (b)` |
| 198 | + #[visit(skip)] |
| 199 | + pub variable: Option<SymbolPrimitive>, |
| 200 | + #[visit(skip)] |
| 201 | + pub mode: Option<GraphPathMode>, |
| 202 | + /// the ordered pattern parts |
| 203 | + pub path: AstNode<GraphMatchPathPattern>, |
| 204 | + /// an optional pattern where e.g.: `WHERE a.name=b.name` in `MATCH [(a)->(b) WHERE a.name=b.name]` |
| 205 | + pub where_clause: Option<Box<Expr>>, |
| 206 | +} |
| 207 | + |
| 208 | +#[derive(Visit, Clone, Debug, PartialEq)] |
| 209 | +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] |
| 210 | +pub enum GraphMatchPathPattern { |
| 211 | + Path(Vec<AstNode<GraphMatchPathPattern>>), |
| 212 | + Union(Vec<AstNode<GraphMatchPathPattern>>), |
| 213 | + Multiset(Vec<AstNode<GraphMatchPathPattern>>), |
| 214 | + |
| 215 | + Questioned(Box<AstNode<GraphMatchPathPattern>>), |
| 216 | + Quantified(GraphMatchPathPatternQuantified), |
| 217 | + |
| 218 | + Sub(Box<AstNode<GraphPathSubPattern>>), |
| 219 | + |
| 220 | + /// A single node in a graph pattern. |
| 221 | + Node(AstNode<GraphMatchNode>), |
| 222 | + |
| 223 | + /// A single edge in a graph pattern. |
| 224 | + Edge(AstNode<GraphMatchEdge>), |
| 225 | + |
| 226 | + #[visit(skip)] |
| 227 | + Simplified(AstNode<GraphMatchSimplified>), |
| 228 | +} |
| 229 | + |
| 230 | +#[derive(Visit, Clone, Debug, PartialEq)] |
| 231 | +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] |
| 232 | +pub struct GraphMatchPathPatternQuantified { |
| 233 | + pub path: Box<AstNode<GraphMatchPathPattern>>, |
| 234 | + #[visit(skip)] |
| 235 | + pub quant: AstNode<GraphMatchQuantifier>, |
| 236 | +} |
| 237 | + |
| 238 | +#[derive(Clone, Debug, PartialEq)] |
| 239 | +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] |
| 240 | +pub struct GraphMatchElement { |
| 241 | + pub variable: Option<SymbolPrimitive>, |
| 242 | + pub label: Option<AstNode<GraphMatchLabel>>, |
| 243 | + pub where_clause: Option<Box<Expr>>, |
| 244 | +} |
| 245 | + |
| 246 | +#[derive(Clone, Debug, PartialEq)] |
| 247 | +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] |
| 248 | +pub struct GraphMatchSimplified { |
| 249 | + pub dir: GraphMatchDirection, |
| 250 | + pub pattern: AstNode<GraphMatchSimplifiedPattern>, |
| 251 | +} |
| 252 | + |
| 253 | +#[derive(Clone, Debug, PartialEq)] |
| 254 | +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] |
| 255 | +pub enum GraphMatchSimplifiedPattern { |
| 256 | + Union(Vec<AstNode<GraphMatchSimplifiedPattern>>), |
| 257 | + Multiset(Vec<AstNode<GraphMatchSimplifiedPattern>>), |
| 258 | + |
| 259 | + Path(Vec<AstNode<GraphMatchSimplifiedPattern>>), |
| 260 | + |
| 261 | + Conjunction(Vec<AstNode<GraphMatchSimplifiedPattern>>), |
| 262 | + |
| 263 | + Questioned(Box<AstNode<GraphMatchSimplifiedPattern>>), |
| 264 | + Quantified( |
| 265 | + Box<AstNode<GraphMatchSimplifiedPattern>>, |
| 266 | + AstNode<GraphMatchQuantifier>, |
| 267 | + ), |
| 268 | + |
| 269 | + /// Direction override |
| 270 | + Direction( |
| 271 | + GraphMatchDirection, |
| 272 | + Box<AstNode<GraphMatchSimplifiedPattern>>, |
| 273 | + ), |
| 274 | + |
| 275 | + Negated(Box<AstNode<GraphMatchSimplifiedPattern>>), |
| 276 | + Label(SymbolPrimitive), |
| 277 | +} |
| 278 | + |
| 279 | +#[derive(Clone, Debug, PartialEq, Eq)] |
| 280 | +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] |
| 281 | +pub enum GraphPathPrefix { |
| 282 | + Mode(GraphPathMode), |
| 283 | + Search(GraphPathSearchPrefix, Option<GraphPathMode>), |
| 284 | +} |
| 285 | + |
| 286 | +/// | Keyword |
| 287 | +/// |------------------ |
| 288 | +/// | ALL |
| 289 | +/// | Any |
| 290 | +/// | ANY k |
| 291 | +/// | ALL SHORTEST |
| 292 | +/// | ANY SHORTEST |
| 293 | +/// | SHORTEST k |
| 294 | +/// | SHORTEST k GROUP |
| 295 | +#[derive(Clone, Debug, PartialEq, Eq)] |
| 296 | +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] |
| 297 | +pub enum GraphPathSearchPrefix { |
| 298 | + All, |
| 299 | + Any, |
| 300 | + AnyK(NonZeroU32), |
| 301 | + AllShortest, |
| 302 | + AnyShortest, |
| 303 | + ShortestK(NonZeroU32), |
| 304 | + ShortestKGroup(Option<NonZeroU32>), |
| 305 | +} |
0 commit comments