vastdb 1.3.10__tar.gz → 1.4.0__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-1.3.10 → vastdb-1.4.0}/CHANGELOG.md +19 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/PKG-INFO +1 -1
- {vastdb-1.3.10 → vastdb-1.4.0}/setup.py +1 -1
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/_internal.py +50 -34
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/conftest.py +9 -2
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/errors.py +57 -3
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/schema.py +7 -6
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/table.py +39 -11
- vastdb-1.4.0/vastdb/tests/test_fixed_list.py +294 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/tests/test_imports.py +39 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/tests/test_nested.py +13 -8
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/tests/test_tables.py +69 -7
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/tests/util.py +12 -2
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb.egg-info/PKG-INFO +1 -1
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb.egg-info/SOURCES.txt +1 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/CONTRIBUTING.md +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/LICENSE +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/MANIFEST.in +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/README.md +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/requirements.txt +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/setup.cfg +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/__init__.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/bench/__init__.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/bench/perf_bench/__init__.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/bench/perf_bench/bench_repo/__init__.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/bench/perf_bench/bench_repo/mega_combo.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/bench/perf_bench/cli.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/bench/perf_bench/common/__init__.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/bench/perf_bench/common/constants.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/bench/perf_bench/common/log_utils.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/bench/perf_bench/common/types.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/bench/perf_bench/common/utils.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/bench/perf_bench/dataset/__init__.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/bench/perf_bench/dataset/generate_secmaster.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/bench/perf_bench/dataset/generate_stocks_dataset.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/bench/perf_bench/dataset/schemas.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/bench/perf_bench/dataset/secmaster.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/bench/perf_bench/orchestrate/__init__.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/bench/perf_bench/orchestrate/bench_spec.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/bench/perf_bench/orchestrate/results_helpers.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/bench/perf_bench/orchestrate/scenario.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/bench/perf_bench/orchestrate/scenario_generator.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/bench/perf_bench/query/__init__.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/bench/perf_bench/query/arrow_common.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/bench/perf_bench/query/query.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/bench/perf_bench/query/query_pyarrow.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/bench/perf_bench/query/query_vastdb.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/bench/perf_bench/run.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/bench/test_perf.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/bench/test_sample.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/bucket.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/config.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/features.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/session.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/tests/__init__.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/tests/metrics.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/tests/test_duckdb.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/tests/test_projections.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/tests/test_sanity.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/tests/test_schemas.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/tests/test_util.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/transaction.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/util.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/__init__.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/__init__.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/__init__.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/__init__.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/__init__.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Aggregate.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/ArraySlice.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/ArraySubscript.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/BinaryLiteral.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/BooleanLiteral.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Bound.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Call.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/CaseFragment.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Cast.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/ConcreteBoundImpl.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/ConditionalCase.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/CurrentRow.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/DateLiteral.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/DecimalLiteral.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Deref.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/DurationLiteral.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Expression.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/ExpressionImpl.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/FieldIndex.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/FieldRef.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Filter.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/FixedSizeBinaryLiteral.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Float16Literal.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Float32Literal.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Float64Literal.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Following.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Frame.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Grouping.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Int16Literal.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Int32Literal.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Int64Literal.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Int8Literal.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/IntervalLiteral.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/IntervalLiteralDaysMilliseconds.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/IntervalLiteralImpl.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/IntervalLiteralMonths.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Join.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/JoinKind.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/KeyValue.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Limit.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/ListLiteral.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Literal.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/LiteralColumn.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/LiteralImpl.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/LiteralRelation.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/MapKey.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/MapLiteral.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/OrderBy.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Ordering.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Plan.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Preceding.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Project.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/RelId.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Relation.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/RelationImpl.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/SetOpKind.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/SetOperation.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/SimpleCase.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/SortKey.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Source.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/StringLiteral.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/StructField.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/StructLiteral.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/TimeLiteral.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/TimestampLiteral.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/UInt16Literal.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/UInt32Literal.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/UInt64Literal.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/UInt8Literal.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Unbounded.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/WindowCall.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/computeir/flatbuf/__init__.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/Binary.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/Block.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/BodyCompression.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/BodyCompressionMethod.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/Bool.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/Buffer.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/CompressionType.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/Date.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/DateUnit.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/Decimal.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/DictionaryBatch.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/DictionaryEncoding.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/DictionaryKind.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/Duration.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/Endianness.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/Feature.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/Field.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/FieldNode.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/FixedSizeBinary.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/FixedSizeList.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/FloatingPoint.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/Footer.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/Int.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/Interval.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/IntervalUnit.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/KeyValue.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/LargeBinary.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/LargeList.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/LargeUtf8.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/List.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/Map.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/Message.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/MessageHeader.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/MetadataVersion.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/Null.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/Precision.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/RecordBatch.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/Schema.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/SparseMatrixCompressedAxis.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/SparseMatrixIndexCSX.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/SparseTensor.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/SparseTensorIndex.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/SparseTensorIndexCOO.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/SparseTensorIndexCSF.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/Struct_.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/Tensor.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/TensorDim.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/Time.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/TimeUnit.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/Timestamp.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/Type.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/Union.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/UnionMode.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/Utf8.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/org/apache/arrow/flatbuf/__init__.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/tabular/AlterColumnRequest.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/tabular/AlterProjectionTableRequest.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/tabular/AlterSchemaRequest.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/tabular/AlterTableRequest.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/tabular/Column.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/tabular/ColumnDetails.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/tabular/ColumnType.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/tabular/CreateProjectionRequest.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/tabular/CreateSchemaRequest.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/tabular/CreateViewRequest.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/tabular/FilterString.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/tabular/GetProjectionTableStatsResponse.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/tabular/GetRowColumnSecurityResponse.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/tabular/GetTableStatsResponse.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/tabular/ImportDataRequest.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/tabular/KeyName.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/tabular/ListProjectionsResponse.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/tabular/ListSchemasResponse.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/tabular/ListTablesResponse.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/tabular/ListViewsResponse.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/tabular/NameString.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/tabular/ObjectDetails.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/tabular/S3File.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/tabular/VipRange.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_flatbuf/tabular/__init__.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_tests/__init__.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_tests/test_ha.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb/vast_tests/test_scale.py +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb.egg-info/dependency_links.txt +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb.egg-info/requires.txt +0 -0
- {vastdb-1.3.10 → vastdb-1.4.0}/vastdb.egg-info/top_level.txt +0 -0
|
@@ -4,6 +4,25 @@ 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
|
+
## [1.4.0] (2025-07-28)
|
|
8
|
+
[1.4.0]: https://github.com/vast-data/vastdb_sdk/compare/v1.3.11...v1.4.0
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Support for inserting rows by columns
|
|
12
|
+
|
|
13
|
+
## [1.3.11] (2025-07-10)
|
|
14
|
+
[1.3.11]: https://github.com/vast-data/vastdb_sdk/compare/v1.3.10...v1.3.11
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
- Support Tables with FixedSizeListArray of Numerics
|
|
18
|
+
|
|
19
|
+
## Fixed
|
|
20
|
+
- Table insert with no rows
|
|
21
|
+
- Boolean predicates
|
|
22
|
+
- List tables with pagination
|
|
23
|
+
- Amount of threads used for parallel queries
|
|
24
|
+
|
|
25
|
+
|
|
7
26
|
## [1.3.10] (2025-05-11)
|
|
8
27
|
[1.3.10]: https://github.com/vast-data/vastdb_sdk/compare/v1.3.9...v1.3.10
|
|
9
28
|
|
|
@@ -69,6 +69,7 @@ import vastdb.vast_flatbuf.org.apache.arrow.flatbuf.Date as fb_date
|
|
|
69
69
|
import vastdb.vast_flatbuf.org.apache.arrow.flatbuf.Decimal as fb_decimal
|
|
70
70
|
import vastdb.vast_flatbuf.org.apache.arrow.flatbuf.Field as fb_field
|
|
71
71
|
import vastdb.vast_flatbuf.org.apache.arrow.flatbuf.FixedSizeBinary as fb_fixed_size_binary
|
|
72
|
+
import vastdb.vast_flatbuf.org.apache.arrow.flatbuf.FixedSizeList as fb_fixed_size_list
|
|
72
73
|
import vastdb.vast_flatbuf.org.apache.arrow.flatbuf.FloatingPoint as fb_floating_point
|
|
73
74
|
import vastdb.vast_flatbuf.org.apache.arrow.flatbuf.Int as fb_int
|
|
74
75
|
import vastdb.vast_flatbuf.org.apache.arrow.flatbuf.List as fb_list
|
|
@@ -497,7 +498,13 @@ class Predicate:
|
|
|
497
498
|
fb_bool.Start(self.builder)
|
|
498
499
|
field_type = fb_bool.End(self.builder)
|
|
499
500
|
|
|
500
|
-
|
|
501
|
+
# Handle both boolean values and string representations
|
|
502
|
+
if isinstance(value, bool):
|
|
503
|
+
value = value
|
|
504
|
+
elif isinstance(value, str):
|
|
505
|
+
value = value.lower() == 'true'
|
|
506
|
+
else:
|
|
507
|
+
value = bool(value)
|
|
501
508
|
elif isinstance(field.type, pa.Decimal128Type):
|
|
502
509
|
literal_type = fb_decimal_lit
|
|
503
510
|
literal_impl = LiteralImpl.DecimalLiteral
|
|
@@ -608,7 +615,7 @@ class FieldNode:
|
|
|
608
615
|
self.debug = debug
|
|
609
616
|
if isinstance(self.type, pa.StructType):
|
|
610
617
|
self.children = [FieldNode(field, index_iter, parent=self) for field in self.type]
|
|
611
|
-
elif
|
|
618
|
+
elif pa.types.is_list(self.type) or pa.types.is_fixed_size_list(self.type):
|
|
612
619
|
self.children = [FieldNode(self.type.value_field, index_iter, parent=self)]
|
|
613
620
|
elif isinstance(self.type, pa.MapType):
|
|
614
621
|
# Map is represented as List<Struct<K, V>> in Arrow
|
|
@@ -752,7 +759,7 @@ def _iter_nested_arrays(column: pa.Array) -> Iterator[pa.Array]:
|
|
|
752
759
|
if not column.type.num_fields == 1: # Note: VAST serializes only a single struct field at a time
|
|
753
760
|
raise ValueError(f'column.type.num_fields: {column.type.num_fields} not eq to 1')
|
|
754
761
|
yield from _iter_nested_arrays(column.field(0))
|
|
755
|
-
elif
|
|
762
|
+
elif pa.types.is_list(column.type) or pa.types.is_fixed_size_list(column.type):
|
|
756
763
|
yield from _iter_nested_arrays(column.values) # Note: Map is serialized in VAST as a List<Struct<K, V>>
|
|
757
764
|
|
|
758
765
|
|
|
@@ -853,10 +860,11 @@ class VastdbApi:
|
|
|
853
860
|
VAST_VERSION_REGEX = re.compile(r'^vast (\d+\.\d+\.\d+\.\d+)$')
|
|
854
861
|
|
|
855
862
|
def __init__(self, endpoint, access_key, secret_key,
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
863
|
+
*,
|
|
864
|
+
ssl_verify=True,
|
|
865
|
+
timeout=None,
|
|
866
|
+
backoff_config: Optional[BackoffConfig] = None,
|
|
867
|
+
version_check=True):
|
|
860
868
|
|
|
861
869
|
from . import version # import lazily here (to avoid circular dependencies)
|
|
862
870
|
self.client_sdk_version = f"VAST Database Python SDK {version()} - 2024 (c)"
|
|
@@ -896,29 +904,30 @@ class VastdbApi:
|
|
|
896
904
|
aws_region='',
|
|
897
905
|
aws_service='s3')
|
|
898
906
|
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
if not server_header.startswith(self.VAST_SERVER_PREFIX):
|
|
907
|
-
raise UnsupportedServer(f'{self.url} is not a VAST DB server endpoint ("{server_header}")')
|
|
908
|
-
|
|
909
|
-
if m := self.VAST_VERSION_REGEX.match(server_header):
|
|
910
|
-
self.vast_version: Tuple[int, ...] = tuple(int(v) for v in m.group(1).split("."))
|
|
911
|
-
return
|
|
907
|
+
if version_check:
|
|
908
|
+
# probe the cluster for its version
|
|
909
|
+
res = self._request(method="GET", url=self._url(command="transaction"), skip_status_check=True) # used only for the response headers
|
|
910
|
+
_logger.debug("headers=%s code=%s content=%s", res.headers, res.status_code, res.content)
|
|
911
|
+
server_header = res.headers.get("Server")
|
|
912
|
+
if server_header is None:
|
|
913
|
+
_logger.error("Response doesn't contain 'Server' header")
|
|
912
914
|
else:
|
|
913
|
-
|
|
915
|
+
if not server_header.startswith(self.VAST_SERVER_PREFIX):
|
|
916
|
+
raise UnsupportedServer(f'{self.url} is not a VAST DB server endpoint ("{server_header}")')
|
|
914
917
|
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
918
|
+
if m := self.VAST_VERSION_REGEX.match(server_header):
|
|
919
|
+
self.vast_version: Tuple[int, ...] = tuple(int(v) for v in m.group(1).split("."))
|
|
920
|
+
return
|
|
921
|
+
else:
|
|
922
|
+
_logger.error("'Server' header '%s' doesn't match the expected pattern", server_header)
|
|
923
|
+
|
|
924
|
+
msg = (
|
|
925
|
+
f'Please use `vastdb` <= 0.0.5.x with current VAST cluster version ("{server_header or "N/A"}"). '
|
|
926
|
+
'To use the latest SDK, please upgrade your cluster to the latest service pack. '
|
|
927
|
+
'Please contact customer.support@vastdata.com for more details.'
|
|
928
|
+
)
|
|
929
|
+
_logger.critical(msg)
|
|
930
|
+
raise NotImplementedError(msg)
|
|
922
931
|
|
|
923
932
|
def __enter__(self):
|
|
924
933
|
"""Allow using this session as a context manager."""
|
|
@@ -935,7 +944,8 @@ class VastdbApi:
|
|
|
935
944
|
secret_key=self.secret_key,
|
|
936
945
|
ssl_verify=self._session.verify,
|
|
937
946
|
timeout=self.timeout,
|
|
938
|
-
backoff_config=self.backoff_config
|
|
947
|
+
backoff_config=self.backoff_config,
|
|
948
|
+
version_check=False)
|
|
939
949
|
|
|
940
950
|
def _single_request(self, *, method, url, skip_status_check=False, **kwargs):
|
|
941
951
|
_logger.debug("Sending request: %s %s %s timeout=%s", method, url, kwargs, self.timeout)
|
|
@@ -1349,12 +1359,12 @@ class VastdbApi:
|
|
|
1349
1359
|
lists = list_tables.GetRootAs(res.content)
|
|
1350
1360
|
tables_length = lists.TablesLength()
|
|
1351
1361
|
count = int(res_headers['tabular-list-count']) if 'tabular-list-count' in res_headers else tables_length
|
|
1352
|
-
return lists, is_truncated, count
|
|
1362
|
+
return lists, next_key, is_truncated, count
|
|
1353
1363
|
|
|
1354
1364
|
def _list_tables_internal(self, bucket, schema, parse_properties, txid=0, client_tags=[], max_keys=1000, next_key=0, name_prefix="",
|
|
1355
1365
|
exact_match=False, expected_retvals=[], include_list_stats=False, count_only=False):
|
|
1356
1366
|
tables = []
|
|
1357
|
-
lists, is_truncated, count = self._list_tables_raw(bucket, schema, txid=txid, client_tags=client_tags, max_keys=max_keys,
|
|
1367
|
+
lists, next_key, is_truncated, count = self._list_tables_raw(bucket, schema, txid=txid, client_tags=client_tags, max_keys=max_keys,
|
|
1358
1368
|
next_key=next_key, name_prefix=name_prefix, exact_match=exact_match, expected_retvals=expected_retvals,
|
|
1359
1369
|
include_list_stats=include_list_stats, count_only=count_only)
|
|
1360
1370
|
bucket_name = lists.BucketName().decode()
|
|
@@ -1368,7 +1378,7 @@ class VastdbApi:
|
|
|
1368
1378
|
return bucket_name, schema_name, tables, next_key, is_truncated, count
|
|
1369
1379
|
|
|
1370
1380
|
def raw_sorting_score(self, bucket, schema, txid, name):
|
|
1371
|
-
lists, _, _ = self._list_tables_raw(bucket, schema, txid=txid, exact_match=True, name_prefix=name, include_list_stats=True)
|
|
1381
|
+
lists, _, _, _ = self._list_tables_raw(bucket, schema, txid=txid, exact_match=True, name_prefix=name, include_list_stats=True)
|
|
1372
1382
|
bucket_name = lists.BucketName().decode()
|
|
1373
1383
|
if not bucket.startswith(bucket_name): # ignore snapshot name
|
|
1374
1384
|
raise ValueError(f'bucket: {bucket} did not start from {bucket_name}')
|
|
@@ -2267,11 +2277,17 @@ def get_field_type(builder: flatbuffers.Builder, field: pa.Field):
|
|
|
2267
2277
|
fb_struct.Start(builder)
|
|
2268
2278
|
field_type = fb_struct.End(builder)
|
|
2269
2279
|
|
|
2270
|
-
elif
|
|
2280
|
+
elif pa.types.is_list(field.type):
|
|
2271
2281
|
field_type_type = Type.List
|
|
2272
2282
|
fb_list.Start(builder)
|
|
2273
2283
|
field_type = fb_list.End(builder)
|
|
2274
2284
|
|
|
2285
|
+
elif pa.types.is_fixed_size_list(field.type):
|
|
2286
|
+
field_type_type = Type.FixedSizeList
|
|
2287
|
+
fb_fixed_size_list.Start(builder)
|
|
2288
|
+
fb_fixed_size_list.AddListSize(builder, field.type.list_size)
|
|
2289
|
+
field_type = fb_fixed_size_list.End(builder)
|
|
2290
|
+
|
|
2275
2291
|
elif isinstance(field.type, pa.MapType):
|
|
2276
2292
|
field_type_type = Type.Map
|
|
2277
2293
|
fb_map.Start(builder)
|
|
@@ -2293,7 +2309,7 @@ def build_field(builder: flatbuffers.Builder, f: pa.Field, name: str):
|
|
|
2293
2309
|
children = None
|
|
2294
2310
|
if isinstance(f.type, pa.StructType):
|
|
2295
2311
|
children = [build_field(builder, child, child.name) for child in list(f.type)]
|
|
2296
|
-
if
|
|
2312
|
+
if pa.types.is_list(f.type) or pa.types.is_fixed_size_list(f.type):
|
|
2297
2313
|
children = [build_field(builder, f.type.value_field, "item")]
|
|
2298
2314
|
if isinstance(f.type, pa.MapType):
|
|
2299
2315
|
children = [
|
|
@@ -6,6 +6,7 @@ import boto3
|
|
|
6
6
|
import pytest
|
|
7
7
|
|
|
8
8
|
import vastdb
|
|
9
|
+
import vastdb.errors
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
def pytest_addoption(parser):
|
|
@@ -65,8 +66,14 @@ def clean_bucket_name(request, test_bucket_name, session):
|
|
|
65
66
|
b = tx.bucket(test_bucket_name)
|
|
66
67
|
for top_schema in b.schemas():
|
|
67
68
|
for s in iter_schemas(top_schema):
|
|
68
|
-
for
|
|
69
|
-
|
|
69
|
+
for t_name in s.tablenames():
|
|
70
|
+
try:
|
|
71
|
+
t = s.table(t_name)
|
|
72
|
+
t.drop()
|
|
73
|
+
except vastdb.errors.NotSupportedSchema:
|
|
74
|
+
# Use internal API to drop the table in case unsupported schema prevents creating a table
|
|
75
|
+
# object.
|
|
76
|
+
tx._rpc.api.drop_table(b.name, s.name, t_name, txid=tx.txid)
|
|
70
77
|
s.drop()
|
|
71
78
|
return test_bucket_name
|
|
72
79
|
|
|
@@ -2,7 +2,9 @@ import logging
|
|
|
2
2
|
import xml.etree.ElementTree
|
|
3
3
|
from dataclasses import dataclass
|
|
4
4
|
from enum import Enum
|
|
5
|
+
from typing import Optional
|
|
5
6
|
|
|
7
|
+
import pyarrow as pa
|
|
6
8
|
import requests
|
|
7
9
|
|
|
8
10
|
|
|
@@ -89,6 +91,9 @@ class ImportFilesError(Exception):
|
|
|
89
91
|
message: str
|
|
90
92
|
error_dict: dict
|
|
91
93
|
|
|
94
|
+
def __post_init__(self):
|
|
95
|
+
self.args = [vars(self)]
|
|
96
|
+
|
|
92
97
|
|
|
93
98
|
class InvalidArgument(Exception):
|
|
94
99
|
pass
|
|
@@ -122,18 +127,27 @@ class NotSupported(Exception):
|
|
|
122
127
|
class MissingBucket(Missing):
|
|
123
128
|
bucket: str
|
|
124
129
|
|
|
130
|
+
def __post_init__(self):
|
|
131
|
+
self.args = [vars(self)]
|
|
132
|
+
|
|
125
133
|
|
|
126
134
|
@dataclass
|
|
127
135
|
class MissingSnapshot(Missing):
|
|
128
136
|
bucket: str
|
|
129
137
|
snapshot: str
|
|
130
138
|
|
|
139
|
+
def __post_init__(self):
|
|
140
|
+
self.args = [vars(self)]
|
|
141
|
+
|
|
131
142
|
|
|
132
143
|
@dataclass
|
|
133
144
|
class MissingSchema(Missing):
|
|
134
145
|
bucket: str
|
|
135
146
|
schema: str
|
|
136
147
|
|
|
148
|
+
def __post_init__(self):
|
|
149
|
+
self.args = [vars(self)]
|
|
150
|
+
|
|
137
151
|
|
|
138
152
|
@dataclass
|
|
139
153
|
class MissingTable(Missing):
|
|
@@ -141,6 +155,9 @@ class MissingTable(Missing):
|
|
|
141
155
|
schema: str
|
|
142
156
|
table: str
|
|
143
157
|
|
|
158
|
+
def __post_init__(self):
|
|
159
|
+
self.args = [vars(self)]
|
|
160
|
+
|
|
144
161
|
|
|
145
162
|
@dataclass
|
|
146
163
|
class MissingProjection(Missing):
|
|
@@ -149,6 +166,9 @@ class MissingProjection(Missing):
|
|
|
149
166
|
table: str
|
|
150
167
|
projection: str
|
|
151
168
|
|
|
169
|
+
def __post_init__(self):
|
|
170
|
+
self.args = [vars(self)]
|
|
171
|
+
|
|
152
172
|
|
|
153
173
|
class Exists(Exception):
|
|
154
174
|
pass
|
|
@@ -159,6 +179,9 @@ class SchemaExists(Exists):
|
|
|
159
179
|
bucket: str
|
|
160
180
|
schema: str
|
|
161
181
|
|
|
182
|
+
def __post_init__(self):
|
|
183
|
+
self.args = [vars(self)]
|
|
184
|
+
|
|
162
185
|
|
|
163
186
|
@dataclass
|
|
164
187
|
class TableExists(Exists):
|
|
@@ -166,6 +189,9 @@ class TableExists(Exists):
|
|
|
166
189
|
schema: str
|
|
167
190
|
table: str
|
|
168
191
|
|
|
192
|
+
def __post_init__(self):
|
|
193
|
+
self.args = [vars(self)]
|
|
194
|
+
|
|
169
195
|
|
|
170
196
|
@dataclass
|
|
171
197
|
class NotSupportedCommand(NotSupported):
|
|
@@ -173,18 +199,37 @@ class NotSupportedCommand(NotSupported):
|
|
|
173
199
|
schema: str
|
|
174
200
|
table: str
|
|
175
201
|
|
|
202
|
+
def __post_init__(self):
|
|
203
|
+
self.args = [vars(self)]
|
|
204
|
+
|
|
176
205
|
|
|
177
206
|
@dataclass
|
|
178
207
|
class NotSupportedVersion(NotSupported):
|
|
179
208
|
err_msg: str
|
|
180
209
|
version: str
|
|
181
210
|
|
|
211
|
+
def __post_init__(self):
|
|
212
|
+
self.args = [vars(self)]
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
@dataclass
|
|
216
|
+
class NotSupportedSchema(NotSupported):
|
|
217
|
+
message: Optional[str] = None
|
|
218
|
+
schema: Optional[pa.Schema] = None
|
|
219
|
+
cause: Optional[Exception] = None
|
|
220
|
+
|
|
221
|
+
def __post_init__(self):
|
|
222
|
+
self.args = [vars(self)]
|
|
223
|
+
|
|
182
224
|
|
|
183
225
|
@dataclass
|
|
184
226
|
class ConnectionError(Exception):
|
|
185
227
|
cause: Exception
|
|
186
228
|
may_retry: bool
|
|
187
229
|
|
|
230
|
+
def __post_init__(self):
|
|
231
|
+
self.args = [vars(self)]
|
|
232
|
+
|
|
188
233
|
|
|
189
234
|
def handle_unavailable(**kwargs):
|
|
190
235
|
if kwargs['code'] == 'SlowDown':
|
|
@@ -192,7 +237,7 @@ def handle_unavailable(**kwargs):
|
|
|
192
237
|
raise ServiceUnavailable(**kwargs)
|
|
193
238
|
|
|
194
239
|
|
|
195
|
-
|
|
240
|
+
HTTP_ERROR_TYPES_MAP = {
|
|
196
241
|
HttpStatus.BAD_REQUEST: BadRequest,
|
|
197
242
|
HttpStatus.FOBIDDEN: Forbidden,
|
|
198
243
|
HttpStatus.NOT_FOUND: NotFound,
|
|
@@ -205,6 +250,10 @@ ERROR_TYPES_MAP = {
|
|
|
205
250
|
HttpStatus.INSUFFICIENT_CAPACITY: InsufficientCapacity,
|
|
206
251
|
}
|
|
207
252
|
|
|
253
|
+
SPECIFIC_ERROR_TYPES_MAP = {
|
|
254
|
+
'TabularUnsupportedColumnType': NotSupportedSchema,
|
|
255
|
+
}
|
|
256
|
+
|
|
208
257
|
|
|
209
258
|
def from_response(res: requests.Response):
|
|
210
259
|
if res.status_code == HttpStatus.SUCCESS.value:
|
|
@@ -234,5 +283,10 @@ def from_response(res: requests.Response):
|
|
|
234
283
|
)
|
|
235
284
|
log.warning("RPC failed: %s", kwargs)
|
|
236
285
|
status = HttpStatus(res.status_code)
|
|
237
|
-
|
|
238
|
-
|
|
286
|
+
http_error_type = HTTP_ERROR_TYPES_MAP.get(status, UnexpectedError)
|
|
287
|
+
http_error = http_error_type(**kwargs) # type: ignore
|
|
288
|
+
# Wrap specific error types if applicable
|
|
289
|
+
if code_str in SPECIFIC_ERROR_TYPES_MAP:
|
|
290
|
+
error_type = SPECIFIC_ERROR_TYPES_MAP[code_str]
|
|
291
|
+
return error_type(message=message_str, cause=http_error)
|
|
292
|
+
return http_error
|
|
@@ -91,6 +91,7 @@ class Schema:
|
|
|
91
91
|
if use_external_row_ids_allocation:
|
|
92
92
|
self.tx._rpc.features.check_external_row_ids_allocation()
|
|
93
93
|
|
|
94
|
+
table.Table.validate_ibis_support_schema(columns)
|
|
94
95
|
self.tx._rpc.api.create_table(self.bucket.name, self.name, table_name, columns, txid=self.tx.txid,
|
|
95
96
|
use_external_row_ids_allocation=use_external_row_ids_allocation,
|
|
96
97
|
sorting_key=sorting_key)
|
|
@@ -109,14 +110,14 @@ class Schema:
|
|
|
109
110
|
log.debug("Found table: %s", t[0])
|
|
110
111
|
return t[0]
|
|
111
112
|
|
|
112
|
-
def _iter_tables(self, table_name=None):
|
|
113
|
+
def _iter_tables(self, table_name=None, page_size=1000):
|
|
113
114
|
next_key = 0
|
|
114
115
|
name_prefix = table_name if table_name else ""
|
|
115
116
|
exact_match = bool(table_name)
|
|
116
117
|
while True:
|
|
117
118
|
_bucket_name, _schema_name, curr_tables, next_key, is_truncated, _ = \
|
|
118
119
|
self.tx._rpc.api.list_tables(
|
|
119
|
-
bucket=self.bucket.name, schema=self.name, next_key=next_key, txid=self.tx.txid,
|
|
120
|
+
bucket=self.bucket.name, schema=self.name, next_key=next_key, max_keys=page_size, txid=self.tx.txid,
|
|
120
121
|
exact_match=exact_match, name_prefix=name_prefix, include_list_stats=exact_match)
|
|
121
122
|
if not curr_tables:
|
|
122
123
|
break
|
|
@@ -124,19 +125,19 @@ class Schema:
|
|
|
124
125
|
if not is_truncated:
|
|
125
126
|
break
|
|
126
127
|
|
|
127
|
-
def tables(self, table_name: str = "") -> List["Table"]:
|
|
128
|
+
def tables(self, table_name: str = "", page_size=1000) -> List["Table"]:
|
|
128
129
|
"""List all tables under this schema if `table_name` is empty.
|
|
129
130
|
|
|
130
131
|
Otherwise, list only the specific table (if exists).
|
|
131
132
|
"""
|
|
132
133
|
return [
|
|
133
134
|
_parse_table_info(table_info, self)
|
|
134
|
-
for table_info in self._iter_tables(table_name=table_name)
|
|
135
|
+
for table_info in self._iter_tables(table_name=table_name, page_size=page_size)
|
|
135
136
|
]
|
|
136
137
|
|
|
137
|
-
def tablenames(self) -> List[str]:
|
|
138
|
+
def tablenames(self, page_size=1000) -> List[str]:
|
|
138
139
|
"""List all table names under this schema."""
|
|
139
|
-
return [table_info.name for table_info in self._iter_tables()]
|
|
140
|
+
return [table_info.name for table_info in self._iter_tables(page_size=page_size)]
|
|
140
141
|
|
|
141
142
|
def drop(self) -> None:
|
|
142
143
|
"""Delete this schema."""
|
|
@@ -126,11 +126,35 @@ class Table:
|
|
|
126
126
|
_imports_table: bool
|
|
127
127
|
sorted_table: bool
|
|
128
128
|
|
|
129
|
+
@staticmethod
|
|
130
|
+
def validate_ibis_support_schema(arrow_schema: pa.Schema):
|
|
131
|
+
"""Validate that the provided Arrow schema is compatible with Ibis.
|
|
132
|
+
|
|
133
|
+
Raises NotSupportedSchema if the schema contains unsupported fields.
|
|
134
|
+
"""
|
|
135
|
+
unsupported_fields = []
|
|
136
|
+
first_exception = None
|
|
137
|
+
for f in arrow_schema:
|
|
138
|
+
try:
|
|
139
|
+
ibis.Schema.from_pyarrow(pa.schema([f]))
|
|
140
|
+
except Exception as e:
|
|
141
|
+
if first_exception is None:
|
|
142
|
+
first_exception = e
|
|
143
|
+
unsupported_fields.append(f)
|
|
144
|
+
|
|
145
|
+
if unsupported_fields:
|
|
146
|
+
raise errors.NotSupportedSchema(
|
|
147
|
+
message=f"Ibis does not support the schema {unsupported_fields=}",
|
|
148
|
+
schema=arrow_schema,
|
|
149
|
+
cause=first_exception
|
|
150
|
+
)
|
|
151
|
+
|
|
129
152
|
def __post_init__(self):
|
|
130
153
|
"""Also, load columns' metadata."""
|
|
131
154
|
self.arrow_schema = self.columns()
|
|
132
155
|
|
|
133
156
|
self._table_path = f'{self.schema.bucket.name}/{self.schema.name}/{self.name}'
|
|
157
|
+
self.validate_ibis_support_schema(self.arrow_schema)
|
|
134
158
|
self._ibis_table = ibis.table(ibis.Schema.from_pyarrow(self.arrow_schema), self._table_path)
|
|
135
159
|
|
|
136
160
|
@property
|
|
@@ -350,12 +374,8 @@ class Table:
|
|
|
350
374
|
if limit_rows:
|
|
351
375
|
config.limit_rows_per_sub_split = limit_rows
|
|
352
376
|
|
|
353
|
-
stats = None
|
|
354
|
-
# Retrieve snapshots only if needed
|
|
355
377
|
if config.data_endpoints is None:
|
|
356
|
-
|
|
357
|
-
log.debug("stats: %s", stats)
|
|
358
|
-
endpoints = stats.endpoints
|
|
378
|
+
endpoints = tuple([self.tx._rpc.api.url])
|
|
359
379
|
else:
|
|
360
380
|
endpoints = tuple(config.data_endpoints)
|
|
361
381
|
log.debug("endpoints: %s", endpoints)
|
|
@@ -385,8 +405,7 @@ class Table:
|
|
|
385
405
|
num_rows = self._get_row_estimate(columns, predicate, query_schema)
|
|
386
406
|
log.debug(f'sorted estimate: {num_rows}')
|
|
387
407
|
if num_rows == 0:
|
|
388
|
-
|
|
389
|
-
stats = self.get_stats()
|
|
408
|
+
stats = self.get_stats()
|
|
390
409
|
num_rows = stats.num_rows
|
|
391
410
|
|
|
392
411
|
config.num_splits = max(1, num_rows // config.rows_per_split)
|
|
@@ -465,7 +484,7 @@ class Table:
|
|
|
465
484
|
|
|
466
485
|
total_num_rows = limit_rows if limit_rows else sys.maxsize
|
|
467
486
|
with concurrent.futures.ThreadPoolExecutor(max_workers=len(endpoints), thread_name_prefix=threads_prefix) as tp: # TODO: concurrency == enpoints is just a heuristic
|
|
468
|
-
futures = [tp.submit(single_endpoint_worker, endpoint) for endpoint in endpoints]
|
|
487
|
+
futures = [tp.submit(single_endpoint_worker, endpoint) for endpoint in endpoints[:config.num_splits]]
|
|
469
488
|
tasks_running = len(futures)
|
|
470
489
|
try:
|
|
471
490
|
while tasks_running > 0:
|
|
@@ -513,16 +532,24 @@ class Table:
|
|
|
513
532
|
columns_name_chunk = columns_names[start:end]
|
|
514
533
|
columns_chunks = columns[start:end]
|
|
515
534
|
arrays_chunks = arrays[start:end]
|
|
516
|
-
columns_chunks.append(INTERNAL_ROW_ID_FIELD)
|
|
535
|
+
columns_chunks.append(INTERNAL_ROW_ID_SORTED_FIELD if self.sorted_table else INTERNAL_ROW_ID_FIELD)
|
|
517
536
|
arrays_chunks.append(row_ids.to_pylist())
|
|
518
537
|
column_record_batch = pa.RecordBatch.from_arrays(arrays_chunks, schema=pa.schema(columns_chunks))
|
|
519
538
|
self.update(rows=column_record_batch, columns=columns_name_chunk)
|
|
520
539
|
return row_ids
|
|
521
540
|
|
|
522
|
-
def insert(self, rows: Union[pa.RecordBatch, pa.Table]):
|
|
541
|
+
def insert(self, rows: Union[pa.RecordBatch, pa.Table], by_columns: bool = False):
|
|
523
542
|
"""Insert a RecordBatch into this table."""
|
|
524
543
|
if self._imports_table:
|
|
525
544
|
raise errors.NotSupportedCommand(self.bucket.name, self.schema.name, self.name)
|
|
545
|
+
if 0 == rows.num_rows:
|
|
546
|
+
log.debug("Ignoring empty insert into %s", self.name)
|
|
547
|
+
return pa.chunked_array([], type=(INTERNAL_ROW_ID_SORTED_FIELD if self.sorted_table else INTERNAL_ROW_ID_FIELD).type)
|
|
548
|
+
|
|
549
|
+
if by_columns:
|
|
550
|
+
self.tx._rpc.features.check_return_row_ids()
|
|
551
|
+
return self.insert_in_column_batches(rows)
|
|
552
|
+
|
|
526
553
|
try:
|
|
527
554
|
row_ids = []
|
|
528
555
|
serialized_slices = util.iter_serialized_slices(rows, MAX_INSERT_ROWS_PER_PATCH)
|
|
@@ -535,7 +562,7 @@ class Table:
|
|
|
535
562
|
self.tx._rpc.features.check_return_row_ids()
|
|
536
563
|
except errors.NotSupportedVersion:
|
|
537
564
|
return # type: ignore
|
|
538
|
-
return pa.chunked_array(row_ids)
|
|
565
|
+
return pa.chunked_array(row_ids, type=(INTERNAL_ROW_ID_SORTED_FIELD if self.sorted_table else INTERNAL_ROW_ID_FIELD).type)
|
|
539
566
|
except errors.TooWideRow:
|
|
540
567
|
self.tx._rpc.features.check_return_row_ids()
|
|
541
568
|
return self.insert_in_column_batches(rows)
|
|
@@ -619,6 +646,7 @@ class Table:
|
|
|
619
646
|
"""Add a new column."""
|
|
620
647
|
if self._imports_table:
|
|
621
648
|
raise errors.NotSupportedCommand(self.bucket.name, self.schema.name, self.name)
|
|
649
|
+
self.validate_ibis_support_schema(new_column)
|
|
622
650
|
self.tx._rpc.api.add_columns(self.bucket.name, self.schema.name, self.name, new_column, txid=self.tx.txid)
|
|
623
651
|
log.info("Added column(s): %s", new_column)
|
|
624
652
|
self.arrow_schema = self.columns()
|