From 918716cf16b8ddfb5cab3b3e71a2fa25b8f83105 Mon Sep 17 00:00:00 2001 From: Srimon Date: Wed, 29 Apr 2026 16:24:39 +0530 Subject: [PATCH] feat: update _parse_create method to support CreateIndexStmt and add quantile validation tests Co-authored-by: Copilot --- src/qql/parser.py | 10 ++++++++-- tests/test_parser.py | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/qql/parser.py b/src/qql/parser.py index 9331dc2..42f9fa2 100644 --- a/src/qql/parser.py +++ b/src/qql/parser.py @@ -151,7 +151,7 @@ def _parse_insert_bulk_body(self) -> InsertBulkStmt: model=model, hybrid=hybrid, sparse_model=sparse_model, ) - def _parse_create(self) -> CreateCollectionStmt: + def _parse_create(self) -> CreateCollectionStmt | CreateIndexStmt: self._expect(TokenKind.CREATE) if self._peek().kind == TokenKind.COLLECTION: self._advance() @@ -213,7 +213,13 @@ def _parse_quantize_clause(self) -> QuantizationConfig: always_ram: bool = False if self._peek().kind == TokenKind.QUANTILE: self._advance() - quantile = float(self._expect(TokenKind.FLOAT).value) + quantile_tok = self._peek() + quantile = float(self._parse_number()) + if not 0.0 <= quantile <= 1.0: + raise QQLSyntaxError( + f"QUANTILE must be between 0 and 1 inclusive, got {quantile}", + quantile_tok.pos, + ) if self._peek().kind == TokenKind.ALWAYS: self._advance() self._expect(TokenKind.RAM) diff --git a/tests/test_parser.py b/tests/test_parser.py index 5eb0673..e0e07d5 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -928,6 +928,16 @@ def test_scalar_with_quantile(self): assert node.quantization.type == QuantizationType.SCALAR assert node.quantization.quantile == pytest.approx(0.99) + def test_scalar_with_quantile_zero(self): + node = parse("CREATE COLLECTION articles QUANTIZE SCALAR QUANTILE 0") + assert node.quantization.type == QuantizationType.SCALAR + assert node.quantization.quantile == pytest.approx(0.0) + + def test_scalar_with_quantile_one(self): + node = parse("CREATE COLLECTION articles QUANTIZE SCALAR QUANTILE 1") + assert node.quantization.type == QuantizationType.SCALAR + assert node.quantization.quantile == pytest.approx(1.0) + def test_scalar_with_always_ram(self): node = parse("CREATE COLLECTION articles QUANTIZE SCALAR ALWAYS RAM") assert node.quantization.always_ram is True @@ -1013,3 +1023,11 @@ def test_quantize_missing_type_raises(self): def test_quantize_unknown_type_raises(self): with pytest.raises(QQLSyntaxError): parse("CREATE COLLECTION articles QUANTIZE FULL") + + def test_scalar_quantile_above_one_raises(self): + with pytest.raises(QQLSyntaxError): + parse("CREATE COLLECTION articles QUANTIZE SCALAR QUANTILE 1.5") + + def test_scalar_quantile_integer_above_one_raises(self): + with pytest.raises(QQLSyntaxError): + parse("CREATE COLLECTION articles QUANTIZE SCALAR QUANTILE 2")