Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fb7fd86

Browse files
committed
feat(ast): constraint, fulltext, vector, and SHOW pipeline types
1 parent 8f95cb5 commit fb7fd86

2 files changed

Lines changed: 238 additions & 9 deletions

File tree

crates/lora-ast/src/ast.rs

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ pub struct Span {
77
}
88

99
impl Span {
10+
#[must_use]
1011
pub const fn new(start: usize, end: usize) -> Self {
1112
Self { start, end }
1213
}
@@ -29,6 +30,215 @@ pub enum SchemaCommand {
2930
CreateIndex(CreateIndex),
3031
DropIndex(DropIndex),
3132
ShowIndexes(ShowIndexes),
33+
CreateConstraint(CreateConstraint),
34+
DropConstraint(DropConstraint),
35+
ShowConstraints(ShowConstraints),
36+
}
37+
38+
#[derive(Debug, Clone)]
39+
pub struct CreateConstraint {
40+
pub name: ConstraintNameSpec,
41+
pub if_not_exists: bool,
42+
pub entity: IndexEntityKind,
43+
/// Pattern variable in the `FOR` clause (`n`, `r`).
44+
pub variable: String,
45+
/// Label / rel-type. Always present — constraints don't accept the
46+
/// wildcard form that LOOKUP indexes do.
47+
pub label: String,
48+
pub properties: Vec<String>,
49+
pub kind: ConstraintKind,
50+
pub span: Span,
51+
}
52+
53+
#[derive(Debug, Clone)]
54+
pub struct DropConstraint {
55+
pub name: ConstraintNameSpec,
56+
pub if_exists: bool,
57+
pub span: Span,
58+
}
59+
60+
#[derive(Debug, Clone)]
61+
pub struct ShowConstraints {
62+
pub pipeline: Option<ShowPipeline>,
63+
pub span: Span,
64+
}
65+
66+
/// `SHOW INDEXES YIELD … [WHERE …] [RETURN …]` tail. Modelled after the
67+
/// Neo4j syntax: YIELD is the anchor, optional WHERE filters the
68+
/// yielded rows, optional RETURN reprojects them. ORDER BY / SKIP /
69+
/// LIMIT can appear on either YIELD or RETURN — semantically applied
70+
/// to the rows at that stage.
71+
#[derive(Debug, Clone)]
72+
pub struct ShowPipeline {
73+
pub yield_part: ShowYield,
74+
pub where_: Option<Expr>,
75+
pub return_part: Option<ShowReturn>,
76+
pub span: Span,
77+
}
78+
79+
#[derive(Debug, Clone)]
80+
pub struct ShowYield {
81+
/// `YIELD *` — pass every catalog column through unchanged.
82+
pub star: bool,
83+
/// `YIELD a, b AS x` items (empty when `star` is true).
84+
pub items: Vec<YieldItem>,
85+
pub order: Vec<SortItem>,
86+
pub skip: Option<Expr>,
87+
pub limit: Option<Expr>,
88+
pub span: Span,
89+
}
90+
91+
#[derive(Debug, Clone)]
92+
pub struct ShowReturn {
93+
pub items: Vec<ProjectionItem>,
94+
pub order: Vec<SortItem>,
95+
pub skip: Option<Expr>,
96+
pub limit: Option<Expr>,
97+
pub span: Span,
98+
}
99+
100+
/// Type filter for `SHOW [TYPE] INDEXES`. `All` is the explicit
101+
/// unfiltered form; `Fulltext` and `Vector` parse but yield no rows
102+
/// because those index types aren't backed by anything in the catalog
103+
/// yet.
104+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
105+
pub enum IndexKindFilter {
106+
All,
107+
Range,
108+
Text,
109+
Point,
110+
Lookup,
111+
Fulltext,
112+
Vector,
113+
}
114+
115+
#[derive(Debug, Clone)]
116+
pub enum ConstraintNameSpec {
117+
Literal(String),
118+
Parameter(String),
119+
}
120+
121+
#[derive(Debug, Clone, PartialEq)]
122+
pub enum ConstraintKind {
123+
/// `IS UNIQUE` — single or composite.
124+
Unique,
125+
/// `IS NOT NULL` — single property only.
126+
Existence,
127+
/// `IS NODE KEY` — single or composite, node only.
128+
NodeKey,
129+
/// `IS RELATIONSHIP KEY` — single or composite, relationship only.
130+
RelationshipKey,
131+
/// `IS :: Type` — single property only.
132+
PropertyType(PropertyTypeExpr),
133+
}
134+
135+
impl ConstraintKind {
136+
/// Human-readable tag for SHOW CONSTRAINTS and diagnostics.
137+
#[must_use]
138+
pub fn type_tag(&self, entity: IndexEntityKind) -> &'static str {
139+
match (self, entity) {
140+
(ConstraintKind::Unique, IndexEntityKind::Node) => "NODE_PROPERTY_UNIQUENESS",
141+
(ConstraintKind::Unique, IndexEntityKind::Relationship) => {
142+
"RELATIONSHIP_PROPERTY_UNIQUENESS"
143+
}
144+
(ConstraintKind::Existence, IndexEntityKind::Node) => "NODE_PROPERTY_EXISTENCE",
145+
(ConstraintKind::Existence, IndexEntityKind::Relationship) => {
146+
"RELATIONSHIP_PROPERTY_EXISTENCE"
147+
}
148+
(ConstraintKind::NodeKey, _) => "NODE_KEY",
149+
(ConstraintKind::RelationshipKey, _) => "RELATIONSHIP_KEY",
150+
(ConstraintKind::PropertyType(_), IndexEntityKind::Node) => "NODE_PROPERTY_TYPE",
151+
(ConstraintKind::PropertyType(_), IndexEntityKind::Relationship) => {
152+
"RELATIONSHIP_PROPERTY_TYPE"
153+
}
154+
}
155+
}
156+
}
157+
158+
/// A closed dynamic union of property types: `T1 | T2 | ...`. A single
159+
/// type is represented as a one-element union.
160+
#[derive(Debug, Clone, PartialEq)]
161+
pub struct PropertyTypeExpr {
162+
pub alternatives: Vec<PropertyTypeTerm>,
163+
}
164+
165+
#[derive(Debug, Clone, PartialEq)]
166+
pub enum PropertyTypeTerm {
167+
Scalar(ScalarType),
168+
List {
169+
inner: Box<PropertyTypeTerm>,
170+
/// `LIST<X NOT NULL>` is the only fully-supported list shape in
171+
/// Neo4j compatibility mode; we keep the flag for grammar fidelity
172+
/// even though we reject `LIST<X>` (nullable elements) at the
173+
/// catalog layer.
174+
not_null: bool,
175+
},
176+
Vector {
177+
coord: VectorCoordType,
178+
dimension: u32,
179+
},
180+
}
181+
182+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
183+
pub enum ScalarType {
184+
Boolean,
185+
String,
186+
Integer,
187+
Float,
188+
Date,
189+
LocalTime,
190+
ZonedTime,
191+
LocalDateTime,
192+
ZonedDateTime,
193+
Duration,
194+
Point,
195+
Map,
196+
Any,
197+
}
198+
199+
impl ScalarType {
200+
#[must_use]
201+
pub const fn as_str(self) -> &'static str {
202+
match self {
203+
ScalarType::Boolean => "BOOLEAN",
204+
ScalarType::String => "STRING",
205+
ScalarType::Integer => "INTEGER",
206+
ScalarType::Float => "FLOAT",
207+
ScalarType::Date => "DATE",
208+
ScalarType::LocalTime => "LOCAL TIME",
209+
ScalarType::ZonedTime => "ZONED TIME",
210+
ScalarType::LocalDateTime => "LOCAL DATETIME",
211+
ScalarType::ZonedDateTime => "ZONED DATETIME",
212+
ScalarType::Duration => "DURATION",
213+
ScalarType::Point => "POINT",
214+
ScalarType::Map => "MAP",
215+
ScalarType::Any => "ANY",
216+
}
217+
}
218+
}
219+
220+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
221+
pub enum VectorCoordType {
222+
Int8,
223+
Int16,
224+
Int32,
225+
Int64,
226+
Float32,
227+
Float64,
228+
}
229+
230+
impl VectorCoordType {
231+
#[must_use]
232+
pub const fn as_str(self) -> &'static str {
233+
match self {
234+
VectorCoordType::Int8 => "INT8",
235+
VectorCoordType::Int16 => "INT16",
236+
VectorCoordType::Int32 => "INT32",
237+
VectorCoordType::Int64 => "INT64",
238+
VectorCoordType::Float32 => "FLOAT32",
239+
VectorCoordType::Float64 => "FLOAT64",
240+
}
241+
}
32242
}
33243

