Skip to content

Commit 5013749

Browse files
committed
GRAPH_TABLE AST
1 parent 5418a88 commit 5013749

File tree

5 files changed

+692
-403
lines changed

5 files changed

+692
-403
lines changed

partiql-ast/src/ast.rs

Lines changed: 231 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010

1111
use rust_decimal::Decimal as RustDecimal;
1212

13-
use std::fmt;
14-
use std::num::NonZeroU32;
15-
1613
#[cfg(feature = "serde")]
1714
use serde::{Deserialize, Serialize};
15+
use std::fmt;
16+
use std::num::NonZeroU32;
17+
use std::ops::Deref;
1818

1919
use partiql_ast_macros::Visit;
2020
use partiql_common::node::NodeId;
@@ -27,6 +27,14 @@ pub struct AstNode<T> {
2727
pub node: T,
2828
}
2929

30+
impl<T> Deref for AstNode<T> {
31+
type Target = T;
32+
33+
fn deref(&self) -> &T {
34+
&self.node
35+
}
36+
}
37+
3038
#[derive(Visit, Clone, Debug, PartialEq)]
3139
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3240
pub enum Item {
@@ -835,12 +843,102 @@ pub enum JoinSpec {
835843
Natural,
836844
}
837845

846+
// TODO #[derive(Visit, Clone, Debug, PartialEq)]
847+
#[derive(Clone, Debug, PartialEq)]
848+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
849+
pub struct GraphTable {
850+
pub graph_match: AstNode<GraphMatch>,
851+
}
852+
838853
/// `<expr> MATCH <graph_pattern>`
839854
#[derive(Visit, Clone, Debug, PartialEq)]
840855
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
841856
pub struct GraphMatch {
842857
pub expr: Box<Expr>,
843-
pub graph_expr: Box<AstNode<GraphMatchExpr>>,
858+
// TODO remove
859+
#[visit(skip)]
860+
pub pattern: AstNode<GraphPattern>,
861+
// TODO remove
862+
#[visit(skip)]
863+
pub shape: Option<GraphTableShape>,
864+
}
865+
866+
// TODO #[derive(Visit, Clone, Debug, PartialEq)]
867+
#[derive(Clone, Debug, PartialEq)]
868+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
869+
pub struct GraphPattern {
870+
// TODO #[visit(skip)]
871+
pub mode: Option<GraphMatchMode>,
872+
pub patterns: Vec<AstNode<GraphPathPattern>>,
873+
// TODO #[visit(skip)]
874+
pub keep: Option<GraphPathPrefix>,
875+
pub where_clause: Option<Box<Expr>>,
876+
}
877+
878+
#[derive(Clone, Debug, PartialEq, Eq)]
879+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
880+
pub enum GraphMatchMode {
881+
DifferentEdges,
882+
RepeatableElements,
883+
}
884+
885+
/// A graph match clause as defined in GPML
886+
/// See https://arxiv.org/abs/2112.06217
887+
#[derive(Visit, Clone, Debug, PartialEq)]
888+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
889+
pub struct GraphMatchExpr {
890+
#[visit(skip)] // TODO
891+
pub patterns: Vec<AstNode<GraphPathPattern>>,
892+
}
893+
894+
#[derive(Clone, Debug, PartialEq)]
895+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
896+
pub enum GraphTableShape {
897+
Rows(AstNode<GraphTableRows>),
898+
Columns(AstNode<GraphTableColumns>),
899+
Export(AstNode<GraphTableExport>),
900+
}
901+
902+
#[derive(Clone, Default, Debug, PartialEq, Eq)]
903+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
904+
pub enum GraphTableRows {
905+
#[default]
906+
OneRowPerMatch,
907+
OneRowPerVertex {
908+
v: SymbolPrimitive,
909+
in_paths: Option<Vec<SymbolPrimitive>>,
910+
},
911+
OneRowPerStep {
912+
v1: SymbolPrimitive,
913+
e: SymbolPrimitive,
914+
v2: SymbolPrimitive,
915+
in_paths: Option<Vec<SymbolPrimitive>>,
916+
},
917+
}
918+
919+
#[derive(Clone, Debug, PartialEq)]
920+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
921+
pub struct GraphTableColumns {
922+
pub columns: Vec<GraphTableColumnDef>,
923+
}
924+
925+
#[derive(Clone, Debug, PartialEq)]
926+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
927+
pub enum GraphTableColumnDef {
928+
Expr(Box<Expr>, Option<SymbolPrimitive>),
929+
AllProperties(SymbolPrimitive),
930+
}
931+
932+
#[derive(Clone, Debug, PartialEq, Eq)]
933+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
934+
pub enum GraphTableExport {
935+
AllSingletons {
936+
except: Option<Vec<SymbolPrimitive>>,
937+
},
938+
Singletons {
939+
exports: Vec<SymbolPrimitive>,
940+
},
941+
NoSingletons,
844942
}
845943

846944
/// The direction of an edge
@@ -853,9 +951,6 @@ pub struct GraphMatch {
853951
/// | Undirected or right | ~[ spec ]~> | ~> |
854952
/// | Left or right | <−[ spec ]−> | <−> |
855953
/// | Left, undirected or right | −[ spec ]− | − |
856-
///
857-
/// Fig. 5. Table of edge patterns:
858-
/// https://arxiv.org/abs/2112.06217
859954
#[derive(Clone, Debug, PartialEq, Eq)]
860955
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
861956
pub enum GraphMatchDirection {
@@ -868,20 +963,6 @@ pub enum GraphMatchDirection {
868963
LeftOrUndirectedOrRight,
869964
}
870965

871-
/// A part of a graph pattern
872-
#[derive(Clone, Debug, PartialEq)]
873-
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
874-
pub enum GraphMatchPatternPart {
875-
/// A single node in a graph pattern.
876-
Node(AstNode<GraphMatchNode>),
877-
878-
/// A single edge in a graph pattern.
879-
Edge(AstNode<GraphMatchEdge>),
880-
881-
/// A sub-pattern.
882-
Pattern(AstNode<GraphMatchPattern>),
883-
}
884-
885966
/// A quantifier for graph edges or patterns. (e.g., the `{2,5}` in `MATCH (x)->{2,5}(y)`)
886967
#[derive(Clone, Debug, PartialEq, Eq)]
887968
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
@@ -890,18 +971,18 @@ pub struct GraphMatchQuantifier {
890971
pub upper: Option<NonZeroU32>,
891972
}
892973

893-
/// A path restrictor
974+
/// A path mode
894975
/// | Keyword | Description
895976
/// |----------------+--------------
977+
/// | WALK |
896978
/// | TRAIL | No repeated edges.
897979
/// | ACYCLIC | No repeated nodes.
898980
/// | SIMPLE | No repeated nodes, except that the first and last nodes may be the same.
899-
///
900-
/// Fig. 7. Table of restrictors:
901-
/// https://arxiv.org/abs/2112.06217
981+
902982
#[derive(Clone, Debug, PartialEq, Eq)]
903983
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
904-
pub enum GraphMatchRestrictor {
984+
pub enum GraphPathMode {
985+
Walk,
905986
Trail,
906987
Acyclic,
907988
Simple,
@@ -911,14 +992,14 @@ pub enum GraphMatchRestrictor {
911992
#[derive(Visit, Clone, Debug, PartialEq)]
912993
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
913994
pub struct GraphMatchNode {
914-
/// an optional node pre-filter, e.g.: `WHERE c.name='Alarm'` in `MATCH (c WHERE c.name='Alarm')`
915-
pub prefilter: Option<Box<Expr>>,
916995
/// the optional element variable of the node match, e.g.: `x` in `MATCH (x)`
917996
#[visit(skip)]
918997
pub variable: Option<SymbolPrimitive>,
919998
/// the optional label(s) to match for the node, e.g.: `Entity` in `MATCH (x:Entity)`
920999
#[visit(skip)]
921-
pub label: Option<Vec<SymbolPrimitive>>,
1000+
pub label: Option<AstNode<GraphMatchLabel>>,
1001+
/// an optional node where clause, e.g.: `WHERE c.name='Alarm'` in `MATCH (c WHERE c.name='Alarm')`
1002+
pub where_clause: Option<Box<Expr>>,
9221003
}
9231004

9241005
/// A single edge in a graph pattern.
@@ -931,67 +1012,150 @@ pub struct GraphMatchEdge {
9311012
/// an optional quantifier for the edge match
9321013
#[visit(skip)]
9331014
pub quantifier: Option<AstNode<GraphMatchQuantifier>>,
934-
/// an optional edge pre-filter, e.g.: `WHERE t.capacity>100` in `MATCH −[t:hasSupply WHERE t.capacity>100]−>`
935-
pub prefilter: Option<Box<Expr>>,
9361015
/// the optional element variable of the edge match, e.g.: `t` in `MATCH −[t]−>`
9371016
#[visit(skip)]
9381017
pub variable: Option<SymbolPrimitive>,
9391018
/// the optional label(s) to match for the edge. e.g.: `Target` in `MATCH −[t:Target]−>`
9401019
#[visit(skip)]
941-
pub label: Option<Vec<SymbolPrimitive>>,
1020+
pub label: Option<AstNode<GraphMatchLabel>>,
1021+
/// an optional edge where clause, e.g.: `WHERE t.capacity>100` in `MATCH −[t:hasSupply WHERE t.capacity>100]−>`
1022+
pub where_clause: Option<Box<Expr>>,
9421023
}
9431024

944-
/// A single graph match pattern.
945-
#[derive(Visit, Clone, Debug, PartialEq)]
1025+
#[derive(Clone, Debug, PartialEq)]
9461026
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
947-
pub struct GraphMatchPattern {
948-
/// an optional restrictor for the entire pattern match
949-
#[visit(skip)]
950-
pub restrictor: Option<GraphMatchRestrictor>,
951-
/// an optional quantifier for the entire pattern match
952-
#[visit(skip)]
953-
pub quantifier: Option<AstNode<GraphMatchQuantifier>>,
954-
/// an optional pattern pre-filter, e.g.: `WHERE a.name=b.name` in `MATCH [(a)->(b) WHERE a.name=b.name]`
955-
pub prefilter: Option<Box<Expr>>,
1027+
pub enum GraphMatchLabel {
1028+
Name(SymbolPrimitive),
1029+
Wildcard,
1030+
Negated(Box<AstNode<GraphMatchLabel>>),
1031+
Conjunction(Vec<AstNode<GraphMatchLabel>>),
1032+
Disjunction(Vec<AstNode<GraphMatchLabel>>),
1033+
}
1034+
1035+
// TODO #[derive(Visit, Clone, Debug, PartialEq)]
1036+
#[derive(Clone, Debug, PartialEq)]
1037+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1038+
pub struct GraphPathPattern {
9561039
/// the optional element variable of the pattern, e.g.: `p` in `MATCH p = (a) −[t]−> (b)`
957-
#[visit(skip)]
1040+
// TODO #[visit(skip)]
9581041
pub variable: Option<SymbolPrimitive>,
1042+
// TODO #[visit(skip)]
1043+
pub prefix: Option<GraphPathPrefix>,
9591044
/// the ordered pattern parts
960-
#[visit(skip)]
961-
pub parts: Vec<GraphMatchPatternPart>,
1045+
// TODO #[visit(skip)]
1046+
pub path: AstNode<GraphMatchPathPattern>,
1047+
}
1048+
1049+
// TODO #[derive(Visit, Clone, Debug, PartialEq)]
1050+
#[derive(Clone, Debug, PartialEq)]
1051+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1052+
pub struct GraphPathSubPattern {
1053+
/// the optional element variable of the pattern, e.g.: `p` in `MATCH p = (a) −[t]−> (b)`
1054+
// TODO #[visit(skip)]
1055+
pub variable: Option<SymbolPrimitive>,
1056+
// TODO #[visit(skip)]
1057+
pub mode: Option<GraphPathMode>,
1058+
/// the ordered pattern parts
1059+
// TODO #[visit(skip)]
1060+
pub path: AstNode<GraphMatchPathPattern>,
1061+
/// an optional pattern where e.g.: `WHERE a.name=b.name` in `MATCH [(a)->(b) WHERE a.name=b.name]`
1062+
pub where_clause: Option<Box<Expr>>,
1063+
}
1064+
1065+
// TODO #[derive(Visit, Clone, Debug, PartialEq)]
1066+
#[derive(Clone, Debug, PartialEq)]
1067+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1068+
pub enum GraphMatchPathPattern {
1069+
Path(Vec<AstNode<GraphMatchPathPattern>>),
1070+
Union(Vec<AstNode<GraphMatchPathPattern>>),
1071+
Multiset(Vec<AstNode<GraphMatchPathPattern>>),
1072+
1073+
Questioned(Box<AstNode<GraphMatchPathPattern>>),
1074+
Quantified(
1075+
Box<AstNode<GraphMatchPathPattern>>,
1076+
AstNode<GraphMatchQuantifier>,
1077+
),
1078+
1079+
Sub(Box<AstNode<GraphPathSubPattern>>),
1080+
1081+
/// A single node in a graph pattern.
1082+
Node(AstNode<GraphMatchNode>),
1083+
1084+
/// A single edge in a graph pattern.
1085+
Edge(AstNode<GraphMatchEdge>),
1086+
1087+
Simplified(AstNode<GraphMatchSimplified>),
1088+
}
1089+
1090+
#[derive(Clone, Debug, PartialEq)]
1091+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1092+
pub struct GraphMatchElement {
1093+
pub variable: Option<SymbolPrimitive>,
1094+
pub label: Option<AstNode<GraphMatchLabel>>,
1095+
pub where_clause: Option<Box<Expr>>,
1096+
}
1097+
1098+
// TODO #[derive(Visit, Clone, Debug, PartialEq)]
1099+
#[derive(Clone, Debug, PartialEq)]
1100+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1101+
pub struct GraphMatchSimplified {
1102+
pub dir: GraphMatchDirection,
1103+
pub pattern: AstNode<GraphMatchSimplifiedPattern>,
1104+
}
1105+
1106+
// TODO #[derive(Visit, Clone, Debug, PartialEq)]
1107+
#[derive(Clone, Debug, PartialEq)]
1108+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1109+
pub enum GraphMatchSimplifiedPattern {
1110+
Union(Vec<AstNode<GraphMatchSimplifiedPattern>>),
1111+
Multiset(Vec<AstNode<GraphMatchSimplifiedPattern>>),
1112+
1113+
Path(Vec<AstNode<GraphMatchSimplifiedPattern>>),
1114+
1115+
Conjunction(Vec<AstNode<GraphMatchSimplifiedPattern>>),
1116+
1117+
Questioned(Box<AstNode<GraphMatchSimplifiedPattern>>),
1118+
Quantified(
1119+
Box<AstNode<GraphMatchSimplifiedPattern>>,
1120+
AstNode<GraphMatchQuantifier>,
1121+
),
1122+
1123+
/// Direction override
1124+
Direction(
1125+
GraphMatchDirection,
1126+
Box<AstNode<GraphMatchSimplifiedPattern>>,
1127+
),
1128+
1129+
Negated(Box<AstNode<GraphMatchSimplifiedPattern>>),
1130+
Label(SymbolPrimitive),
1131+
}
1132+
1133+
#[derive(Clone, Debug, PartialEq, Eq)]
1134+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1135+
pub enum GraphPathPrefix {
1136+
Mode(GraphPathMode),
1137+
Search(GraphPathSearchPrefix, Option<GraphPathMode>),
9621138
}
9631139

964-
/// A path selector
9651140
/// | Keyword
9661141
/// |------------------
967-
/// | ANY SHORTEST
968-
/// | ALL SHORTEST
969-
/// | ANY
1142+
/// | ALL
1143+
/// | Any
9701144
/// | ANY k
1145+
/// | ALL SHORTEST
1146+
/// | ANY SHORTEST
9711147
/// | SHORTEST k
9721148
/// | SHORTEST k GROUP
973-
///
974-
/// Fig. 8. Table of restrictors:
975-
/// https://arxiv.org/abs/2112.06217
9761149
#[derive(Clone, Debug, PartialEq, Eq)]
9771150
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
978-
pub enum GraphMatchSelector {
979-
AnyShortest,
980-
AllShortest,
1151+
pub enum GraphPathSearchPrefix {
1152+
All,
9811153
Any,
9821154
AnyK(NonZeroU32),
1155+
AllShortest,
1156+
AnyShortest,
9831157
ShortestK(NonZeroU32),
984-
ShortestKGroup(NonZeroU32),
985-
}
986-
987-
/// A graph match clause as defined in GPML
988-
/// See https://arxiv.org/abs/2112.06217
989-
#[derive(Visit, Clone, Debug, PartialEq)]
990-
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
991-
pub struct GraphMatchExpr {
992-
#[visit(skip)]
993-
pub selector: Option<GraphMatchSelector>,
994-
pub patterns: Vec<AstNode<GraphMatchPattern>>,
1158+
ShortestKGroup(Option<NonZeroU32>),
9951159
}
9961160

9971161
/// GROUP BY <`grouping_strategy`> <`group_key`>[, <`group_key`>]... \[AS <symbol>\]

0 commit comments

Comments
 (0)