use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
pub struct Location {
pub line: usize,
pub column: usize,
pub offset: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Document {
pub statement: Statement,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Statement {
Query(Query),
Select(SelectStatement),
Call(CallStatement),
CatalogStatement(CatalogStatement),
DataStatement(DataStatement),
SessionStatement(SessionStatement),
TransactionStatement(TransactionStatement),
IndexStatement(IndexStatement),
Declare(DeclareStatement),
Let(LetStatement),
Next(NextStatement),
AtLocation(AtLocationStatement),
ProcedureBody(ProcedureBodyStatement),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SelectStatement {
pub distinct: DistinctQualifier,
pub return_items: SelectItems,
pub from_clause: Option<FromClause>,
pub where_clause: Option<WhereClause>,
pub group_clause: Option<GroupClause>,
pub having_clause: Option<HavingClause>,
pub order_clause: Option<OrderClause>,
pub limit_clause: Option<LimitClause>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum SelectItems {
Wildcard {
location: Location,
},
Explicit {
items: Vec<ReturnItem>,
location: Location,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FromClause {
pub graph_expressions: Vec<FromGraphExpression>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FromGraphExpression {
pub graph_expression: GraphExpression,
pub match_statement: Option<MatchClause>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CallStatement {
pub procedure_name: String,
pub arguments: Vec<Expression>,
pub yield_clause: Option<YieldClause>,
pub where_clause: Option<WhereClause>, pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct YieldClause {
pub items: Vec<YieldItem>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct YieldItem {
pub column_name: String,
pub alias: Option<String>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Query {
Basic(BasicQuery),
SetOperation(SetOperation),
Limited {
query: Box<Query>,
order_clause: Option<OrderClause>,
limit_clause: Option<LimitClause>,
},
WithQuery(WithQuery),
MutationPipeline(MutationPipeline),
Let(LetStatement),
For(ForStatement),
Filter(FilterStatement),
Return(ReturnQuery),
Unwind(UnwindStatement),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WithQuery {
pub segments: Vec<QuerySegment>,
pub final_return: ReturnClause,
pub group_clause: Option<GroupClause>,
pub having_clause: Option<HavingClause>,
pub order_clause: Option<OrderClause>,
pub limit_clause: Option<LimitClause>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MutationPipeline {
pub segments: Vec<QuerySegment>,
pub final_mutation: FinalMutation,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum FinalMutation {
Remove(Vec<RemoveItem>),
Set(Vec<SetItem>),
Delete {
expressions: Vec<Expression>,
detach: bool,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct QuerySegment {
pub match_clause: MatchClause,
pub where_clause: Option<WhereClause>,
pub with_clause: Option<WithClause>,
pub unwind_clause: Option<UnwindClause>,
pub post_unwind_where: Option<WhereClause>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BasicQuery {
pub match_clause: MatchClause,
pub where_clause: Option<WhereClause>,
pub return_clause: ReturnClause,
pub group_clause: Option<GroupClause>,
pub having_clause: Option<HavingClause>,
pub order_clause: Option<OrderClause>,
pub limit_clause: Option<LimitClause>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ReturnQuery {
pub return_clause: ReturnClause,
pub group_clause: Option<GroupClause>,
pub having_clause: Option<HavingClause>,
pub order_clause: Option<OrderClause>,
pub limit_clause: Option<LimitClause>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum SetOperationType {
Union,
UnionAll,
Intersect,
IntersectAll,
Except,
ExceptAll,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SetOperation {
pub left: Box<Query>,
pub operation: SetOperationType,
pub right: Box<Query>,
pub limit_clause: Option<LimitClause>,
pub order_clause: Option<OrderClause>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LetStatement {
pub variable_definitions: Vec<VariableDefinition>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VariableDefinition {
pub variable_name: String,
pub expression: Expression,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ForStatement {
pub variable: String,
pub alias: Option<String>,
pub expression: Expression,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FilterStatement {
pub where_clause: WhereClause,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UnwindStatement {
pub expression: Expression,
pub variable: String,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MatchClause {
pub patterns: Vec<PathPattern>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum PathType {
Walk,
Trail,
SimplePath,
AcyclicPath,
}
impl Default for PathType {
fn default() -> Self {
PathType::Walk }
}
impl PathType {
pub fn allows_repeated_vertices(&self) -> bool {
matches!(self, PathType::Walk | PathType::Trail)
}
pub fn allows_repeated_edges(&self) -> bool {
matches!(self, PathType::Walk)
}
pub fn as_str(&self) -> &'static str {
match self {
PathType::Walk => "WALK",
PathType::Trail => "TRAIL",
PathType::SimplePath => "SIMPLE PATH",
PathType::AcyclicPath => "ACYCLIC PATH",
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PathPattern {
pub assignment: Option<String>, pub path_type: Option<PathType>, pub elements: Vec<PatternElement>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum PatternElement {
Node(Node),
Edge(Edge),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Node {
pub identifier: Option<String>,
pub labels: Vec<String>,
pub properties: Option<PropertyMap>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Edge {
pub identifier: Option<String>,
pub labels: Vec<String>,
pub properties: Option<PropertyMap>,
pub direction: EdgeDirection,
pub quantifier: Option<PathQuantifier>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum EdgeDirection {
Outgoing, Incoming, Both, Undirected, }
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum PathQuantifier {
Optional,
Exact(u32),
Range { min: u32, max: u32 },
AtLeast(u32),
AtMost(u32),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PropertyMap {
pub properties: Vec<Property>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Property {
pub key: String,
pub value: Expression,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WhereClause {
pub condition: Expression,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum DistinctQualifier {
None, Distinct, All, }
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ReturnClause {
pub distinct: DistinctQualifier,
pub items: Vec<ReturnItem>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ReturnItem {
pub expression: Expression,
pub alias: Option<String>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WithClause {
pub distinct: DistinctQualifier,
pub items: Vec<WithItem>,
pub where_clause: Option<WhereClause>,
pub order_clause: Option<OrderClause>,
pub limit_clause: Option<LimitClause>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WithItem {
pub expression: Expression,
pub alias: Option<String>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UnwindClause {
pub expression: Expression,
pub variable: String,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OrderClause {
pub items: Vec<OrderItem>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OrderItem {
pub expression: Expression,
pub direction: OrderDirection,
pub nulls_ordering: Option<NullsOrdering>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum OrderDirection {
Ascending,
Descending,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum NullsOrdering {
First,
Last,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LimitClause {
pub count: usize,
pub offset: Option<usize>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GroupClause {
pub expressions: Vec<Expression>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HavingClause {
pub condition: Expression,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Expression {
Binary(BinaryExpression),
Unary(UnaryExpression),
FunctionCall(FunctionCall),
PropertyAccess(PropertyAccess),
Variable(Variable),
Parameter(Parameter),
Literal(Literal),
Case(CaseExpression),
PathConstructor(PathConstructor),
Cast(CastExpression),
Subquery(SubqueryExpression),
ExistsSubquery(ExistsSubqueryExpression),
NotExistsSubquery(NotExistsSubqueryExpression),
InSubquery(InSubqueryExpression),
NotInSubquery(NotInSubqueryExpression),
QuantifiedComparison(QuantifiedComparisonExpression),
IsPredicate(IsPredicateExpression),
Pattern(PatternExpression),
ArrayIndex(ArrayIndexExpression),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BinaryExpression {
pub left: Box<Expression>,
pub operator: Operator,
pub right: Box<Expression>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UnaryExpression {
pub operator: Operator,
pub expression: Box<Expression>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FunctionCall {
pub name: String,
pub distinct: DistinctQualifier,
pub arguments: Vec<Expression>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PropertyAccess {
pub object: String,
pub property: String,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Variable {
pub name: String,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Parameter {
pub name: String,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum Operator {
Plus,
Minus,
Star,
Slash,
Percent,
Caret,
Equal,
NotEqual,
LessThan,
LessEqual,
GreaterThan,
GreaterEqual,
Regex,
And,
Or,
Not,
Xor,
In,
NotIn,
Contains,
Starts,
Ends,
Exists,
Like,
Matches, FuzzyEqual, Concat,
Within,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Literal {
String(String),
Integer(i64),
Float(f64),
Boolean(bool),
Null,
DateTime(String),
Duration(String),
TimeWindow(String),
Vector(Vec<f64>),
List(Vec<Literal>),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum CatalogStatement {
CreateSchema(CreateSchemaStatement),
DropSchema(DropSchemaStatement),
CreateGraph(CreateGraphStatement),
DropGraph(DropGraphStatement),
TruncateGraph(TruncateGraphStatement),
ClearGraph(ClearGraphStatement),
CreateGraphType(CreateGraphTypeStatement),
DropGraphType(DropGraphTypeStatement),
AlterGraphType(AlterGraphTypeStatement),
CreateUser(CreateUserStatement),
DropUser(DropUserStatement),
CreateRole(CreateRoleStatement),
DropRole(DropRoleStatement),
GrantRole(GrantRoleStatement),
RevokeRole(RevokeRoleStatement),
CreateProcedure(CreateProcedureStatement),
DropProcedure(DropProcedureStatement),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CreateSchemaStatement {
pub schema_path: CatalogPath,
pub if_not_exists: bool,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DropSchemaStatement {
pub schema_path: CatalogPath,
pub if_exists: bool,
pub cascade: bool,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CreateGraphStatement {
pub graph_path: CatalogPath,
pub graph_type_spec: Option<GraphTypeSpec>,
pub if_not_exists: bool,
pub or_replace: bool,
pub as_query: Option<Box<Query>>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DropGraphStatement {
pub graph_path: CatalogPath,
pub if_exists: bool,
pub cascade: bool,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TruncateGraphStatement {
pub graph_path: CatalogPath,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ClearGraphStatement {
pub graph_path: Option<CatalogPath>, pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CreateGraphTypeStatement {
pub graph_type_path: CatalogPath,
pub copy_of: Option<CatalogPath>,
pub graph_type_spec: GraphTypeSpec,
pub if_not_exists: bool,
pub or_replace: bool,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DropGraphTypeStatement {
pub graph_type_path: CatalogPath,
pub if_exists: bool,
pub cascade: bool,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AlterGraphTypeStatement {
pub name: String,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CatalogPath {
pub segments: Vec<String>,
pub location: Location,
}
impl CatalogPath {
pub fn new(segments: Vec<String>, location: Location) -> Self {
Self { segments, location }
}
pub fn to_string(&self) -> String {
format!("/{}", self.segments.join("/"))
}
pub fn name(&self) -> Option<&String> {
self.segments.last()
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct GraphTypeSpec {
pub vertex_types: Vec<VertexTypeSpec>,
pub edge_types: Vec<EdgeTypeSpec>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct VertexTypeSpec {
pub identifier: Option<String>,
pub labels: Option<LabelExpression>,
pub properties: Option<PropertyTypeList>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct EdgeTypeSpec {
pub identifier: Option<String>,
pub labels: Option<LabelExpression>,
pub properties: Option<PropertyTypeList>,
pub source_vertex: Option<String>,
pub destination_vertex: Option<String>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct LabelExpression {
pub terms: Vec<LabelTerm>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct LabelTerm {
pub factors: Vec<LabelFactor>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum LabelFactor {
Identifier(String),
Wildcard, Parenthesized(Box<LabelExpression>),
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct PropertyTypeList {
pub properties: Vec<PropertyTypeDecl>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct PropertyTypeDecl {
pub name: String,
pub type_spec: TypeSpec,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum TypeSpec {
Boolean,
String {
max_length: Option<usize>,
},
Bytes {
max_length: Option<usize>,
},
Decimal {
precision: Option<u8>,
scale: Option<u8>,
},
Integer,
BigInt,
SmallInt,
Int128,
Int256,
Float {
precision: Option<u8>,
},
Float32, Real,
Double,
Vector {
dimension: Option<usize>,
}, Date,
Time {
precision: Option<u8>,
with_timezone: bool,
},
Timestamp {
precision: Option<u8>,
with_timezone: bool,
},
ZonedTime {
precision: Option<u8>,
},
ZonedDateTime {
precision: Option<u8>,
},
LocalTime {
precision: Option<u8>,
},
LocalDateTime {
precision: Option<u8>,
},
Duration {
precision: Option<u8>,
},
Reference {
target_type: Option<Box<TypeSpec>>,
},
Path,
List {
element_type: Box<TypeSpec>,
max_length: Option<usize>,
},
Record,
Graph {
graph_type_spec: Option<Box<GraphTypeSpec>>,
},
BindingTable,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum DataStatement {
Insert(InsertStatement),
MatchInsert(MatchInsertStatement),
Set(SetStatement),
MatchSet(MatchSetStatement),
Remove(RemoveStatement),
MatchRemove(MatchRemoveStatement),
Delete(DeleteStatement),
MatchDelete(MatchDeleteStatement),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InsertStatement {
pub graph_patterns: Vec<PathPattern>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MatchInsertStatement {
pub match_clause: MatchClause,
pub with_clause: Option<WithClause>,
pub where_clause: Option<WhereClause>,
pub insert_graph_patterns: Vec<PathPattern>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SetStatement {
pub items: Vec<SetItem>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum SetItem {
PropertyAssignment {
property: PropertyAccess,
value: Expression,
},
VariableAssignment {
variable: String,
value: Expression,
},
LabelAssignment {
variable: String,
labels: LabelExpression,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RemoveStatement {
pub items: Vec<RemoveItem>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum RemoveItem {
Property(PropertyAccess),
Label {
variable: String,
labels: LabelExpression,
},
Variable(String),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DeleteStatement {
pub expressions: Vec<Expression>,
pub detach: bool,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MatchSetStatement {
pub match_clause: MatchClause,
pub with_clause: Option<WithClause>,
pub where_clause: Option<WhereClause>,
pub items: Vec<SetItem>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MatchRemoveStatement {
pub match_clause: MatchClause,
pub with_clause: Option<WithClause>,
pub where_clause: Option<WhereClause>,
pub items: Vec<RemoveItem>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MatchDeleteStatement {
pub match_clause: MatchClause,
pub with_clause: Option<WithClause>,
pub where_clause: Option<WhereClause>,
pub expressions: Vec<Expression>,
pub detach: bool,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum SessionStatement {
SessionSet(SessionSetStatement),
SessionReset(SessionResetStatement),
SessionClose(SessionCloseStatement),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SessionSetStatement {
pub clause: SessionSetClause,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum SessionSetClause {
Schema {
schema_reference: CatalogPath,
},
Graph {
graph_expression: GraphExpression,
},
TimeZone {
time_zone: String,
},
GraphParameter {
parameter: String,
graph_initializer: GraphExpression,
if_not_exists: bool,
},
BindingTableParameter {
parameter: String,
binding_table_initializer: Box<Query>,
if_not_exists: bool,
},
ValueParameter {
parameter: String,
value_initializer: Expression,
if_not_exists: bool,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SessionResetStatement {
pub args: Option<SessionResetArgs>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum SessionResetArgs {
All { target: SessionResetTarget },
Schema,
Graph,
TimeZone,
Parameter { parameter: String },
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum SessionResetTarget {
Parameters,
Characteristics,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SessionCloseStatement {
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DeclareStatement {
pub variable_declarations: Vec<VariableDeclaration>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VariableDeclaration {
pub variable_name: String,
pub type_spec: TypeSpec,
pub initial_value: Option<Expression>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NextStatement {
pub target_statement: Option<Box<Statement>>,
pub yield_clause: Option<YieldClause>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ProcedureBodyStatement {
pub variable_definitions: Vec<DeclareStatement>,
pub initial_statement: Box<Statement>,
pub chained_statements: Vec<ChainedStatement>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ChainedStatement {
pub yield_clause: Option<YieldClause>,
pub statement: Box<Statement>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AtLocationStatement {
pub location_path: CatalogPath,
pub statements: Vec<Statement>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum GraphExpression {
Reference(CatalogPath),
Union {
left: Box<GraphExpression>,
right: Box<GraphExpression>,
all: bool,
},
CurrentGraph,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CreateUserStatement {
pub username: String,
pub password: Option<String>, pub roles: Vec<String>,
pub if_not_exists: bool,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DropUserStatement {
pub username: String,
pub if_exists: bool,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CreateRoleStatement {
pub role_name: String,
pub description: Option<String>,
pub permissions: Vec<PermissionSpec>,
pub if_not_exists: bool,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DropRoleStatement {
pub role_name: String,
pub if_exists: bool,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GrantRoleStatement {
pub role_name: String,
pub username: String,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RevokeRoleStatement {
pub role_name: String,
pub username: String,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PermissionSpec {
pub resource_type: String,
pub resource_name: Option<String>,
pub action: String,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CreateProcedureStatement {
pub procedure_name: String,
pub parameters: Vec<ProcedureParameter>,
pub procedure_body: ProcedureBodyStatement,
pub or_replace: bool,
pub if_not_exists: bool,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DropProcedureStatement {
pub procedure_name: String,
pub if_exists: bool,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ProcedureParameter {
pub name: String,
pub type_spec: TypeSpec,
pub default_value: Option<Expression>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CaseExpression {
pub case_type: CaseType,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PathConstructor {
pub elements: Vec<Expression>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CastExpression {
pub expression: Box<Expression>,
pub target_type: TypeSpec,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SubqueryExpression {
pub query: Box<Query>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ExistsSubqueryExpression {
pub query: Box<Query>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NotExistsSubqueryExpression {
pub query: Box<Query>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InSubqueryExpression {
pub expression: Box<Expression>,
pub query: Box<Query>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NotInSubqueryExpression {
pub expression: Box<Expression>,
pub query: Box<Query>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum CaseType {
Simple(SimpleCaseExpression),
Searched(SearchedCaseExpression),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SimpleCaseExpression {
pub test_expression: Box<Expression>,
pub when_branches: Vec<SimpleWhenBranch>,
pub else_expression: Option<Box<Expression>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SimpleWhenBranch {
pub when_values: Vec<Expression>, pub then_expression: Box<Expression>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SearchedCaseExpression {
pub when_branches: Vec<SearchedWhenBranch>,
pub else_expression: Option<Box<Expression>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SearchedWhenBranch {
pub condition: Box<Expression>,
pub then_expression: Box<Expression>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Quantifier {
All,
Any,
Some,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct QuantifiedComparisonExpression {
pub left: Box<Expression>,
pub operator: Operator,
pub quantifier: Quantifier,
pub subquery: Box<Expression>,
pub location: Location,
}
impl std::fmt::Display for TypeSpec {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
TypeSpec::Boolean => write!(f, "BOOLEAN"),
TypeSpec::String { max_length } => match max_length {
Some(len) => write!(f, "STRING({})", len),
None => write!(f, "STRING"),
},
TypeSpec::Bytes { max_length } => match max_length {
Some(len) => write!(f, "BYTES({})", len),
None => write!(f, "BYTES"),
},
TypeSpec::Decimal { precision, scale } => match (precision, scale) {
(Some(p), Some(s)) => write!(f, "DECIMAL({},{})", p, s),
(Some(p), None) => write!(f, "DECIMAL({})", p),
_ => write!(f, "DECIMAL"),
},
TypeSpec::Integer => write!(f, "INTEGER"),
TypeSpec::BigInt => write!(f, "BIGINT"),
TypeSpec::SmallInt => write!(f, "SMALLINT"),
TypeSpec::Int128 => write!(f, "INT128"),
TypeSpec::Int256 => write!(f, "INT256"),
TypeSpec::Float { precision } => match precision {
Some(p) => write!(f, "FLOAT({})", p),
None => write!(f, "FLOAT"),
},
TypeSpec::Float32 => write!(f, "FLOAT32"),
TypeSpec::Real => write!(f, "REAL"),
TypeSpec::Double => write!(f, "DOUBLE"),
TypeSpec::Vector { dimension } => match dimension {
Some(d) => write!(f, "VECTOR[{}]", d),
None => write!(f, "VECTOR"),
},
TypeSpec::Date => write!(f, "DATE"),
TypeSpec::Time {
precision,
with_timezone,
} => {
let base = match precision {
Some(p) => format!("TIME({})", p),
None => "TIME".to_string(),
};
if *with_timezone {
write!(f, "{} WITH TIME ZONE", base)
} else {
write!(f, "{}", base)
}
}
TypeSpec::Timestamp {
precision,
with_timezone,
} => {
let base = match precision {
Some(p) => format!("TIMESTAMP({})", p),
None => "TIMESTAMP".to_string(),
};
if *with_timezone {
write!(f, "{} WITH TIME ZONE", base)
} else {
write!(f, "{}", base)
}
}
TypeSpec::ZonedTime { precision } => match precision {
Some(p) => write!(f, "TIME({}) WITH TIME ZONE", p),
None => write!(f, "TIME WITH TIME ZONE"),
},
TypeSpec::ZonedDateTime { precision } => match precision {
Some(p) => write!(f, "TIMESTAMP({}) WITH TIME ZONE", p),
None => write!(f, "TIMESTAMP WITH TIME ZONE"),
},
TypeSpec::LocalTime { precision } => match precision {
Some(p) => write!(f, "TIME({})", p),
None => write!(f, "TIME"),
},
TypeSpec::LocalDateTime { precision } => match precision {
Some(p) => write!(f, "TIMESTAMP({})", p),
None => write!(f, "TIMESTAMP"),
},
TypeSpec::Duration { precision } => match precision {
Some(p) => write!(f, "DURATION({})", p),
None => write!(f, "DURATION"),
},
TypeSpec::Reference { target_type } => match target_type {
Some(t) => write!(f, "REF({})", t),
None => write!(f, "REF"),
},
TypeSpec::Path => write!(f, "PATH"),
TypeSpec::List {
element_type,
max_length,
} => match max_length {
Some(len) => write!(f, "{}[{}]", element_type, len),
None => write!(f, "{}[]", element_type),
},
TypeSpec::Record => write!(f, "RECORD"),
TypeSpec::Graph { .. } => write!(f, "GRAPH"),
TypeSpec::BindingTable => write!(f, "BINDING_TABLE"),
}
}
}
impl TypeSpec {
pub fn is_nullable(&self) -> bool {
match self {
TypeSpec::Reference { target_type } => target_type.is_none(),
TypeSpec::List { .. } => false, _ => false, }
}
pub fn is_scalar(&self) -> bool {
matches!(
self,
TypeSpec::Boolean
| TypeSpec::String { .. }
| TypeSpec::Bytes { .. }
| TypeSpec::Decimal { .. }
| TypeSpec::Integer
| TypeSpec::BigInt
| TypeSpec::SmallInt
| TypeSpec::Int128
| TypeSpec::Int256
| TypeSpec::Float { .. }
| TypeSpec::Real
| TypeSpec::Double
| TypeSpec::Date
| TypeSpec::Time { .. }
| TypeSpec::Timestamp { .. }
| TypeSpec::ZonedTime { .. }
| TypeSpec::ZonedDateTime { .. }
| TypeSpec::LocalTime { .. }
| TypeSpec::LocalDateTime { .. }
| TypeSpec::Duration { .. }
)
}
pub fn is_collection(&self) -> bool {
matches!(self, TypeSpec::List { .. })
}
pub fn is_temporal(&self) -> bool {
matches!(
self,
TypeSpec::Date
| TypeSpec::Time { .. }
| TypeSpec::Timestamp { .. }
| TypeSpec::ZonedTime { .. }
| TypeSpec::ZonedDateTime { .. }
| TypeSpec::LocalTime { .. }
| TypeSpec::LocalDateTime { .. }
)
}
pub fn is_numeric(&self) -> bool {
matches!(
self,
TypeSpec::Decimal { .. }
| TypeSpec::Integer
| TypeSpec::BigInt
| TypeSpec::SmallInt
| TypeSpec::Int128
| TypeSpec::Int256
| TypeSpec::Float { .. }
| TypeSpec::Real
| TypeSpec::Double
)
}
pub fn is_exact_numeric(&self) -> bool {
matches!(
self,
TypeSpec::Integer
| TypeSpec::BigInt
| TypeSpec::SmallInt
| TypeSpec::Int128
| TypeSpec::Int256
| TypeSpec::Decimal { .. }
)
}
pub fn is_approximate_numeric(&self) -> bool {
matches!(
self,
TypeSpec::Float { .. } | TypeSpec::Real | TypeSpec::Double
)
}
pub fn element_type(&self) -> Option<&TypeSpec> {
match self {
TypeSpec::List { element_type, .. } => Some(element_type),
_ => None,
}
}
pub fn has_timezone(&self) -> bool {
match self {
TypeSpec::Time { with_timezone, .. } => *with_timezone,
TypeSpec::Timestamp { with_timezone, .. } => *with_timezone,
TypeSpec::ZonedTime { .. } | TypeSpec::ZonedDateTime { .. } => true,
TypeSpec::LocalTime { .. } | TypeSpec::LocalDateTime { .. } => false,
TypeSpec::Date => false,
_ => false,
}
}
pub fn has_time_component(&self) -> bool {
match self {
TypeSpec::Date => false,
TypeSpec::Time { .. }
| TypeSpec::Timestamp { .. }
| TypeSpec::ZonedTime { .. }
| TypeSpec::ZonedDateTime { .. }
| TypeSpec::LocalTime { .. }
| TypeSpec::LocalDateTime { .. } => true,
_ => false,
}
}
pub fn has_date_component(&self) -> bool {
match self {
TypeSpec::Date
| TypeSpec::Timestamp { .. }
| TypeSpec::ZonedDateTime { .. }
| TypeSpec::LocalDateTime { .. } => true,
TypeSpec::Time { .. } | TypeSpec::ZonedTime { .. } | TypeSpec::LocalTime { .. } => {
false
}
_ => false,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct IsPredicateExpression {
pub subject: Box<Expression>,
pub predicate_type: IsPredicateType,
pub negated: bool,
pub target: Option<Box<Expression>>, pub type_spec: Option<TypeSpec>, pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ArrayIndexExpression {
pub array: Box<Expression>,
pub index: Box<Expression>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum IsPredicateType {
Null,
True,
False,
Unknown,
Normalized,
Directed,
Source,
Destination,
Typed,
Label(LabelExpression),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PatternExpression {
pub pattern: PathPattern,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum TransactionStatement {
StartTransaction(StartTransactionStatement),
Commit(CommitStatement),
Rollback(RollbackStatement),
SetTransactionCharacteristics(SetTransactionCharacteristicsStatement),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StartTransactionStatement {
pub characteristics: Option<TransactionCharacteristics>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CommitStatement {
pub work: bool,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RollbackStatement {
pub work: bool,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SetTransactionCharacteristicsStatement {
pub characteristics: TransactionCharacteristics,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TransactionCharacteristics {
pub isolation_level: Option<IsolationLevel>,
pub access_mode: Option<AccessMode>,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum IsolationLevel {
ReadUncommitted,
ReadCommitted,
RepeatableRead,
Serializable,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum AccessMode {
ReadOnly,
ReadWrite,
}
impl IsolationLevel {
pub fn as_str(&self) -> &'static str {
match self {
IsolationLevel::ReadUncommitted => "READ UNCOMMITTED",
IsolationLevel::ReadCommitted => "READ COMMITTED",
IsolationLevel::RepeatableRead => "REPEATABLE READ",
IsolationLevel::Serializable => "SERIALIZABLE",
}
}
}
impl AccessMode {
pub fn as_str(&self) -> &'static str {
match self {
AccessMode::ReadOnly => "READ ONLY",
AccessMode::ReadWrite => "READ WRITE",
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum IndexStatement {
CreateIndex(CreateIndexStatement),
DropIndex(DropIndexStatement),
AlterIndex(AlterIndexStatement),
OptimizeIndex(OptimizeIndexStatement),
ReindexIndex(ReindexStatement),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CreateIndexStatement {
pub name: String,
pub table: String,
pub columns: Vec<String>,
pub index_type: IndexTypeSpecifier,
pub options: IndexOptions,
pub if_not_exists: bool,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DropIndexStatement {
pub name: String,
pub if_exists: bool,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AlterIndexStatement {
pub name: String,
pub operation: AlterIndexOperation,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OptimizeIndexStatement {
pub name: String,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ReindexStatement {
pub name: String,
pub location: Location,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum AlterIndexOperation {
Rebuild,
SetOption(String, Value),
Optimize,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum IndexTypeSpecifier {
Graph(GraphIndexTypeSpecifier),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum GraphIndexTypeSpecifier {
AdjacencyList,
PathIndex,
ReachabilityIndex,
PatternIndex,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct IndexOptions {
pub parameters: std::collections::HashMap<String, Value>,
pub location: Location,
}
impl Default for IndexOptions {
fn default() -> Self {
Self {
parameters: std::collections::HashMap::new(),
location: Location::default(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum Value {
String(String),
Number(f64),
Integer(i64),
Boolean(bool),
Array(Vec<Value>),
Null,
}