34244
#[derive(Debug, Clone)]
@@ -48,7 +258,12 @@ pub struct CreateIndex {
48258
pub variable: String,
49259
/// `Some(label_or_type)` for property indexes; `None` for `LOOKUP` token indexes
50260
/// where the label/type is the wildcard captured by `labels(n)` / `type(r)`.
261+
/// For `FULLTEXT` (which accepts `:A|B|C`) this carries the first label; the
262+
/// rest live in `additional_labels`.
51263
pub label: Option<String>,
264+
/// Extra labels beyond `label`. Only populated for `FULLTEXT` indexes
265+
/// declared with the `(n:A|B|C)` pattern.
266+
pub additional_labels: Vec<String>,
52267
/// Property keys covered by the index. Empty for `LOOKUP` token indexes.
53268
pub properties: Vec<String>,
54269
pub options: Option<IndexOptions>,
@@ -61,15 +276,20 @@ pub enum IndexKind {
61276
Text,
62277
Point,
63278
Lookup,
279+
Vector,
280+
Fulltext,
64281
}
65282

66283
impl IndexKind {
284+
#[must_use]
67285
pub const fn as_str(self) -> &'static str {
68286
match self {
69287
IndexKind::Range => "RANGE",
70288
IndexKind::Text => "TEXT",
71289
IndexKind::Point => "POINT",
72290
IndexKind::Lookup => "LOOKUP",
291+
IndexKind::Vector => "VECTOR",
292+
IndexKind::Fulltext => "FULLTEXT",
73293
}
74294
}
75295
}
@@ -81,6 +301,7 @@ pub enum IndexEntityKind {
81301
}
82302

