grafeo_adapters/query/gql/ast.rs
1//! GQL Abstract Syntax Tree.
2
3use grafeo_common::utils::error::SourceSpan;
4
5/// A GQL statement.
6#[derive(Debug, Clone)]
7pub enum Statement {
8 /// A query statement (MATCH, RETURN, etc.)
9 Query(QueryStatement),
10 /// A data modification statement (INSERT, DELETE, etc.)
11 DataModification(DataModificationStatement),
12 /// A schema statement (CREATE NODE TYPE, etc.)
13 Schema(SchemaStatement),
14 /// A procedure call statement (CALL ... YIELD).
15 Call(CallStatement),
16 /// A composite query (UNION, EXCEPT, INTERSECT, OTHERWISE).
17 CompositeQuery {
18 /// The left query.
19 left: Box<Statement>,
20 /// The composite operation.
21 op: CompositeOp,
22 /// The right query.
23 right: Box<Statement>,
24 },
25 /// A session or transaction command.
26 SessionCommand(SessionCommand),
27 /// EXPLAIN: returns the query plan without executing.
28 Explain(Box<Statement>),
29 /// PROFILE: executes the query and returns per-operator metrics.
30 Profile(Box<Statement>),
31}
32
33/// GQL transaction isolation level (ISO/IEC 39075 Section 19).
34#[derive(Debug, Clone, Copy, PartialEq, Eq)]
35pub enum TransactionIsolationLevel {
36 /// READ COMMITTED
37 ReadCommitted,
38 /// SNAPSHOT ISOLATION (also matches REPEATABLE READ)
39 SnapshotIsolation,
40 /// SERIALIZABLE
41 Serializable,
42}
43
44/// Target for `SESSION RESET` (ISO/IEC 39075 Section 7.2).
45///
46/// The spec allows resetting schema, graph, time zone, and parameters
47/// independently. `All` resets all characteristics.
48#[derive(Debug, Clone, Copy, PartialEq, Eq)]
49pub enum SessionResetTarget {
50 /// `SESSION RESET [ALL CHARACTERISTICS]`: resets everything.
51 All,
52 /// `SESSION RESET SCHEMA`: resets session schema only (Section 7.2 GR1).
53 Schema,
54 /// `SESSION RESET [PROPERTY] GRAPH`: resets session graph only (Section 7.2 GR2).
55 Graph,
56 /// `SESSION RESET TIME ZONE`: resets time zone (Section 7.2 GR3).
57 TimeZone,
58 /// `SESSION RESET [ALL] PARAMETERS`: resets all session parameters (Section 7.2 GR4).
59 Parameters,
60}
61
62/// Session and transaction commands.
63#[derive(Debug, Clone)]
64pub enum SessionCommand {
65 /// `USE GRAPH name`
66 UseGraph(String),
67 /// `CREATE [PROPERTY] GRAPH name [IF NOT EXISTS] [TYPED type_name] [LIKE source | AS COPY OF source] [OPEN | ANY]`
68 CreateGraph {
69 /// Graph name.
70 name: String,
71 /// IF NOT EXISTS flag.
72 if_not_exists: bool,
73 /// Optional graph type binding.
74 typed: Option<String>,
75 /// LIKE source_graph: clone schema only.
76 like_graph: Option<String>,
77 /// AS COPY OF source_graph: clone schema and data.
78 copy_of: Option<String>,
79 /// ANY GRAPH / OPEN: schema-free graph (no type enforcement).
80 open: bool,
81 },
82 /// `DROP [PROPERTY] GRAPH [IF EXISTS] name`
83 DropGraph {
84 /// Graph name.
85 name: String,
86 /// IF EXISTS flag.
87 if_exists: bool,
88 },
89 /// `SESSION SET GRAPH name`
90 SessionSetGraph(String),
91 /// `SESSION SET SCHEMA name` (ISO/IEC 39075 Section 7.1 GR1: independent from graph)
92 SessionSetSchema(String),
93 /// `SESSION SET TIME ZONE 'tz'`
94 SessionSetTimeZone(String),
95 /// `SESSION SET PARAMETER $name = value`
96 SessionSetParameter(String, Expression),
97 /// `SESSION RESET [ALL | SCHEMA | GRAPH | TIME ZONE | PARAMETER]`
98 /// (ISO/IEC 39075 Section 7.2: schema and graph can be reset independently)
99 SessionReset(SessionResetTarget),
100 /// `SESSION CLOSE`
101 SessionClose,
102 /// `START TRANSACTION [READ ONLY | READ WRITE] [ISOLATION LEVEL <level>]`
103 StartTransaction {
104 /// Whether the transaction is read-only (default: false = read-write).
105 read_only: bool,
106 /// Optional isolation level override.
107 isolation_level: Option<TransactionIsolationLevel>,
108 },
109 /// `COMMIT`
110 Commit,
111 /// `ROLLBACK`
112 Rollback,
113 /// `SAVEPOINT name`
114 Savepoint(String),
115 /// `ROLLBACK TO SAVEPOINT name`
116 RollbackToSavepoint(String),
117 /// `RELEASE SAVEPOINT name`
118 ReleaseSavepoint(String),
119}
120
121/// Composite query operation.
122#[derive(Debug, Clone, Copy, PartialEq, Eq)]
123pub enum CompositeOp {
124 /// UNION (distinct).
125 Union,
126 /// UNION ALL (keep duplicates).
127 UnionAll,
128 /// EXCEPT (set difference, distinct).
129 Except,
130 /// EXCEPT ALL (set difference, keep duplicates).
131 ExceptAll,
132 /// INTERSECT (set intersection, distinct).
133 Intersect,
134 /// INTERSECT ALL (set intersection, keep duplicates).
135 IntersectAll,
136 /// OTHERWISE (fallback if left is empty).
137 Otherwise,
138 /// NEXT (linear composition: output of left feeds into right).
139 Next,
140}
141
142/// A CALL procedure statement (ISO GQL Section 15).
143///
144/// ```text
145/// CALL procedure_name(args)
146/// [YIELD field [AS alias], ...]
147/// [WHERE predicate]
148/// [RETURN expr [AS alias], ... [ORDER BY ...] [SKIP n] [LIMIT n]]
149/// ```
150#[derive(Debug, Clone)]
151pub struct CallStatement {
152 /// Qualified procedure name, e.g. `["grafeo", "pagerank"]`.
153 pub procedure_name: Vec<String>,
154 /// Positional arguments passed to the procedure.
155 pub arguments: Vec<Expression>,
156 /// Optional YIELD clause selecting result columns.
157 pub yield_items: Option<Vec<YieldItem>>,
158 /// Optional WHERE clause filtering yielded rows.
159 pub where_clause: Option<WhereClause>,
160 /// Optional RETURN clause with projection, ORDER BY, SKIP, LIMIT.
161 pub return_clause: Option<ReturnClause>,
162 /// Source span.
163 pub span: Option<SourceSpan>,
164}
165
166/// A single YIELD item: `field_name [AS alias]`.
167#[derive(Debug, Clone)]
168pub struct YieldItem {
169 /// Column name from the procedure result.
170 pub field_name: String,
171 /// Optional alias.
172 pub alias: Option<String>,
173 /// Source span.
174 pub span: Option<SourceSpan>,
175}
176
177/// File format for LOAD DATA statements.
178#[derive(Debug, Clone, Copy, PartialEq, Eq)]
179pub enum LoadFormat {
180 /// CSV (comma-separated values).
181 Csv,
182 /// JSON Lines (one JSON object per line).
183 Jsonl,
184 /// Apache Parquet columnar format.
185 Parquet,
186}
187
188/// LOAD DATA clause: reads data from a file and produces rows.
189#[derive(Debug, Clone)]
190pub struct LoadDataClause {
191 /// File path (local filesystem).
192 pub path: String,
193 /// File format.
194 pub format: LoadFormat,
195 /// Whether the file has a header row (CSV only).
196 pub with_headers: bool,
197 /// Variable name to bind each row to.
198 pub variable: String,
199 /// Optional field terminator override (CSV only).
200 pub field_terminator: Option<char>,
201 /// Source span.
202 pub span: SourceSpan,
203}
204
205/// A clause in a query, preserving source order for correct variable scoping.
206#[derive(Debug, Clone)]
207pub enum QueryClause {
208 /// A MATCH clause.
209 Match(MatchClause),
210 /// An UNWIND clause.
211 Unwind(UnwindClause),
212 /// A FOR clause (desugared to UNWIND).
213 For(UnwindClause),
214 /// A CREATE/INSERT clause.
215 Create(InsertStatement),
216 /// A DELETE clause.
217 Delete(DeleteStatement),
218 /// A SET clause.
219 Set(SetClause),
220 /// A MERGE clause.
221 Merge(MergeClause),
222 /// A LET clause (variable bindings).
223 Let(Vec<(String, Expression)>),
224 /// An inline CALL { subquery } clause (optional = OPTIONAL CALL { ... }).
225 InlineCall {
226 /// The inner subquery.
227 subquery: QueryStatement,
228 /// Whether this is OPTIONAL CALL (left-join semantics).
229 optional: bool,
230 },
231 /// A CALL procedure clause within a query.
232 CallProcedure(CallStatement),
233 /// A LOAD DATA clause.
234 LoadData(LoadDataClause),
235}
236
237/// A query statement.
238#[derive(Debug, Clone)]
239pub struct QueryStatement {
240 /// MATCH clauses (regular and optional).
241 pub match_clauses: Vec<MatchClause>,
242 /// Optional WHERE clause.
243 pub where_clause: Option<WhereClause>,
244 /// SET clauses for property updates.
245 pub set_clauses: Vec<SetClause>,
246 /// REMOVE clauses for label/property removal.
247 pub remove_clauses: Vec<RemoveClause>,
248 /// WITH clauses for query chaining.
249 pub with_clauses: Vec<WithClause>,
250 /// UNWIND clauses for list expansion.
251 pub unwind_clauses: Vec<UnwindClause>,
252 /// MERGE clauses for conditional create/match.
253 pub merge_clauses: Vec<MergeClause>,
254 /// CREATE clauses (Cypher-style data modification within query).
255 pub create_clauses: Vec<InsertStatement>,
256 /// DELETE clauses (data removal within query).
257 pub delete_clauses: Vec<DeleteStatement>,
258 /// Required RETURN clause.
259 pub return_clause: ReturnClause,
260 /// Optional HAVING clause (filters aggregate results).
261 pub having_clause: Option<HavingClause>,
262 /// Ordered clauses preserving source order (for UNWIND/FOR variable scoping).
263 pub ordered_clauses: Vec<QueryClause>,
264 /// Source span in the original query.
265 pub span: Option<SourceSpan>,
266}
267
268/// A HAVING clause for filtering aggregate results.
269#[derive(Debug, Clone)]
270pub struct HavingClause {
271 /// The filter expression.
272 pub expression: Expression,
273 /// Source span.
274 pub span: Option<SourceSpan>,
275}
276
277/// A SET clause.
278#[derive(Debug, Clone)]
279pub struct SetClause {
280 /// Property assignments.
281 pub assignments: Vec<PropertyAssignment>,
282 /// Map assignments (SET n = {map} or SET n += {map}).
283 pub map_assignments: Vec<MapAssignment>,
284 /// Label operations (add labels to nodes).
285 pub label_operations: Vec<LabelOperation>,
286 /// Source span.
287 pub span: Option<SourceSpan>,
288}
289
290/// A map assignment for SET n = {map} or SET n += {map}.
291#[derive(Debug, Clone)]
292pub struct MapAssignment {
293 /// Variable name.
294 pub variable: String,
295 /// Map expression (typically a map literal or variable).
296 pub map_expr: Expression,
297 /// Whether to replace all properties (true for `=`) or merge (false for `+=`).
298 pub replace: bool,
299}
300
301/// A label operation for adding/removing labels.
302#[derive(Debug, Clone)]
303pub struct LabelOperation {
304 /// Variable name.
305 pub variable: String,
306 /// Labels to add.
307 pub labels: Vec<String>,
308}
309
310/// A REMOVE clause for removing labels or properties.
311#[derive(Debug, Clone)]
312pub struct RemoveClause {
313 /// Label removal operations.
314 pub label_operations: Vec<LabelOperation>,
315 /// Property removal operations (variable.property pairs).
316 pub property_removals: Vec<(String, String)>,
317 /// Source span.
318 pub span: Option<SourceSpan>,
319}
320
321/// Path traversal mode (ISO GQL sec 16.6).
322#[derive(Debug, Clone, Copy, PartialEq, Eq)]
323pub enum PathMode {
324 /// Allows repeated nodes and edges.
325 Walk,
326 /// No repeated edges.
327 Trail,
328 /// No repeated nodes except endpoints.
329 Simple,
330 /// No repeated nodes at all.
331 Acyclic,
332}
333
334/// Path search prefix for ISO GQL shortest path queries.
335#[derive(Debug, Clone, PartialEq, Eq)]
336pub enum PathSearchPrefix {
337 /// `ALL`: enumerate all matching paths.
338 All,
339 /// `ANY`: return any single matching path.
340 Any,
341 /// `ANY k`: return up to k matching paths.
342 AnyK(usize),
343 /// `ALL SHORTEST`: return all paths of minimum length.
344 AllShortest,
345 /// `ANY SHORTEST`: return any single shortest path.
346 AnyShortest,
347 /// `SHORTEST k`: return the k shortest paths.
348 ShortestK(usize),
349 /// `SHORTEST k GROUPS`: return paths grouped by length.
350 ShortestKGroups(usize),
351}
352
353/// Match mode controlling edge/node uniqueness (ISO GQL sec 16.5).
354#[derive(Debug, Clone, Copy, PartialEq, Eq)]
355pub enum MatchMode {
356 /// `DIFFERENT EDGES`: each edge matched at most once (like TRAIL).
357 DifferentEdges,
358 /// `REPEATABLE ELEMENTS`: edges and nodes may repeat (like WALK).
359 RepeatableElements,
360}
361
362/// A MATCH clause.
363#[derive(Debug, Clone)]
364pub struct MatchClause {
365 /// Whether this is an OPTIONAL MATCH.
366 pub optional: bool,
367 /// Path mode for traversal (WALK, TRAIL, SIMPLE, ACYCLIC).
368 pub path_mode: Option<PathMode>,
369 /// Path search prefix (ANY, ALL SHORTEST, SHORTEST k, etc.).
370 pub search_prefix: Option<PathSearchPrefix>,
371 /// Match mode (DIFFERENT EDGES, REPEATABLE ELEMENTS).
372 pub match_mode: Option<MatchMode>,
373 /// Graph patterns to match, potentially with aliases and path functions.
374 pub patterns: Vec<AliasedPattern>,
375 /// Source span.
376 pub span: Option<SourceSpan>,
377}
378
379/// A pattern with optional alias and path function wrapper.
380#[derive(Debug, Clone)]
381pub struct AliasedPattern {
382 /// Optional alias for the pattern (e.g., `p` in `p = (a)-[*]-(b)`).
383 pub alias: Option<String>,
384 /// Optional path function wrapping the pattern.
385 pub path_function: Option<PathFunction>,
386 /// Per-pattern KEEP clause (ISO GQL sec 16.5).
387 pub keep: Option<MatchMode>,
388 /// The underlying pattern.
389 pub pattern: Pattern,
390}
391
392/// Path functions for shortest path queries.
393#[derive(Debug, Clone, Copy, PartialEq, Eq)]
394pub enum PathFunction {
395 /// Find the shortest path between two nodes.
396 ShortestPath,
397 /// Find all shortest paths between two nodes.
398 AllShortestPaths,
399}
400
401/// A WITH clause for query chaining.
402#[derive(Debug, Clone)]
403pub struct WithClause {
404 /// Whether to use DISTINCT.
405 pub distinct: bool,
406 /// Items to pass to the next query part (empty when `is_wildcard` is true).
407 pub items: Vec<ReturnItem>,
408 /// Whether this is `WITH *` (pass all variables through).
409 pub is_wildcard: bool,
410 /// Optional WHERE clause after WITH.
411 pub where_clause: Option<WhereClause>,
412 /// LET bindings attached to this WITH clause (e.g. `WITH n LET x = n.age * 2`).
413 pub let_bindings: Vec<(String, Expression)>,
414 /// Source span.
415 pub span: Option<SourceSpan>,
416}
417
418/// An UNWIND clause for expanding lists into rows.
419#[derive(Debug, Clone)]
420pub struct UnwindClause {
421 /// The expression to unwind (typically a list).
422 pub expression: Expression,
423 /// The alias for each element.
424 pub alias: String,
425 /// Optional variable for 1-based element position (FOR ... WITH ORDINALITY var).
426 pub ordinality_var: Option<String>,
427 /// Optional variable for 0-based element position (FOR ... WITH OFFSET var).
428 pub offset_var: Option<String>,
429 /// Source span.
430 pub span: Option<SourceSpan>,
431}
432
433/// A MERGE clause for creating or matching patterns.
434#[derive(Debug, Clone)]
435pub struct MergeClause {
436 /// The pattern to merge.
437 pub pattern: Pattern,
438 /// Actions to perform on create.
439 pub on_create: Option<Vec<PropertyAssignment>>,
440 /// Actions to perform on match.
441 pub on_match: Option<Vec<PropertyAssignment>>,
442 /// Source span.
443 pub span: Option<SourceSpan>,
444}
445
446/// A graph pattern.
447#[derive(Debug, Clone)]
448pub enum Pattern {
449 /// A node pattern.
450 Node(NodePattern),
451 /// An edge pattern connecting nodes.
452 Path(PathPattern),
453 /// A quantified (parenthesized) path pattern: `((a)-[e]->(b)){2,5}`.
454 Quantified {
455 /// The inner subpattern to repeat.
456 pattern: Box<Pattern>,
457 /// Minimum repetitions.
458 min: u32,
459 /// Maximum repetitions (None = unbounded).
460 max: Option<u32>,
461 /// G048: Subpath variable declaration, e.g. `(p = (a)-[e]->(b)){2,5}`.
462 subpath_var: Option<String>,
463 /// G049: Path mode prefix inside parenthesized pattern, e.g. `(TRAIL (a)-[]->(b)){2,5}`.
464 path_mode: Option<PathMode>,
465 /// G050: WHERE clause inside parenthesized pattern, e.g. `((a)-[e]->(b) WHERE e.w > 5){2,5}`.
466 where_clause: Option<Expression>,
467 },
468 /// A union of alternative path patterns: `(a)-[:T1]->(b) | (a)-[:T2]->(c)`.
469 /// Set semantics: duplicates are removed.
470 Union(Vec<Pattern>),
471 /// A multiset union of alternative path patterns: `(a)-[:T1]->(b) |+| (a)-[:T2]->(c)`.
472 /// Bag semantics: duplicates are preserved (G030).
473 MultisetUnion(Vec<Pattern>),
474}
475
476/// A label expression for GQL IS syntax (e.g., `IS Person | Employee`, `IS Person & !Employee`).
477#[derive(Debug, Clone)]
478pub enum LabelExpression {
479 /// A single label name.
480 Label(String),
481 /// Conjunction (AND): all labels must match.
482 Conjunction(Vec<LabelExpression>),
483 /// Disjunction (OR): any label must match.
484 Disjunction(Vec<LabelExpression>),
485 /// Negation (NOT): label must not match.
486 Negation(Box<LabelExpression>),
487 /// Wildcard (%): matches any label.
488 Wildcard,
489}
490
491/// A node pattern like (n:Person) or (n IS Person | Employee).
492#[derive(Debug, Clone)]
493pub struct NodePattern {
494 /// Variable name (optional).
495 pub variable: Option<String>,
496 /// Labels to match (colon syntax: `:Label1:Label2`).
497 pub labels: Vec<String>,
498 /// Label expression (IS syntax: `IS Person | Employee`).
499 pub label_expression: Option<LabelExpression>,
500 /// Property filters.
501 pub properties: Vec<(String, Expression)>,
502 /// Element pattern WHERE clause: `(n WHERE n.age > 30)`.
503 pub where_clause: Option<Expression>,
504 /// Source span.
505 pub span: Option<SourceSpan>,
506}
507
508/// A path pattern like `(a)-[:KNOWS]->(b)`.
509#[derive(Debug, Clone)]
510pub struct PathPattern {
511 /// Source node pattern.
512 pub source: NodePattern,
513 /// Edge patterns.
514 pub edges: Vec<EdgePattern>,
515 /// Source span.
516 pub span: Option<SourceSpan>,
517}
518
519/// An edge pattern like `-[:KNOWS]->` or `-[:KNOWS*1..3]->`.
520#[derive(Debug, Clone)]
521pub struct EdgePattern {
522 /// Variable name (optional).
523 pub variable: Option<String>,
524 /// Edge types to match.
525 pub types: Vec<String>,
526 /// Direction of the edge.
527 pub direction: EdgeDirection,
528 /// Target node pattern.
529 pub target: NodePattern,
530 /// Variable-length path: minimum hops (None means 1).
531 pub min_hops: Option<u32>,
532 /// Variable-length path: maximum hops (None means unlimited or same as min).
533 pub max_hops: Option<u32>,
534 /// Property filters for the edge.
535 pub properties: Vec<(String, Expression)>,
536 /// Element pattern WHERE clause: `-[e WHERE e.weight > 5]->`.
537 pub where_clause: Option<Expression>,
538 /// Questioned edge: `->?` means "optional" (0 or 1 hop).
539 pub questioned: bool,
540 /// Source span.
541 pub span: Option<SourceSpan>,
542}
543
544/// Direction of an edge.
545#[derive(Debug, Clone, Copy, PartialEq, Eq)]
546pub enum EdgeDirection {
547 /// Outgoing edge: ->
548 Outgoing,
549 /// Incoming edge: <-
550 Incoming,
551 /// Undirected edge: -
552 Undirected,
553}
554
555/// A WHERE clause.
556#[derive(Debug, Clone)]
557pub struct WhereClause {
558 /// The filter expression.
559 pub expression: Expression,
560 /// Source span.
561 pub span: Option<SourceSpan>,
562}
563
564/// A RETURN clause.
565#[derive(Debug, Clone)]
566pub struct ReturnClause {
567 /// Whether to return DISTINCT results.
568 pub distinct: bool,
569 /// Items to return (empty when `is_wildcard` is true).
570 pub items: Vec<ReturnItem>,
571 /// Whether this is `RETURN *` (return all bound variables).
572 pub is_wildcard: bool,
573 /// Explicit GROUP BY expressions.
574 pub group_by: Vec<Expression>,
575 /// Optional ORDER BY.
576 pub order_by: Option<OrderByClause>,
577 /// Optional SKIP.
578 pub skip: Option<Expression>,
579 /// Optional LIMIT.
580 pub limit: Option<Expression>,
581 /// Whether this is a FINISH statement (consume input, return empty).
582 pub is_finish: bool,
583 /// Source span.
584 pub span: Option<SourceSpan>,
585}
586
587/// An item in a RETURN clause.
588#[derive(Debug, Clone)]
589pub struct ReturnItem {
590 /// The expression to return.
591 pub expression: Expression,
592 /// Optional alias (AS name).
593 pub alias: Option<String>,
594 /// Source span.
595 pub span: Option<SourceSpan>,
596}
597
598/// An ORDER BY clause.
599#[derive(Debug, Clone)]
600pub struct OrderByClause {
601 /// Sort items.
602 pub items: Vec<OrderByItem>,
603 /// Source span.
604 pub span: Option<SourceSpan>,
605}
606
607/// A sort item.
608#[derive(Debug, Clone)]
609pub struct OrderByItem {
610 /// The expression to sort by.
611 pub expression: Expression,
612 /// Sort order.
613 pub order: SortOrder,
614 /// Optional null ordering (NULLS FIRST / NULLS LAST).
615 pub nulls: Option<NullsOrdering>,
616}
617
618/// Sort order.
619#[derive(Debug, Clone, Copy, PartialEq, Eq)]
620pub enum SortOrder {
621 /// Ascending order.
622 Asc,
623 /// Descending order.
624 Desc,
625}
626
627/// Null ordering for ORDER BY (ISO GQL feature GA03).
628#[derive(Debug, Clone, Copy, PartialEq, Eq)]
629pub enum NullsOrdering {
630 /// Nulls sort before all non-null values.
631 First,
632 /// Nulls sort after all non-null values.
633 Last,
634}
635
636/// A data modification statement.
637#[derive(Debug, Clone)]
638pub enum DataModificationStatement {
639 /// INSERT statement.
640 Insert(InsertStatement),
641 /// DELETE statement.
642 Delete(DeleteStatement),
643 /// SET statement.
644 Set(SetStatement),
645}
646
647/// An INSERT statement.
648#[derive(Debug, Clone)]
649pub struct InsertStatement {
650 /// Patterns to insert.
651 pub patterns: Vec<Pattern>,
652 /// Source span.
653 pub span: Option<SourceSpan>,
654}
655
656/// A target for a DELETE statement: either a variable name or a general expression.
657#[derive(Debug, Clone)]
658pub enum DeleteTarget {
659 /// A simple variable reference (e.g., `DELETE n`).
660 Variable(String),
661 /// A general expression (e.g., `DELETE n.friend`, `DELETE head(collect(n))`).
662 Expression(Expression),
663}
664
665/// A DELETE statement.
666#[derive(Debug, Clone)]
667pub struct DeleteStatement {
668 /// Targets to delete (variables or expressions).
669 pub targets: Vec<DeleteTarget>,
670 /// Whether to use DETACH DELETE.
671 pub detach: bool,
672 /// Source span.
673 pub span: Option<SourceSpan>,
674}
675
676/// A SET statement.
677#[derive(Debug, Clone)]
678pub struct SetStatement {
679 /// Property assignments.
680 pub assignments: Vec<PropertyAssignment>,
681 /// Source span.
682 pub span: Option<SourceSpan>,
683}
684
685/// A property assignment.
686#[derive(Debug, Clone)]
687pub struct PropertyAssignment {
688 /// Variable name.
689 pub variable: String,
690 /// Property key.
691 pub property: String,
692 /// Value expression.
693 pub value: Expression,
694}
695
696/// A schema statement.
697#[derive(Debug, Clone)]
698pub enum SchemaStatement {
699 /// CREATE NODE TYPE.
700 CreateNodeType(CreateNodeTypeStatement),
701 /// CREATE EDGE TYPE.
702 CreateEdgeType(CreateEdgeTypeStatement),
703 /// CREATE VECTOR INDEX.
704 CreateVectorIndex(CreateVectorIndexStatement),
705 /// DROP NODE TYPE.
706 DropNodeType {
707 /// Type name.
708 name: String,
709 /// IF EXISTS flag.
710 if_exists: bool,
711 },
712 /// DROP EDGE TYPE.
713 DropEdgeType {
714 /// Type name.
715 name: String,
716 /// IF EXISTS flag.
717 if_exists: bool,
718 },
719 /// CREATE INDEX (property, text, btree).
720 CreateIndex(CreateIndexStatement),
721 /// DROP INDEX.
722 DropIndex {
723 /// Index name.
724 name: String,
725 /// IF EXISTS flag.
726 if_exists: bool,
727 },
728 /// CREATE CONSTRAINT.
729 CreateConstraint(CreateConstraintStatement),
730 /// DROP CONSTRAINT.
731 DropConstraint {
732 /// Constraint name.
733 name: String,
734 /// IF EXISTS flag.
735 if_exists: bool,
736 },
737 /// CREATE GRAPH TYPE.
738 CreateGraphType(CreateGraphTypeStatement),
739 /// DROP GRAPH TYPE.
740 DropGraphType {
741 /// Type name.
742 name: String,
743 /// IF EXISTS flag.
744 if_exists: bool,
745 },
746 /// CREATE SCHEMA.
747 CreateSchema {
748 /// Schema name.
749 name: String,
750 /// IF NOT EXISTS flag.
751 if_not_exists: bool,
752 },
753 /// DROP SCHEMA.
754 DropSchema {
755 /// Schema name.
756 name: String,
757 /// IF EXISTS flag.
758 if_exists: bool,
759 },
760 /// ALTER NODE TYPE.
761 AlterNodeType(AlterTypeStatement),
762 /// ALTER EDGE TYPE.
763 AlterEdgeType(AlterTypeStatement),
764 /// ALTER GRAPH TYPE.
765 AlterGraphType(AlterGraphTypeStatement),
766 /// CREATE PROCEDURE.
767 CreateProcedure(CreateProcedureStatement),
768 /// DROP PROCEDURE.
769 DropProcedure {
770 /// Procedure name.
771 name: String,
772 /// IF EXISTS flag.
773 if_exists: bool,
774 },
775 /// SHOW CONSTRAINTS: lists all constraints.
776 ShowConstraints,
777 /// SHOW INDEXES: lists all indexes.
778 ShowIndexes,
779 /// SHOW NODE TYPES: lists all registered node types.
780 ShowNodeTypes,
781 /// SHOW EDGE TYPES: lists all registered edge types.
782 ShowEdgeTypes,
783 /// SHOW GRAPH TYPES: lists all registered graph types.
784 ShowGraphTypes,
785 /// SHOW GRAPH TYPE `name`: shows details of a specific graph type.
786 ShowGraphType(String),
787 /// SHOW CURRENT GRAPH TYPE: shows the graph type bound to the current graph.
788 ShowCurrentGraphType,
789 /// SHOW GRAPHS: lists all named graphs in the database (or in the current schema).
790 ShowGraphs,
791 /// SHOW SCHEMAS: lists all schema namespaces.
792 ShowSchemas,
793}
794
795/// A CREATE NODE TYPE statement.
796#[derive(Debug, Clone)]
797pub struct CreateNodeTypeStatement {
798 /// Type name.
799 pub name: String,
800 /// Property definitions.
801 pub properties: Vec<PropertyDefinition>,
802 /// Parent types for inheritance (GQL `EXTENDS`).
803 pub parent_types: Vec<String>,
804 /// IF NOT EXISTS flag.
805 pub if_not_exists: bool,
806 /// OR REPLACE flag.
807 pub or_replace: bool,
808 /// Source span.
809 pub span: Option<SourceSpan>,
810}
811
812/// A CREATE EDGE TYPE statement.
813#[derive(Debug, Clone)]
814pub struct CreateEdgeTypeStatement {
815 /// Type name.
816 pub name: String,
817 /// Property definitions.
818 pub properties: Vec<PropertyDefinition>,
819 /// Allowed source node types (GQL `CONNECTING`).
820 pub source_node_types: Vec<String>,
821 /// Allowed target node types.
822 pub target_node_types: Vec<String>,
823 /// IF NOT EXISTS flag.
824 pub if_not_exists: bool,
825 /// OR REPLACE flag.
826 pub or_replace: bool,
827 /// Source span.
828 pub span: Option<SourceSpan>,
829}
830
831/// An inline element type definition within a graph type body.
832#[derive(Debug, Clone)]
833pub enum InlineElementType {
834 /// Inline node type: `NODE TYPE Name (prop1 TYPE, ...)`
835 Node {
836 /// Type name.
837 name: String,
838 /// Property definitions (may be empty).
839 properties: Vec<PropertyDefinition>,
840 /// Key label sets (GG21): labels that form the key for this type.
841 key_labels: Vec<String>,
842 },
843 /// Inline edge type: `EDGE TYPE Name (prop1 TYPE, ...)`
844 Edge {
845 /// Type name.
846 name: String,
847 /// Property definitions (may be empty).
848 properties: Vec<PropertyDefinition>,
849 /// Key label sets (GG21): labels that form the key for this type.
850 key_labels: Vec<String>,
851 /// Allowed source node types.
852 source_node_types: Vec<String>,
853 /// Allowed target node types.
854 target_node_types: Vec<String>,
855 },
856}
857
858impl InlineElementType {
859 /// Returns the type name for this element.
860 #[must_use]
861 pub fn name(&self) -> &str {
862 match self {
863 Self::Node { name, .. } | Self::Edge { name, .. } => name,
864 }
865 }
866}
867
868/// A CREATE GRAPH TYPE statement.
869#[derive(Debug, Clone)]
870pub struct CreateGraphTypeStatement {
871 /// Graph type name.
872 pub name: String,
873 /// Allowed node types (empty = open).
874 pub node_types: Vec<String>,
875 /// Allowed edge types (empty = open).
876 pub edge_types: Vec<String>,
877 /// Inline element type definitions (GG03).
878 pub inline_types: Vec<InlineElementType>,
879 /// Copy type from existing graph (GG04): `LIKE <graph_name>`.
880 pub like_graph: Option<String>,
881 /// Whether unlisted types are also allowed.
882 pub open: bool,
883 /// IF NOT EXISTS flag.
884 pub if_not_exists: bool,
885 /// OR REPLACE flag.
886 pub or_replace: bool,
887 /// Source span.
888 pub span: Option<SourceSpan>,
889}
890
891/// A CREATE VECTOR INDEX statement.
892///
893/// Creates an index for vector similarity search on a node property.
894///
895/// # Syntax
896///
897/// ```text
898/// CREATE VECTOR INDEX index_name ON :Label(property)
899/// [DIMENSION dim]
900/// [METRIC metric_name]
901/// ```
902///
903/// # Example
904///
905/// ```text
906/// CREATE VECTOR INDEX movie_embeddings ON :Movie(embedding)
907/// DIMENSION 384
908/// METRIC 'cosine'
909/// ```
910#[derive(Debug, Clone)]
911pub struct CreateVectorIndexStatement {
912 /// Index name.
913 pub name: String,
914 /// Node label to index.
915 pub node_label: String,
916 /// Property containing the vector.
917 pub property: String,
918 /// Vector dimensions (optional, can be inferred).
919 pub dimensions: Option<usize>,
920 /// Distance metric (default: cosine).
921 pub metric: Option<String>,
922 /// Source span.
923 pub span: Option<SourceSpan>,
924}
925
926/// A CREATE INDEX statement.
927///
928/// # Syntax
929///
930/// ```text
931/// CREATE INDEX name FOR (n:Label) ON (n.property) [USING TEXT|VECTOR|BTREE]
932/// ```
933#[derive(Debug, Clone)]
934pub struct CreateIndexStatement {
935 /// Index name.
936 pub name: String,
937 /// Index kind (property, text, vector, btree).
938 pub index_kind: IndexKind,
939 /// Node label to index.
940 pub label: String,
941 /// Properties to index.
942 pub properties: Vec<String>,
943 /// Additional options (dimensions, metric for vector indexes).
944 pub options: IndexOptions,
945 /// IF NOT EXISTS flag.
946 pub if_not_exists: bool,
947 /// Source span.
948 pub span: Option<SourceSpan>,
949}
950
951/// Kind of index.
952#[derive(Debug, Clone, Copy, PartialEq, Eq)]
953pub enum IndexKind {
954 /// Default property index (hash-based).
955 Property,
956 /// Full-text search index (BM25).
957 Text,
958 /// Vector similarity index (HNSW).
959 Vector,
960 /// B-tree range index.
961 BTree,
962}
963
964/// Additional options for index creation.
965#[derive(Debug, Clone, Default)]
966pub struct IndexOptions {
967 /// Vector dimensions (for vector indexes).
968 pub dimensions: Option<usize>,
969 /// Distance metric (for vector indexes).
970 pub metric: Option<String>,
971}
972
973/// A CREATE CONSTRAINT statement.
974///
975/// # Syntax
976///
977/// ```text
978/// CREATE CONSTRAINT [name] FOR (n:Label) ON (n.property) UNIQUE|NOT NULL
979/// ```
980#[derive(Debug, Clone)]
981pub struct CreateConstraintStatement {
982 /// Constraint name (optional).
983 pub name: Option<String>,
984 /// Constraint kind.
985 pub constraint_kind: ConstraintKind,
986 /// Node label this constraint applies to.
987 pub label: String,
988 /// Properties constrained.
989 pub properties: Vec<String>,
990 /// IF NOT EXISTS flag.
991 pub if_not_exists: bool,
992 /// Source span.
993 pub span: Option<SourceSpan>,
994}
995
996/// Kind of constraint.
997#[derive(Debug, Clone, Copy, PartialEq, Eq)]
998pub enum ConstraintKind {
999 /// Unique value constraint.
1000 Unique,
1001 /// Composite key constraint (unique combination).
1002 NodeKey,
1003 /// Property must not be null.
1004 NotNull,
1005 /// Property must exist.
1006 Exists,
1007}
1008
1009/// A property definition in a schema.
1010#[derive(Debug, Clone)]
1011pub struct PropertyDefinition {
1012 /// Property name.
1013 pub name: String,
1014 /// Property type.
1015 pub data_type: String,
1016 /// Whether the property is nullable.
1017 pub nullable: bool,
1018 /// Optional default value (literal text from the DDL).
1019 pub default_value: Option<String>,
1020}
1021
1022/// An ALTER NODE TYPE or ALTER EDGE TYPE statement.
1023#[derive(Debug, Clone)]
1024pub struct AlterTypeStatement {
1025 /// Type name to alter.
1026 pub name: String,
1027 /// Changes to apply.
1028 pub alterations: Vec<TypeAlteration>,
1029 /// Source span.
1030 pub span: Option<SourceSpan>,
1031}
1032
1033/// A single alteration to a node or edge type.
1034#[derive(Debug, Clone)]
1035pub enum TypeAlteration {
1036 /// Add a property to the type.
1037 AddProperty(PropertyDefinition),
1038 /// Remove a property from the type.
1039 DropProperty(String),
1040}
1041
1042/// An ALTER GRAPH TYPE statement.
1043#[derive(Debug, Clone)]
1044pub struct AlterGraphTypeStatement {
1045 /// Graph type name to alter.
1046 pub name: String,
1047 /// Changes to apply.
1048 pub alterations: Vec<GraphTypeAlteration>,
1049 /// Source span.
1050 pub span: Option<SourceSpan>,
1051}
1052
1053/// A single alteration to a graph type.
1054#[derive(Debug, Clone)]
1055pub enum GraphTypeAlteration {
1056 /// Add a node type to the graph type.
1057 AddNodeType(String),
1058 /// Remove a node type from the graph type.
1059 DropNodeType(String),
1060 /// Add an edge type to the graph type.
1061 AddEdgeType(String),
1062 /// Remove an edge type from the graph type.
1063 DropEdgeType(String),
1064}
1065
1066/// A CREATE PROCEDURE statement.
1067///
1068/// # Syntax
1069///
1070/// ```text
1071/// CREATE [OR REPLACE] PROCEDURE name(param1 type, ...)
1072/// RETURNS (col1 type, ...)
1073/// AS { <GQL query body> }
1074/// ```
1075#[derive(Debug, Clone)]
1076pub struct CreateProcedureStatement {
1077 /// Procedure name.
1078 pub name: String,
1079 /// Parameter definitions.
1080 pub params: Vec<ProcedureParam>,
1081 /// Return column definitions.
1082 pub returns: Vec<ProcedureReturn>,
1083 /// Raw GQL query body.
1084 pub body: String,
1085 /// IF NOT EXISTS flag.
1086 pub if_not_exists: bool,
1087 /// OR REPLACE flag.
1088 pub or_replace: bool,
1089 /// Source span.
1090 pub span: Option<SourceSpan>,
1091}
1092
1093/// A stored procedure parameter.
1094#[derive(Debug, Clone)]
1095pub struct ProcedureParam {
1096 /// Parameter name.
1097 pub name: String,
1098 /// Type name (e.g. "INT64", "STRING").
1099 pub param_type: String,
1100}
1101
1102/// A stored procedure return column.
1103#[derive(Debug, Clone)]
1104pub struct ProcedureReturn {
1105 /// Column name.
1106 pub name: String,
1107 /// Type name.
1108 pub return_type: String,
1109}
1110
1111/// An expression.
1112#[derive(Debug, Clone)]
1113pub enum Expression {
1114 /// A literal value.
1115 Literal(Literal),
1116 /// A variable reference.
1117 Variable(String),
1118 /// A parameter reference ($name).
1119 Parameter(String),
1120 /// A property access (var.prop).
1121 PropertyAccess {
1122 /// The variable.
1123 variable: String,
1124 /// The property name.
1125 property: String,
1126 },
1127 /// A binary operation.
1128 Binary {
1129 /// Left operand.
1130 left: Box<Expression>,
1131 /// Operator.
1132 op: BinaryOp,
1133 /// Right operand.
1134 right: Box<Expression>,
1135 },
1136 /// A unary operation.
1137 Unary {
1138 /// Operator.
1139 op: UnaryOp,
1140 /// Operand.
1141 operand: Box<Expression>,
1142 },
1143 /// A function call.
1144 FunctionCall {
1145 /// Function name.
1146 name: String,
1147 /// Arguments.
1148 args: Vec<Expression>,
1149 /// Whether DISTINCT is applied to arguments.
1150 distinct: bool,
1151 },
1152 /// A list expression.
1153 List(Vec<Expression>),
1154 /// A CASE expression.
1155 Case {
1156 /// Optional input expression.
1157 input: Option<Box<Expression>>,
1158 /// When clauses.
1159 whens: Vec<(Expression, Expression)>,
1160 /// Else clause.
1161 else_clause: Option<Box<Expression>>,
1162 },
1163 /// EXISTS subquery expression: checks if inner query returns results.
1164 ExistsSubquery {
1165 /// The inner query pattern to check for existence.
1166 query: Box<QueryStatement>,
1167 },
1168 /// COUNT subquery expression: counts rows from inner query.
1169 CountSubquery {
1170 /// The inner query pattern to count.
1171 query: Box<QueryStatement>,
1172 },
1173 /// VALUE { subquery }: evaluates subquery and returns scalar result.
1174 ValueSubquery {
1175 /// The inner subquery.
1176 query: Box<QueryStatement>,
1177 },
1178 /// A map literal: `{key: value, ...}`.
1179 Map(Vec<(String, Expression)>),
1180 /// Index access: `expr[index]`.
1181 IndexAccess {
1182 /// The base expression.
1183 base: Box<Expression>,
1184 /// The index expression.
1185 index: Box<Expression>,
1186 },
1187 /// LET ... IN ... END expression.
1188 LetIn {
1189 /// Variable bindings.
1190 bindings: Vec<(String, Expression)>,
1191 /// The body expression.
1192 body: Box<Expression>,
1193 },
1194 /// List comprehension: `[x IN list WHERE predicate | expression]`.
1195 ListComprehension {
1196 /// Iteration variable name.
1197 variable: String,
1198 /// Source list expression.
1199 list_expr: Box<Expression>,
1200 /// Optional filter predicate.
1201 filter_expr: Option<Box<Expression>>,
1202 /// Mapping expression for each element.
1203 map_expr: Box<Expression>,
1204 },
1205 /// List predicate: `all/any/none/single(x IN list WHERE predicate)`.
1206 ListPredicate {
1207 /// Predicate kind.
1208 kind: ListPredicateKind,
1209 /// Iteration variable name.
1210 variable: String,
1211 /// Source list expression.
1212 list_expr: Box<Expression>,
1213 /// Predicate expression.
1214 predicate: Box<Expression>,
1215 },
1216 /// Reduce accumulator: `reduce(acc = init, x IN list | expression)`.
1217 Reduce {
1218 /// Accumulator variable name.
1219 accumulator: String,
1220 /// Initial value for the accumulator.
1221 initial: Box<Expression>,
1222 /// Iteration variable name.
1223 variable: String,
1224 /// Source list expression.
1225 list: Box<Expression>,
1226 /// Body expression (references both accumulator and variable).
1227 expression: Box<Expression>,
1228 },
1229}
1230
1231/// The kind of list predicate function.
1232#[derive(Debug, Clone, PartialEq, Eq)]
1233pub enum ListPredicateKind {
1234 /// `all(x IN list WHERE pred)`: true if pred holds for every element.
1235 All,
1236 /// `any(x IN list WHERE pred)`: true if pred holds for at least one.
1237 Any,
1238 /// `none(x IN list WHERE pred)`: true if pred holds for none.
1239 None,
1240 /// `single(x IN list WHERE pred)`: true if pred holds for exactly one.
1241 Single,
1242}
1243
1244/// A literal value.
1245#[derive(Debug, Clone, PartialEq)]
1246pub enum Literal {
1247 /// Null literal.
1248 Null,
1249 /// Boolean literal.
1250 Bool(bool),
1251 /// Integer literal.
1252 Integer(i64),
1253 /// Float literal.
1254 Float(f64),
1255 /// String literal.
1256 String(String),
1257 /// Typed date literal: `DATE '2024-01-15'`
1258 Date(String),
1259 /// Typed time literal: `TIME '14:30:00'`
1260 Time(String),
1261 /// Typed duration literal: `DURATION 'P1Y2M'`
1262 Duration(String),
1263 /// Typed datetime literal: `DATETIME '2024-01-15T14:30:00Z'`
1264 Datetime(String),
1265 /// Typed zoned datetime literal: `ZONED DATETIME '2024-01-15T14:30:00+05:30'`
1266 ZonedDatetime(String),
1267 /// Typed zoned time literal: `ZONED TIME '14:30:00+05:30'`
1268 ZonedTime(String),
1269}
1270
1271/// A binary operator.
1272#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1273pub enum BinaryOp {
1274 // Comparison
1275 /// Equal.
1276 Eq,
1277 /// Not equal.
1278 Ne,
1279 /// Less than.
1280 Lt,
1281 /// Less than or equal.
1282 Le,
1283 /// Greater than.
1284 Gt,
1285 /// Greater than or equal.
1286 Ge,
1287
1288 // Logical
1289 /// Logical AND.
1290 And,
1291 /// Logical OR.
1292 Or,
1293 /// Logical XOR.
1294 Xor,
1295
1296 // Arithmetic
1297 /// Addition.
1298 Add,
1299 /// Subtraction.
1300 Sub,
1301 /// Multiplication.
1302 Mul,
1303 /// Division.
1304 Div,
1305 /// Modulo.
1306 Mod,
1307
1308 // String
1309 /// String concatenation.
1310 Concat,
1311 /// LIKE pattern matching.
1312 Like,
1313 /// IN list membership.
1314 In,
1315 /// STARTS WITH prefix matching.
1316 StartsWith,
1317 /// ENDS WITH suffix matching.
1318 EndsWith,
1319 /// CONTAINS substring matching.
1320 Contains,
1321}
1322
1323/// A unary operator.
1324#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1325pub enum UnaryOp {
1326 /// Logical NOT.
1327 Not,
1328 /// Unary minus.
1329 Neg,
1330 /// Unary plus (identity).
1331 Pos,
1332 /// IS NULL.
1333 IsNull,
1334 /// IS NOT NULL.
1335 IsNotNull,
1336}