use std::collections::HashMap;
use crate::types::Span;
#[derive(Debug, Clone, PartialEq)]
pub enum Statement {
Match(MatchStatement),
Create(CreateStatement),
MatchCreate(MatchCreateStatement),
MatchMerge(MatchMergeStatement),
Delete(DeleteStatement),
Set(SetStatement),
Remove(RemoveStatement),
Merge(MergeStatement),
Unwind(UnwindStatement),
Return(ReturnStatement),
MultiClause(MultiClauseStatement),
Explain(Box<Statement>),
Union {
statements: Vec<Statement>,
all: bool,
},
CreateIndex {
label: String,
properties: Vec<String>,
},
DropIndex {
label: String,
properties: Vec<String>,
},
Call {
procedure_name: String,
args: Vec<Expr>,
implicit_args: bool,
yield_items: Option<Vec<(String, Option<String>)>>,
yield_star: bool,
return_clause: Option<ReturnClause>,
order_by: Vec<SortItem>,
skip: Option<Box<Expr>>,
limit: Option<Box<Expr>>,
},
}
#[allow(clippy::large_enum_variant)]
#[derive(Debug, Clone, PartialEq)]
pub enum Clause {
Match {
patterns: Vec<Pattern>,
optional_patterns: Vec<OptionalMatch>,
where_clause: Option<Expr>,
},
Create {
patterns: Vec<Pattern>,
},
Merge {
pattern: Pattern,
on_create: Vec<SetItem>,
on_match: Vec<SetItem>,
},
With(WithClause),
Unwind(UnwindClause),
Set {
items: Vec<SetItem>,
},
Remove {
items: Vec<RemoveItem>,
},
Call {
procedure_name: String,
args: Vec<Expr>,
implicit_args: bool,
yield_items: Option<Vec<(String, Option<String>)>>,
yield_star: bool,
},
Delete {
exprs: Vec<Expr>,
detach: bool,
},
}
#[derive(Debug, Clone, PartialEq)]
pub struct MultiClauseStatement {
pub clauses: Vec<Clause>,
pub return_clause: Option<ReturnClause>,
pub order_by: Vec<SortItem>,
pub skip: Option<Expr>,
pub limit: Option<Expr>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct ReturnStatement {
pub return_clause: ReturnClause,
pub order_by: Vec<SortItem>,
pub skip: Option<Expr>,
pub limit: Option<Expr>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct OptionalMatch {
pub patterns: Vec<Pattern>,
pub where_clause: Option<Expr>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct MatchStatement {
pub patterns: Vec<Pattern>,
pub optional_patterns: Vec<OptionalMatch>,
pub where_clause: Option<Expr>,
pub intermediate_clauses: Vec<IntermediateClause>,
pub return_clause: ReturnClause,
pub order_by: Vec<SortItem>,
pub skip: Option<Expr>,
pub limit: Option<Expr>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct WithClause {
pub items: Vec<ReturnItem>,
pub distinct: bool,
pub order_by: Vec<SortItem>,
pub skip: Option<Expr>,
pub limit: Option<Expr>,
pub where_clause: Option<Expr>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct CreateStatement {
pub patterns: Vec<Pattern>,
pub return_clause: Option<ReturnClause>,
pub order_by: Vec<SortItem>,
pub skip: Option<Expr>,
pub limit: Option<Expr>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct MatchCreateStatement {
pub patterns: Vec<Pattern>,
pub where_clause: Option<Expr>,
pub create_patterns: Vec<Pattern>,
pub return_clause: Option<ReturnClause>,
pub order_by: Vec<SortItem>,
pub skip: Option<Expr>,
pub limit: Option<Expr>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct DeleteStatement {
pub patterns: Vec<Pattern>,
pub optional_patterns: Vec<OptionalMatch>,
pub where_clause: Option<Expr>,
pub detach: bool,
pub exprs: Vec<Expr>,
pub return_clause: Option<ReturnClause>,
pub order_by: Vec<SortItem>,
pub skip: Option<Expr>,
pub limit: Option<Expr>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct SetStatement {
pub patterns: Vec<Pattern>,
pub optional_patterns: Vec<OptionalMatch>,
pub where_clause: Option<Expr>,
pub items: Vec<SetItem>,
pub intermediate_clauses: Vec<IntermediateClause>,
pub return_clause: Option<ReturnClause>,
pub order_by: Vec<SortItem>,
pub skip: Option<Expr>,
pub limit: Option<Expr>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum SetItem {
Property(Assignment),
Label {
variable: String,
labels: Vec<String>,
},
MapOverwrite {
variable: String,
value: Expr,
},
MapMerge {
variable: String,
value: Expr,
},
}
#[derive(Debug, Clone, PartialEq)]
pub struct RemoveStatement {
pub patterns: Vec<Pattern>,
pub optional_patterns: Vec<OptionalMatch>,
pub where_clause: Option<Expr>,
pub items: Vec<RemoveItem>,
pub return_clause: Option<ReturnClause>,
pub order_by: Vec<SortItem>,
pub skip: Option<Expr>,
pub limit: Option<Expr>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum RemoveItem {
Property {
variable: String,
property: String,
},
Label {
variable: String,
labels: Vec<String>,
},
}
#[derive(Debug, Clone, PartialEq)]
pub struct MatchMergeStatement {
pub patterns: Vec<Pattern>,
pub where_clause: Option<Expr>,
pub merge_pattern: Pattern,
pub on_create: Vec<SetItem>,
pub on_match: Vec<SetItem>,
pub return_clause: Option<ReturnClause>,
pub order_by: Vec<SortItem>,
pub skip: Option<Expr>,
pub limit: Option<Expr>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct MergeStatement {
pub pattern: Pattern,
pub on_create: Vec<SetItem>,
pub on_match: Vec<SetItem>,
pub return_clause: Option<ReturnClause>,
pub order_by: Vec<SortItem>,
pub skip: Option<Expr>,
pub limit: Option<Expr>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct UnwindStatement {
pub expr: Expr,
pub alias: String,
pub body: UnwindBody,
}
#[derive(Debug, Clone, PartialEq)]
pub enum UnwindBody {
Return {
where_clause: Option<Expr>,
intermediate_clauses: Vec<IntermediateClause>,
return_clause: ReturnClause,
order_by: Vec<SortItem>,
skip: Option<Expr>,
limit: Option<Expr>,
},
Create {
patterns: Vec<Pattern>,
intermediate_clauses: Vec<IntermediateClause>,
return_clause: Option<ReturnClause>,
order_by: Vec<SortItem>,
skip: Option<Expr>,
limit: Option<Expr>,
},
}
#[allow(clippy::large_enum_variant)]
#[derive(Debug, Clone, PartialEq)]
pub enum IntermediateClause {
With(WithClause),
Unwind(UnwindClause),
Match(IntermediateMatch),
}
#[derive(Debug, Clone, PartialEq)]
pub struct IntermediateMatch {
pub patterns: Vec<Pattern>,
pub optional_patterns: Vec<OptionalMatch>,
pub where_clause: Option<Expr>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct UnwindClause {
pub expr: Expr,
pub alias: String,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ShortestPathMode {
None,
Single,
All,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Pattern {
pub elements: Vec<PatternElement>,
pub path_variable: Option<String>,
pub shortest_path_mode: ShortestPathMode,
}
#[derive(Debug, Clone, PartialEq)]
pub enum PatternElement {
Node(NodePattern),
Relationship(RelPattern),
}
#[derive(Debug, Clone, PartialEq)]
pub struct NodePattern {
pub variable: Option<String>,
pub labels: Vec<String>,
pub properties: HashMap<String, Expr>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct RelPattern {
pub variable: Option<String>,
pub rel_types: Vec<String>,
pub properties: HashMap<String, Expr>,
pub direction: RelDirection,
pub var_length: Option<(u32, u32)>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RelDirection {
Outgoing, Incoming, Undirected, }
#[derive(Debug, Clone, PartialEq)]
pub struct ReturnClause {
pub items: Vec<ReturnItem>,
pub distinct: bool,
}
#[derive(Debug, Clone, PartialEq)]
pub struct ReturnItem {
pub expr: Expr,
pub alias: Option<String>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct SortItem {
pub expr: Expr,
pub descending: bool,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Assignment {
pub variable: String,
pub property: String,
pub value: Expr,
}
#[derive(Debug, Clone)]
pub struct Expr {
pub kind: ExprKind,
pub span: Span,
}
impl PartialEq for Expr {
fn eq(&self, other: &Self) -> bool {
self.kind == other.kind
}
}
impl Expr {
pub fn new(kind: ExprKind, span: Span) -> Self {
Self { kind, span }
}
pub fn synthetic(kind: ExprKind) -> Self {
Self {
kind,
span: Span::synthetic(),
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum ExprKind {
Literal(LiteralValue),
Property(String, String),
Variable(String),
Parameter(String),
BinaryOp {
left: Box<Expr>,
op: BinOp,
right: Box<Expr>,
},
Not(Box<Expr>),
IsNull(Box<Expr>),
IsNotNull(Box<Expr>),
FunctionCall {
name: String,
args: Vec<Expr>,
distinct: bool,
original_text: Option<String>,
},
Case {
operand: Option<Box<Expr>>,
alternatives: Vec<(Box<Expr>, Box<Expr>)>,
default: Option<Box<Expr>>,
},
List(Vec<Expr>),
ListComprehension {
variable: String,
list_expr: Box<Expr>,
filter: Option<Box<Expr>>,
map_expr: Option<Box<Expr>>,
},
PatternComprehension {
path_variable: Option<String>,
pattern: Pattern,
where_clause: Option<Box<Expr>>,
map_expr: Box<Expr>,
},
Exists {
patterns: Vec<Pattern>,
where_clause: Option<Box<Expr>>,
},
ExistsSubquery(Box<Statement>),
MapLiteral(Vec<(String, Expr)>),
Index { expr: Box<Expr>, index: Box<Expr> },
DotAccess { expr: Box<Expr>, key: String },
Slice {
expr: Box<Expr>,
start: Option<Box<Expr>>,
end: Option<Box<Expr>>,
},
Quantifier {
kind: QuantifierKind,
variable: String,
list_expr: Box<Expr>,
predicate: Box<Expr>,
},
HasLabel(String, Vec<String>),
PatternPredicate(Pattern),
Star,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum QuantifierKind {
None,
Single,
Any,
All,
}
#[derive(Debug, Clone, PartialEq)]
pub enum LiteralValue {
Null,
Bool(bool),
I64(i64),
F64(f64),
String(String),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BinOp {
Eq,
Neq,
Lt,
Gt,
Lte,
Gte,
And,
Or,
Xor,
StartsWith,
EndsWith,
Contains,
RegexMatch,
In,
Add,
Sub,
Mul,
Div,
Mod,
Pow,
}