vastdb 0.1.5__tar.gz → 0.1.6__tar.gz
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-0.1.5 → vastdb-0.1.6}/CHANGELOG.md +12 -0
- {vastdb-0.1.5/vastdb.egg-info → vastdb-0.1.6}/PKG-INFO +1 -1
- {vastdb-0.1.5 → vastdb-0.1.6}/setup.py +1 -1
- {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/bench/test_perf.py +1 -2
- {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/bucket.py +12 -37
- {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/conftest.py +13 -4
- {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/errors.py +5 -1
- {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/internal_commands.py +1 -20
- {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/schema.py +45 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/session.py +24 -8
- {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/table.py +18 -6
- {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/tests/test_imports.py +3 -3
- {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/tests/test_nested.py +4 -4
- vastdb-0.1.6/vastdb/tests/test_projections.py +121 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/tests/test_schemas.py +49 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/tests/test_tables.py +53 -28
- {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/transaction.py +23 -14
- {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/util.py +1 -0
- {vastdb-0.1.5 → vastdb-0.1.6/vastdb.egg-info}/PKG-INFO +1 -1
- vastdb-0.1.5/vastdb/tests/test_projections.py +0 -43
- {vastdb-0.1.5 → vastdb-0.1.6}/LICENSE +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/MANIFEST.in +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/README.md +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/requirements.txt +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/setup.cfg +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/__init__.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/__init__.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/__init__.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/__init__.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/__init__.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Aggregate.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/ArraySlice.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/ArraySubscript.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/BinaryLiteral.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/BooleanLiteral.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Bound.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Call.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/CaseFragment.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Cast.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/ConcreteBoundImpl.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/ConditionalCase.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/CurrentRow.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/DateLiteral.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/DecimalLiteral.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Deref.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/DurationLiteral.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Expression.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/ExpressionImpl.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/FieldIndex.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/FieldRef.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Filter.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/FixedSizeBinaryLiteral.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Float16Literal.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Float32Literal.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Float64Literal.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Following.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Frame.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Grouping.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Int16Literal.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Int32Literal.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Int64Literal.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Int8Literal.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/IntervalLiteral.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/IntervalLiteralDaysMilliseconds.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/IntervalLiteralImpl.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/IntervalLiteralMonths.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Join.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/JoinKind.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/KeyValue.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Limit.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/ListLiteral.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Literal.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/LiteralColumn.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/LiteralImpl.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/LiteralRelation.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/MapKey.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/MapLiteral.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/OrderBy.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Ordering.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Plan.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Preceding.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Project.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/RelId.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Relation.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/RelationImpl.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/SetOpKind.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/SetOperation.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/SimpleCase.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/SortKey.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Source.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/StringLiteral.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/StructField.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/StructLiteral.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/TimeLiteral.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/TimestampLiteral.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/UInt16Literal.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/UInt32Literal.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/UInt64Literal.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/UInt8Literal.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Unbounded.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/WindowCall.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/__init__.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Binary.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Block.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/BodyCompression.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/BodyCompressionMethod.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Bool.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Buffer.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/CompressionType.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Date.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/DateUnit.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Decimal.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/DictionaryBatch.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/DictionaryEncoding.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/DictionaryKind.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Duration.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Endianness.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Feature.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Field.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/FieldNode.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/FixedSizeBinary.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/FixedSizeList.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/FloatingPoint.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Footer.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Int.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Interval.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/IntervalUnit.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/KeyValue.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/LargeBinary.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/LargeList.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/LargeUtf8.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/List.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Map.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Message.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/MessageHeader.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/MetadataVersion.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Null.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Precision.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/RecordBatch.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Schema.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/SparseMatrixCompressedAxis.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/SparseMatrixIndexCSX.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/SparseTensor.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/SparseTensorIndex.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/SparseTensorIndexCOO.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/SparseTensorIndexCSF.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Struct_.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Tensor.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/TensorDim.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Time.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/TimeUnit.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Timestamp.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Type.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Union.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/UnionMode.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Utf8.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/__init__.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/tabular/AlterColumnRequest.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/tabular/AlterProjectionTableRequest.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/tabular/AlterSchemaRequest.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/tabular/AlterTableRequest.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/tabular/Column.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/tabular/ColumnType.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/tabular/CreateProjectionRequest.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/tabular/CreateSchemaRequest.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/tabular/GetProjectionTableStatsResponse.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/tabular/GetTableStatsResponse.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/tabular/ImportDataRequest.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/tabular/ListProjectionsResponse.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/tabular/ListSchemasResponse.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/tabular/ListTablesResponse.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/tabular/ObjectDetails.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/tabular/S3File.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/tabular/VipRange.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/tabular/__init__.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/__init__.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/bench/__init__.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/tests/__init__.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/tests/test_duckdb.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/tests/test_sanity.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/tests/test_util.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/tests/util.py +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vastdb.egg-info/SOURCES.txt +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vastdb.egg-info/dependency_links.txt +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vastdb.egg-info/requires.txt +0 -0
- {vastdb-0.1.5 → vastdb-0.1.6}/vastdb.egg-info/top_level.txt +0 -0
|
@@ -4,6 +4,18 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
6
6
|
|
|
7
|
+
## [0.1.6] (2024-05-23)
|
|
8
|
+
[0.1.6]: https://github.com/vast-data/vastdb_sdk/compare/v0.1.5...v0.1.6
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Allow listing and querying Catalog snapshots
|
|
12
|
+
- Support nested schemas
|
|
13
|
+
- Use automatic split estimation
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
- Allow using specific semi-sorted projection (needs VAST 5.1+ release)
|
|
17
|
+
- Add a client-side check for too large requests
|
|
18
|
+
|
|
7
19
|
## [0.1.5] (2024-05-16)
|
|
8
20
|
[0.1.5]: https://github.com/vast-data/vastdb_sdk/compare/v0.1.4...v0.1.5
|
|
9
21
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import time
|
|
3
3
|
|
|
4
|
-
import pyarrow as pa
|
|
5
4
|
import pytest
|
|
6
5
|
|
|
7
6
|
from vastdb import util
|
|
@@ -20,7 +19,7 @@ def test_bench(session, clean_bucket_name, parquets_path, crater_path):
|
|
|
20
19
|
t = util.create_table_from_files(s, 't1', files, config=ImportConfig(import_concurrency=8))
|
|
21
20
|
config = QueryConfig(num_splits=8, num_sub_splits=4)
|
|
22
21
|
s = time.time()
|
|
23
|
-
pa_table =
|
|
22
|
+
pa_table = t.select(columns=['sid'], predicate=t['sid'] == 10033007, config=config).read_all()
|
|
24
23
|
e = time.time()
|
|
25
24
|
log.info("'SELECT sid from TABLE WHERE sid = 10033007' returned in %s seconds.", e - s)
|
|
26
25
|
if crater_path:
|
|
@@ -5,7 +5,7 @@ It is possible to list and access VAST snapshots generated over a bucket.
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
import logging
|
|
8
|
-
from dataclasses import dataclass
|
|
8
|
+
from dataclasses import dataclass, field
|
|
9
9
|
from typing import TYPE_CHECKING, List, Optional
|
|
10
10
|
|
|
11
11
|
from . import errors, schema, transaction
|
|
@@ -22,48 +22,23 @@ class Bucket:
|
|
|
22
22
|
|
|
23
23
|
name: str
|
|
24
24
|
tx: "transaction.Transaction"
|
|
25
|
+
_root_schema: "Schema" = field(init=False, compare=False, repr=False)
|
|
25
26
|
|
|
26
|
-
def
|
|
27
|
+
def __post_init__(self):
|
|
28
|
+
"""Root schema is empty."""
|
|
29
|
+
self._root_schema = schema.Schema(name="", bucket=self)
|
|
30
|
+
|
|
31
|
+
def create_schema(self, name: str, fail_if_exists=True) -> "Schema":
|
|
27
32
|
"""Create a new schema (a container of tables) under this bucket."""
|
|
28
|
-
|
|
29
|
-
if fail_if_exists:
|
|
30
|
-
raise errors.SchemaExists(self.name, path)
|
|
31
|
-
else:
|
|
32
|
-
return current
|
|
33
|
-
self.tx._rpc.api.create_schema(self.name, path, txid=self.tx.txid)
|
|
34
|
-
log.info("Created schema: %s", path)
|
|
35
|
-
return self.schema(path) # type: ignore[return-value]
|
|
33
|
+
return self._root_schema.create_schema(name=name, fail_if_exists=fail_if_exists)
|
|
36
34
|
|
|
37
|
-
def schema(self,
|
|
35
|
+
def schema(self, name: str, fail_if_missing=True) -> Optional["Schema"]:
|
|
38
36
|
"""Get a specific schema (a container of tables) under this bucket."""
|
|
39
|
-
|
|
40
|
-
log.debug("schema: %s", s)
|
|
41
|
-
if not s:
|
|
42
|
-
if fail_if_missing:
|
|
43
|
-
raise errors.MissingSchema(self.name, path)
|
|
44
|
-
else:
|
|
45
|
-
return None
|
|
46
|
-
assert len(s) == 1, f"Expected to receive only a single schema, but got: {len(s)}. ({s})"
|
|
47
|
-
log.debug("Found schema: %s", s[0].name)
|
|
48
|
-
return s[0]
|
|
37
|
+
return self._root_schema.schema(name=name, fail_if_missing=fail_if_missing)
|
|
49
38
|
|
|
50
|
-
def schemas(self,
|
|
39
|
+
def schemas(self, batch_size=None):
|
|
51
40
|
"""List bucket's schemas."""
|
|
52
|
-
schemas
|
|
53
|
-
next_key = 0
|
|
54
|
-
exact_match = bool(name)
|
|
55
|
-
log.debug("list schemas param: schema=%s, exact_match=%s", name, exact_match)
|
|
56
|
-
while True:
|
|
57
|
-
_bucket_name, curr_schemas, next_key, is_truncated, _ = \
|
|
58
|
-
self.tx._rpc.api.list_schemas(bucket=self.name, next_key=next_key, txid=self.tx.txid,
|
|
59
|
-
name_prefix=name, exact_match=exact_match)
|
|
60
|
-
if not curr_schemas:
|
|
61
|
-
break
|
|
62
|
-
schemas.extend(curr_schemas)
|
|
63
|
-
if not is_truncated:
|
|
64
|
-
break
|
|
65
|
-
|
|
66
|
-
return [schema.Schema(name=name, bucket=self) for name, *_ in schemas]
|
|
41
|
+
return self._root_schema.schemas(batch_size=batch_size)
|
|
67
42
|
|
|
68
43
|
def snapshot(self, name, fail_if_missing=True) -> Optional["Bucket"]:
|
|
69
44
|
"""Get snapshot by name (if exists)."""
|
|
@@ -30,14 +30,23 @@ def test_bucket_name(request):
|
|
|
30
30
|
return request.config.getoption("--tabular-bucket-name")
|
|
31
31
|
|
|
32
32
|
|
|
33
|
+
def iter_schemas(s):
|
|
34
|
+
"""Recusively scan all schemas."""
|
|
35
|
+
children = s.schemas()
|
|
36
|
+
for c in children:
|
|
37
|
+
yield from iter_schemas(c)
|
|
38
|
+
yield s
|
|
39
|
+
|
|
40
|
+
|
|
33
41
|
@pytest.fixture(scope="function")
|
|
34
42
|
def clean_bucket_name(request, test_bucket_name, session):
|
|
35
43
|
with session.transaction() as tx:
|
|
36
44
|
b = tx.bucket(test_bucket_name)
|
|
37
|
-
for
|
|
38
|
-
for
|
|
39
|
-
t.
|
|
40
|
-
|
|
45
|
+
for top_schema in b.schemas():
|
|
46
|
+
for s in iter_schemas(top_schema):
|
|
47
|
+
for t in s.tables():
|
|
48
|
+
t.drop()
|
|
49
|
+
s.drop()
|
|
41
50
|
return test_bucket_name
|
|
42
51
|
|
|
43
52
|
|
|
@@ -6,7 +6,6 @@ import struct
|
|
|
6
6
|
import urllib.parse
|
|
7
7
|
from collections import defaultdict, namedtuple
|
|
8
8
|
from enum import Enum
|
|
9
|
-
from ipaddress import IPv4Address, IPv6Address
|
|
10
9
|
from typing import Any, Dict, Iterator, List, Optional, Union
|
|
11
10
|
|
|
12
11
|
import flatbuffers
|
|
@@ -1031,25 +1030,7 @@ class VastdbApi:
|
|
|
1031
1030
|
num_rows = stats.NumRows()
|
|
1032
1031
|
size_in_bytes = stats.SizeInBytes()
|
|
1033
1032
|
is_external_rowid_alloc = stats.IsExternalRowidAlloc()
|
|
1034
|
-
endpoints = []
|
|
1035
|
-
if stats.VipsLength() == 0:
|
|
1036
|
-
endpoints.append(self.url)
|
|
1037
|
-
else:
|
|
1038
|
-
url = urllib3.util.parse_url(self.url)
|
|
1039
|
-
|
|
1040
|
-
ip_cls = IPv6Address if (stats.AddressType() == "ipv6") else IPv4Address
|
|
1041
|
-
vips = [stats.Vips(i) for i in range(stats.VipsLength())]
|
|
1042
|
-
ips = []
|
|
1043
|
-
# extract the vips into list of IPs
|
|
1044
|
-
for vip in vips:
|
|
1045
|
-
start_ip = int(ip_cls(vip.StartAddress().decode()))
|
|
1046
|
-
ips.extend(ip_cls(start_ip + i) for i in range(vip.AddressCount()))
|
|
1047
|
-
# build a list of endpoint URLs, reusing schema and port (if specified when constructing the session).
|
|
1048
|
-
# it is assumed that the client can access the returned IPs (e.g. if they are part of the VIP pool).
|
|
1049
|
-
for ip in ips:
|
|
1050
|
-
d = url._asdict()
|
|
1051
|
-
d['host'] = str(ip)
|
|
1052
|
-
endpoints.append(str(urllib3.util.Url(**d)))
|
|
1033
|
+
endpoints = [self.url] # we cannot replace the host by a VIP address in HTTPS-based URLs
|
|
1053
1034
|
return TableStatsResult(num_rows, size_in_bytes, is_external_rowid_alloc, tuple(endpoints))
|
|
1054
1035
|
|
|
1055
1036
|
def alter_table(self, bucket, schema, name, txid=0, client_tags=[], table_properties="",
|
|
@@ -31,6 +31,51 @@ class Schema:
|
|
|
31
31
|
"""VAST transaction used for this schema."""
|
|
32
32
|
return self.bucket.tx
|
|
33
33
|
|
|
34
|
+
def _subschema_full_name(self, name: str) -> str:
|
|
35
|
+
return f"{self.name}/{name}" if self.name else name
|
|
36
|
+
|
|
37
|
+
def create_schema(self, name: str, fail_if_exists=True) -> "Schema":
|
|
38
|
+
"""Create a new schema (a container of tables) under this schema."""
|
|
39
|
+
if current := self.schema(name, fail_if_missing=False):
|
|
40
|
+
if fail_if_exists:
|
|
41
|
+
raise errors.SchemaExists(self.bucket.name, name)
|
|
42
|
+
else:
|
|
43
|
+
return current
|
|
44
|
+
full_name = self._subschema_full_name(name)
|
|
45
|
+
self.tx._rpc.api.create_schema(self.bucket.name, full_name, txid=self.tx.txid)
|
|
46
|
+
log.info("Created schema: %s", full_name)
|
|
47
|
+
return self.schema(name) # type: ignore[return-value]
|
|
48
|
+
|
|
49
|
+
def schema(self, name: str, fail_if_missing=True) -> Optional["Schema"]:
|
|
50
|
+
"""Get a specific schema (a container of tables) under this schema."""
|
|
51
|
+
_bucket_name, schemas, _next_key, _is_truncated, _ = \
|
|
52
|
+
self.tx._rpc.api.list_schemas(bucket=self.bucket.name, schema=self.name, next_key=0, txid=self.tx.txid,
|
|
53
|
+
name_prefix=name, exact_match=True, max_keys=1)
|
|
54
|
+
names = [name for name, *_ in schemas]
|
|
55
|
+
log.debug("Found schemas: %s", names)
|
|
56
|
+
if not names:
|
|
57
|
+
if fail_if_missing:
|
|
58
|
+
raise errors.MissingSchema(self.bucket.name, self._subschema_full_name(name))
|
|
59
|
+
else:
|
|
60
|
+
return None
|
|
61
|
+
|
|
62
|
+
assert len(names) == 1, f"Expected to receive only a single schema, but got {len(schemas)}: ({schemas})"
|
|
63
|
+
return schema.Schema(name=self._subschema_full_name(names[0]), bucket=self.bucket)
|
|
64
|
+
|
|
65
|
+
def schemas(self, batch_size=None) -> List["Schema"]:
|
|
66
|
+
"""List child schemas."""
|
|
67
|
+
next_key = 0
|
|
68
|
+
if not batch_size:
|
|
69
|
+
batch_size = 1000
|
|
70
|
+
result: List["Schema"] = []
|
|
71
|
+
while True:
|
|
72
|
+
_bucket_name, curr_schemas, next_key, is_truncated, _ = \
|
|
73
|
+
self.tx._rpc.api.list_schemas(bucket=self.bucket.name, schema=self.name, next_key=next_key, max_keys=batch_size, txid=self.tx.txid)
|
|
74
|
+
result.extend(schema.Schema(name=self._subschema_full_name(name), bucket=self.bucket) for name, *_ in curr_schemas)
|
|
75
|
+
if not is_truncated:
|
|
76
|
+
break
|
|
77
|
+
return result
|
|
78
|
+
|
|
34
79
|
def create_table(self, table_name: str, columns: pa.Schema, fail_if_exists=True) -> "Table":
|
|
35
80
|
"""Create a new table under this schema."""
|
|
36
81
|
if current := self.table(table_name, fail_if_missing=False):
|
|
@@ -7,12 +7,15 @@ For more details see:
|
|
|
7
7
|
- [Tabular identity policy with the proper permissions](https://support.vastdata.com/s/article/UUID-14322b60-d6a2-89ac-3df0-3dfbb6974182)
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
|
+
import logging
|
|
10
11
|
import os
|
|
11
12
|
|
|
12
13
|
import boto3
|
|
13
14
|
|
|
14
15
|
from . import errors, internal_commands, transaction
|
|
15
16
|
|
|
17
|
+
log = logging.getLogger()
|
|
18
|
+
|
|
16
19
|
|
|
17
20
|
class Features:
|
|
18
21
|
"""VAST database features - check if server is already support a feature."""
|
|
@@ -21,15 +24,28 @@ class Features:
|
|
|
21
24
|
"""Save the server version."""
|
|
22
25
|
self.vast_version = vast_version
|
|
23
26
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
self.check_imports_table = self._check(
|
|
28
|
+
"Imported objects' table feature requires 5.2+ VAST release",
|
|
29
|
+
vast_version >= (5, 2))
|
|
30
|
+
|
|
31
|
+
self.check_return_row_ids = self._check(
|
|
32
|
+
"Returning row IDs requires 5.1+ VAST release",
|
|
33
|
+
vast_version >= (5, 1))
|
|
34
|
+
|
|
35
|
+
self.check_enforce_semisorted_projection = self._check(
|
|
36
|
+
"Semi-sorted projection enforcement requires 5.1+ VAST release",
|
|
37
|
+
vast_version >= (5, 1))
|
|
38
|
+
|
|
39
|
+
def _check(self, msg, supported):
|
|
40
|
+
log.debug("%s (current version is %s): supported=%s", msg, self.vast_version, supported)
|
|
41
|
+
if not supported:
|
|
42
|
+
def fail():
|
|
43
|
+
raise errors.NotSupportedVersion(msg, self.vast_version)
|
|
44
|
+
return fail
|
|
28
45
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
raise errors.NotSupportedVersion("return_row_ids requires 5.1+", self.vast_version)
|
|
46
|
+
def noop():
|
|
47
|
+
pass
|
|
48
|
+
return noop
|
|
33
49
|
|
|
34
50
|
|
|
35
51
|
class Session:
|
|
@@ -54,7 +54,8 @@ class QueryConfig:
|
|
|
54
54
|
num_sub_splits: int = 4
|
|
55
55
|
|
|
56
56
|
# used to split the table into disjoint subsets of rows, to be processed concurrently using multiple RPCs
|
|
57
|
-
|
|
57
|
+
# will be estimated from the table's row count, if not explicitly set
|
|
58
|
+
num_splits: Optional[int] = None
|
|
58
59
|
|
|
59
60
|
# each endpoint will be handled by a separate worker thread
|
|
60
61
|
# a single endpoint can be specified more than once to benefit from multithreaded execution
|
|
@@ -64,12 +65,15 @@ class QueryConfig:
|
|
|
64
65
|
limit_rows_per_sub_split: int = 128 * 1024
|
|
65
66
|
|
|
66
67
|
# each fiber will read the following number of rowgroups coninuously before skipping
|
|
67
|
-
# in order to use semi-sorted projections this value must be 8
|
|
68
|
+
# in order to use semi-sorted projections this value must be 8 (this is the hard coded size of a row groups per row block).
|
|
68
69
|
num_row_groups_per_sub_split: int = 8
|
|
69
70
|
|
|
70
71
|
# can be disabled for benchmarking purposes
|
|
71
72
|
use_semi_sorted_projections: bool = True
|
|
72
73
|
|
|
74
|
+
# enforce using a specific semi-sorted projection (if enabled above)
|
|
75
|
+
semi_sorted_projection_name: Optional[str] = None
|
|
76
|
+
|
|
73
77
|
# used to estimate the number of splits, given the table rows' count
|
|
74
78
|
rows_per_split: int = 4000000
|
|
75
79
|
|
|
@@ -117,7 +121,8 @@ class SelectSplitState:
|
|
|
117
121
|
limit_rows=self.config.limit_rows_per_sub_split,
|
|
118
122
|
sub_split_start_row_ids=self.subsplits_state.items(),
|
|
119
123
|
enable_sorted_projections=self.config.use_semi_sorted_projections,
|
|
120
|
-
query_imports_table=self.table._imports_table
|
|
124
|
+
query_imports_table=self.table._imports_table,
|
|
125
|
+
projection=self.config.semi_sorted_projection_name)
|
|
121
126
|
pages_iter = internal_commands.parse_query_data_response(
|
|
122
127
|
conn=response.raw,
|
|
123
128
|
schema=self.query_data_request.response_schema,
|
|
@@ -313,11 +318,16 @@ class Table:
|
|
|
313
318
|
|
|
314
319
|
# Take a snapshot of enpoints
|
|
315
320
|
stats = self.get_stats()
|
|
321
|
+
log.debug("stats: %s", stats)
|
|
316
322
|
endpoints = stats.endpoints if config.data_endpoints is None else config.data_endpoints
|
|
323
|
+
log.debug("endpoints: %s", endpoints)
|
|
324
|
+
|
|
325
|
+
if config.num_splits is None:
|
|
326
|
+
config.num_splits = max(1, stats.num_rows // config.rows_per_split)
|
|
327
|
+
log.debug("config: %s", config)
|
|
317
328
|
|
|
318
|
-
if
|
|
319
|
-
|
|
320
|
-
log.debug(f"num_rows={stats.num_rows} rows_per_splits={config.rows_per_split} num_splits={config.num_splits} ")
|
|
329
|
+
if config.semi_sorted_projection_name:
|
|
330
|
+
self.tx._rpc.features.check_enforce_semisorted_projection()
|
|
321
331
|
|
|
322
332
|
if columns is None:
|
|
323
333
|
columns = [f.name for f in self.arrow_schema]
|
|
@@ -342,6 +352,8 @@ class Table:
|
|
|
342
352
|
schema=query_schema,
|
|
343
353
|
predicate=predicate,
|
|
344
354
|
field_names=columns)
|
|
355
|
+
if len(query_data_request.serialized) > util.MAX_QUERY_DATA_REQUEST_SIZE:
|
|
356
|
+
raise errors.TooLargeRequest(f"{len(query_data_request.serialized)} bytes")
|
|
345
357
|
|
|
346
358
|
splits_queue: queue.Queue[int] = queue.Queue()
|
|
347
359
|
|
|
@@ -38,13 +38,13 @@ def test_parallel_imports(session, clean_bucket_name, s3):
|
|
|
38
38
|
t.create_imports_table()
|
|
39
39
|
log.info("Starting import of %d files", num_files)
|
|
40
40
|
t.import_files(files)
|
|
41
|
-
arrow_table =
|
|
41
|
+
arrow_table = t.select(columns=['num']).read_all()
|
|
42
42
|
assert arrow_table.num_rows == num_rows * num_files
|
|
43
|
-
arrow_table =
|
|
43
|
+
arrow_table = t.select(columns=['num'], predicate=t['num'] == 100).read_all()
|
|
44
44
|
assert arrow_table.num_rows == num_files
|
|
45
45
|
import_table = t.imports_table()
|
|
46
46
|
# checking all imports are on the imports table:
|
|
47
|
-
objects_name =
|
|
47
|
+
objects_name = import_table.select(columns=["ObjectName"]).read_all()
|
|
48
48
|
objects_name = objects_name.to_pydict()
|
|
49
49
|
object_names = set(objects_name['ObjectName'])
|
|
50
50
|
prefix = 'prq'
|
|
@@ -22,13 +22,13 @@ def test_nested_select(session, clean_bucket_name):
|
|
|
22
22
|
])
|
|
23
23
|
|
|
24
24
|
with prepare_data(session, clean_bucket_name, 's', 't', expected) as t:
|
|
25
|
-
actual =
|
|
25
|
+
actual = t.select().read_all()
|
|
26
26
|
assert actual == expected
|
|
27
27
|
|
|
28
28
|
names = [f.name for f in columns]
|
|
29
29
|
for n in range(len(names) + 1):
|
|
30
30
|
for cols in itertools.permutations(names, n):
|
|
31
|
-
actual =
|
|
31
|
+
actual = t.select(columns=cols).read_all()
|
|
32
32
|
assert actual == expected.select(cols)
|
|
33
33
|
|
|
34
34
|
|
|
@@ -53,7 +53,7 @@ def test_nested_filter(session, clean_bucket_name):
|
|
|
53
53
|
])
|
|
54
54
|
|
|
55
55
|
with prepare_data(session, clean_bucket_name, 's', 't', expected) as t:
|
|
56
|
-
actual =
|
|
56
|
+
actual = t.select().read_all()
|
|
57
57
|
assert actual == expected
|
|
58
58
|
|
|
59
59
|
names = list('xyzw')
|
|
@@ -62,7 +62,7 @@ def test_nested_filter(session, clean_bucket_name):
|
|
|
62
62
|
ibis_predicate = functools.reduce(
|
|
63
63
|
operator.and_,
|
|
64
64
|
(t[col] > 2 for col in cols))
|
|
65
|
-
actual =
|
|
65
|
+
actual = t.select(predicate=ibis_predicate).read_all()
|
|
66
66
|
|
|
67
67
|
arrow_predicate = functools.reduce(
|
|
68
68
|
operator.and_,
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import time
|
|
3
|
+
|
|
4
|
+
import pyarrow as pa
|
|
5
|
+
|
|
6
|
+
from vastdb.table import QueryConfig
|
|
7
|
+
|
|
8
|
+
log = logging.getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def test_basic_projections(session, clean_bucket_name):
|
|
12
|
+
with session.transaction() as tx:
|
|
13
|
+
s = tx.bucket(clean_bucket_name).create_schema('s1')
|
|
14
|
+
columns = pa.schema([
|
|
15
|
+
('a', pa.int8()),
|
|
16
|
+
('b', pa.int16()),
|
|
17
|
+
('c', pa.string()),
|
|
18
|
+
('d', pa.int16()),
|
|
19
|
+
('e', pa.int64()),
|
|
20
|
+
('s', pa.struct([('x', pa.int8()), ('y', pa.int16())]))
|
|
21
|
+
])
|
|
22
|
+
|
|
23
|
+
assert s.tables() == []
|
|
24
|
+
t = s.create_table('t1', columns)
|
|
25
|
+
assert s.tables() == [t]
|
|
26
|
+
|
|
27
|
+
sorted_columns = ['a']
|
|
28
|
+
unsorted_columns = ['b']
|
|
29
|
+
p1 = t.create_projection('p1', sorted_columns, unsorted_columns)
|
|
30
|
+
|
|
31
|
+
sorted_columns = ['b']
|
|
32
|
+
unsorted_columns = ['c', 'd']
|
|
33
|
+
p2 = t.create_projection('p2', sorted_columns, unsorted_columns)
|
|
34
|
+
|
|
35
|
+
projs = t.projections()
|
|
36
|
+
assert projs == [t.projection('p1'), t.projection('p2')]
|
|
37
|
+
p1 = t.projection('p1')
|
|
38
|
+
assert p1.name == 'p1'
|
|
39
|
+
p2 = t.projection('p2')
|
|
40
|
+
assert p2.name == 'p2'
|
|
41
|
+
|
|
42
|
+
p1.rename('p_new')
|
|
43
|
+
p2.drop()
|
|
44
|
+
projs = t.projections()
|
|
45
|
+
assert len(projs) == 1
|
|
46
|
+
assert projs[0].name == 'p_new'
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def test_query_data_with_projection(session, clean_bucket_name):
|
|
50
|
+
columns = pa.schema([
|
|
51
|
+
('a', pa.int64()),
|
|
52
|
+
('b', pa.int64()),
|
|
53
|
+
('s', pa.utf8()),
|
|
54
|
+
])
|
|
55
|
+
# need to be large enough in order to consider as projection
|
|
56
|
+
|
|
57
|
+
GROUP_SIZE = 128 * 1024
|
|
58
|
+
expected = pa.table(schema=columns, data=[
|
|
59
|
+
[i for i in range(GROUP_SIZE)],
|
|
60
|
+
[i for i in reversed(range(GROUP_SIZE))],
|
|
61
|
+
[f's{i}' for i in range(GROUP_SIZE)],
|
|
62
|
+
])
|
|
63
|
+
|
|
64
|
+
expected_projection_p1 = pa.table(schema=columns, data=[
|
|
65
|
+
[i for i in reversed(range(GROUP_SIZE - 5, GROUP_SIZE))],
|
|
66
|
+
[i for i in range(5)],
|
|
67
|
+
[f's{i}' for i in reversed(range(GROUP_SIZE - 5, GROUP_SIZE))],
|
|
68
|
+
])
|
|
69
|
+
|
|
70
|
+
expected_projection_p2 = pa.table(schema=columns, data=[
|
|
71
|
+
[i for i in range(GROUP_SIZE - 5, GROUP_SIZE)],
|
|
72
|
+
[i for i in reversed(range(5))],
|
|
73
|
+
[f's{i}' for i in range(GROUP_SIZE - 5, GROUP_SIZE)],
|
|
74
|
+
])
|
|
75
|
+
|
|
76
|
+
schema_name = "schema"
|
|
77
|
+
table_name = "table"
|
|
78
|
+
with session.transaction() as tx:
|
|
79
|
+
s = tx.bucket(clean_bucket_name).create_schema(schema_name)
|
|
80
|
+
t = s.create_table(table_name, expected.schema)
|
|
81
|
+
|
|
82
|
+
sorted_columns = ['b']
|
|
83
|
+
unsorted_columns = ['a', 's']
|
|
84
|
+
t.create_projection('p1', sorted_columns, unsorted_columns)
|
|
85
|
+
|
|
86
|
+
sorted_columns = ['a']
|
|
87
|
+
unsorted_columns = ['b', 's']
|
|
88
|
+
t.create_projection('p2', sorted_columns, unsorted_columns)
|
|
89
|
+
|
|
90
|
+
with session.transaction() as tx:
|
|
91
|
+
s = tx.bucket(clean_bucket_name).schema(schema_name)
|
|
92
|
+
t = s.table(table_name)
|
|
93
|
+
t.insert(expected)
|
|
94
|
+
actual = pa.Table.from_batches(t.select(columns=['a', 'b', 's']))
|
|
95
|
+
assert actual == expected
|
|
96
|
+
|
|
97
|
+
time.sleep(3)
|
|
98
|
+
|
|
99
|
+
with session.transaction() as tx:
|
|
100
|
+
config = QueryConfig()
|
|
101
|
+
# in nfs mock server num row groups per row block is 1 so need to change this in the config
|
|
102
|
+
config.num_row_groups_per_sub_split = 1
|
|
103
|
+
|
|
104
|
+
s = tx.bucket(clean_bucket_name).schema(schema_name)
|
|
105
|
+
t = s.table(table_name)
|
|
106
|
+
projection_actual = pa.Table.from_batches(t.select(columns=['a', 'b', 's'], predicate=(t['b'] < 5), config=config))
|
|
107
|
+
# no projection supply - need to be with p1 projeciton
|
|
108
|
+
assert expected_projection_p1 == projection_actual
|
|
109
|
+
|
|
110
|
+
config.semi_sorted_projection_name = 'p1'
|
|
111
|
+
projection_actual = pa.Table.from_batches(t.select(columns=['a', 'b', 's'], predicate=(t['b'] < 5), config=config))
|
|
112
|
+
# expecting results of projection p1 since we asked it specificaly
|
|
113
|
+
assert expected_projection_p1 == projection_actual
|
|
114
|
+
|
|
115
|
+
config.semi_sorted_projection_name = 'p2'
|
|
116
|
+
projection_actual = pa.Table.from_batches(t.select(columns=['a', 'b', 's'], predicate=(t['b'] < 5), config=config))
|
|
117
|
+
# expecting results of projection p2 since we asked it specificaly
|
|
118
|
+
assert expected_projection_p2 == projection_actual
|
|
119
|
+
|
|
120
|
+
t.drop()
|
|
121
|
+
s.drop()
|
|
@@ -61,3 +61,52 @@ def test_list_snapshots(session, clean_bucket_name):
|
|
|
61
61
|
with session.transaction() as tx:
|
|
62
62
|
b = tx.bucket(clean_bucket_name)
|
|
63
63
|
b.snapshots() # VAST Catalog may create some snapshots
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def test_nested_schemas(session, clean_bucket_name):
|
|
67
|
+
with session.transaction() as tx:
|
|
68
|
+
b = tx.bucket(clean_bucket_name)
|
|
69
|
+
s1 = b.create_schema('s1')
|
|
70
|
+
s1_s2 = s1.create_schema('s2')
|
|
71
|
+
s1_s3 = s1.create_schema('s3')
|
|
72
|
+
s1_s3_s4 = s1_s3.create_schema('s4')
|
|
73
|
+
s5 = b.create_schema('s5')
|
|
74
|
+
|
|
75
|
+
assert b.schema('s1') == s1
|
|
76
|
+
assert s1.schema('s2') == s1_s2
|
|
77
|
+
assert s1.schema('s3') == s1_s3
|
|
78
|
+
assert s1_s3.schema('s4') == s1_s3_s4
|
|
79
|
+
assert b.schema('s5') == s5
|
|
80
|
+
|
|
81
|
+
assert b.schemas() == [s1, s5]
|
|
82
|
+
assert s1.schemas() == [s1_s2, s1_s3]
|
|
83
|
+
assert s1_s2.schemas() == []
|
|
84
|
+
assert s1_s3.schemas() == [s1_s3_s4]
|
|
85
|
+
assert s1_s3_s4.schemas() == []
|
|
86
|
+
assert s5.schemas() == []
|
|
87
|
+
|
|
88
|
+
s1_s3_s4.drop()
|
|
89
|
+
assert s1_s3.schemas() == []
|
|
90
|
+
s1_s3.drop()
|
|
91
|
+
assert s1.schemas() == [s1_s2]
|
|
92
|
+
s1_s2.drop()
|
|
93
|
+
assert s1.schemas() == []
|
|
94
|
+
|
|
95
|
+
assert b.schemas() == [s1, s5]
|
|
96
|
+
s1.drop()
|
|
97
|
+
assert b.schemas() == [s5]
|
|
98
|
+
s5.drop()
|
|
99
|
+
assert b.schemas() == []
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def test_schema_pagination(session, clean_bucket_name):
|
|
103
|
+
with session.transaction() as tx:
|
|
104
|
+
b = tx.bucket(clean_bucket_name)
|
|
105
|
+
names = [f's{i}' for i in range(10)]
|
|
106
|
+
schemas = [b.create_schema(name) for name in names]
|
|
107
|
+
assert b.schemas(batch_size=3) == schemas
|
|
108
|
+
|
|
109
|
+
s0 = b.schema('s0')
|
|
110
|
+
names = [f'q{i}' for i in range(10)]
|
|
111
|
+
subschemas = [s0.create_schema(name) for name in names]
|
|
112
|
+
assert s0.schemas(batch_size=3) == subschemas
|