vastdb 1.3.3__py3-none-any.whl → 1.3.5__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
@@ -58,6 +58,10 @@ import vast_flatbuf.org.apache.arrow.computeir.flatbuf.Source as fb_source
58
58
  import vast_flatbuf.org.apache.arrow.computeir.flatbuf.StringLiteral as fb_string_lit
59
59
  import vast_flatbuf.org.apache.arrow.computeir.flatbuf.TimeLiteral as fb_time_lit
60
60
  import vast_flatbuf.org.apache.arrow.computeir.flatbuf.TimestampLiteral as fb_timestamp_lit
61
+ import vast_flatbuf.org.apache.arrow.computeir.flatbuf.UInt8Literal as fb_uint8_lit
62
+ import vast_flatbuf.org.apache.arrow.computeir.flatbuf.UInt16Literal as fb_uint16_lit
63
+ import vast_flatbuf.org.apache.arrow.computeir.flatbuf.UInt32Literal as fb_uint32_lit
64
+ import vast_flatbuf.org.apache.arrow.computeir.flatbuf.UInt64Literal as fb_uint64_lit
61
65
  import vast_flatbuf.org.apache.arrow.flatbuf.Binary as fb_binary
62
66
  import vast_flatbuf.org.apache.arrow.flatbuf.Bool as fb_bool
63
67
  import vast_flatbuf.org.apache.arrow.flatbuf.Date as fb_date
@@ -115,6 +119,8 @@ TABULAR_INVALID_ROW_ID = 0xFFFFFFFFFFFF # (1<<48)-1
115
119
  ESTORE_INVALID_EHANDLE = UINT64_MAX
116
120
  IMPORTED_OBJECTS_TABLE_NAME = "vastdb-imported-objects"
117
121
 
122
+ KAFKA_TOPICS_SCHEMA_NAME = 'kafka_topics'
123
+
118
124
  """
119
125
  S3 Tabular API
120
126
  """
@@ -341,50 +347,57 @@ class Predicate:
341
347
  fb_expression.AddImpl(self.builder, offset_call)
342
348
  return fb_expression.End(self.builder)
343
349
 
350
+ # see https://github.com/apache/arrow/blob/main/format/Schema.fbs
351
+ # https://github.com/apache/arrow/blob/apache-arrow-7.0.0/experimental/computeir/Expression.fbs
352
+ # https://github.com/apache/arrow/blob/apache-arrow-7.0.0/experimental/computeir/Literal.fbs
344
353
  def build_literal(self, field: pa.Field, value):
345
354
  literal_type: Any
346
355
 
347
- if field.type.equals(pa.int64()):
348
- literal_type = fb_int64_lit
349
- literal_impl = LiteralImpl.Int64Literal
356
+ if field.type.equals(pa.int64()) or field.type.equals(pa.uint64()):
357
+ is_signed = field.type.equals(pa.int64())
358
+ literal_type = fb_int64_lit if is_signed else fb_uint64_lit
359
+ literal_impl = LiteralImpl.Int64Literal if is_signed else LiteralImpl.UInt64Literal
350
360
 
351
361
  field_type_type = Type.Int
352
362
  fb_int.Start(self.builder)
353
363
  fb_int.AddBitWidth(self.builder, field.type.bit_width)
354
- fb_int.AddIsSigned(self.builder, True)
364
+ fb_int.AddIsSigned(self.builder, is_signed)
355
365
  field_type = fb_int.End(self.builder)
356
366
 
357
367
  value = int(value)
358
- elif field.type.equals(pa.int32()):
359
- literal_type = fb_int32_lit
360
- literal_impl = LiteralImpl.Int32Literal
368
+ elif field.type.equals(pa.int32()) or field.type.equals(pa.uint32()):
369
+ is_signed = field.type.equals(pa.int32())
370
+ literal_type = fb_int32_lit if is_signed else fb_uint32_lit
371
+ literal_impl = LiteralImpl.Int32Literal if is_signed else LiteralImpl.UInt32Literal
361
372
 
362
373
  field_type_type = Type.Int
363
374
  fb_int.Start(self.builder)
364
375
  fb_int.AddBitWidth(self.builder, field.type.bit_width)