83303
impl IndexEntityKind {
304+
#[must_use]
84305
pub const fn as_str(self) -> &'static str {
85306
match self {
86307
IndexEntityKind::Node => "NODE",
@@ -103,6 +324,11 @@ pub struct IndexOptions {
103324

104325
#[derive(Debug, Clone)]
105326
pub struct ShowIndexes {
327+
/// Optional index-type filter (e.g. `SHOW RANGE INDEXES`). `None`
328+
/// means no filter clause was written; `Some(IndexKindFilter::All)`
329+
/// is the explicit `SHOW ALL INDEXES` form (semantically the same).
330+
pub filter: Option<IndexKindFilter>,
331+
pub pipeline: Option<ShowPipeline>,
106332
pub span: Span,
107333
}
108334

@@ -543,6 +769,7 @@ pub enum ListPredicateKind {
543769
}
544770

545771
impl Expr {
772+
#[must_use]
546773
pub fn span(&self) -> Span {
547774
match self {
548775
Expr::Variable(v) => v.span,

crates/lora-ast/src/lib.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@
88
pub mod ast;
99

1010
pub use ast::{
11-
BinaryOp, Create, CreateIndex, Delete, Direction, Document, DropIndex, Expr, InQueryCall,
12-
IndexEntityKind, IndexKind, IndexNameSpec, IndexOptions, ListPredicateKind,
13-
MapProjectionSelector, Match, Merge, MergeAction, MultiPartQuery, NodePattern, Pattern,
14-
PatternElement, PatternElementChain, PatternPart, ProcedureInvocation, ProcedureInvocationKind,
15-
ProcedureName, ProjectionBody, ProjectionItem, Query, QueryPart, RangeLiteral, ReadingClause,
16-
RegularQuery, RelationshipDetail, RelationshipPattern, Remove, RemoveItem, Return,
17-
SchemaCommand, Set, SetItem, ShowIndexes, SinglePartQuery, SingleQuery, SortDirection,
18-
SortItem, Span, StandaloneCall, Statement, UnaryOp, UnionPart, Unwind, UpdatingClause,
19-
Variable, With, YieldItem,
11+
BinaryOp, ConstraintKind, ConstraintNameSpec, Create, CreateConstraint, CreateIndex, Delete,
12+
Direction, Document, DropConstraint, DropIndex, Expr, InQueryCall, IndexEntityKind, IndexKind,
13+
IndexKindFilter, IndexNameSpec, IndexOptions, ListPredicateKind, MapProjectionSelector, Match,
14+
Merge, MergeAction, MultiPartQuery, NodePattern, Pattern, PatternElement, PatternElementChain,
15+
PatternPart, ProcedureInvocation, ProcedureInvocationKind, ProcedureName, ProjectionBody,
16+
ProjectionItem, PropertyTypeExpr, PropertyTypeTerm, Query, QueryPart, RangeLiteral,
17+
ReadingClause, RegularQuery, RelationshipDetail, RelationshipPattern, Remove, RemoveItem,
18+
Return, ScalarType, SchemaCommand, Set, SetItem, ShowConstraints, ShowIndexes, ShowPipeline,
19+
ShowReturn, ShowYield, SinglePartQuery, SingleQuery, SortDirection, SortItem, Span,
20+
StandaloneCall, Statement, UnaryOp, UnionPart, Unwind, UpdatingClause, Variable,
21+
VectorCoordType, With, YieldItem,
2022
};

0 commit comments

Comments
 (0)