|
6 | 6 | BetweenExpr, |
7 | 7 | CompareExpr, |
8 | 8 | CreateCollectionStmt, |
| 9 | + CreateIndexStmt, |
9 | 10 | DeleteStmt, |
10 | 11 | DropCollectionStmt, |
11 | 12 | FilterExpr, |
@@ -150,34 +151,45 @@ def _parse_insert_bulk_body(self) -> InsertBulkStmt: |
150 | 151 |
|
151 | 152 | def _parse_create(self) -> CreateCollectionStmt: |
152 | 153 | self._expect(TokenKind.CREATE) |
153 | | - self._expect(TokenKind.COLLECTION) |
154 | | - collection = self._parse_identifier() |
155 | | - hybrid: bool = False |
156 | | - model: str | None = None |
157 | | - |
158 | | - if self._peek().kind == TokenKind.HYBRID: |
159 | | - # Bare HYBRID shorthand — backward compat |
| 154 | + if self._peek().kind == TokenKind.COLLECTION: |
160 | 155 | self._advance() |
161 | | - hybrid = True |
162 | | - elif self._peek().kind == TokenKind.USING: |
163 | | - self._advance() # consume USING |
| 156 | + collection = self._parse_identifier() |
| 157 | + hybrid: bool = False |
| 158 | + model: str | None = None |
| 159 | + |
164 | 160 | if self._peek().kind == TokenKind.HYBRID: |
165 | | - self._advance() # consume HYBRID |
| 161 | + # Bare HYBRID shorthand — backward compat |
| 162 | + self._advance() |
166 | 163 | hybrid = True |
167 | | - # Optional DENSE MODEL sub-clause |
168 | | - if self._peek().kind == TokenKind.DENSE: |
169 | | - self._advance() # consume DENSE |
| 164 | + elif self._peek().kind == TokenKind.USING: |
| 165 | + self._advance() # consume USING |
| 166 | + if self._peek().kind == TokenKind.HYBRID: |
| 167 | + self._advance() # consume HYBRID |
| 168 | + hybrid = True |
| 169 | + # Optional DENSE MODEL sub-clause |
| 170 | + if self._peek().kind == TokenKind.DENSE: |
| 171 | + self._advance() # consume DENSE |
| 172 | + self._expect(TokenKind.MODEL) |
| 173 | + model = self._expect(TokenKind.STRING).value |
| 174 | + else: |
170 | 175 | self._expect(TokenKind.MODEL) |
171 | 176 | model = self._expect(TokenKind.STRING).value |
172 | | - else: |
173 | | - self._expect(TokenKind.MODEL) |
174 | | - model = self._expect(TokenKind.STRING).value |
175 | 177 |
|
176 | | - return CreateCollectionStmt( |
177 | | - collection=collection, |
178 | | - hybrid=hybrid, |
179 | | - model=model, |
180 | | - ) |
| 178 | + return CreateCollectionStmt( |
| 179 | + collection=collection, |
| 180 | + hybrid=hybrid, |
| 181 | + model=model, |
| 182 | + ) |
| 183 | + |
| 184 | + self._expect(TokenKind.INDEX) |
| 185 | + self._expect(TokenKind.ON) |
| 186 | + self._expect(TokenKind.COLLECTION) |
| 187 | + collection = self._parse_identifier() |
| 188 | + self._expect(TokenKind.FOR) |
| 189 | + field_name = self._parse_field_path() |
| 190 | + self._expect(TokenKind.TYPE) |
| 191 | + schema = self._expect(TokenKind.IDENTIFIER).value.lower() |
| 192 | + return CreateIndexStmt(collection=collection, field_name=field_name, schema=schema) |
181 | 193 |
|
182 | 194 | def _parse_drop(self) -> DropCollectionStmt: |
183 | 195 | self._expect(TokenKind.DROP) |
@@ -356,20 +368,24 @@ def _parse_delete(self) -> DeleteStmt: |
356 | 368 | self._expect(TokenKind.FROM) |
357 | 369 | collection = self._parse_identifier() |
358 | 370 | self._expect(TokenKind.WHERE) |
359 | | - self._expect(TokenKind.ID) |
360 | | - self._expect(TokenKind.EQUALS) |
361 | | - tok = self._peek() |
362 | | - if tok.kind == TokenKind.STRING: |
363 | | - self._advance() |
364 | | - point_id: str | int = tok.value |
365 | | - elif tok.kind == TokenKind.INTEGER: |
| 371 | + if self._peek().kind == TokenKind.ID: |
366 | 372 | self._advance() |
367 | | - point_id = int(tok.value) |
368 | | - else: |
369 | | - raise QQLSyntaxError( |
370 | | - f"Expected string or integer for point id, got '{tok.value}'", tok.pos |
371 | | - ) |
372 | | - return DeleteStmt(collection=collection, point_id=point_id) |
| 373 | + self._expect(TokenKind.EQUALS) |
| 374 | + tok = self._peek() |
| 375 | + if tok.kind == TokenKind.STRING: |
| 376 | + self._advance() |
| 377 | + point_id: str | int = tok.value |
| 378 | + elif tok.kind == TokenKind.INTEGER: |
| 379 | + self._advance() |
| 380 | + point_id = int(tok.value) |
| 381 | + else: |
| 382 | + raise QQLSyntaxError( |
| 383 | + f"Expected string or integer for point id, got '{tok.value}'", tok.pos |
| 384 | + ) |
| 385 | + return DeleteStmt(collection=collection, point_id=point_id) |
| 386 | + |
| 387 | + query_filter = self._parse_filter_expr() |
| 388 | + return DeleteStmt(collection=collection, query_filter=query_filter) |
373 | 389 |
|
374 | 390 | # ── WHERE clause filter parsing (precedence: NOT > AND > OR) ───────── |
375 | 391 |
|
|
0 commit comments