365
- fb_int.AddIsSigned(self.builder, True)
376
+ fb_int.AddIsSigned(self.builder, is_signed)
366
377
  field_type = fb_int.End(self.builder)
367
378
 
368
379
  value = int(value)
369
- elif field.type.equals(pa.int16()):
370
- literal_type = fb_int16_lit
371
- literal_impl = LiteralImpl.Int16Literal
380
+ elif field.type.equals(pa.int16()) or field.type.equals(pa.uint16()):
381
+ is_signed = field.type.equals(pa.int16())
382
+ literal_type = fb_int16_lit if is_signed else fb_uint16_lit
383
+ literal_impl = LiteralImpl.Int16Literal if is_signed else LiteralImpl.UInt16Literal
372
384
 
373
385
  field_type_type = Type.Int
374
386
  fb_int.Start(self.builder)
375
387
  fb_int.AddBitWidth(self.builder, field.type.bit_width)
376
- fb_int.AddIsSigned(self.builder, True)
388
+ fb_int.AddIsSigned(self.builder, is_signed)
377
389
  field_type = fb_int.End(self.builder)
378
390
 
379
391
  value = int(value)
380
- elif field.type.equals(pa.int8()):
381
- literal_type = fb_int8_lit
382
- literal_impl = LiteralImpl.Int8Literal
392
+ elif field.type.equals(pa.int8()) or field.type.equals(pa.uint8()):
393
+ is_signed = field.type.equals(pa.int8())
394
+ literal_type = fb_int8_lit if is_signed else fb_uint8_lit
395
+ literal_impl = LiteralImpl.Int8Literal if is_signed else LiteralImpl.UInt8Literal
383
396
 
384
397
  field_type_type = Type.Int
385
398
  fb_int.Start(self.builder)
386
399
  fb_int.AddBitWidth(self.builder, field.type.bit_width)
387
- fb_int.AddIsSigned(self.builder, True)
400
+ fb_int.AddIsSigned(self.builder, is_signed)
388
401
  field_type = fb_int.End(self.builder)
389
402
 
390
403
  value = int(value)
@@ -776,15 +789,14 @@ def _decode_table_props(s):
776
789
  TableInfo = namedtuple('TableInfo', 'name properties handle num_rows size_in_bytes num_partitions')
777
790
 
778
791
 
779
- def _parse_table_info(obj):
792
+ def _parse_table_info(obj, parse_properties):
780
793
  name = obj.Name().decode()
781
794
  properties = obj.Properties().decode()
782
795
  handle = obj.Handle().decode()
783
796
  num_rows = obj.NumRows()
784
797
  used_bytes = obj.SizeInBytes()
785
798
  num_partitions = obj.NumPartitions()
786
- if num_partitions != 0:
787
- properties = _decode_table_props(properties)
799
+ properties = parse_properties(properties)
788
800
  return TableInfo(name, properties, handle, num_rows, used_bytes, num_partitions)
789
801
 
790
802
 
@@ -1098,9 +1110,29 @@ class VastdbApi:
1098
1110
 
1099
1111
  return snapshots, is_truncated, marker
1100
1112
 
