forked from vlasky/sqlite-vec
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest-parser.py
More file actions
283 lines (222 loc) · 12.7 KB
/
Copy pathtest-parser.py
File metadata and controls
283 lines (222 loc) · 12.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
"""
Tests for vec0 table definition parser edge cases.
These tests verify that the parser correctly rejects malformed table definitions.
They specifically target the bug fixes where `&&` was incorrectly used instead of `||`
in parser condition checks (e.g., vec0_parse_table_option, vec0_parse_partition_key_definition,
vec0_parse_auxiliary_column_definition, vec0_parse_primary_key_definition, vec0_parse_vector_column).
"""
import sqlite3
import pytest
from collections import OrderedDict
def exec(db, sql, parameters=[]):
"""Execute SQL and return result dict, capturing errors."""
try:
rows = db.execute(sql, parameters).fetchall()
except (sqlite3.OperationalError, sqlite3.DatabaseError) as e:
return {
"error": e.__class__.__name__,
"message": str(e),
}
a = []
for row in rows:
o = OrderedDict()
for k in row.keys():
o[k] = row[k]
a.append(o)
result = OrderedDict()
result["sql"] = sql
result["rows"] = a
return result
class TestTableOptionParser:
"""Tests for vec0_parse_table_option edge cases."""
def test_missing_equals_sign(self, db, snapshot):
"""Table option without '=' should fail."""
result = exec(db, "create virtual table v using vec0(chunk_size 8, a float[4])")
assert result == snapshot(name="missing equals sign")
def test_missing_value(self, db, snapshot):
"""Table option with '=' but no value should fail."""
result = exec(db, "create virtual table v using vec0(chunk_size=, a float[4])")
assert result == snapshot(name="missing value after equals")
def test_missing_key(self, db, snapshot):
"""Table option with '=' but no key should fail."""
result = exec(db, "create virtual table v using vec0(=8, a float[4])")
assert result == snapshot(name="missing key before equals")
def test_extra_tokens_after_value(self, db, snapshot):
"""Table option with extra tokens after value should fail."""
result = exec(db, "create virtual table v using vec0(chunk_size=8 extra, a float[4])")
assert result == snapshot(name="extra tokens after value")
def test_valid_table_option(self, db):
"""Sanity check: valid table option should succeed."""
db.execute("create virtual table v using vec0(chunk_size=8, a float[4])")
# If we get here without exception, it worked
db.execute("drop table v")
class TestPartitionKeyParser:
"""Tests for vec0_parse_partition_key_definition edge cases."""
def test_missing_type(self, db, snapshot):
"""Partition key without type should fail."""
result = exec(db, "create virtual table v using vec0(p partition key, a float[4])")
assert result == snapshot(name="partition key missing type")
def test_missing_partition_keyword(self, db, snapshot):
"""Column with just 'key' but not 'partition' should fail or parse differently."""
result = exec(db, "create virtual table v using vec0(p int key, a float[4])")
assert result == snapshot(name="missing partition keyword")
def test_missing_key_keyword(self, db, snapshot):
"""Column with 'partition' but not 'key' should fail."""
result = exec(db, "create virtual table v using vec0(p int partition, a float[4])")
assert result == snapshot(name="missing key keyword")
def test_invalid_type(self, db, snapshot):
"""Partition key with invalid type should fail."""
result = exec(db, "create virtual table v using vec0(p blob partition key, a float[4])")
assert result == snapshot(name="invalid partition key type")
def test_valid_int_partition_key(self, db):
"""Sanity check: valid int partition key should succeed."""
db.execute("create virtual table v using vec0(p int partition key, a float[4])")
db.execute("drop table v")
def test_valid_text_partition_key(self, db):
"""Sanity check: valid text partition key should succeed."""
db.execute("create virtual table v using vec0(p text partition key, a float[4])")
db.execute("drop table v")
class TestAuxiliaryColumnParser:
"""Tests for vec0_parse_auxiliary_column_definition edge cases."""
def test_plus_without_name(self, db, snapshot):
"""Auxiliary column '+' without column name should fail."""
result = exec(db, "create virtual table v using vec0(+ text, a float[4])")
assert result == snapshot(name="plus without column name")
def test_plus_without_type(self, db, snapshot):
"""Auxiliary column with name but no type should fail."""
result = exec(db, "create virtual table v using vec0(+aux, a float[4])")
assert result == snapshot(name="auxiliary without type")
def test_invalid_auxiliary_type(self, db, snapshot):
"""Auxiliary column with invalid type should fail."""
result = exec(db, "create virtual table v using vec0(+aux varchar, a float[4])")
assert result == snapshot(name="invalid auxiliary type")
def test_valid_text_auxiliary(self, db):
"""Sanity check: valid text auxiliary column should succeed."""
db.execute("create virtual table v using vec0(+aux text, a float[4])")
db.execute("drop table v")
def test_valid_integer_auxiliary(self, db):
"""Sanity check: valid integer auxiliary column should succeed."""
db.execute("create virtual table v using vec0(+aux integer, a float[4])")
db.execute("drop table v")
def test_valid_float_auxiliary(self, db):
"""Sanity check: valid float auxiliary column should succeed."""
db.execute("create virtual table v using vec0(+aux float, a float[4])")
db.execute("drop table v")
def test_valid_blob_auxiliary(self, db):
"""Sanity check: valid blob auxiliary column should succeed."""
db.execute("create virtual table v using vec0(+aux blob, a float[4])")
db.execute("drop table v")
class TestPrimaryKeyParser:
"""Tests for vec0_parse_primary_key_definition edge cases."""
def test_missing_type(self, db, snapshot):
"""Primary key without type should fail."""
result = exec(db, "create virtual table v using vec0(id primary key, a float[4])")
assert result == snapshot(name="primary key missing type")
def test_missing_primary_keyword(self, db, snapshot):
"""Column with 'key' but not 'primary' should fail or parse differently."""
result = exec(db, "create virtual table v using vec0(id int key, a float[4])")
assert result == snapshot(name="missing primary keyword")
def test_missing_key_keyword(self, db, snapshot):
"""Column with 'primary' but not 'key' should fail."""
result = exec(db, "create virtual table v using vec0(id int primary, a float[4])")
assert result == snapshot(name="missing key keyword after primary")
def test_invalid_type(self, db, snapshot):
"""Primary key with invalid type should fail."""
result = exec(db, "create virtual table v using vec0(id blob primary key, a float[4])")
assert result == snapshot(name="invalid primary key type")
def test_valid_int_primary_key(self, db):
"""Sanity check: valid int primary key should succeed."""
db.execute("create virtual table v using vec0(id int primary key, a float[4])")
db.execute("drop table v")
def test_valid_text_primary_key(self, db):
"""Sanity check: valid text primary key should succeed."""
db.execute("create virtual table v using vec0(id text primary key, a float[4])")
db.execute("drop table v")
class TestVectorColumnParser:
"""Tests for vec0_parse_vector_column edge cases."""
def test_missing_dimensions(self, db, snapshot):
"""Vector column without dimensions should fail."""
result = exec(db, "create virtual table v using vec0(a float)")
assert result == snapshot(name="vector missing dimensions")
def test_missing_type(self, db, snapshot):
"""Vector column without type should fail."""
result = exec(db, "create virtual table v using vec0(a [4])")
assert result == snapshot(name="vector missing type")
def test_zero_dimensions(self, db, snapshot):
"""Vector column with zero dimensions should fail."""
result = exec(db, "create virtual table v using vec0(a float[0])")
assert result == snapshot(name="zero dimensions")
def test_negative_dimensions(self, db, snapshot):
"""Vector column with negative dimensions should fail."""
result = exec(db, "create virtual table v using vec0(a float[-1])")
assert result == snapshot(name="negative dimensions")
def test_distance_metric_missing_equals(self, db, snapshot):
"""distance_metric without '=' should fail."""
result = exec(db, "create virtual table v using vec0(a float[4] distance_metric l2)")
assert result == snapshot(name="distance_metric missing equals")
def test_distance_metric_missing_value(self, db, snapshot):
"""distance_metric= without value should fail."""
result = exec(db, "create virtual table v using vec0(a float[4] distance_metric=)")
assert result == snapshot(name="distance_metric missing value")
def test_distance_metric_invalid_value(self, db, snapshot):
"""distance_metric with invalid value should fail."""
result = exec(db, "create virtual table v using vec0(a float[4] distance_metric=invalid)")
assert result == snapshot(name="distance_metric invalid value")
def test_valid_float_vector(self, db):
"""Sanity check: valid float vector should succeed."""
db.execute("create virtual table v using vec0(a float[4])")
db.execute("drop table v")
def test_valid_int8_vector(self, db):
"""Sanity check: valid int8 vector should succeed."""
db.execute("create virtual table v using vec0(a int8[4])")
db.execute("drop table v")
def test_valid_bit_vector(self, db):
"""Sanity check: valid bit vector should succeed."""
db.execute("create virtual table v using vec0(a bit[64])")
db.execute("drop table v")
def test_valid_distance_metric_l2(self, db):
"""Sanity check: valid L2 distance metric should succeed."""
db.execute("create virtual table v using vec0(a float[4] distance_metric=l2)")
db.execute("drop table v")
def test_valid_distance_metric_cosine(self, db):
"""Sanity check: valid cosine distance metric should succeed."""
db.execute("create virtual table v using vec0(a float[4] distance_metric=cosine)")
db.execute("drop table v")
def test_valid_distance_metric_l1(self, db):
"""Sanity check: valid L1 distance metric should succeed."""
db.execute("create virtual table v using vec0(a float[4] distance_metric=L1)")
db.execute("drop table v")
class TestMalformedDefinitions:
"""Tests for completely malformed table definitions."""
def test_empty_definition(self, db, snapshot):
"""Empty vec0 definition should fail."""
result = exec(db, "create virtual table v using vec0()")
assert result == snapshot(name="empty definition")
def test_only_whitespace(self, db, snapshot):
"""Definition with only whitespace should fail."""
result = exec(db, "create virtual table v using vec0( )")
assert result == snapshot(name="only whitespace")
def test_just_comma(self, db, snapshot):
"""Definition with just comma should fail."""
result = exec(db, "create virtual table v using vec0(,)")
assert result == snapshot(name="just comma")
def test_trailing_comma(self, db, snapshot):
"""Definition with trailing comma should fail."""
result = exec(db, "create virtual table v using vec0(a float[4],)")
assert result == snapshot(name="trailing comma")
def test_leading_comma(self, db, snapshot):
"""Definition with leading comma should fail."""
result = exec(db, "create virtual table v using vec0(, a float[4])")
assert result == snapshot(name="leading comma")
def test_double_comma(self, db, snapshot):
"""Definition with double comma should fail."""
result = exec(db, "create virtual table v using vec0(a float[4],, b float[4])")
assert result == snapshot(name="double comma")
def test_number_only(self, db, snapshot):
"""Definition with just a number should fail."""
result = exec(db, "create virtual table v using vec0(123)")
assert result == snapshot(name="number only")
def test_special_characters(self, db, snapshot):
"""Definition with special characters should fail."""
result = exec(db, "create virtual table v using vec0(@#$)")
assert result == snapshot(name="special characters")