vastdb 2.0.7__py3-none-any.whl → 2.0.8__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
vastdb/_internal.py CHANGED
@@ -808,9 +808,9 @@ def _parse_table_info(obj, parse_properties):
808
808
  sorting_done = bool(sorting_score_raw >> 63)
809
809
 
810
810
  vector_index_enabled = obj.VectorIndexEnabled() if hasattr(obj, 'VectorIndexEnabled') else False
811
- vector_index_column_name = obj.VectorIndexColumnName().decode() if hasattr(obj, 'VectorIndexColumnName') and obj.VectorIndexColumnName() else None
812
- vector_index_distance_metric = obj.VectorIndexDistanceMetric().decode() if hasattr(obj, 'VectorIndexDistanceMetric') and obj.VectorIndexDistanceMetric() else None
813
- vector_index_sql_function_name = obj.VectorIndexSqlFunctionName().decode() if hasattr(obj, 'VectorIndexSqlFunctionName') and obj.VectorIndexSqlFunctionName() else None
811
+ vector_index_column_name = obj.VectorIndexColumnName().decode() if hasattr(obj, 'VectorIndexColumnName') and obj.VectorIndexColumnName() else ""
812
+ vector_index_distance_metric = obj.VectorIndexDistanceMetric().decode() if hasattr(obj, 'VectorIndexDistanceMetric') and obj.VectorIndexDistanceMetric() else ""
813
+ vector_index_sql_function_name = obj.VectorIndexSqlFunctionName().decode() if hasattr(obj, 'VectorIndexSqlFunctionName') and obj.VectorIndexSqlFunctionName() else ""
814
814
 
815
815
  return TableInfo(name, properties, handle, num_rows, used_bytes, num_partitions, sorting_key_enabled,
816
816
  sorting_score, write_amplification, acummulative_row_insertion_count, sorting_done,
vastdb/schema.py CHANGED
@@ -14,7 +14,7 @@ from vastdb.table_metadata import TableMetadata, TableRef, TableType
14
14
 
15
15
  from . import bucket, errors, schema, table
16
16
  from ._ibis_support import validate_ibis_support_schema
17
- from ._internal import VectorIndexSpec
17
+ from ._internal import VectorIndex, VectorIndexSpec
18
18
 
19
19
  if TYPE_CHECKING:
20
20
  from .table import Table
@@ -178,7 +178,17 @@ def _parse_table_info(table_info, schema: "schema.Schema"):
178
178
  table=table_info.name)
179
179
 
180
180
  table_type = TableType.Elysium if table_info.sorting_key_enabled else TableType.Regular
181
- table_metadata = TableMetadata(ref, table_type=table_type)
181
+
182
+ # populate vector_index from list_tables if vector index is enabled
183
+ vector_index = None
184
+ if table_info.vector_index_enabled:
185
+ vector_index = VectorIndex(
186
+ column=table_info.vector_index_column_name,
187
+ distance_metric=table_info.vector_index_distance_metric,
188
+ sql_distance_function=table_info.vector_index_sql_function_name
189
+ )
190
+
191
+ table_metadata = TableMetadata(ref, table_type=table_type, vector_index=vector_index)
182
192
 