1101
- def create_table(self, bucket, schema, name, arrow_schema=None, txid=0, client_tags=[], expected_retvals=[],
1102
- topic_partitions=0, create_imports_table=False, use_external_row_ids_allocation=False,
1103
- message_timestamp_type=None, retention_ms=None, message_timestamp_after_max_ms=None, message_timestamp_before_max_ms=None):
1113
+ def create_table(self, bucket, schema, name, arrow_schema=None,
1114
+ txid=0, client_tags=[], expected_retvals=[],
1115
+ create_imports_table=False, use_external_row_ids_allocation=False, table_props=None):
1116
+ self._create_table_internal(bucket=bucket, schema=schema, name=name, arrow_schema=arrow_schema,
1117
+ txid=txid, client_tags=client_tags, expected_retvals=expected_retvals,
1118
+ create_imports_table=create_imports_table, use_external_row_ids_allocation=use_external_row_ids_allocation,
1119
+ table_props=table_props)
1120
+
1121
+ def create_topic(self, bucket, name, topic_partitions, expected_retvals=[],
1122
+ message_timestamp_type=None, retention_ms=None, message_timestamp_after_max_ms=None,
1123
+ message_timestamp_before_max_ms=None):
1124
+ table_props = _encode_table_props(message_timestamp_type=message_timestamp_type,
1125
+ retention_ms=retention_ms,
1126
+ message_timestamp_after_max_ms=message_timestamp_after_max_ms,
1127
+ message_timestamp_before_max_ms=message_timestamp_before_max_ms)
1128
+
1129
+ self._create_table_internal(bucket=bucket, schema=KAFKA_TOPICS_SCHEMA_NAME, name=name, arrow_schema=None,
1130
+ expected_retvals=expected_retvals, topic_partitions=topic_partitions,
1131
+ table_props=table_props)
1132
+
1133
+ def _create_table_internal(self, bucket, schema, name, arrow_schema=None,
1134
+ txid=0, client_tags=[], expected_retvals=[], topic_partitions=0,
1135
+ create_imports_table=False, use_external_row_ids_allocation=False, table_props=None):
1104
1136
  """
1105
1137
  Create a table, use the following request
1106
1138
  POST /bucket/schema/table?table HTTP/1.1
@@ -1131,10 +1163,8 @@ class VastdbApi:
1131
1163
  if create_imports_table:
1132
1164
  url_params['sub-table'] = IMPORTED_OBJECTS_TABLE_NAME
1133
1165
 
1134
- if topic_partitions > 0:
1135
- table_props = _encode_table_props(message_timestamp_type=message_timestamp_type, retention_ms=retention_ms, message_timestamp_after_max_ms=message_timestamp_after_max_ms, message_timestamp_before_max_ms=message_timestamp_before_max_ms)
1136
- if table_props is not None:
1137
- url_params['table-props'] = table_props
1166
+ if table_props is not None:
1167
+ url_params['table-props'] = table_props
1138
1168
 
1139
1169
  self._request(
1140
1170
  method="POST",
@@ -1163,9 +1193,22 @@ class VastdbApi:
1163
1193
  endpoints = [self.url] # we cannot replace the host by a VIP address in HTTPS-based URLs
1164
1194
  return TableStatsResult(num_rows, size_in_bytes, is_external_rowid_alloc, tuple(endpoints))
1165
1195
 
1166
- def alter_table(self, bucket, schema, name, txid=0, client_tags=[], table_properties="",
1196
+ def alter_topic(self, bucket, name,
1167
1197
  new_name="", expected_retvals=[],
1168
- message_timestamp_type=None, retention_ms=None, message_timestamp_after_max_ms=None, message_timestamp_before_max_ms=None):
1198
+ message_timestamp_type=None, retention_ms=None, message_timestamp_after_max_ms=None,
1199
+ message_timestamp_before_max_ms=None):
1200
+ table_properties = _encode_table_props(message_timestamp_type=message_timestamp_type,
1201
+ retention_ms=retention_ms,
1202
+ message_timestamp_after_max_ms=message_timestamp_after_max_ms,
1203
+ message_timestamp_before_max_ms=message_timestamp_before_max_ms)
1204
+ if table_properties is None:
1205
+ table_properties = ""
1206
+
1207
+ self.alter_table(bucket=bucket, schema=KAFKA_TOPICS_SCHEMA_NAME, name=name,
1208
+ table_properties=table_properties, expected_retvals=expected_retvals)
1209
+
1210
+ def alter_table(self, bucket, schema, name, txid=0, client_tags=[], table_properties="",
1211
+ new_name="", expected_retvals=[]):
1169
1212
  """
1170
1213
  PUT /mybucket/myschema/mytable?table HTTP/1.1
1171
1214
  Content-Length: ContentLength
