Skip to main content

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}