#[derive(Debug, Clone, PartialEq)]
pub enum Literal {
Int(i64),
Float(f64),
String(String),
Bool(bool),
Null,
Param(String),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PropAccess {
pub var: String,
pub prop: String,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CompareOp {
Eq,
Ne,
Lt,
Le,
Gt,
Ge,
StartsWith,
EndsWith,
Contains,
}
#[derive(Debug, Clone, PartialEq)]
pub enum Expr {
And(Box<Expr>, Box<Expr>),
Or(Box<Expr>, Box<Expr>),
Not(Box<Expr>),
Compare(PropAccess, CompareOp, Literal),
PropCompare(PropAccess, CompareOp, PropAccess),
IsNull(PropAccess),
HasLabel(String, String),
VarEq(String, String),
GeneralCompare(ReturnExpr, CompareOp, ReturnExpr),
GeneralIsNull(ReturnExpr),
GeneralBare(ReturnExpr),
Pattern(Pattern),
Exists {
pattern: Box<Pattern>,
where_clause: Option<Box<Expr>>,
},
ExistsSubquery(Box<Statement>),
EdgeNotInSet {
edge_var: String,
edge_set_var: String,
},
}
#[derive(Debug, Clone, PartialEq)]
pub enum ReturnExpr {
Var(String),
Prop(PropAccess),
PropOf(Box<ReturnExpr>, String),
Lit(Literal),
Call {
name: String,
args: Vec<ReturnExpr>,
distinct: bool,
},
CountStar,
Case {
test: Option<Box<ReturnExpr>>,
whens: Vec<(ReturnExpr, ReturnExpr)>,
else_: Option<Box<ReturnExpr>>,
},
Arith(Box<ReturnExpr>, ArithOp, Box<ReturnExpr>),
Neg(Box<ReturnExpr>),
ListLit(Vec<ReturnExpr>),
Index(Box<ReturnExpr>, Box<ReturnExpr>),
Slice(
Box<ReturnExpr>,
Option<Box<ReturnExpr>>,
Option<Box<ReturnExpr>>,
),
ListComp {
var: String,
source: Box<ReturnExpr>,
where_clause: Option<Box<ReturnExpr>>,
project: Option<Box<ReturnExpr>>,
},
Quantifier {
kind: QuantifierKind,
var: String,
source: Box<ReturnExpr>,
where_clause: Option<Box<ReturnExpr>>,
},
MapLit(Vec<(String, ReturnExpr)>),
And(Box<ReturnExpr>, Box<ReturnExpr>),
Or(Box<ReturnExpr>, Box<ReturnExpr>),
Xor(Box<ReturnExpr>, Box<ReturnExpr>),
Not(Box<ReturnExpr>),
Compare(Box<ReturnExpr>, CompareOp, Box<ReturnExpr>),
IsNull(Box<ReturnExpr>),
In(Box<ReturnExpr>, Box<ReturnExpr>),
HasLabel(String, Vec<String>),
PatternPredicate(Pattern),
PatternComprehension {
path_var: Option<String>,
pattern: Box<Pattern>,
where_clause: Option<Box<Expr>>,
projection: Box<ReturnExpr>,
},
ExistsPattern {
pattern: Box<Pattern>,
where_clause: Option<Box<Expr>>,
},
ExistsSubquery(Box<Statement>),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum QuantifierKind {
All,
Any,
None,
Single,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ArithOp {
Add,
Sub,
Mul,
Div,
Mod,
Pow,
}
pub fn is_aggregate_name(name: &str) -> bool {
matches!(
name.to_ascii_lowercase().as_str(),
"count" | "sum" | "avg" | "min" | "max" | "collect" | "percentilecont" | "percentiledisc"
)
}
pub fn is_percentile_name(name: &str) -> bool {
matches!(
name.to_ascii_lowercase().as_str(),
"percentilecont" | "percentiledisc"
)
}
#[derive(Debug, Clone, PartialEq)]
pub struct ReturnItem {
pub expr: ReturnExpr,
pub alias: Option<String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SortDir {
Asc,
Desc,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RelDirection {
Right,
Left,
Either,
}
#[derive(Debug, Clone, PartialEq)]
pub struct NodePattern {
pub var: Option<String>,
pub labels: Vec<String>,
pub props: Vec<(String, ReturnExpr)>,
pub has_explicit_props: bool,
}
#[derive(Debug, Clone, PartialEq)]
pub struct RelPattern {
pub var: Option<String>,
pub rel_types: Vec<String>,
pub props: Vec<(String, ReturnExpr)>,
pub direction: RelDirection,
pub hop_range: Option<(u32, Option<u32>)>,
pub capture_path_segment: bool,
pub rel_list_var: Option<String>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Pattern {
pub start: NodePattern,
pub hops: Vec<(RelPattern, NodePattern)>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum Tail {
Return(Vec<ReturnItem>, bool),
ReturnStar(bool),
Delete(Vec<ReturnExpr>, Option<ReturnTail>),
DetachDelete(Vec<ReturnExpr>, Option<ReturnTail>),
Set(Vec<SetItem>, Option<ReturnTail>),
Remove(Vec<RemoveItem>, Option<ReturnTail>),
Create(Vec<Pattern>, Option<ReturnTail>),
}
#[derive(Debug, Clone, PartialEq)]
pub struct ReturnTail {
pub items: Vec<ReturnItem>,
pub distinct: bool,
}
#[derive(Debug, Clone, PartialEq)]
pub enum SetItem {
Prop(PropAccess, ReturnExpr),
Labels(String, Vec<String>),
MapAssign {
var: String,
value: ReturnExpr,
merge: bool,
},
}
#[derive(Debug, Clone, PartialEq)]
pub enum RemoveItem {
Prop(PropAccess),
Labels(String, Vec<String>),
}
#[derive(Debug, Clone, PartialEq)]
pub enum WithExpr {
And(Box<WithExpr>, Box<WithExpr>),
Or(Box<WithExpr>, Box<WithExpr>),
Not(Box<WithExpr>),
Compare(ReturnExpr, CompareOp, ReturnExpr),
IsNull(ReturnExpr),
Bare(ReturnExpr),
}
#[derive(Debug, Clone, PartialEq)]
pub struct WithClause {
pub items: Vec<ReturnItem>,
pub star: bool,
pub distinct: bool,
pub where_clause: Option<WithExpr>,
pub order_by: Option<Vec<(ReturnExpr, SortDir)>>,
pub skip: Option<ReturnExpr>,
pub limit: Option<ReturnExpr>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct QueryPart {
pub optional: bool,
pub path_var: Option<String>,
pub shortest_path: bool,
pub pattern: Pattern,
pub where_clause: Option<Expr>,
pub with: Option<WithClause>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct UnwindClause {
pub source: UnwindSource,
pub var: String,
pub where_clause: Option<WithExpr>,
pub with: Option<WithClause>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct UnwindSource(pub ReturnExpr);
#[derive(Debug, Clone, PartialEq)]
pub struct MergeClause {
pub pattern: Pattern,
pub path_var: Option<String>,
pub on_create: Vec<SetItem>,
pub on_match: Vec<SetItem>,
pub with: Option<WithClause>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct CallClause {
pub name: String,
pub args: Option<Vec<ReturnExpr>>,
pub with: Option<WithClause>,
pub yield_items: Option<CallYield>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum CallYield {
Star,
Items(Vec<(String, Option<String>)>, Option<Box<Expr>>),
}
#[derive(Debug, Clone, PartialEq)]
pub enum QueryClause {
Match(QueryPart),
Unwind(UnwindClause),
Merge(MergeClause),
With(WithClause),
Set(Vec<SetItem>),
Delete {
items: Vec<ReturnExpr>,
detach: bool,
},
Remove(Vec<RemoveItem>),
Create(Vec<Pattern>),
Call(CallClause),
}
#[derive(Debug, Clone, PartialEq)]
pub enum Statement {
Create(Vec<Pattern>),
CreateIndex {
label: String,
prop: String,
unique: bool,
},
Explain(Box<Statement>),
Match {
clauses: Vec<QueryClause>,
tail: Option<Tail>,
order_by: Option<Vec<(ReturnExpr, SortDir)>>,
skip: Option<Box<ReturnExpr>>,
limit: Option<Box<ReturnExpr>>,
},
Union {
parts: Vec<Statement>,
all: bool,
},
StandaloneCall(Box<CallClause>),
}