@@ -1177,10 +1220,8 @@ class VastdbApi:
1177
1220
  """
1178
1221
  builder = flatbuffers.Builder(1024)
1179
1222
 
1180
- if message_timestamp_type is not None or retention_ms is not None or message_timestamp_after_max_ms is not None or message_timestamp_before_max_ms is not None:
1181
- table_properties = _encode_table_props(message_timestamp_type=message_timestamp_type, retention_ms=retention_ms, message_timestamp_after_max_ms=message_timestamp_after_max_ms, message_timestamp_before_max_ms=message_timestamp_before_max_ms)
1182
- if table_properties is None:
1183
- table_properties = ""
1223
+ if table_properties is None:
1224
+ table_properties = ""
1184
1225
 
1185
1226
  properties = builder.CreateString(table_properties)
1186
1227
  tabular_alter_table.Start(builder)
@@ -1200,6 +1241,10 @@ class VastdbApi:
1200
1241
  url=self._url(bucket=bucket, schema=schema, table=name, command="table", url_params=url_params),
1201
1242
  data=alter_table_req, headers=headers)
1202
1243
 
1244
+ def drop_topic(self, bucket, name, expected_retvals=[]):
1245
+ self.drop_table(bucket=bucket, schema=KAFKA_TOPICS_SCHEMA_NAME, name=name,
1246
+ expected_retvals=expected_retvals)
1247
+
1203
1248
  def drop_table(self, bucket, schema, name, txid=0, client_tags=[], expected_retvals=[], remove_imports_table=False):
1204
1249
  """
1205
1250
  DELETE /mybucket/schema_path/mytable?table HTTP/1.1
@@ -1216,8 +1261,26 @@ class VastdbApi:
1216
1261
  url=self._url(bucket=bucket, schema=schema, table=name, command="table", url_params=url_params),
1217
1262
  headers=headers)
1218
1263
 
1264
+ def list_topics(self, bucket, max_keys=1000, next_key=0, name_prefix="",
1265
+ exact_match=False, expected_retvals=[], include_list_stats=False, count_only=False):
1266
+ return self._list_tables_internal(bucket=bucket, schema=KAFKA_TOPICS_SCHEMA_NAME,
1267
+ parse_properties=_decode_table_props, max_keys=max_keys,
1268
+ next_key=next_key, name_prefix=name_prefix, exact_match=exact_match,
1269
+ expected_retvals=expected_retvals,
1270
+ include_list_stats=include_list_stats, count_only=count_only)
1271
+
1219
1272
  def list_tables(self, bucket, schema, txid=0, client_tags=[], max_keys=1000, next_key=0, name_prefix="",
1220
1273
  exact_match=False, expected_retvals=[], include_list_stats=False, count_only=False):
