Skip to main content

hawdb_sql_syntax/
ast.rs

1// Copyright 2026 Nowledge
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use crate::Span;
16
17#[derive(Debug, Clone, PartialEq, Eq)]
18pub enum PgqStatement {
19    CreatePropertyGraph(CreatePropertyGraph),
20}
21
22#[derive(Debug, Clone, PartialEq, Eq)]
23pub enum RelationalStatementSyntax {
24    Select(Box<PostgresSelectSyntax>),
25    Explain {
26        analyze: bool,
27        select: Box<PostgresSelectSyntax>,
28    },
29}
30
31#[derive(Debug, Clone, PartialEq, Eq)]
32pub enum PostgresStatementSyntax {
33    CreatePropertyGraph(CreatePropertyGraph),
34    Select(Box<PostgresSelectSyntax>),
35}
36
37#[derive(Debug, Clone, PartialEq, Eq)]
38pub struct PostgresSelectSyntax {
39    pub distinct: bool,
40    pub projection: Vec<LabeledExpressionSyntax>,
41    pub from: Vec<PostgresFromSyntax>,
42    pub selection: Option<ExpressionSyntax>,
43    pub group_by: Vec<ExpressionSyntax>,
44    pub having: Option<ExpressionSyntax>,
45    pub order_by: Vec<OrderBySyntax>,
46    pub limit: Option<ExpressionSyntax>,
47    pub offset: Option<ExpressionSyntax>,
48    pub locking: Option<LockingClauseSyntax>,
49    pub span: Span,
50}
51
52#[derive(Debug, Clone, PartialEq, Eq)]
53pub struct PostgresFromSyntax {
54    pub relation: PostgresFromItemSyntax,
55    pub joins: Vec<PostgresJoinSyntax>,
56    pub span: Span,
57}
58
59#[derive(Debug, Clone, PartialEq, Eq)]
60pub enum PostgresFromItemSyntax {
61    Relation(RelationTableSyntax),
62    GraphTable(GraphTable),
63}
64
65#[derive(Debug, Clone, PartialEq, Eq)]
66pub struct PostgresJoinSyntax {
67    pub kind: PostgresJoinKind,
68    pub relation: PostgresFromItemSyntax,
69    pub condition: Option<ExpressionSyntax>,
70    pub span: Span,
71}
72
73#[derive(Debug, Clone, Copy, PartialEq, Eq)]
74pub enum PostgresJoinKind {
75    Inner,
76    Left,
77    Cross,
78}
79
80#[derive(Debug, Clone, PartialEq, Eq)]
81pub struct OrderBySyntax {
82    pub expression: ExpressionSyntax,
83    pub direction: Option<OrderDirectionSyntax>,
84    pub nulls: Option<NullOrderSyntax>,
85    pub span: Span,
86}
87
88#[derive(Debug, Clone, Copy, PartialEq, Eq)]
89pub enum OrderDirectionSyntax {
90    Ascending,
91    Descending,
92}
93
94#[derive(Debug, Clone, Copy, PartialEq, Eq)]
95pub enum NullOrderSyntax {
96    First,
97    Last,
98}
99
100#[derive(Debug, Clone, Copy, PartialEq, Eq)]
101pub struct LockingClauseSyntax {
102    pub nonblocking: bool,
103    pub strength: LockStrengthSyntax,
104    pub span: Span,
105}
106
107#[derive(Debug, Clone, Copy, PartialEq, Eq)]
108pub enum LockStrengthSyntax {
109    Share,
110    Update,
111}
112
113#[derive(Debug, Clone, PartialEq, Eq)]
114pub struct TableFunctionArgumentSyntax {
115    pub name: Option<Identifier>,
116    pub expression: ExpressionSyntax,
117}
118
119#[derive(Debug, Clone, PartialEq, Eq)]
120pub struct RelationTableSyntax {
121    pub name: QualifiedName,
122    pub arguments: Option<Vec<TableFunctionArgumentSyntax>>,
123    pub alias: Option<TableAlias>,
124    pub span: Span,
125}
126
127#[derive(Debug, Clone, PartialEq, Eq)]
128pub struct Identifier {
129    pub span: Span,
130    pub quoted: bool,
131}
132
133#[derive(Debug, Clone, PartialEq, Eq)]
134pub struct QualifiedName {
135    pub parts: Vec<Identifier>,
136    pub span: Span,
137}
138
139#[derive(Debug, Clone, PartialEq, Eq)]
140pub struct CreatePropertyGraph {
141    pub temporary: bool,
142    pub name: QualifiedName,
143    pub vertex_tables: Vec<VertexTableDefinition>,
144    pub edge_tables: Vec<EdgeTableDefinition>,
145    pub span: Span,
146}
147
148#[derive(Debug, Clone, PartialEq, Eq)]
149pub struct VertexTableDefinition {
150    pub table: QualifiedName,
151    pub alias: Option<Identifier>,
152    pub key: Vec<Identifier>,
153    pub exposure: Option<ElementExposure>,
154    pub span: Span,
155}
156
157#[derive(Debug, Clone, PartialEq, Eq)]
158pub struct EdgeTableDefinition {
159    pub table: QualifiedName,
160    pub alias: Option<Identifier>,
161    pub key: Vec<Identifier>,
162    pub source: EdgeEndpoint,
163    pub destination: EdgeEndpoint,
164    pub exposure: Option<ElementExposure>,
165    pub span: Span,
166}
167
168#[derive(Debug, Clone, PartialEq, Eq)]
169pub struct EdgeEndpoint {
170    pub key: Vec<Identifier>,
171    pub vertex: Identifier,
172    pub vertex_key: Vec<Identifier>,
173    pub span: Span,
174}
175
176#[derive(Debug, Clone, PartialEq, Eq)]
177pub struct ElementExposure {
178    pub labels: Vec<ElementLabelExposure>,
179    pub span: Span,
180}
181
182#[derive(Debug, Clone, PartialEq, Eq)]
183pub struct ElementLabelExposure {
184    pub label: ElementLabel,
185    pub properties: PropertyExposure,
186    pub span: Span,
187}
188
189#[derive(Debug, Clone, PartialEq, Eq)]
190pub enum ElementLabel {
191    Implicit,
192    Default,
193    Named(Identifier),
194}
195
196#[derive(Debug, Clone, PartialEq, Eq)]
197pub enum PropertyExposure {
198    AllColumns,
199    NoProperties,
200    Expressions(Vec<LabeledExpressionSyntax>),
201}
202
203#[derive(Debug, Clone, PartialEq, Eq)]
204pub struct LabeledExpressionSyntax {
205    pub expression: ExpressionSyntax,
206    pub alias: Option<Identifier>,
207    pub span: Span,
208}
209
210#[derive(Debug, Clone, PartialEq, Eq)]
211pub struct GraphTable {
212    pub graph: QualifiedName,
213    pub pattern: GraphPatternSyntax,
214    pub columns: Vec<GraphTableColumn>,
215    pub alias: Option<TableAlias>,
216    pub span: Span,
217}
218
219#[derive(Debug, Clone, PartialEq, Eq)]
220pub struct GraphPatternSyntax {
221    pub paths: Vec<GraphPathSyntax>,
222    pub predicate: Option<ExpressionSyntax>,
223    pub span: Span,
224}
225
226#[derive(Debug, Clone, PartialEq, Eq)]
227pub struct GraphPathSyntax {
228    pub factors: Vec<GraphPathFactorSyntax>,
229    pub span: Span,
230}
231
232#[derive(Debug, Clone, PartialEq, Eq)]
233pub struct GraphPathFactorSyntax {
234    pub primary: GraphPathPrimarySyntax,
235    pub quantifier: Option<GraphPatternQuantifier>,
236    pub span: Span,
237}
238
239#[derive(Debug, Clone, PartialEq, Eq)]
240pub enum GraphPathPrimarySyntax {
241    Vertex(GraphElementPatternSyntax),
242    Edge(GraphEdgePatternSyntax),
243    Parenthesized {
244        path: Box<GraphPathSyntax>,
245        predicate: Option<ExpressionSyntax>,
246        span: Span,
247    },
248}
249
250#[derive(Debug, Clone, PartialEq, Eq)]
251pub struct GraphElementPatternSyntax {
252    pub variable: Option<Identifier>,
253    pub labels: Vec<Identifier>,
254    pub predicate: Option<ExpressionSyntax>,
255    pub span: Span,
256}
257
258#[derive(Debug, Clone, PartialEq, Eq)]
259pub struct GraphEdgePatternSyntax {
260    pub direction: GraphEdgeDirection,
261    pub variable: Option<Identifier>,
262    pub labels: Vec<Identifier>,
263    pub predicate: Option<ExpressionSyntax>,
264    pub abbreviated: bool,
265    pub span: Span,
266}
267
268#[derive(Debug, Clone, Copy, PartialEq, Eq)]
269pub enum GraphEdgeDirection {
270    Left,
271    Right,
272    Any,
273}
274
275#[derive(Debug, Clone, PartialEq, Eq)]
276pub struct GraphPatternQuantifier {
277    pub min: u32,
278    pub max: u32,
279    pub span: Span,
280}
281
282/// The time zone clause of `TIMESTAMP [ (p) ] { WITH | WITHOUT } TIME ZONE`.
283#[derive(Debug, Clone, Copy, PartialEq, Eq)]
284pub enum TimeZoneSyntax {
285    With,
286    Without,
287}
288
289#[derive(Debug, Clone, PartialEq, Eq)]
290pub struct ExpressionSyntax {
291    pub kind: ExpressionKindSyntax,
292    pub span: Span,
293}
294
295#[derive(Debug, Clone, PartialEq, Eq)]
296pub enum ExpressionKindSyntax {
297    Column(QualifiedName),
298    Wildcard(Option<QualifiedName>),
299    Parameter(u32),
300    Literal(LiteralSyntax),
301    TypedString {
302        data_type: Identifier,
303        /// `WITH TIME ZONE` or `WITHOUT TIME ZONE` after the type name.
304        time_zone: Option<TimeZoneSyntax>,
305        value: Span,
306    },
307    Unary {
308        operator: UnaryOperatorSyntax,
309        expression: Box<ExpressionSyntax>,
310    },
311    Binary {
312        left: Box<ExpressionSyntax>,
313        operator: BinaryOperatorSyntax,
314        right: Box<ExpressionSyntax>,
315    },
316    Like {
317        expression: Box<ExpressionSyntax>,
318        pattern: Box<ExpressionSyntax>,
319        escape: Option<Box<ExpressionSyntax>>,
320        negated: bool,
321        case_insensitive: bool,
322    },
323    Filtered {
324        function: Box<ExpressionSyntax>,
325        predicate: Box<ExpressionSyntax>,
326    },
327    IsNull {
328        expression: Box<ExpressionSyntax>,
329        negated: bool,
330    },
331    InList {
332        expression: Box<ExpressionSyntax>,
333        values: Vec<ExpressionSyntax>,
334        negated: bool,
335    },
336    Between {
337        expression: Box<ExpressionSyntax>,
338        low: Box<ExpressionSyntax>,
339        high: Box<ExpressionSyntax>,
340        negated: bool,
341    },
342    Function {
343        name: QualifiedName,
344        arguments: Vec<ExpressionSyntax>,
345        distinct: bool,
346    },
347    Cast {
348        expression: Box<ExpressionSyntax>,
349        data_type: QualifiedName,
350        type_parameters: Vec<Span>,
351        /// `WITH TIME ZONE` or `WITHOUT TIME ZONE` after the type modifiers.
352        time_zone: Option<TimeZoneSyntax>,
353    },
354    Collate {
355        expression: Box<ExpressionSyntax>,
356        collation: QualifiedName,
357    },
358    Parenthesized(Box<ExpressionSyntax>),
359}
360
361#[derive(Debug, Clone, PartialEq, Eq)]
362pub enum LiteralSyntax {
363    Null,
364    Boolean(bool),
365    Number(Span),
366    String(Span),
367}
368
369#[derive(Debug, Clone, Copy, PartialEq, Eq)]
370pub enum UnaryOperatorSyntax {
371    Not,
372    Plus,
373    Minus,
374}
375
376#[derive(Debug, Clone, Copy, PartialEq, Eq)]
377pub enum BinaryOperatorSyntax {
378    Or,
379    And,
380    Equal,
381    NotEqual,
382    Less,
383    LessOrEqual,
384    Greater,
385    GreaterOrEqual,
386    Concat,
387    Add,
388    Subtract,
389    Multiply,
390    Divide,
391    Modulo,
392}
393
394#[derive(Debug, Clone, PartialEq, Eq)]
395pub struct GraphTableColumn {
396    pub expression: ExpressionSyntax,
397    pub alias: Option<Identifier>,
398    pub span: Span,
399}
400
401#[derive(Debug, Clone, PartialEq, Eq)]
402pub struct TableAlias {
403    pub name: Identifier,
404    pub columns: Vec<Identifier>,
405    pub span: Span,
406}