#[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)]
pub enum Expr {
And(Box<Expr>, Box<Expr>),
Or(Box<Expr>, Box<Expr>),
Not(Box<Expr>),
Compare(PropAccess, CompareOp, Literal),
HasLabel(String, String),
VarEq(String, String),
}
#[derive(Debug, Clone)]
pub enum ReturnExpr {
Var(String),
Prop(PropAccess),
Lit(Literal),
Call {
name: String,
args: Vec<ReturnExpr>,
distinct: bool,
},
CountStar,
Case {
test: Option<Box<ReturnExpr>>,
whens: Vec<(ReturnExpr, ReturnExpr)>,
else_: Option<Box<ReturnExpr>>,
},
}
pub fn is_aggregate_name(name: &str) -> bool {
matches!(name.to_ascii_lowercase().as_str(), "count" | "sum" | "avg" | "min" | "max" | "collect")
}
#[derive(Debug, Clone)]
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)]
pub struct NodePattern {
pub var: Option<String>,
pub labels: Vec<String>,
pub props: Vec<(String, Literal)>,
}
#[derive(Debug, Clone)]
pub struct RelPattern {
pub var: Option<String>,
pub rel_type: Option<String>,
pub props: Vec<(String, Literal)>,
pub direction: RelDirection,
pub hop_range: Option<(u32, Option<u32>)>,
}
#[derive(Debug, Clone)]
pub struct Pattern {
pub start: NodePattern,
pub hops: Vec<(RelPattern, NodePattern)>,
}
#[derive(Debug, Clone)]
pub enum Tail {
Return(Vec<ReturnItem>, bool),
Delete(Vec<String>),
DetachDelete(Vec<String>),
Set(Vec<SetItem>),
Remove(Vec<RemoveItem>),
Create(Vec<Pattern>),
}
#[derive(Debug, Clone)]
pub enum SetItem {
Prop(PropAccess, Literal),
Labels(String, Vec<String>),
}
#[derive(Debug, Clone)]
pub enum RemoveItem {
Prop(PropAccess),
Labels(String, Vec<String>),
}
#[derive(Debug, Clone)]
pub enum WithExpr {
And(Box<WithExpr>, Box<WithExpr>),
Or(Box<WithExpr>, Box<WithExpr>),
Not(Box<WithExpr>),
Compare(ReturnExpr, CompareOp, Literal),
}
#[derive(Debug, Clone)]
pub struct WithClause {
pub items: Vec<ReturnItem>,
pub where_clause: Option<WithExpr>,
pub order_by: Option<Vec<(ReturnExpr, SortDir)>>,
pub limit: Option<i64>,
}
#[derive(Debug, Clone)]
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)]
pub struct UnwindClause {
pub source: UnwindSource,
pub var: String,
pub where_clause: Option<WithExpr>,
pub with: Option<WithClause>,
}
#[derive(Debug, Clone)]
pub enum UnwindSource {
Var(String),
List(Vec<Literal>),
}
#[derive(Debug, Clone)]
pub struct MergeClause {
pub pattern: Pattern,
pub on_create: Vec<SetItem>,
pub on_match: Vec<SetItem>,
pub with: Option<WithClause>,
}
#[derive(Debug, Clone)]
pub enum QueryClause {
Match(QueryPart),
Unwind(UnwindClause),
Merge(MergeClause),
}
#[derive(Debug, Clone)]
pub enum Statement {
Create(Vec<Pattern>),
Match {
clauses: Vec<QueryClause>,
tail: Option<Tail>,
order_by: Option<Vec<(ReturnExpr, SortDir)>>,
limit: Option<i64>,
},
}