1274
+ def parse_properties(x):
1275
+ return x
1276
+ return self._list_tables_internal(bucket=bucket, schema=schema, txid=txid, client_tags=client_tags,
1277
+ parse_properties=parse_properties, max_keys=max_keys, next_key=next_key,
1278
+ name_prefix=name_prefix, exact_match=exact_match,
1279
+ expected_retvals=expected_retvals,
1280
+ include_list_stats=include_list_stats, count_only=count_only)
1281
+
1282
+ def _list_tables_internal(self, bucket, schema, parse_properties, txid=0, client_tags=[], max_keys=1000, next_key=0, name_prefix="",
1283
+ exact_match=False, expected_retvals=[], include_list_stats=False, count_only=False):
1221
1284
  """
1222
1285
  GET /mybucket/schema_path?table HTTP/1.1
1223
1286
  tabular-txid: TransactionId
@@ -1254,7 +1317,7 @@ class VastdbApi:
1254
1317
  tables_length = lists.TablesLength()
1255
1318
  count = int(res_headers['tabular-list-count']) if 'tabular-list-count' in res_headers else tables_length
1256
1319
  for i in range(tables_length):
1257
- tables.append(_parse_table_info(lists.Tables(i)))
1320
+ tables.append(_parse_table_info(lists.Tables(i), parse_properties))
1258
1321
 
1259
1322
  return bucket_name, schema_name, tables, next_key, is_truncated, count
1260
1323
 
@@ -1826,7 +1889,7 @@ class VastdbApi:
1826
1889
  raise ValueError(f'bucket: {bucket} did not start from {bucket_name}')
1827
1890
  projections_length = lists.ProjectionsLength()
1828
1891
  for i in range(projections_length):
1829
- projections.append(_parse_table_info(lists.Projections(i)))
1892
+ projections.append(_parse_table_info(lists.Projections(i), lambda x: x))
1830
1893
 
1831
1894
  return bucket_name, schema_name, table_name, projections, next_key, is_truncated, count
1832
1895
 
vastdb/tests/metrics.py CHANGED
@@ -29,7 +29,7 @@ class Table:
29
29
  self.conn = conn
30
30
  self.name = name
31
31
  columns = ", ".join(
32
- f"{f.name} {_MAP_SQLITE_TYPES[f.type]}"
32
+ f"{f.name} {_MAP_SQLITE_TYPES[f.type]}" # type: ignore
33
33
  for f in self.fields
34
34
  )
35
35
  cmd = f"CREATE TABLE {self.name} ({columns})"
@@ -388,6 +388,33 @@ def test_types(session, clean_bucket_name):
388
388
  assert select(t['ts9'] == ts_literal) == expected.filter(pc.field('ts9') == ts_literal)
389
389
 
390
390
 
391
+ def test_unsigned_filters(session, clean_bucket_name):
392
+ columns = pa.schema([
393
+ ('a', pa.uint8()),
394
+ ('b', pa.uint16()),
395
+ ('c', pa.uint32()),
396
+ ('d', pa.uint64()),
397
+ ])
398
+
399
+ expected = pa.table(schema=columns, data=[
400
+ [1, 2, 3],
401
+ [11, 22, 33],
402
+ [111, 222, 333],
403
+ [1111, 2222, 3333],
404
+ ])
405
+
406
+ with prepare_data(session, clean_bucket_name, 's', 't', expected) as table:
407
+ def select(predicate):
408
+ return table.select(predicate=predicate).read_all()
409
+
410
+ assert select(True) == expected
411
+ for t in [table, ibis._]:
412
+ assert select(t['a'] > 2) == expected.filter(pc.field('a') > 2)
413
+ assert select(t['b'] > 22) == expected.filter(pc.field('b') > 22)
414
+ assert select(t['c'] > 222) == expected.filter(pc.field('c') > 222)
415
+ assert select(t['d'] > 2222) == expected.filter(pc.field('d') > 2222)
416
+
417
+
391
418
  def test_filters(session, clean_bucket_name):
392
419
  columns = pa.schema([
393
420
  ('a', pa.int32()),
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vastdb
3
- Version: 1.3.3
3
+ Version: 1.3.5
4
4
  Summary: VAST Data SDK
5
5
  Home-page: https://github.com/vast-data/vastdb_sdk
6
6
  Author: VAST DATA
@@ -151,7 +151,7 @@ vast_flatbuf/tabular/S3File.py,sha256=KC9c2oS5-JXwTTriUVFdjOvRG0B54Cq9kviSDZY3NI
151
151
  vast_flatbuf/tabular/VipRange.py,sha256=_BJd1RRZAcK76T9vlsHzXKYVsPVaz6WTEAqStMQCAUQ,2069
152
152
  vast_flatbuf/tabular/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
153
153
  vastdb/__init__.py,sha256=J1JjKiFkKC95BHowfh9kJfQFTjRce-QMsc6zF_FfxC0,432
154
- vastdb/_internal.py,sha256=nLa2G6FwjPiirjXo4HBc3Cs6P2XH8ub1yBsy1Zxu0R8,95257
154
+ vastdb/_internal.py,sha256=N3Z5uQ9aYj-UlzJTtBBXpht2JV685emtiVhawm1zlKQ,99787
155
155
  vastdb/bucket.py,sha256=5KuKhPjZOevznZqWHDVVocejvAy7dcwobPuV6BJCfPc,2544
156
156
  vastdb/config.py,sha256=1tMYtzKXerGcIUjH4tIGEvZNWvO4fviCEdcNCnELJZo,2269
157
157
  vastdb/conftest.py,sha256=X2kVveySPQYZlVBXUMoo7Oea5IsvmJzjdqq3fpH2kVw,3469
@@ -191,21 +191,21 @@ vastdb/bench/perf_bench/query/query.py,sha256=h98Ui6vUTw16LHMY0ufkLnyVO3QCR8f1cX
191
191
  vastdb/bench/perf_bench/query/query_pyarrow.py,sha256=Dj5YPUvb4dAj7RskHfJcPijJnM-rdYIAItEF2dp4jfo,2305
192
192
  vastdb/bench/perf_bench/query/query_vastdb.py,sha256=SZYem_EmsaynEftAa_VFobjSJZDAcli9BckyRS3SFvg,2810
193
193
  vastdb/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
194
- vastdb/tests/metrics.py,sha256=N6ELJUmZubhAMmUtDbisXr6TFhSDgVCTTU05gBVxHRA,1010
194
+ vastdb/tests/metrics.py,sha256=ZCSeBYFSPMG3yI0JrAHs2CrY6wFjx_5GwRTYHVAwLKA,1026
195
195
  vastdb/tests/test_duckdb.py,sha256=STw_1PwTQR8Naz6s0p6lQTV1ZTKKhe3LPBUbhqzTCu0,1880
196
196
  vastdb/tests/test_imports.py,sha256=xKub3-bisFjH0BsZM8COfiUWuMrtoOoQKprF6VQT9RI,5669
197
197
  vastdb/tests/test_nested.py,sha256=LPU6uV3Ri23dBzAEMFQqRPbqapV5LfmiHSHkhILPIY0,6332
198
198
  vastdb/tests/test_projections.py,sha256=3y1kubwVrzO-xoR0hyps7zrjOJI8niCYspaFTN16Q9w,4540
199
199
  vastdb/tests/test_sanity.py,sha256=bv1ypGDzvOgmMvGbucDYiLQu8krQLlE6NB3M__q87x8,3303
200
200
  vastdb/tests/test_schemas.py,sha256=l70YQMlx2UL1KRQhApriiG2ZM7GJF-IzWU31H3Yqn1U,3312
201
- vastdb/tests/test_tables.py,sha256=711oTcdw431zs5LAyDxvTaJqF86xYwVCo5iZxSpH58o,39184
201
+ vastdb/tests/test_tables.py,sha256=PwtUTmQdm4HDZJVq981h7RKcFDma2Loxz6FeQhQSu2Y,40101
202
202
  vastdb/tests/test_util.py,sha256=n7gvT5Wg6b6bxgqkFXkYqvFd_W1GlUdVfmPv66XYXyA,1956
203
203
  vastdb/tests/util.py,sha256=dpRJYbboDnlqL4qIdvScpp8--5fxRUBIcIYitrfcj9o,555
204
204
  vastdb/vast_tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
205
205
  vastdb/vast_tests/test_ha.py,sha256=744P4G6VJ09RIkHhMQL4wlipCBJWQVMhyvUrSc4k1HQ,975
206
206
  vastdb/vast_tests/test_scale.py,sha256=5jGwOdZH6Tv5tPdZYPWoqcxOceI2jA5i2D1zNKZHER4,3958
207
- vastdb-1.3.3.dist-info/LICENSE,sha256=obffan7LYrq7hLHNrY7vHcn2pKUTBUYXMKu-VOAvDxU,11333
208
- vastdb-1.3.3.dist-info/METADATA,sha256=xqBDm4Puvz348pzEDM7b_IIs-nZDSha7Sgg0RHHh94w,1340
209
- vastdb-1.3.3.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
210
- vastdb-1.3.3.dist-info/top_level.txt,sha256=Vsj2MKtlhPg0J4so64slQtnwjhgoPmJgcG-6YcVAwVc,20
211
- vastdb-1.3.3.dist-info/RECORD,,
207
+ vastdb-1.3.5.dist-info/LICENSE,sha256=obffan7LYrq7hLHNrY7vHcn2pKUTBUYXMKu-VOAvDxU,11333
208
+ vastdb-1.3.5.dist-info/METADATA,sha256=Vsfa6X_4snlbZNOVzNZ5x_HKEDzZozAn1Q3i9rCpRv4,1340
209
+ vastdb-1.3.5.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
210
+ vastdb-1.3.5.dist-info/top_level.txt,sha256=Vsj2MKtlhPg0J4so64slQtnwjhgoPmJgcG-6YcVAwVc,20
211
+ vastdb-1.3.5.dist-info/RECORD,,
File without changes