183
193
  return table.Table(handle=int(table_info.handle),
184
194
  metadata=table_metadata,
vastdb/table.py CHANGED
@@ -824,9 +824,8 @@ class TableInTransaction(ITable):
824
824
 
825
825
  Both Elysium and Vector Index tables use global row IDs.
826
826
  """
827
- # check if table has vector index from loaded stats
828
- has_vector_index = (self._metadata.stats is not None and
829
- self._metadata.stats.vector_index is not None)
827
+ # _vector_index is set from list_tables or synced from stats.vector_index by _parse_stats_vector_index()
828
+ has_vector_index = self._metadata._vector_index is not None
830
829
  return self._is_sorted_table or has_vector_index
831
830
 
832
831
  def vector_search(
vastdb/table_metadata.py CHANGED
@@ -173,14 +173,14 @@ class TableMetadata:
173
173
  self._parse_stats_vector_index()
174
174
 
175
175
  def _parse_stats_vector_index(self):
176
- vector_index_is_set = self._vector_index is not None
176
+ if self._vector_index is not None and self._stats.vector_index != self._vector_index:
177
+ is_empty_placeholder = not self._vector_index.column and not self._vector_index.distance_metric
178
+ if not is_empty_placeholder:
179
+ raise ValueError(
180
+ f"Table has index {self._stats.vector_index}, but was initialized as {self._vector_index}"
181
+ )
177
182
 
178
- if vector_index_is_set and self._stats.vector_index != self._vector_index:
179
- raise ValueError(
180
- f"Table has index {self._stats.vector_index}, but was initialized as {self._vector_index}"
181
- )
182
- else:
183
- self._vector_index = self._stats.vector_index
183
+ self._vector_index = self._stats.vector_index
184
184
 
185
185
  def _set_sorted_table(self, tx: "Transaction"):
186
186
  self._table_type = TableType.Elysium
@@ -9,6 +9,7 @@ from contextlib import closing
9
9
  from tempfile import NamedTemporaryFile
10
10
 
11
11
  import ibis
12
+ import numpy as np
12
13
  import pandas as pd
13
14
  import pyarrow as pa
14
15
  import pyarrow.compute as pc
@@ -390,6 +391,7 @@ def test_types(session, clean_bucket_name):
390
391
  ('a2', pa.int16()),
391
392
  ('a4', pa.int64()),
392
393
  ('b', pa.float32()),
394
+ ('f16', pa.float16()),
393
395
  ('s', pa.string()),
394
396
  ('d', pa.decimal128(7, 3)),
395
397
  ('bin', pa.binary()),
@@ -410,6 +412,7 @@ def test_types(session, clean_bucket_name):
410
412
  [1999, 2000, 2001],
411
413
  [11122221, 222111122, 333333],
412
414
  [0.5, 1.5, 2.5],
415
+ [np.float16(0.5), np.float16(1.5), np.float16(2.5)],
413
416
  ["a", "v", "s"],
414
417
  [decimal.Decimal('110.52'), decimal.Decimal('231.15'), decimal.Decimal('3332.44')],
415
418
  [b"\x01\x02", b"\x01\x05", b"\x01\x07"],
@@ -436,6 +439,13 @@ def test_types(session, clean_bucket_name):
436
439
  assert select(t['a2'] == 2000) == expected.filter(pc.field('a2') == 2000)
437
440
  assert select(t['a4'] == 222111122) == expected.filter(pc.field('a4') == 222111122)
438
441
  assert select(t['b'] == 1.5) == expected.filter(pc.field('b') == 1.5)
442
+
443
+ # Test float16 predicate (PyArrow compute doesn't support float16, so validate manually)
444
+ f16_literal = np.float16(1.5)
445
+ result = select(t['f16'] == f16_literal)
446
+ assert len(result) == 1, f"Expected 1 row for f16==1.5, got {len(result)}"
447
+ assert np.float16(result.column('f16')[0].as_py()) == f16_literal
448
+
439
449
  assert select(t['s'] == "v") == expected.filter(pc.field('s') == "v")
440
450
  assert select(t['d'] == 231.15) == expected.filter(pc.field('d') == 231.15)
441
451
  assert select(t['bin'] == b"\x01\x02") == expected.filter(pc.field('bin') == b"\x01\x02")
@@ -468,6 +478,59 @@ def test_types(session, clean_bucket_name):
468
478
  assert select(t['ts9'] == ts_literal) == expected.filter(pc.field('ts9') == ts_literal)
469
479
 
470
480
 
481
+ @pytest.mark.parametrize("element_type,test_name", [
482
+ (pa.float32(), "float32"),
483
+ (pa.float16(), "float16"),
484
+ ])
485
+ def test_vector_types(session, clean_bucket_name, element_type, test_name):
486
+ """Test vector (fixed-size list) columns with different element types."""
487
+ vector_dim = 3
488
+ vec_type = pa.list_(pa.field('', element_type, False), vector_dim)
489
+
490
+ columns = pa.schema([
491
+ ('id', pa.int32()),
492
+ ('vector', vec_type),
493
+ ])
494
+
495
+ # Create test data based on element type
496
+ if element_type == pa.float16():
497
+ test_vectors = [
498
+ [np.float16(1.0), np.float16(2.0), np.float16(3.0)],
499
+ [np.float16(4.5), np.float16(5.5), np.float16(6.5)],
500
+ [np.float16(-1.0), np.float16(0.0), np.float16(1.0)],
501
+ ]
502
+ else: # float32
503
+ test_vectors = [
504
+ [1.0, 2.0, 3.0],
505
+ [4.5, 5.5, 6.5],
506
+ [-1.0, 0.0, 1.0],
507
+ ]
508
+
509
+ expected = pa.table(schema=columns, data=[
510
+ [0, 1, 2],
511
+ test_vectors,
512
+ ])
513
+
514
+ with prepare_data(session, clean_bucket_name, 's', 't', expected) as table:
515
+ # Read back and verify
516
+ actual = table.select().read_all()
517
+ assert actual.schema == columns
518
+ assert len(actual) == 3
519
+
520
+ # Verify vector data
521
+ actual_vectors = actual.column('vector').to_pylist()
522
+ for i, (actual_vec, expected_vec) in enumerate(zip(actual_vectors, test_vectors)):
523
+ assert len(actual_vec) == vector_dim, f"Wrong vector dimension at row {i}"
524
+ for j, (act, exp) in enumerate(zip(actual_vec, expected_vec)):
525
+ if element_type == pa.float16():
526
+ assert np.float16(act) == np.float16(exp), \
527
+ f"Mismatch at row {i}, element {j}: {act} != {exp}"
528
+ else:
529
+ assert act == exp, f"Mismatch at row {i}, element {j}: {act} != {exp}"
530
+
531
+ log.info(f"Vector type test ({test_name}) passed successfully")
532
+
533
+
471
534
  @pytest.mark.parametrize("arrow_type,internal_support", [
472
535
  # Types not supported by Vast.
473
536
  (pa.null(), False),
@@ -160,3 +160,165 @@ def test_vector_index_metadata_from_stats(session: Session, clean_bucket_name: s
160
160
  assert table._metadata._vector_index.distance_metric == "l2sq"
161
161
 
162
162
  log.info("✓ Vector index metadata correctly retrieved from stats")
163
+
164
+
165
+ @pytest.fixture
166
+ def vector_index_test_tables(session: Session, clean_bucket_name: str):
167
+ """
168
+ Fixture that creates a schema with 4 test tables:
169
+ - regular_table: no vector index
170
+ - vector_table_l2: l2sq distance metric
171
+ - vector_table_ip: ip distance metric
172
+ - vector_table_cosine: cosine distance metric
173
+
174
+ Returns a tuple of (schema, table_names_dict, expected_metrics) where:
175
+ - table_names_dict contains the names of all created tables
176
+ - expected_metrics is a list of (metric_key, column, distance_metric, sql_function) tuples
177
+ """
178
+ schema_name = "vector_list_schema"
179
+ vector_dimension = 5
180
+
181
+ with session.transaction() as tx:
182
+ bucket = tx.bucket(clean_bucket_name)
183
+ schema = bucket.create_schema(schema_name)
184
+
185
+ # Create test tables
186
+ vec_type = pa.list_(pa.field('', pa.float32(), False), vector_dimension)
187
+ arrow_schema = pa.schema([
188
+ ('id', pa.int64()),
189
+ ('embedding', vec_type)
190
+ ])
191
+
192
+ table_names = {}
193
+ expected_metrics = []
194
+
195
+ # Regular table without vector index
196
+ table_name = "regular_table"
197
+ schema.create_table(table_name, arrow_schema)
198
+ table_names["regular"] = table_name
199
+ log.info(f"Created regular table: {table_name}")
200
+
201
+ # Vector index table with l2sq metric
202
+ table_name = "vector_table_l2"
203
+ schema.create_table(table_name, arrow_schema, vector_index=VectorIndexSpec("embedding", "l2sq"))
204
+ table_names["l2"] = table_name
205
+ expected_metrics.append(("l2", "embedding", "l2sq", "array_distance"))
206
+ log.info(f"Created vector index table (l2sq): {table_name}")
207
+
208
+ # Vector index table with ip metric
209
+ table_name = "vector_table_ip"
210
+ schema.create_table(table_name, arrow_schema, vector_index=VectorIndexSpec("embedding", "ip"))
211
+ table_names["ip"] = table_name
212
+ expected_metrics.append(("ip", "embedding", "ip", "array_inner_product"))
213
+ log.info(f"Created vector index table (ip): {table_name}")
214
+
215
+ # Vector index table with cosine metric
216
+ table_name = "vector_table_cosine"
217
+ schema.create_table(table_name, arrow_schema, vector_index=VectorIndexSpec("embedding", "cosine"))
218
+ table_names["cosine"] = table_name
219
+ expected_metrics.append(("cosine", "embedding", "cosine", "array_cosine_distance"))
220
+ log.info(f"Created vector index table (cosine): {table_name}")
221
+
222
+ yield schema, table_names, expected_metrics
223
+
224
+
225
+ def _check_vector_index_metadata(actual_column, actual_metric, actual_sql_func,
226
+ expected_column, expected_metric, expected_sql_func,
227
+ expect_full_metadata: bool,
228
+ table_name: str = "table"):
229
+ """Pure checker helper to validate vector index metadata values.
230
+
231
+ Args:
232
+ actual_column: Actual column name from result
233
+ actual_metric: Actual distance metric from result
234
+ actual_sql_func: Actual SQL function name from result
235
+ expected_column: Expected column name (when full metadata is present)
236
+ expected_metric: Expected distance metric (when full metadata is present)
237
+ expected_sql_func: Expected SQL function name (when full metadata is present)
238
+ expect_full_metadata: Whether full metadata should be present
239
+ table_name: Name of table for error messages
240
+ """
241
+ # Determine actual expected values based on metadata presence
242
+ if expect_full_metadata:
243
+ expected_col = expected_column
244
+ expected_met = expected_metric
245
+ expected_sql = expected_sql_func
246
+ else:
247
+ # When metadata is not loaded, both Table objects and TableInfo use empty strings
248
+ expected_col = ""
249
+ expected_met = ""
250
+ expected_sql = ""
251
+
252
+ assert actual_column == expected_col, \
253
+ f"Expected column='{expected_col}', got '{actual_column}' for {table_name}"
254
+ assert actual_metric == expected_met, \
255
+ f"Expected metric='{expected_met}', got '{actual_metric}' for {table_name}"
256
+ assert actual_sql_func == expected_sql, \
257
+ f"Expected sql_func='{expected_sql}', got '{actual_sql_func}' for {table_name}"
258
+
259
+
260
+ @pytest.mark.parametrize("test_case,use_public_api,include_metadata,expect_full_metadata", [
261
+ # Test 1: Public API schema.tables() - returns Table objects with empty metadata
262
+ ("schema.tables() public API", True, None, False),
263
+ # Test 2: Internal API with full metadata enabled
264
+ ("_iter_tables(include_vector_index_metadata=True)", False, True, True),
265
+ # Test 3: Internal API with metadata disabled - returns flag only
266
+ ("_iter_tables(include_vector_index_metadata=False)", False, False, False),
267
+ ])
268
+ def test_list_tables_vector_index_metadata(session: Session, vector_index_test_tables,
269
+ test_case: str, use_public_api: bool,
270
+ include_metadata: Optional[bool], expect_full_metadata: bool):
271
+ """
272
+ Test that list_tables APIs return correct vector index metadata based on parameters.
273
+
274
+ Tests three scenarios:
275
+ 1. schema.tables() - public API returns Table objects with vector_index placeholder (empty strings)
276
+ 2. _iter_tables(include_vector_index_metadata=True) - returns full metadata
277
+ 3. _iter_tables(include_vector_index_metadata=False) - returns flag only, no expensive metadata
278
+ """
279
+ schema, table_names, expected_metrics = vector_index_test_tables
280
+
281
+ log.info(f"Testing: {test_case}")
282
+
283
+ # Call the appropriate API and extract vector index info into uniform structure
284
+ if use_public_api:
285
+ # Public API returns Table objects with _vector_index
286
+ results = schema.tables()
287
+ results_by_name = {t.name: (t, t._metadata._vector_index) for t in results}
288
+ else:
289
+ # Internal API returns table info objects with individual vector_index fields
290
+ # Create a simple object to match _vector_index interface
291
+ from types import SimpleNamespace
292
+ results = list(schema._iter_tables(include_vector_index_metadata=include_metadata))
293
+ results_by_name = {}
294
+ for t in results:
295
+ # Create object with same attributes as VectorIndex for uniform access
296
+ vi = SimpleNamespace(
297
+ column=t.vector_index_column_name,
298
+ distance_metric=t.vector_index_distance_metric,
299
+ sql_distance_function=t.vector_index_sql_function_name,
300
+ ) if t.vector_index_enabled else None
301
+ results_by_name[t.name] = (t, vi)
302
+
303
+ assert len(results) == 4, f"Expected 4 tables, got {len(results)}"
304
+
305
+ # Validate regular table (no vector index)
306
+ _, regular_vi = results_by_name[table_names["regular"]]
307
+ assert regular_vi is None, \
308
+ "Expected vector_index=None for regular table"
309
+
310
+ # Validate vector index tables
311
+ for metric_key, expected_column, expected_metric, expected_sql_func in expected_metrics:
312
+ _, vi = results_by_name[table_names[metric_key]]
313
+
314
+ assert vi is not None, \
315
+ f"Expected vector_index present for {metric_key}"
316
+
317
+ _check_vector_index_metadata(
318
+ vi.column, vi.distance_metric, vi.sql_distance_function,
319
+ expected_column, expected_metric, expected_sql_func,
320
+ expect_full_metadata,
321
+ table_name=metric_key
322
+ )
323
+
324
+ log.info(f"{test_case} validated successfully")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vastdb
3
- Version: 2.0.7
3
+ Version: 2.0.8
4
4
  Summary: VAST Data SDK
5
5
  Home-page: https://github.com/vast-data/vastdb_sdk
6
6
  Author: VAST DATA
@@ -20,6 +20,7 @@ Description-Content-Type: text/markdown
20
20
  License-File: LICENSE
21
21
  Requires-Dist: aws-requests-auth
22
22
  Requires-Dist: ibis-framework~=10.1
23
+ Requires-Dist: sqlglot<28.7,>=23.4
23
24
  Requires-Dist: pyarrow~=18.0
24
25
  Requires-Dist: pyarrow-hotfix==0.7
25
26
  Requires-Dist: flatbuffers
@@ -1,17 +1,17 @@
1
1
  vastdb/__init__.py,sha256=uf-AXdzsD4nPxFP7WxkcAXGG0whv8BHLrrXCJtsPGaQ,436
2
2
  vastdb/_adbc.py,sha256=aUjn0hC92U5Jh2jQYeMFzTHYnVP086dVHlMoIoxhvh0,5985
3
3
  vastdb/_ibis_support.py,sha256=sJieOMvDWpsciPKh1mJzS56jxLtCRVlvK41hW84vexM,866
4
- vastdb/_internal.py,sha256=jpgfZFDz12Yo1Lwj6JbhFLWo8PmLCKyppqpc32IBvgM,114719
4
+ vastdb/_internal.py,sha256=-xN2v4nVn8CERbKT2Ub_xDqqy337YjK_d2Dllb8yhEY,114713
5
5
  vastdb/_table_interface.py,sha256=dRcXzC7j1SSpBQ4jCOPF_Zgg66LSt0tBeILM8W_A71c,4130
6
6
  vastdb/bucket.py,sha256=ulkTI_7xw5FYVzcrTFC7G2ijmTTVSmvJZUdgzycGHR0,2588
7
7
  vastdb/config.py,sha256=OehnsWrjzv0-SUouEXmkrKBugiWyhXOn4XiSLV3s9yk,2342
8
8
  vastdb/conftest.py,sha256=vDNqhYMsF630_ueXofnT2zhuSEpjcc4hxcXAjPqlxDI,5525
9
9
  vastdb/errors.py,sha256=GVmiwyrfHrag8GL55ivcF5Kwc1Ro4wvvaJAcuIWvmO0,5764
10
10
  vastdb/features.py,sha256=ivYbvhiGA858B00vhs_CNzlVV9QDUe53yW6V3J5EoxM,1874
11
- vastdb/schema.py,sha256=84h2volDYlaHMhnm0Cg4-sQrdr2rXoQfa_TKjylAUyY,7900
11
+ vastdb/schema.py,sha256=jYEjddYnWxp0-3UsN3B7Kqthagrfy4NtULRwreaMM2c,8325
12
12
  vastdb/session.py,sha256=oUiTx8x_5XOs6EnNvFjon9dSVTk89XhOZ-SfLR8sITQ,2529
13
- vastdb/table.py,sha256=JyHZ6U1fTg9G4XAAQHC5cWlxb2b6hnYRWcA0kM_03RY,46716
14
- vastdb/table_metadata.py,sha256=PSwx1A25AmcCs4ig-Sx_xyXr7xqyGaNIk2LMnIvrwmM,7358
13
+ vastdb/table.py,sha256=1fdzD2eNYBTh9PjGrGamHZ9pjtF5aZULzxhyXSD4z04,46698
14
+ vastdb/table_metadata.py,sha256=HWs3s0LP2gx9EemMb5N7OYnd3zdAletX_DubhvtIOEs,7451
15
15
  vastdb/transaction.py,sha256=JaTvUw86HZ-qFiqjR1fmHndF5bSgMtVWj549MtGsZ5Q,4734
16
16
  vastdb/util.py,sha256=8CUnVRsJukC3uNHNoB5D0qPf0FxS8OSdVB84nNoLJKc,6290
17
17
  vastdb/bench/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -53,9 +53,9 @@ vastdb/tests/test_projections.py,sha256=v43WrIdz_Ru4j3VeZ7medRPafzuw1eKMZfbAE56x
53
53
  vastdb/tests/test_sanity.py,sha256=bv1ypGDzvOgmMvGbucDYiLQu8krQLlE6NB3M__q87x8,3303
54
54
  vastdb/tests/test_schemas.py,sha256=l70YQMlx2UL1KRQhApriiG2ZM7GJF-IzWU31H3Yqn1U,3312
55
55
  vastdb/tests/test_table_in_tx.py,sha256=-OFGaZMZQc78HOmR23xHIsH7d0VBneFG3tGdDlogceM,9105
56
- vastdb/tests/test_tables.py,sha256=yU5fBeHentNe22Rc1e73mj33M0nl63Y_acOy6VTzF-4,54496
56
+ vastdb/tests/test_tables.py,sha256=HZBulgWhLh74MSSkOzOnWYiG4cQOi8T7-N8E3IMnIPo,56927
57
57
  vastdb/tests/test_util.py,sha256=n7gvT5Wg6b6bxgqkFXkYqvFd_W1GlUdVfmPv66XYXyA,1956
58
- vastdb/tests/test_vector_index.py,sha256=qgppSQG77PUgmdXzfprX1mxUkkqq7tbxCA3MRaYFFgQ,6460
58
+ vastdb/tests/test_vector_index.py,sha256=3JEyL2JqTWOACxJ0nihmOfLxX-ICVisCZMK1EfOOu-w,13871
59
59
  vastdb/tests/test_vector_search.py,sha256=50mnBFuw0PAApMLkYwDUMV5VxQorswzD_f_XdpaEXTo,7103
60
60
  vastdb/tests/util.py,sha256=cv8Qcvy92vpBbiiuqXr7pAfbh2K8ziBVZ_j1EQ4vT6o,5994
61
61
  vastdb/vast_flatbuf/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -219,8 +219,8 @@ vastdb/vast_flatbuf/tabular/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMp
219
219
  vastdb/vast_tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
220
220
  vastdb/vast_tests/test_ha.py,sha256=744P4G6VJ09RIkHhMQL4wlipCBJWQVMhyvUrSc4k1HQ,975
221
221
  vastdb/vast_tests/test_scale.py,sha256=RZ4K4DQB1N4XOBIfNqp3-aIDeXHIqXN115gQpjSyIXA,4055
222
- vastdb-2.0.7.dist-info/licenses/LICENSE,sha256=obffan7LYrq7hLHNrY7vHcn2pKUTBUYXMKu-VOAvDxU,11333
223
- vastdb-2.0.7.dist-info/METADATA,sha256=P1r6sOebX-XL4NPzidEDDprrQHp5cIaLJ6iyro5fKBU,1721
224
- vastdb-2.0.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
225
- vastdb-2.0.7.dist-info/top_level.txt,sha256=nnKAaZaQa8GFbYpWAexr_B9HrhonZbUlX6hL6AC--yA,7
226
- vastdb-2.0.7.dist-info/RECORD,,
222
+ vastdb-2.0.8.dist-info/licenses/LICENSE,sha256=obffan7LYrq7hLHNrY7vHcn2pKUTBUYXMKu-VOAvDxU,11333
223
+ vastdb-2.0.8.dist-info/METADATA,sha256=YCzUbEjArA0qr6cY1xAuZ-I6BXcShcrrqY6VzMscqIs,1756
224
+ vastdb-2.0.8.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
225
+ vastdb-2.0.8.dist-info/top_level.txt,sha256=nnKAaZaQa8GFbYpWAexr_B9HrhonZbUlX6hL6AC--yA,7
226
+ vastdb-2.0.8.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5