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.
Files changed (186) hide show
  1. {vastdb-0.1.5 → vastdb-0.1.6}/CHANGELOG.md +12 -0
  2. {vastdb-0.1.5/vastdb.egg-info → vastdb-0.1.6}/PKG-INFO +1 -1
  3. {vastdb-0.1.5 → vastdb-0.1.6}/setup.py +1 -1
  4. {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/bench/test_perf.py +1 -2
  5. {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/bucket.py +12 -37
  6. {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/conftest.py +13 -4
  7. {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/errors.py +5 -1
  8. {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/internal_commands.py +1 -20
  9. {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/schema.py +45 -0
  10. {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/session.py +24 -8
  11. {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/table.py +18 -6
  12. {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/tests/test_imports.py +3 -3
  13. {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/tests/test_nested.py +4 -4
  14. vastdb-0.1.6/vastdb/tests/test_projections.py +121 -0
  15. {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/tests/test_schemas.py +49 -0
  16. {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/tests/test_tables.py +53 -28
  17. {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/transaction.py +23 -14
  18. {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/util.py +1 -0
  19. {vastdb-0.1.5 → vastdb-0.1.6/vastdb.egg-info}/PKG-INFO +1 -1
  20. vastdb-0.1.5/vastdb/tests/test_projections.py +0 -43
  21. {vastdb-0.1.5 → vastdb-0.1.6}/LICENSE +0 -0
  22. {vastdb-0.1.5 → vastdb-0.1.6}/MANIFEST.in +0 -0
  23. {vastdb-0.1.5 → vastdb-0.1.6}/README.md +0 -0
  24. {vastdb-0.1.5 → vastdb-0.1.6}/requirements.txt +0 -0
  25. {vastdb-0.1.5 → vastdb-0.1.6}/setup.cfg +0 -0
  26. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/__init__.py +0 -0
  27. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/__init__.py +0 -0
  28. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/__init__.py +0 -0
  29. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/__init__.py +0 -0
  30. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/__init__.py +0 -0
  31. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Aggregate.py +0 -0
  32. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/ArraySlice.py +0 -0
  33. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/ArraySubscript.py +0 -0
  34. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/BinaryLiteral.py +0 -0
  35. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/BooleanLiteral.py +0 -0
  36. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Bound.py +0 -0
  37. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Call.py +0 -0
  38. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/CaseFragment.py +0 -0
  39. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Cast.py +0 -0
  40. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/ConcreteBoundImpl.py +0 -0
  41. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/ConditionalCase.py +0 -0
  42. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/CurrentRow.py +0 -0
  43. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/DateLiteral.py +0 -0
  44. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/DecimalLiteral.py +0 -0
  45. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Deref.py +0 -0
  46. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/DurationLiteral.py +0 -0
  47. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Expression.py +0 -0
  48. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/ExpressionImpl.py +0 -0
  49. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/FieldIndex.py +0 -0
  50. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/FieldRef.py +0 -0
  51. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Filter.py +0 -0
  52. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/FixedSizeBinaryLiteral.py +0 -0
  53. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Float16Literal.py +0 -0
  54. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Float32Literal.py +0 -0
  55. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Float64Literal.py +0 -0
  56. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Following.py +0 -0
  57. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Frame.py +0 -0
  58. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Grouping.py +0 -0
  59. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Int16Literal.py +0 -0
  60. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Int32Literal.py +0 -0
  61. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Int64Literal.py +0 -0
  62. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Int8Literal.py +0 -0
  63. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/IntervalLiteral.py +0 -0
  64. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/IntervalLiteralDaysMilliseconds.py +0 -0
  65. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/IntervalLiteralImpl.py +0 -0
  66. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/IntervalLiteralMonths.py +0 -0
  67. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Join.py +0 -0
  68. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/JoinKind.py +0 -0
  69. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/KeyValue.py +0 -0
  70. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Limit.py +0 -0
  71. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/ListLiteral.py +0 -0
  72. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Literal.py +0 -0
  73. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/LiteralColumn.py +0 -0
  74. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/LiteralImpl.py +0 -0
  75. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/LiteralRelation.py +0 -0
  76. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/MapKey.py +0 -0
  77. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/MapLiteral.py +0 -0
  78. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/OrderBy.py +0 -0
  79. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Ordering.py +0 -0
  80. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Plan.py +0 -0
  81. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Preceding.py +0 -0
  82. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Project.py +0 -0
  83. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/RelId.py +0 -0
  84. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Relation.py +0 -0
  85. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/RelationImpl.py +0 -0
  86. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/SetOpKind.py +0 -0
  87. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/SetOperation.py +0 -0
  88. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/SimpleCase.py +0 -0
  89. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/SortKey.py +0 -0
  90. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Source.py +0 -0
  91. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/StringLiteral.py +0 -0
  92. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/StructField.py +0 -0
  93. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/StructLiteral.py +0 -0
  94. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/TimeLiteral.py +0 -0
  95. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/TimestampLiteral.py +0 -0
  96. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/UInt16Literal.py +0 -0
  97. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/UInt32Literal.py +0 -0
  98. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/UInt64Literal.py +0 -0
  99. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/UInt8Literal.py +0 -0
  100. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/Unbounded.py +0 -0
  101. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/WindowCall.py +0 -0
  102. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/computeir/flatbuf/__init__.py +0 -0
  103. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Binary.py +0 -0
  104. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Block.py +0 -0
  105. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/BodyCompression.py +0 -0
  106. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/BodyCompressionMethod.py +0 -0
  107. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Bool.py +0 -0
  108. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Buffer.py +0 -0
  109. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/CompressionType.py +0 -0
  110. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Date.py +0 -0
  111. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/DateUnit.py +0 -0
  112. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Decimal.py +0 -0
  113. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/DictionaryBatch.py +0 -0
  114. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/DictionaryEncoding.py +0 -0
  115. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/DictionaryKind.py +0 -0
  116. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Duration.py +0 -0
  117. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Endianness.py +0 -0
  118. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Feature.py +0 -0
  119. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Field.py +0 -0
  120. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/FieldNode.py +0 -0
  121. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/FixedSizeBinary.py +0 -0
  122. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/FixedSizeList.py +0 -0
  123. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/FloatingPoint.py +0 -0
  124. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Footer.py +0 -0
  125. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Int.py +0 -0
  126. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Interval.py +0 -0
  127. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/IntervalUnit.py +0 -0
  128. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/KeyValue.py +0 -0
  129. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/LargeBinary.py +0 -0
  130. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/LargeList.py +0 -0
  131. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/LargeUtf8.py +0 -0
  132. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/List.py +0 -0
  133. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Map.py +0 -0
  134. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Message.py +0 -0
  135. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/MessageHeader.py +0 -0
  136. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/MetadataVersion.py +0 -0
  137. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Null.py +0 -0
  138. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Precision.py +0 -0
  139. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/RecordBatch.py +0 -0
  140. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Schema.py +0 -0
  141. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/SparseMatrixCompressedAxis.py +0 -0
  142. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/SparseMatrixIndexCSX.py +0 -0
  143. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/SparseTensor.py +0 -0
  144. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/SparseTensorIndex.py +0 -0
  145. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/SparseTensorIndexCOO.py +0 -0
  146. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/SparseTensorIndexCSF.py +0 -0
  147. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Struct_.py +0 -0
  148. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Tensor.py +0 -0
  149. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/TensorDim.py +0 -0
  150. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Time.py +0 -0
  151. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/TimeUnit.py +0 -0
  152. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Timestamp.py +0 -0
  153. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Type.py +0 -0
  154. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Union.py +0 -0
  155. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/UnionMode.py +0 -0
  156. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/Utf8.py +0 -0
  157. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/org/apache/arrow/flatbuf/__init__.py +0 -0
  158. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/tabular/AlterColumnRequest.py +0 -0
  159. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/tabular/AlterProjectionTableRequest.py +0 -0
  160. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/tabular/AlterSchemaRequest.py +0 -0
  161. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/tabular/AlterTableRequest.py +0 -0
  162. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/tabular/Column.py +0 -0
  163. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/tabular/ColumnType.py +0 -0
  164. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/tabular/CreateProjectionRequest.py +0 -0
  165. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/tabular/CreateSchemaRequest.py +0 -0
  166. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/tabular/GetProjectionTableStatsResponse.py +0 -0
  167. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/tabular/GetTableStatsResponse.py +0 -0
  168. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/tabular/ImportDataRequest.py +0 -0
  169. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/tabular/ListProjectionsResponse.py +0 -0
  170. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/tabular/ListSchemasResponse.py +0 -0
  171. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/tabular/ListTablesResponse.py +0 -0
  172. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/tabular/ObjectDetails.py +0 -0
  173. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/tabular/S3File.py +0 -0
  174. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/tabular/VipRange.py +0 -0
  175. {vastdb-0.1.5 → vastdb-0.1.6}/vast_flatbuf/tabular/__init__.py +0 -0
  176. {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/__init__.py +0 -0
  177. {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/bench/__init__.py +0 -0
  178. {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/tests/__init__.py +0 -0
  179. {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/tests/test_duckdb.py +0 -0
  180. {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/tests/test_sanity.py +0 -0
  181. {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/tests/test_util.py +0 -0
  182. {vastdb-0.1.5 → vastdb-0.1.6}/vastdb/tests/util.py +0 -0
  183. {vastdb-0.1.5 → vastdb-0.1.6}/vastdb.egg-info/SOURCES.txt +0 -0
  184. {vastdb-0.1.5 → vastdb-0.1.6}/vastdb.egg-info/dependency_links.txt +0 -0
  185. {vastdb-0.1.5 → vastdb-0.1.6}/vastdb.egg-info/requires.txt +0 -0
  186. {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,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vastdb
3
- Version: 0.1.5
3
+ Version: 0.1.6
4
4
  Summary: VAST Data SDK
5
5
  Home-page: https://github.com/vast-data/vastdb_sdk
6
6
  Author: VAST DATA
@@ -29,7 +29,7 @@ setup(
29
29
  name='vastdb',
30
30
  python_requires='>=3.9.0',
31
31
  description='VAST Data SDK',
32
- version='0.1.5' + suffix,
32
+ version='0.1.6' + suffix,
33
33
  url='https://github.com/vast-data/vastdb_sdk',
34
34
  author='VAST DATA',
35
35
  author_email='hello@vastdata.com',
@@ -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 = pa.Table.from_batches(t.select(columns=['sid'], predicate=t['sid'] == 10033007, config=config))
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 create_schema(self, path: str, fail_if_exists=True) -> "Schema":
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
- if current := self.schema(path, fail_if_missing=False):
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, path: str, fail_if_missing=True) -> Optional["Schema"]:
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
- s = self.schemas(path)
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, name: Optional[str] = None) -> List["Schema"]:
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 s in b.schemas():
38
- for t in s.tables():
39
- t.drop()
40
- s.drop()
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
 
@@ -89,7 +89,11 @@ class InvalidArgument(Exception):
89
89
  pass
90
90
 
91
91
 
92
- class TooWideRow(InvalidArgument):
92
+ class TooLargeRequest(InvalidArgument):
93
+ pass
94
+
95
+
96
+ class TooWideRow(TooLargeRequest):
93
97
  pass
94
98
 
95
99
 
@@ -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
- def check_imports_table(self):
25
- """Check if the feature that support imports table is supported."""
26
- if self.vast_version < (5, 2):
27
- raise errors.NotSupportedVersion("import_table requires 5.2+", self.vast_version)
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
- def check_return_row_ids(self):
30
- """Check if insert/update/delete can return the row_ids."""
31
- if self.vast_version < (5, 1):
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
- num_splits: int = 1
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 stats.num_rows > config.rows_per_split and config.num_splits is None:
319
- config.num_splits = stats.num_rows // config.rows_per_split
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 = pa.Table.from_batches(t.select(columns=['num']))
41
+ arrow_table = t.select(columns=['num']).read_all()
42
42
  assert arrow_table.num_rows == num_rows * num_files
43
- arrow_table = pa.Table.from_batches(t.select(columns=['num'], predicate=t['num'] == 100))
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 = pa.Table.from_batches(import_table.select(columns=["ObjectName"]))
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 = pa.Table.from_batches(t.select())
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 = pa.Table.from_batches(t.select(columns=cols))
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 = pa.Table.from_batches(t.select())
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 = pa.Table.from_batches(t.select(predicate=ibis_predicate), t.arrow_schema)
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